Содержание статьи
Все шире и шире получают распространение Bug Bounty программы — программы вознаграждения за уязвимости различных вендоров. И порой при поиске уязвимостей находятся места, которые явно небезопасны (например — self-XSS), но доказать от них угрозу сложно. Но чем крупнее (хотя, скорее, адекватнее) вендор (например, Google), тем он охотнее обсуждает и просит показать угрозу от сообщенной уязвимости и при успехе — вознаграждает :). Эта статья — подборка сложных ситуаций и рассказ, как же можно доказать угрозу и сделать интернет безопаснее.
DNS Misconfiguration
Суть уязвимости заключается в присутствии в записях о доменах поддоменов, указывающих на адреса, принадлежащие локальной сети.
Предположим, что при переборе поддоменов мы нашли что-то вроде local.target.com, который указывает на адрес 127.0.0.1 (или просто на IP из локальной сети).
Рассмотрим случай, когда поддомен указывает на адрес 127.0.0.1. Предположим, что у нас есть какая-то организация, работающая через тонкие клиенты, соответственно, сотрудники «сидят» на одной машине, у которой IP-адрес 127.0.0.1. В таком случае атакующим может быть локальный пользователь данной системы. Для реализации атаки злоумышленнику необходимо забиндить порт на «верхних» уровнях, например 10024 (так как «нижние» порты потребуют соответствующих привилегий). После чего злоумышленник отправляет жертве (другому пользователю этой же системы) письмо, в котором содержатся ресурсы, подгружающиеся с адреса уязвимой системы, указывающего на локальный IP, например <img src = http://local.target.com:10024/>
. Как только жертва откроет письмо, то она попытается подгрузить картинку с **.target.com, передав злоумышленнику свои куки, которые успешно подхватит открытый ранее снифер, хотя можно обойтись и netcat. Еще небольшой трюк: часто на подобных системах, да и не только, установлена служба CUPS (для принтеров), в интерфейсе которой есть множество XSS. В таком случае эксплуатацией ошибки с локальным адресом одного из поддоменов может воспользоваться и удаленный атакующий. Например, заставив пользователя перейти по такой ссылке:http://local.target.com:631/jobs/?job_id=&job_printer_name=Click%20Me&job_printer_uri=javascript:alert(document.cookie)
, можно провести XSS и получить куки *.target.com.
В случае если домен указывает на IP из локальной сети, можно показать следующий вектор: находясь в одной локальной сети с жертвой, можно занять нужный IP-адрес поддомена и попросить пользователя перейти по ссылке.
За подобную находку Шимон Грушецкий (Szymon Gruszecki) получил 100 долларов в селф-баунти hackerone (репорт 1509).
Self-XSS
XSS-атака — одна из самых популярных в вебе. Суть состоит в том, чтобы внедрить свой JavaScript на страницу, которую откроет жертва. Self-XSS — подвид XSS-атак, суть аналогична, но отрабатывает только в браузере атакующего.
Представь себе, что ты можешь где-то подставить JavaScript, он успешно отрабатывает, но… только для тебя! То есть XSS-атаку провести можно, но только против самого себя. Очень глупая ситуация :). А теперь давай сообразим вектор. Представим сайт target.com, где авторизована жертва. Чаще всего мы можем разлогинить жертву через CSRF (шаг 1), затем залогинить ее под собой, также через CSRF (шаг 2, да, мы «спалим» свои креды, но это неважно). Итак, состояние: жертва залогинена на target.com, где мы подставляем наш JavaScript. Следующий шаг (номер 3) таков, что мы просто рисуем окошко с авторизацией и сообщением наподобие «Ваша сессия истекла» (через уже имеющийся JS) на сайте (URL совпадает, выглядит легитимно!) и логируем вводимые данные (логин:пароль) жертвой на нашем сервере. «Нереально», — скажешь ты, но будешь не прав. Есть человек, которому подобный вектор засчитали, возможно за волю к победе, но малый процент успешности атаки против других пользователей был доказан!
![Статья от ONsec_lab про домены, указывающие на IP-адрес из локальной сети. С некоторым списком](https://xakep.ru/wp-content/uploads/2014/10/local.png)
Google и self-XSS
Продолжая тему self-XSS атак, хочу обратить твое внимание на компанию Google как одну из самых щедрых в плане гонораров за найденные уязвимости. В зависимости от сервиса Google практически любой self-XSS вектор можно сразу считать как не self, ведь что в Gmail, что в Google Analytics по умолчанию есть функция, позволяющая «расшарить» свой аккаунт с другими пользователями, просто указав их email. Из историй сразу вспоминается XSS в имени загружаемого файла в Analytics, которая выполнялась только для своего аккаунта. Но (вспомни пример выше) данный вектор мог бы быть использован против других пользователей. Неизвестного автора данной «фичи», естественно, отблагодарили :).
User’s data leak — злобные рефереры
Уязвимость подразумевает халатную обработку чувствительных данных пользователя — присутствие в GET-запросах значений сессий, индексация в поисковиках и так далее.
Текущая, наиболее распространенная версия протокола HTTP включает в себя заголовок referer, который содержит URL, откуда «пришел» пользователь. Представь себе, к примеру, ситуацию: пользователь сбрасывает пароль, получает письмо на почту, переходит по ссылке с токеном для смены пароля, а ему показывается какая-нибудь картинка с другого сайта (например, комикс с xkcd.com, как правильно выбирать пароли) уже на самом сервисе, где меняется пароль. Запрос этой картинки произойдет… Да-да, с значением referer, где указан токен для сброса пароля. В итоге владелец домена, откуда подгружается контент (например, картинки), может сливать токены для сброса пароля и менять их быстрее, чем пользователь. За подобную находку на HackerOne заплатили 100 долларов.
Web Server Misconfiguration — небезопасные редиректы
Уязвимость представляет собой недостатки конфигурации веб-сервера, в частности значение параметра Strict Transport Security.
В общем случае не принято передавать какие-либо чувствительные данные (пароли, номера карт и тому подобное) напрямую через HTTP, следует использовать HTTPS, а лучше, чтобы вообще весь ресурс работал через HTTPS. И как это обычно происходит? Пользователь обращается к сайту по HTTP — http://site.com, получая примерно такой ответ сервера:
HTTP/1.1 302 Found
Server: nginx/1.2.4
Date: Mon, 28 Apr 2014 15:22:23 GMT
Content-Type: text/html; charset=windows-1251
Content-Length: 0
Connection: keep-alive
X-Powered-By: PHP/5.3
Location: https://site.com/
Данный ответ перенаправит пользователя на HTTPS-версию сайта для предотвращения man-in-the-middle атаки. Но… ведь атакующий может начать перехватывать данные раньше, подменив ответ сервера, чтобы пользователя никуда не перенаправляло. Чтобы это предотвратить, в ответе сервера используется заголовок Strict-Transport-Security. Он говорит браузеру, чтобы тот больше не посещал данный ресурс по HTTP, а сразу обращался к нему по HTTPS, и указывает время, которое данное правило имеет силу (заходить только по HTTPS) для данного сайта. Давай представим ситуацию: пользователь первый раз посещает веб-сайт из потенциально безопасной среды (например, с домашнего компьютера), ответ сервера был перехвачен, и заголовок Strict-Transport-Security «подчищен» злоумышленником. После этого пользователь снова посещает ресурс из небезопасной среды, например из кафе, где ему никто не «подрезал» заголовки и пользователь безопасно зашел на сайт. Так вот, вернемся к Bug Bounty. Был ресурс, где все настроено корректно — хидер отправлялся при редиректе с HTTP на HTTPS. Но вот время, которое данное правило действительно с момента установки, было относительно недолгим — 180 дней. Кстати, стоит отметить, что существует pre-shared list, где перечислены сайты, на которые можно заходить только по HTTPS (HSTS preload list), —goo.gl/KxrNtl.
![Награда за специфичную настройку CSP](https://xakep.ru/wp-content/uploads/2014/10/csp.png)
Misconfiguration — Content-Security-Policy — и есть, и нет
Уязвимость заключается в том, что веб-приложение некорректно определяет правила раздачи Content Security Policy.
Многим известен заголовок Content Security Policy (CSP), который все больше и больше приходит в массы. Он передается в ответе веб-сервера и сообщает браузеру, откуда и какой контент можно подгружать (картинки и тому подобное). В основном он предназначен для защиты от последствий XSS-атак, так как тот же снифер уже не внедришь со своего сайта (при корректных правилах CSP). Но дело в том, что не все браузеры его поддерживают и возможны случаи, когда разработчики принимают решение, что не надо отсылать данный заголовок клиенту, если его браузер не поддерживает CSP. Получается, что разработчики определяют белый список браузеров (по факту — список полей UserAgent), кому отсылать данный заголовок. В итоге имеем следующие проблемы:
- ответ без CSP-заголовка может быть закеширован клиентской стороной (например, на прокси-сервере). Хотя, бывает, и на серверной, где-нибудь на промежуточных кеш-серверах. Как итог — этот же ответ (без CSP) может быть отдан пользователю, у кого браузер поддерживает CSP;
- все больше и больше создается браузеров — форков Chromium, где пользователи выставляют свой UA, которого нет в белом списке по ясным причинам.
Как видишь, данные ситуации могут привести к случаю из заголовка — CSP и есть, и нет, даже для тех, кто его поддерживает. На HackerOne за подобную вещь также наградили, но все думают точно так же. Например, у Facebook ситуация сложная: они работают именно по белым спискам и не всем отсылают CSP (только хрому версии выше Х, FF выше версии Y, но не между A1 и B1), так как если аудитория ресурса очень большая (как у Facebook), то важен вопрос совместимости (у FF в определенных версиях с этим проблемы) и лучше не отсылать заголовок, чтобы не потерять аудиторию. Позднее они планируют убрать это правило.
WWW
Наиболее полный список программ выплат по багам: https://bugcrowd.com/list-of-bug-bountyprograms
Web Application Misconfiguration — небезопасный %username%
Уязвимость заключается в некорректной архитектуре веб-приложения, функционал которого позволяет атакующему подменить содержимое служебных файлов, находящихся в веб-директории приложения.
На разных сайтах по-разному генерируется URI для доступа к личному профилю. Чаще всего это что-то типа /users/username/, но бывает, что имя пользователя идет сразу после домена, например http://example.com/username. Давай разовьем ситуацию и предположим, что в имени пользователя разрешены точки... Приходим к тому, что мы можем зарегистрировать пользователя с интересным именем, например robots.txt, и, возможно, подменять содержимое файла для поисковых роботов, дав им проиндексировать то, что не нужно! Далеко за примером ходить не надо, наверняка ты помнишь случай с утечкой SMS на сайте «МегаФона». Кроме того, можно вообразить и другие ситуации, которые позволят поломать основной функционал сайта.
Выводы
Как видишь, существует много различных способов проэксплуатировать, на первый взгляд, не имеющий никакой угрозы баг. Многое зависит от смекалки, опыта, знания условий эксплуатации и воображения :). Советую поглядывать различные баги на hackerone.com, ведь многие уязвимости после закрытия становятся публичными. Там же можно почитать про утечку полных путей через CSS-файлы, отсутствие SPF-записи в домене и, как следствие, возможность спуфить адрес отправляемой почты (ведь SMTP позволяет спуфить адрес отправителя «по стандарту»), а также про многое другое, не менее интересное и немного странное :). Happy bughunting!