Skip to main content

Особенности Safari в client-side атаках

By 12 декабря 2017Blog

Что делает браузер, чтобы открыть страницу? Для начала, он отправляет запрос DNS серверу, чтобы узнать, с каким IP ему иметь дело.  Как известно, DNS-сервер может отвечать на произвольный запрос, если такая настройка (wildcard) присутствует.

Например, воспользовавшись утилитой dig попробуй отправить такой запрос:

dig "x^x`<\">'\!x=x.yandex.ru" A

DNS сервер вернет IP адрес.

Но что будет, если перенаправить пользователя на такой домен в браузере? Будет ли браузер вообще пытаться открыть такой URL? Конечно нет! Браузер перед отправкой запроса проверяет,  является ли строка доменным именем!

Только если это не Safari…

Потому что может

Особое свойство Safari — он посылает DNS запрос, даже если у доменного имени присутствуют спецсимволы. Правда и CURL не имеет механизма проверки подлинности домена, но этой утилите можно простить. Подобное поведение порождает целый класс client-side уязвимостей, о которых мы сейчас и поговорим.
Чтобы убедиться, наличие такой суперсилы можно проверить на домене hsts.pro. Safari будет пытаться открывать ресурс, если помимо букв и цифр содержатся следующие спецсимволы:

Вот попробуй —
http://!"$&'()*+,-;<=>^_`{|}~.hsts.pro
(разумеется, только для Safari и если DNS сервер, который ты используешь дает ответ, например 8.8.8.8 отвечает корректно).

Более того, туда можно записать и непечатаемые символы:
%01-%08, %0b-%0c, %0e-1f, %7f.

XSS via Host header

Если на страницу попадает текущий домен, к примеру, с помощью $_SERVER[‘HTTP_HOST’], то можно попробовать провести внедрение произвольного javascript сценария. Разумеется, уязвимое веб-приложение должно отвечать на такой поддомен. Из других минусов — как выяснилось при тестах, некоторые DNS сервера не позволяют отправлять символы “(“ и “)”. Если не пускает скобки, используем фичу js — шаблонные строки. Чтобы вызвать функцию, например, alert() — достаточно использовать вместо скобок символ бэктика — alert``.
А такие символы как “/”, символ пробела или табуляции и вовсе не могут быть частью доменного имени. Однако, так как мы имеем доступ и к управляющим символам, пробел может заменить символ смены страницы — %0c. Символ перевода курсора на новую страницу, в нашем случае, будет равнозначным с пробелом.

Таким образом, ссылка вида
http://a">'><img%0csrc%0conerror=alert``>a.hsts.pro
будет корректно воспринята браузером и в качестве домена, и в качестве тега при попадании в html, а значит, если не будет мешать XSS Auditor — функция alert выполнится.

Дальше — проще, если понадобится указать “/” внутри атрибута — можно использовать, например, его мнемоник — &sol;

Cookie Injection

Другой, очевидный вариант использования, это инъекция в Cookie. Если в домене будет содержаться знак «;» — это даст возможность отрезать часть заголовка и внедрить свою логику, если заголовок создания cookie также зависит от заголовка HOST. Использование подобного когда во многих проектах — норма:

Даже если XSS отсутствует и ты видишь, что приходит заголовок Set-Cookie с атрибутом domain, попробуй изменить домен таким образом, чтобы выполнить инъекцию.
Более того, (как уже показывал Black2Fan) — Safari имеет еще одну забавную фичу — перечисление нескольких Cookie в одном заголовке Set-Cookie через запятую. Поэтому, используя специально сформированную ссылку можно устанавливать произвольные Cookie в браузер жертвы, закрыв предыдущую печеньку символом “;”, а через запятую перечислить куки, которые ты хочешь установить.

XSS via Referer

Всем известно, что браузеры преобразуют спецсимволы в их URLEncode представления, поэтому даже если содержимое Referer попадает на страницу, перенаправить пользователя с страницы
site/<script>alert()</script>.html
и выполнить XSS не получится, так как до веб-приложения этот заголовок дойдет как
Referer: http://site/%3Cscript%3Ealert()%3C%2Fscript%3E.html
На сайте я оставил r.php с параметром u, который можно использовать для перенаправлений. Попробуй перейти сюда:
http://hsts.pro/r.php?u=//hsts.pro/referer.php&xss=<script>alert()</script>

Но все меняется, если жертва использует Safari. Ведь все спецсимволы, которые содержатся в доменном имени будут проходить функцию URLDecode, и придут в заголовке на уязвимую страницу в подходящем для нас виде.

А чтобы убедиться, что все работает — вот тебе ссылка:
http://a<img%0csrc=x%0conerror=alert``>.hsts.pro/r.php?u=//hsts.pro/referer.php

Что-то еще?

А как поведет себя веб-сервер, получив в качестве заголовка Origin спецсимволы, которых в принципе в домене быть не может (ну мы-то знаем)?
Как уже выяснил один из охотников на ошибки, символ бэктика (%60), мог обойти проверку заголовка Origin и смог выполнить XHR запрос в обход логики работы веб-приложения на одном из серверов Yahoo — вжух.

Поэтому, кто знает, как поведет себя тот или иной сайт, если в заголовке Origin будут присутствовать посторонние символы. Рекомендую в первую очередь проверить:
victim.com&.evil.domain
victim.com`.evil.domain
victim.com%01.evil.domain

А напоследок

Забавно, что Safari все больше и больше превращается в Internet Explorer. До этого Host Header XSS и обход URLEncode были только в нем, но теперь вектор атаки расширился на пользователей MacOS. Если ты придумал, как еще использовать подобное поведение браузера — обязательно напиши об этом в комментариях.

Обязательно попробуй подобные атаки на BugBounty, авось 😉

Join the discussion 3 комментария

Leave a Reply