Эксклюзивно для форума LIMB.cc
Server-Side Request Forgery уязвимость может выглядеть достаточно хитрой для понимания.
Суть уязвимости в том, что атакующий заставляет сервер отправлять запросы туда, куда сервер достучаться может, а пользователь напрямую - нет. Происходит это из-за доверительного отношения внутри инфраструктуры.
То есть сервер может видеть внутреннюю сеть, получать конфигурационные файлы и отправлять запросы другим сервисам, а пользователь не может.
Это хорошо демонстрируется на примере сайта, который по введенной ссылке показывает предпросмотр страниц. Может возникнуть вопрос, типа, что это за нелепая функциональность? В реальности это могут быть сервисы, которые скачивают чего-то откуда-то, типа скачивания музыки или видео. Так вот, пользователь вводит URL --> сервер скачивает страницу --> показывает заголовок, картинку и описание. По логике пользователь должен подставить, например, site.com, но вместо этого пейлод http://127.127.127.127/latest/meta-data/ заставляет отдать чувствительную информацию.
Почему это может происходить и какие еще внутренние сервисы? С точки зрения кода все может выглядеть как две программы, скачать.py и index.html, и пользовательский интерфейс ссылки, который index.html передает на скачать.py. И вот то мы теоретически можем попробовать подцепить, скажем, третью программу чувствительная.c - это довольно упрощено, но даже отсюда становится понятным, что необходимо понимать, что происходит внутри сервиса.
SSRF бывают разных типов и техник, также по касательной эта уязвимость может задеть темы CRLF-инъекции, HTTP request smuggling, но на данный момент этим можно пренебречь, сфокусировавшись на сути.
Где именно возникает SSRF? Проведя мозговой штурм, получаются такие варианты:
Гипотеза Symfony
Скажу сразу, она не сработала :( хотя ее паттерн верен в своей сути, и подход можно использовать.
Как я уже заметил, на этапе постэксплуатации очень кстати будет получить как можно больше информации о внутренней инфраструктуре для составления пейлода, бить огромными списками нецелесообразно.
А что если попробовать найти ресурсы с открытым файлом /phpinfo? phpinfo - отличный инструмент разведки, он покажет внутренние IP и порты, пути до корня и include_path, allow_url_fopen, allow_url_include, включен ли curl, Registered PHP Streams.
Открытый phpinfo может быть на сайтах, которые используют PHP. Например: Laravel, Symfony, CodeIgniter, Yii, CakePHP, Zend Framework.
Моя статистика по Symfony такова: из 14 000 сайтов около 300 имеют открытый /phpinfo, то есть около 2–3%.
Вернемся к маркерам. Проще всего на большой выборке попробовать работать по ним следующим образом: url=, redirect=, next=, callback=, image=, page=, host=, site=, dest=, file=, path=, source=, endpoint=.
Для массового и тихого получения ссылок возьму https://github.com/tomnomnom/waybackurls , команда main.go url.
В 20 % случаев (по выборке с открытыми phpinfo) удается получить страницы с нужными маркерами. Часть из них мусорные, типа с utm параметром, и, к сожалению, ни одна из них, кажется, не содержит SSRF. Для большинства сайтов WayBackUrls вообще ничего не вернет.
Ручное тестирование. Одной из главных проблем при тестировании является составление пейлода. При тестировании желательно найти аналог кавычки для SQL-инъекций. Хотелось найти простую форму проверки. Считается, что пейлодом может быть 127.0.0.1 или localhost, но что именно я должен увидеть в ответе? Правильный ответ - любые изменения в сравнении с чистым запросом, но какие именно - это непредсказуемо.
Думая над этим, я пришел к выводу, что идеальным пейлодом будет favicon: находим в коде страницы маршрут к favicon и подставляем в параметр, можно заменить URL на localhost.
Единственную интересную особенность, которую я обнаружил, была по адресу /backend/base?file=bootstrap. Она встречалась на нескольких ресурсах и показалась достаточно интересной, но оказалась неэксплуатируемой. Выяснилось, что она относится к Shopware и позволяет читать файл bootstrap.js, но не позволяет выйти за его пределы из-за smarty_internal_templatebase.php. Эта гипотеза задумывалась как та, что позволит получить чувствительные файлы или выйти на RCE, например, через использование gopher в связке с открытым Redis без авторизации. WayBackUrls можно заменить на более мощный краулер или взять не Symfony, или взять другую выборку Symfony, поскольку найденная мной весьма публична, но суть паттерна весьма истинна.
Дорки и SSRFmap
Другой способ - это, конечно же, дорки. Как вариант: inurl:".php?url=", и почти сразу вижу потенциальную SSRF. Пейлод - http://127.0.0.1/. Вижу разницу в ответах и реакциях сервиса.
Минусы в том, что сайт может использовать любые технологии, что затрудняет пост-эксплуатацию.
Есть такой инструмент https://github.com/swisskyrepo/SSRFmap - sqlmap из мира SSRF? Работает очень просто. Предварительно сохраняем запрос в текстовый файл: https://github.com/swisskyrepo/SSRFmap/tree/master/examples
Команда: python3 ssrfmap.py -r r.txt -p url -m readfiles,portscan пробивает все основные файлы и сохраняет их в папку с сайтом, сканирует порты, помимо получения файлов в нем есть RCE-эксплойты. Чего в нем нет, так это механизма тамперов. Реальный пример: параметр кодируется в base64, и чтобы использовать его, придется лезть в исходный код SSRFmap.
SSRFmap выглядит очень крутым инструментом. Мне не очень нравятся гугл-дорки для получения сайтов, но этот способ действительно работает.
CVE
В завершении рассмотрю SSRF CVE за 2025 год. Я просмотрел все, и мне показались интересными следующие CVE наглядными примерами. У них есть хорошие PoC, легко разобраться что к чему:
Server-Side Request Forgery уязвимость может выглядеть достаточно хитрой для понимания.
Суть уязвимости в том, что атакующий заставляет сервер отправлять запросы туда, куда сервер достучаться может, а пользователь напрямую - нет. Происходит это из-за доверительного отношения внутри инфраструктуры.
То есть сервер может видеть внутреннюю сеть, получать конфигурационные файлы и отправлять запросы другим сервисам, а пользователь не может.
Это хорошо демонстрируется на примере сайта, который по введенной ссылке показывает предпросмотр страниц. Может возникнуть вопрос, типа, что это за нелепая функциональность? В реальности это могут быть сервисы, которые скачивают чего-то откуда-то, типа скачивания музыки или видео. Так вот, пользователь вводит URL --> сервер скачивает страницу --> показывает заголовок, картинку и описание. По логике пользователь должен подставить, например, site.com, но вместо этого пейлод http://127.127.127.127/latest/meta-data/ заставляет отдать чувствительную информацию.
Почему это может происходить и какие еще внутренние сервисы? С точки зрения кода все может выглядеть как две программы, скачать.py и index.html, и пользовательский интерфейс ссылки, который index.html передает на скачать.py. И вот то мы теоретически можем попробовать подцепить, скажем, третью программу чувствительная.c - это довольно упрощено, но даже отсюда становится понятным, что необходимо понимать, что происходит внутри сервиса.
SSRF бывают разных типов и техник, также по касательной эта уязвимость может задеть темы CRLF-инъекции, HTTP request smuggling, но на данный момент этим можно пренебречь, сфокусировавшись на сути.
Где именно возникает SSRF? Проведя мозговой штурм, получаются такие варианты:
- Выгрузка со сторонних сервисов чего угодно
- Проверка ссылок или предпросмотр страниц
- Документ-конвертеры
- Наличие чата (например, поддержки или между пользователями; здесь имеется в виду наличие сокет-соединений на сайте)
- Любой параметр URL, где приложение может инициировать внешний запрос: url=, redirect=, next=, callback=, image=, page=, host=, site=, dest=, file=, path=, source=, endpoint= в том числе POST, например, JSON с URL-параметром
Гипотеза Symfony
Скажу сразу, она не сработала :( хотя ее паттерн верен в своей сути, и подход можно использовать.
Как я уже заметил, на этапе постэксплуатации очень кстати будет получить как можно больше информации о внутренней инфраструктуре для составления пейлода, бить огромными списками нецелесообразно.
А что если попробовать найти ресурсы с открытым файлом /phpinfo? phpinfo - отличный инструмент разведки, он покажет внутренние IP и порты, пути до корня и include_path, allow_url_fopen, allow_url_include, включен ли curl, Registered PHP Streams.
Открытый phpinfo может быть на сайтах, которые используют PHP. Например: Laravel, Symfony, CodeIgniter, Yii, CakePHP, Zend Framework.
Моя статистика по Symfony такова: из 14 000 сайтов около 300 имеют открытый /phpinfo, то есть около 2–3%.
Вернемся к маркерам. Проще всего на большой выборке попробовать работать по ним следующим образом: url=, redirect=, next=, callback=, image=, page=, host=, site=, dest=, file=, path=, source=, endpoint=.
Для массового и тихого получения ссылок возьму https://github.com/tomnomnom/waybackurls , команда main.go url.
В 20 % случаев (по выборке с открытыми phpinfo) удается получить страницы с нужными маркерами. Часть из них мусорные, типа с utm параметром, и, к сожалению, ни одна из них, кажется, не содержит SSRF. Для большинства сайтов WayBackUrls вообще ничего не вернет.
Ручное тестирование. Одной из главных проблем при тестировании является составление пейлода. При тестировании желательно найти аналог кавычки для SQL-инъекций. Хотелось найти простую форму проверки. Считается, что пейлодом может быть 127.0.0.1 или localhost, но что именно я должен увидеть в ответе? Правильный ответ - любые изменения в сравнении с чистым запросом, но какие именно - это непредсказуемо.
Думая над этим, я пришел к выводу, что идеальным пейлодом будет favicon: находим в коде страницы маршрут к favicon и подставляем в параметр, можно заменить URL на localhost.
Единственную интересную особенность, которую я обнаружил, была по адресу /backend/base?file=bootstrap. Она встречалась на нескольких ресурсах и показалась достаточно интересной, но оказалась неэксплуатируемой. Выяснилось, что она относится к Shopware и позволяет читать файл bootstrap.js, но не позволяет выйти за его пределы из-за smarty_internal_templatebase.php. Эта гипотеза задумывалась как та, что позволит получить чувствительные файлы или выйти на RCE, например, через использование gopher в связке с открытым Redis без авторизации. WayBackUrls можно заменить на более мощный краулер или взять не Symfony, или взять другую выборку Symfony, поскольку найденная мной весьма публична, но суть паттерна весьма истинна.
Дорки и SSRFmap
Другой способ - это, конечно же, дорки. Как вариант: inurl:".php?url=", и почти сразу вижу потенциальную SSRF. Пейлод - http://127.0.0.1/. Вижу разницу в ответах и реакциях сервиса.
Не удалось прогрузить медиа
Минусы в том, что сайт может использовать любые технологии, что затрудняет пост-эксплуатацию.
Есть такой инструмент https://github.com/swisskyrepo/SSRFmap - sqlmap из мира SSRF? Работает очень просто. Предварительно сохраняем запрос в текстовый файл: https://github.com/swisskyrepo/SSRFmap/tree/master/examples
Команда: python3 ssrfmap.py -r r.txt -p url -m readfiles,portscan пробивает все основные файлы и сохраняет их в папку с сайтом, сканирует порты, помимо получения файлов в нем есть RCE-эксплойты. Чего в нем нет, так это механизма тамперов. Реальный пример: параметр кодируется в base64, и чтобы использовать его, придется лезть в исходный код SSRFmap.
SSRFmap выглядит очень крутым инструментом. Мне не очень нравятся гугл-дорки для получения сайтов, но этот способ действительно работает.
CVE
В завершении рассмотрю SSRF CVE за 2025 год. Я просмотрел все, и мне показались интересными следующие CVE наглядными примерами. У них есть хорошие PoC, легко разобраться что к чему:
- CVE-2025-29457 - требует авторизации в MyBB 1.8.38, PoC - https://www.yuque.com/morysummer/vx41bz/vro4dvxzuiwlg6uv
- CVE-2025-27152 - в очень популярной JavaScript-библиотеке axios до версии 1.8.2, описана на GitHub. Уязвимость проявляется при наличии заранее заданного baseURL. Особенность в том, что токен может передаваться дальше, и он не должен иметь определенных ролей, так как запрос может пойти на внутренние маршруты. Если они защищены ролевым токеном, токен с недостаточными правами не будет принят.
- CVE-2025-46568 - в Stirling-PDF до версии 0.44.3. В конвертер URL в PDF загружается HTML-файл, предварительно созданный на контролируемом домене, и на выходе получается PDF с возможностью SSRF. Подробности на GitHub
👍44
❤️7
😁4
😮12
😢7
💯2
LIMB