Уже на протяжении довольно длительного времени я охочусь за уязвимостями на платформе HackerOne, выделяю некоторое количество времени вне основной работы, чтобы проверить любимые и новые программы. Бесчисленное количество раз приходилось натыкаться на cookie-based XSS уязвимость, которая и станет главной героиней этой статьи. Данный тип уязвимости возникает, когда значение параметра cookie рефлектится на страницу. По умолчанию они считаются self-XSS, если мы, в свою очередь, не докажем их опасность. Собственно, сегодня я расскажу, как эксплуатировать cookie-based XSS уязвимости, а также приведу пример из тестирования одной компании, от которой я получил $7300 в целом за исследование.
Для того, чтобы выполнить javascript на стороне пользователя, необходимо найти способ установки cookie и, если потребуется, заманить жертву на страницу, где, в свою очередь, внедряется кука. Возможные способы эксплуатации данного бага:
⠀1. CRLF injection. Данная уязвимость возникает, когда отсутствует надлежащая проверка и блокировка символов переноса строки. Мы можем внедрить хедер Set-cookie в ответ с желаемым названием, а также значением куки и установить её в браузере. Пример из реальной жизни: Скользкая CRLF injection на домене twitter.com в редиректе, - https://twitter.com/login?redirect_after_login=/jjjkkk嘊嘍Set-Cookie:jjjjj=a;domain=twitter.com
Репорты о данном типе уязвимости можно почитать на HackerOne hackerone.com/hacktivity?order_direction=DESC&order_field=popular&filter=type%3Apublic&querystring=crlf%20injection
2. XSS уязвимость на поддомене. Необходимо, чтобы XSS была общедоступна и находилась на wildcard *.vulnerabledomain.com. Для многих bug bounty программ поддомены - это out of scope, тоесть в большинстве случаев баги либо вообще не принимают, либо же принимают с пометкой «not eligible for the bounty». В таких случаях отступать не следует, но ради связки с cookie-based XSS можно инвестировать своё время на поиск XSS, чтобы получить вознаграждение. Если XSS обнаружена, мы можем устанавливать или удалять куку с помощью document.cookie функции.
Повышение импакта: Зачастую жертва доверяет главному домену vulnerabledomain.com больше, чем, например, jira.vulnerabledomain.com, да ещё и с URL /plugins/servlet/oauth/users/icon-uri?consumerUri=https://maliciousdomain.com. С большей вероятностью она перейдет на главный домен, нежели чем на поддомен, если этот поддомен не связан с личным кабинетом или авторизацией. Исходя из вышеизложенного, мы можем использовать in-site редирект функциональность для редиректа на поддомен vulnerabledomain.com/login?redirectUrl=https://jira.vulnerabledomain.com/path для лучшего эффекта.
Если у жертвы есть активная сессия, редирект будет автоматическим, если нет,- нужна авторизация. Когда юзер кликнет по такой ссылке, кука будет установлена и с поддомена, на которой присутствует Reflected XSS его можно будет направить дальше по течению - на страницу с cookie-based XSS, где может сработать эксплойт, который, в свою очередь, схватит значение CSRF токена и выполнит запрос на смену email адреса. Таким образом, связка двух XSS уязвимостей может привести к account takeover, если не возникнет попутных проблем, таких как дополнительное подтверждение смены email паролем или кодом со старого ящика.
3. Обнаружение тестовых файлов, которые позволяют устанавливать куки. Достаточно расчехлить тулзу обнаружения контента (dirb, dirserach, etc), начать копать и, если разработчики забыли выполнить очистку, то можно наткнуться на подобные файлы.
Недавно я обнаружил тестовую servlet html страницу, на которой возможно было устанавливать куку с произвольным именем и значением. Защита на POST запросе, конечно же, отсутствовала, поэтому если жертва посетила бы CSRF эксплойт (или можно поменять POST на GET), появилась бы возможность установить куку в её браузере.
Этот баг квалифицировали как недо-альтернативу CRLF injection, пофиксили удалением /examples/ и выплатили $150 как за low-severity bug. Хотя h1 triager поставил medium, разработчики все-таки склонились к тому, что это low severity.
4. Man in the middle attack (MITM). Данный способ возможно применить только в случае отсутствия secure флага на cookie. Если вы не знаете, что это за флаг или просто хотите освежить память, советую просмотреть презентацию «Cookie security» с OWASP London 2017 www.owasp.org/images/a/a0/OWASPLondon20171130_Cookie_Security_Myths_Misconceptions_David_Johansson.pdf.
Для успешной атаки необходимо, чтобы жертва находилась в сети атакующего или на резолвинг dns можно было бы повлиять. Для того, чтобы проверить уязвимость, необходимо:
1) захостить файл index.php со следующим содержимым:
<?php if ($_SERVER['HTTP_HOST'] == 'non-existed-subdomain.vulnerabledomain.com') { setrawcookie("VID",'\'+alert(123123123)+\'', time()+36000, "/", ".vulnerabledomain.com",0,1); } ?>
2) Добавить в ваш /etc/hosts/ файл следующую строку: 127.0.0.1 non-existed-subdomain.vulnerabledomain.com
3) Посетить non-existed-subdomain.vulnerabledomain.com и после открыть страницу, на которой рефлектится кука.
Замечательный пример MITM эксплуатации на e.mail.ru, - https://hackerone.com/reports/312548,- как можно заметить, MITM хватило для доказательства небольшой опасности уязвимости, но награда не соответствовала уровню Stored XSS, так как был показан только «локальный» способ эксплуатации, то есть не «in-the-wild». Если бы исследователь потратил немного времени на поиск XSS или CRLF injection (которых бесчисленное количество), находящихся на *.mail.ru, можно было бы несколько увеличить награду.
Но далеко не все программы на hackerone принимают cookie-based XSS через MITM. Если в scope exclusions говорится «Self XSS», то данную эксплуатацию могут посчитать как Self XSS и выставить informative или n/a, что не всегда приятно. Сейчас я расскажу о подобном случае, который произошел со мной во время очередной охоты на платформе.
Тестируя сайт, я внезапно увидел, что значение куки redacted отражается на одной из поддиректорий сайта. Первое, что я сделал - проверил отображение символов ' "/<>. Выяснилось, что фильтруются только символы <>, а это говорит нам о том, что мы не можем выйти за пределы , но так же становится понятно, что остальные символы не фильтруются. Долго не думая внедряем '-alert(document.domain)-' и js выполняется.
Так как разработчики не наделили cookie флагом secure, в данном случае действует MITM способ. Было принято решение отправить репорт в программу cо следующим импактом:
HackerOne staff (triager) дал четко понять, что это self-XSS и я должен try-harder:
После этого я принялся бороздить просторы сайта и пытаться найти CRLF injection или XSS, чтобы доказать опасность.
⠀Пришлось расширить список поддоменов с помощью брута по большому словарю, скрапингу поддоменов с SSL сертификатов и с помощью некоторых других уловок. Результат не заставил себя долго ждать, так как большинство тулзов я запускаю c VPS. Время от времени попутно так же обнаруживались другие баги, которые я репортил, делая in-scope из out-of-scope, если нужно. Попадалось много Open Redirect-ов и даже Improper Access Control баг на $5000, но нужных уязвимостей для связки все никак не удавалось поймать. Выше упомянутый баг довольно интересный и опасный, целый поддомен увели в офлайн сразу после репорта, возможно, в будущем раскрою репорт на странице hackerone.com/w2w, если программа станет публичной.
Спустя неделю были проверены результаты скрипта для обнаружения контента, где нашелся эндпоинт /verification, которому я сначала не придал особого значения, но все же натравил на него скрипт,- обнаружилась поддиректория /verification/login. После перехода показывалась страница /verification/login/?redirect_uri=https://vulnerabledomain.com, которая перенаправляла к значению redirect_uri после входа или сразу редиректила, если была сессия. После полета в интрудер обнаружился обход open redirect protection, - vulnerabledomain.com@anotherdomain.com. Попытался раскрутить баг до XSS - пейлоад javascript:alert(1) потерпел неудачу, javascript:alert(1)// тоже. А вот пейлоад javascript://https://vulnerablesite.com/%250A1?alert(1):0 выстрелил, потому что из-за присутствия vulnerablesite.com, параметр прошел white-list валидацию.
После безумного вождения мышью по окну оповещения (всегда так делаю), я сразу же принялся за свою cookie-based XSS. С помощью javascript:https://vulnerabledomain.com/%0A1?document%2ecookie%20%3d%20%27SID%3d137gf6g67f76fg6766123%5c%27-alert%28document%2edomain%29-%5c%27%3b%20expires%3dFri%2c%203%20Aug%202019%2020%3a47%3a11%20UTC%3b%20path%3d%2f%3b%20domain%3d%2evulnerabledomain%2ecom%3b%27%3a0 кука успешно садилась на *.vulnerabledomain.com. После перехода на страницу с кукой вылетел заветный алерт! Double XSS, ура! :) Я дополнил репорт и стал ждать ответа.
В этот же день прилетела «Nice catch» от триаджера (если можно это так назвать), и bounty была выплачена. Благослови Господи компании, которые платят на triage!
За DOM based XSS, с помощью которой я устанавливал куку, тоже прилетела bounty.
Итоги тестирования
$1000 + $1000 + $200 (OR)+ $100(OR) = $2300
Данная программа функционирует уже больше года, но менее чем за месяц я смог занять в ней первое место и уйти с тестированием довольно далеко,- попытался пофазить большинство эндпойнтов, оценить их реакцию, понять, как работает сайт и даже тестировал desktop приложение. Эта баг баунти программа стала одной из самых любимых на HackerOne. Надеюсь и вы тоже когда-нибудь найдете ту самую! :)
Также, именно эта программа дала мне новый буст(mail.ru - первый), - с помощью него я добрался до 2500 репутации (привет hoodie) и попал на 36-е место в лидерборде по репутации за 90 дней, что должно дать свежие приватки. Хотя, кажется, приватки прилетают независимо от присутствия в лидерборде, я часто отменяю старые приватки и жду новые в очереди.
Краткий бриф
- Cookie-based XSS вполне эксплуатирумые. Если постараться и копнуть немного глубже, то можно получить баунти вместо n/a, уничтожения сигнала и -5 к репутации.
- Если программа старая, это не значит, что в ней не будет уязвимостей. Если плоды долго висят на дереве, low-hanging фрукты сорвут и сразу же заберут домой (subdomain takeovers, др). Другие же фрукты продолжают висеть, но повыше. Для того, чтобы их достать, нужно приложить некоторые усилия.
- Иногда лучше сосредоточиться на одной программе на долгое время, найти максимально много уязвимостей и мониторить ее. Лучше найти ту программу, которая вам больше по душе и ломать её.
- Упорство и желание понять, как работает веб приложение, а так же те или иные функциональности и их взаимодействие между собой- это ключ для успешного поиска уязвимостей в баг баунти.
Если вы хотите быть в курсе моих последних статей и новостей, советую подписаться на телеграм канал / твиттер, ссылки на которые можно найти внизу.