![](https://habrastorage.org/webt/86/pw/n8/86pwn8n9ymnkztsrrwohplrzh1q.jpeg)
В марте 2020 года началась пандемия, поэтому у меня появилось множество свободного времени. Им нужно было распорядиться с умом, и я решил получить сертификат OSWE. Сдав 8 августа экзамен, я взял пару недель отдыха, а затем в середине сентября сказал сам себе: “Знаешь что? Моё имя не появлялось в зале славы Facebook в 2020 году, хотя бывает там ежегодно. Пора решить эту задачу!”.
Мне никогда не доводилось находить уязвимости на одном из поддоменов Facebook, поэтому я изучил статьи и нашёл один пост про поддомен Facebook, привлёкший моё внимание. Это отличный пост, рекомендую его прочитать: [Баг преобразования HTML в PDF приводит к RCE на сервере Facebook].
Прочитав этот пост, я понял, что в таком огромном веб-приложении можно найти множество уязвимостей.
Моей основной мишенью стал
https://legal.tapprd.thefacebook.com
, я намеревался реализовать RCE (Remote Code Execution, удалённое выполнение кода) или нечто подобное.Я запустил инструменты фаззинга, чтобы узнать все конечные точки этого веб-приложения, вздремнул на два часа и посмотрел фильм. Потом вернулся к компьютеру и обнаружил неплохие результаты.
Каталоги с ответом 403:
/tapprd/
/tapprd/content/
/tapprd/services/
/tapprd/Content/
/tapprd/api/
/tapprd/Services/
/tapprd/temp/
/tapprd/logs/
/tapprd/logs/portal/
/tapprd/logs/api/
/tapprd/certificates/
/tapprd/logs/auth/
/tapprd/logs/Portal/
/tapprd/API/
/tapprd/webroot/
/tapprd/logs/API/
/tapprd/certificates/sso/
/tapprd/callback/
/tapprd/logs/callback/
/tapprd/Webroot/
/tapprd/certificates/dkim/
/tapprd/SERVICES/
Думаю, этого результата вполне достаточно для того, чтобы подтвердить мою теорию об огромности этого приложения. Затем я начал читать файлы Javascript, чтобы разобраться, как работает веб-сайт, какие методы он использует, и т. д.
Я заметил способ обхода перенаправления на Login SSO на
https://legal.tapprd.thefacebook.com/tapprd/portal/authentication/login
и после анализа страницы логина я обнаружил такую конечную точку: /tapprd/auth/identity/user/forgotpassword
Проведя фаззинг со стороны конечной точки пользователя, я выявил ещё одну конечную точку
/savepassword
, ожидающую POST-запроса, Изучив файлы Javascript, я разобрался, как работает страница, что необходим сгенерированный токен и xsrf-токен и т. д. Сначала я подумал, что стоит попробовать проверить, можно ли изменять их вручную при помощи burp suite
, но получил ошибку сбоя выполнения операции.Я подумал, что дело может быть в неправильном адресе электронной почты или чём-то подобном. Попробуем подобрать электронную почту администратора. Я начал записывать произвольные адреса электронной почты, составив список слов, а затем использовал burp, чтобы проверить, что получится.
Вернувшись через пару часов я увидел те же самые ошибки, плюс ещё один результат. Это было перенаправление 302 на страницу логина. Ого, чёрт возьми, сработало!
Позвольте мне объяснить, что здесь произошло: я отправлял случайные запросы с CSRF-токеном при помощи программы-взломщика и случайные адреса электронной почты с новым паролем конечной точке
/savepassword
, и одним из результатов стал редирект 302.![](https://habrastorage.org/webt/bn/gr/ho/bngrho3utaigz0qe89qqvzuo85s.png)
Редирект
Теперь я мог зайти на страницу логина, ввести электронную почту и новый пароль — БУМ, вход в приложение успешно выполнен и у меня появился доступ к панели администратора!
![](https://habrastorage.org/webt/fy/ma/ox/fymaoxc1swf7jaxf1s5geugg1gw.png)
Я прочитал отчёт хакера, который нашёл предыдущий RCE, реализуемый при помощи PDF, компания дала ему награду всего в 1000 долларов. Поэтому я решил: так, нужно произвести хорошее впечатление и написать идеальный эксплойт, чтобы получить высокий Impact.
Я быстро написал на Python простой скрипт для эксплуатации этой уязвимости: вводишь адрес электронной почты и новый пароль, а скрипт изменяет пароль.
![](https://habrastorage.org/webt/1f/jq/r6/1fjqr6giqsbotwtylxqkmuzgque.png)
Impact здесь был настолько велик, потому что сотрудники Facebook логинились под своими рабочими аккаунтами. То есть они использовали собственные токены доступа аккаунтов Facebook и вероятно, если бы другой злоумышленник захотел бы использовать этот эксплойт, это дало бы ему доступ к аккаунтам некоторых сотрудников Facebook
Затем я сообщил об уязвимости, и мой отчёт рассмотрели.
2 октября я получил награду в размере 7500 долларов
![](https://habrastorage.org/webt/ws/tf/cy/wstfcy23gy6rvepyaznbn9olnk8.png)
Мне так понравился эксплойт этой уязвимости, и я решил, что этого недостаточно, скрипт слишком слабый! Стоит продолжать копать глубже.
Так я нашёл ещё две уязвимости, о которых я расскажу во второй части статьи.
Часть вторая
В первой части я обнаружил возможность захвата аккаунта незащищённым API, что позволило мне изменять пароль любого администраторского аккаунта без участия пользователя, за что отдел безопасности Facebook выплатил мне 7500 долларов. Во второй части я обнаружил способ захвата аккаунта при помощи манипуляций с куки. Объединив его с внутренним SSRF, я получил награду в xxxxx долларов. Да, пятизначную сумму… Ну, давайте приступим.
Перед публикацией статью проверили несколько сторон, и мне пришлось получить письменное разрешение на неё, поэтому часть имён и информации могла быть изменена по требованию компании Facebook и её партнёров.
Когда я обнаружил уязвимость из первой части статьи, Facebook устранила её на следующий день после получения отчёта. Затем я приступил к изучению истории
burp suite
, чтобы понять, как всё это работает.![](https://habrastorage.org/webt/4o/gc/ro/4ogcro8ukuw_zow5b7snfjorpww.png)
Как видно из скриншота (цифра 1 на синем фоне), в качестве куки используется ASPXAUTH. Идеально!
Понимаете, к чему я клоню? ASPXAUTH с вероятностью 80% означает, что они уязвимы, но для этого требуется следующая информация:
validationKey
(строка): преобразованный в шестнадцатеричный код ключ, используемый для проверки подписи.decryptionMethod
(строка): (по умолчанию «AES»).decryptionIV
(строка): преобразованный в шестнадцатеричный код ключ вектора инициализации (по умолчанию — вектор, состоящий из нулей).decryptionKey
(строка): преобразованный в шестнадцатеричный код ключ, используемый для расшифровки.
Подробнее об этом можно прочитать здесь: MachineKey Class.
У меня нет информации ни по одному из пунктов, так почему я предположил, что здесь есть уязвимость?
На самом деле, я этого не знаю, но в большинстве приложений с ASPXAUTH в зашифрованных куки с ключами шифрования обычно используются только электронная почта или пользователь, а также время действия куки. Я много раз использовал этот способ в баунти-программах других веб-сайтов, и он работал.
Мне нужно было найти способ обойти эту систему, по крайней мере, попытка не пытка. Я зашёл в Google и поискал другие веб-сайты, на которых используется то же приложение. Предполагалось, что мне повезёт и я найду веб-сайт, использующий то же приложение и те же ключи шифрования, и мне достаточно будет подобрать правильное имя пользователя администратора.
Я нашёл ещё один веб-сайт, использующий то же приложение, регистрация у него была активна, поэтому я зарегистрировался с именем пользователя администратора Facebook, перехватил запрос, взял ASPXAUTH и заменил его на ASPXAUTH Facebook с истекшим сроком. Угадайте, что произошло?
![](https://habrastorage.org/webt/a8/yq/zr/a8yqzrsma9jppff9c9pap6ppgxu.png)
![](https://habrastorage.org/webt/6j/_8/bn/6j_8bnaw4syfg4onmzcwpaeow7y.gif)
Я уже соскучился по этой панели, но наконец-то вернулся к ней. Теперь давайте немного поговорим об оплошности ASP.net, которую должно учитывать большинство разработчиков при создании приложений для обеспечения их безопасности:
- ASPXAUTH должен храниться в базе данных, а приложение должно проверять его правильность.
- В качестве дополнительной проверки ASPXAUTH иногда должен содержать не только имя пользователя.
- У каждого сайта должны быть уникальные ключи шифрования и расшифровки (ключи по умолчанию нужно изменить).
Вывод 1: я мог залогиниться в любой администраторский аккаунт, зная всего лишь его имя пользователя; сложность этой уязвимости я считаю очень низкой, а её impact высоким. Если я сообщу только об этой уязвимости, то получу всего 7500 долларов, как и в первой части, но мне хотелось большего.
В панели я заметил нечто любопытное, а именно опцию создания форм и ещё одну опцию — API-триггер. Я кое-что заподозрил, скорее всего, существует возможность неограниченного SSRF (Server-Side Request Forgery, подделки серверных запросов). Поэтому я написал письмо в отдел безопасности Facebook, рассказав, что в приложении почти стопроцентно есть критическая уязвимость SSRF, попросив разрешение её протестировать. Мне пришёл ответ:
![](https://habrastorage.org/webt/v3/je/uv/v3jeuv_gpzyllvgbb0agwg-zaqi.png)
В то время я всё ещё обсуждал с ними отчёт из первой части (захват аккаунта), потому что об этих уязвимостях я сообщил через неделю после первой. Как видите, отдел безопасности Facebook продолжал считать, что я утверждаю о наличии ещё одного обхода авторизации и SSRF, даже после того, как я объяснил уязвимости с доказательствами. Судя по этому, мне дали разрешение на тестирование SSRF.
Спустя какое-то время я написал небольшой скрипт и загрузил его в их редактор. Скрипт позволял мне отправлять любой запрос с любыми данными (GET, POST, PUT, PATCH, HEAD, OPTIONS) на любой URL, как внутренний, так и внешний.
![](https://habrastorage.org/webt/xz/yj/1g/xzyj1gsfe1n7mlczfsxbd2a3fsk.png)
Из бэкенда скрипта я мог менять метод запроса и отправляемые данные, и т.п.
На этом этапе я мог расширить эту уязвимость до RCE, может быть, до LFI (Local File Inclusion, добавление локальных файлов), если зайду чуть дальше (в этом я не уверен полностью, позже я попросил у Facebook разрешение на реверс-инжиниринг приложения, но они отказали, и сообщили, что не считают, что я смог бы расширить атаку).
Тогда я попробовал атаковать Facebook скриптом-канарейкой. Снова угадайте, что произошло?
![](https://habrastorage.org/webt/lq/ln/vs/lqlnvslh7maniakanfze4v7jlhe.png)
Я получил свой канареечный токен. Что дальше? Мне нужно написать новый отчёт со всеми подробностями, в том числе скриптами и PoC (доказательством правильности концепции), как мне и говорили выше.
Вывод 2: написав скрипт для отправки произвольных запросов, я мог получить внутренний SSRF и обеспечить доступ к внутренней сети Facebook. Сложность этой атаки я считаю низкой, а Impact критическим.
Полный Impact этого SSRF:
Успешная SSRF-атака часто может приводить к несанкционированным действиям или доступу к данным во внутренней сети Facebook, или в самом уязвимом приложении, или в других бэкенд-системах, с которым связано приложение. В некоторых ситуациях уязвимость SSRF может позволить злоумышленнику выполнять произвольные команды.
SSRF-эксплойт, обеспечивающий соединения с внешними сторонними системами, может привести к дальнейшим атакам злоумышленников, источником которых будет казаться организация, ответственная за хостинг уязвимого приложения, что способно вызвать потенциальные юридические последствия и ущерб репутации.
Подробнее об уязвимостях SSRF можно прочитать в статье portswigger.
Последний вывод: я объединил обе уязвимости в цепочку, дойдя до точки, имеющей доступ к внутренней сети Facebook (SSRF), воспользовавшись захватом аккаунта (Account takeover), чтобы добраться до моего загруженного на сервер скрипта внутри приложения, отправляющего нужные мне произвольные запросы.
Давайте поговорим о том, чего я могу достигнуть при помощи обнаруженной мной цепочки уязвимостей:
- Я могу получить доступ к аккаунту любого сотрудника Facebook в панели юридического отдела.
- Не нужно объяснять, насколько важную информацию может злоумышленник получить после входа.
- Я мог использовать SSRF для доступа к внутренней сети Facebook (intern.our.facebook.com).
- Думаю, что приложив ещё немного усилий, я бы смог расширить эту уязвимость и использовать её для сканирования внутренней сети/серверов.
Все мы знаем, насколько критичен SSRF, особенно если он не ограничен по частоте. Я могу с лёгкостью изменять тип контента и методы запросов. По информации из руководств об оплате Facebook эта уязвимость должна быть вознаграждена суммой 40 000 долларов с бонусом 5000 долларов, если я смогу изменять тип контента запросов и метод запросов.
После длительного ожидания я получил от Facebook такое сообщение:
![](https://habrastorage.org/webt/ou/3s/zh/ou3szhu_htk3em-qcdzevs2aewk.png)
Получил награду от Facebook в сумме 40 000 долларов плюс бонус 2 000 долларов (вместо ожидавшихся 7 000 долларов).
Я задал им вопрос о том, почему не получил бонус за полный контроль (5 000 долларов), и получил такой ответ:
![](https://habrastorage.org/webt/l_/jv/sc/l_jvscgh4covezwb8iwpfxudy4a.png)
![](https://habrastorage.org/webt/ka/g9/0o/kag90ofdz3sqnn8hpkxpozpdxn8.png)
В целом с первой уязвимостью это составило 54 800 долларов.
Я сообщил об этой уязвимости спустя несколько дней после отчёта об уязвимости из первой части.
Хронология отчётов:
- Среда, 9 сентября 2020 года — отправлен отчёт об уязвимостях.
- Понедельник, 26 октября 2020 года — компания Facebook попросила меня открыть новый отчёт.~Предприняты меры по устранению.
- Понедельник, 26 октября 2020 года — отчёт рассмотрен.
- Четверг, 25 февраля 2021 года — проблема устранена, выплачено вознаграждение. Примерно шесть месяцев, ага.
- Пятница, 5 марта 2021 года — выплачен бонус 5300 долларов.
Хочу дать ценный совет охотникам за багами. Когда вы видите ASPXAUTH, пробуйте получить куки с другого веб-сайта, использующего то же приложение, и протестируйте тот же способ, что и у меня:
- Создайте новые куки ASPXAUTH с другого веб-сайта.
- Проверьте, будут ли работать куки на исследуемом веб-сайте.
Мне понравился процесс, но ожидание в течение полугода и закрытие отчётов по иррациональным причинам напрягало. Я благодарен, но пришлось упорно потрудиться, и это не единственный SSRF, который я нашёл. На самом деле, я обнаружил более любопытные, но Facebook закрыл отчёты как «информативные», поскольку компания подписала с поставщиком соглашение, заключённое несколькими неделями после рассмотрения отчётов. В конечном итоге это не моя проблема, так что приятным такой опыт не назовёшь.
В конце хочу извиниться, если что-то было непонятно. Для публикации второй части потребовалось некоторое время — как говорилось выше, я ждал письменного разрешения и пересмотра отчёта. Поэтому многие аспекты были удалены или отцензурированы, чтобы сохранить конфиденциальность третьих сторон.