Статья SSRF уязвимость: поиск, эксплуатация и цепочки атак в пентесте

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


На одном из пентестов API финтех-стартапа мы нашли параметр callback_url в эндпоинте вебхуков. Подставили адрес Burp Collaborator - через секунду пришёл DNS-запрос с внутреннего IP. Ещё через двадцать минут у нас были временные IAM-креды от AWS через обращение к 169.254.169.254. Вся цепочка от обнаружения SSRF уязвимости до чтения содержимого S3-бакетов заняла меньше часа - при наличии WAF на входе. Ниже - пошаговый разбор того, как мы ищем, подтверждаем и эксплуатируем Server-Side Request Forgery на реальных проектах.

Место SSRF в цепочке атаки​

SSRF - не финальная цель, а точка входа. Один HTTP-запрос превращает внешний пентест во внутренний. Сервер уже за периметром, пользуется implicit trust внутренней сети - и этим можно злоупотребить. В терминах MITRE ATT&CK эксплуатация SSRF уязвимости покрывает несколько тактик:
  • Initial Access - Exploit Public-Facing Application (T1190): атакующий через веб-приложение заставляет сервер выполнять запросы к произвольным адресам
  • Credential Access - Cloud Instance Metadata API (T1552.005): через SSRF читаются метаданные облачных инстансов с IAM-кредами
  • Discovery - Network Service Discovery (T1046): сервер работает как прокси для маппинга внутренней сети, обнаружения открытых портов и сервисов
  • Lateral Movement - Exploitation of Remote Services (T1210): полученные креды или доступ к внутренним API позволяют двигаться вглубь инфраструктуры
Типичная последовательность: recon эндпоинтов → обнаружение параметра с URL → подтверждение SSRF (OOB или in-band) → чтение облачных метаданных или сканирование внутренней сети → эскалация через полученные данные. До SSRF нужен fingerprinting: какие эндпоинты принимают URL, какие протоколы поддерживает серверный HTTP-клиент, какой облачный провайдер используется. После SSRF - зависит от добычи: если получены IAM-креды, следующий шаг - перечисление S3/RDS/Secrets Manager; если обнаружен внутренний сервис без аутентификации - прямая эксплуатация.

Обнаружение точек входа SSRF при пентесте​

Где искать: параметры, заголовки, скрытые функции​

Поиск SSRF уязвимостей начинается не с payloads, а с маппинга attack surface. Каждая функция, где приложение принимает URL от пользователя - потенциальная точка входа. На практике SSRF атака веб-приложение чаще всего поражает через:

Webhook-обработчики - параметры callback_url, webhook, notify_url. Приложение шлёт POST-запрос на указанный адрес, и контролируемый URL уходит напрямую в серверный HTTP-клиент. Применимо: внешний пентест, modern-инфраструктура с микросервисами.

Загрузка файлов по URL - поля image_url, file_url, import_url. PDF-генераторы (wkhtmltopdf, Puppeteer), импорт данных, превью ссылок - классика. Применимо: любой пентест, legacy и modern.

Интеграции и SSO - redirect-параметры, OAuth callback URL, custom SSO. Валидация тут часто ослаблена, потому что «это же наш партнёр». Ага, конечно.

Заголовки - Host, X-Forwarded-Host, X-Original-URL. По данным Ростелеком-Солар, SSRF через заголовок Host в их практике приводил к blind SSRF с возможностью сканирования внутренней сети - порты localhost идентифицировались по разнице в статус-кодах ответа.

На этапе recon я прогоняю все запросы через Burp Suite и помечаю каждый параметр, принимающий URL-подобное значение. Дальше - ffuf для фаззинга скрытых параметров: ffuf -w params.txt -u "https://target.com/api/fetch?FUZZ=https://attacker.com" -fs 0 помогает найти неочевидные параметры, которые не видны в UI.

Decision tree: от подозрения к подтверждению​

Перед тем как стрелять payloads, определяем тип потенциальной SSRF:

УсловиеДействиеИнструмент
Параметр принимает полный URL, ответ возвращается клиентуТестировать Full SSRF: подставить http://127.0.0.1, анализировать тело ответаBurp Repeater
Параметр принимает URL, но ответ не виденТестировать Blind SSRF: подставить OOB-адрес, ждать callbackBurp Collaborator, interactsh
Фильтрация по домену или IP - запрос блокируетсяПробовать bypass: альтернативные IP, redirect, DNS rebindingSSRFmap, ручные payloads
Ответ отличается по времени или статус-коду для разных IPSemi-blind SSRF: маппить сеть через timing и HTTP-кодыBurp Intruder с таймерами

Decision tree работает и для внешнего, и для внутреннего пентеста. Разница: при внутреннем пентесте SSRF может быть менее критичной, если атакующий уже имеет сетевой доступ к тем же ресурсам. Максимальная ценность SSRF - при внешнем пентесте, где она даёт прыжок за периметр.

Blind SSRF: обнаружение через out-of-band каналы​

Когда сервер выполняет запрос, но не возвращает ответ клиенту, обнаружение blind SSRF требует OOB-канала - внешнего сервера, фиксирующего входящее соединение.

На практике это выглядит так: подставляем в уязвимый параметр адрес Burp Collaborator (или self-hosted interactsh-server) и ждём DNS-lookup или HTTP-запрос. Callback пришёл - SSRF подтверждена, даже если в HTTP-ответе приложения ничего не изменилось. Пример: параметр avatar_url в API профиля. Отправляем avatar_url=http://uniqueid.oast.fun/ssrf-test. Collaborator фиксирует DNS-резолв с IP сервера - значит, сервер выполнил запрос.

Ограничения по окружению: для OOB-канала нужен выход в интернет со стороны сервера-жертвы. В изолированных средах без интернета (DMZ, air-gapped) OOB не работает - приходится полагаться на semi-blind технику. Отправляем запросы к разным портам localhost и измеряем время ответа. Открытый порт (например, http://127.0.0.1:3306) вернёт ответ быстрее или с другим статус-кодом, чем закрытый (http://127.0.0.1:9999). Именно так в кейсе Ростелеком-Солар идентифицировали MySQL на порту 3306 через blind SSRF в заголовке Host.

Отдельный случай - out-of-band SSRF через DNS: даже если HTTP-трафик наружу заблокирован, DNS-резолв часто разрешён. Payload вида http://uniqueid.attacker-dns.com может не дойти до HTTP-сервера атакующего, но DNS-запрос зафиксируется - этого достаточно для подтверждения уязвимости. DNS почти всегда пролезает - запомните это.

Эксплуатация SSRF: payloads для внутренней сети и облачных метаданных​

Требования к окружению​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме


Ограничение для modern-инфраструктуры: если приложение использует HTTP-клиент с жёстким ограничением портов (только 80/443), сканирование будет неполным. Контейнеризация (Docker, Kubernetes) тоже меняет картину - SSRF внутренние сервисы могут быть доступны не по IP, а по DNS-именам (например, http://redis-service:6379). В Kubernetes я обычно начинаю с http://kubernetes.default.svc - если отвечает, можно копать дальше.

SSRF и облачные метаданные: AWS, GCP, Azure

SSRF облачные метаданные - главная цель в cloud-native приложениях. Каждый провайдер предоставляет metadata endpoint на предсказуемом адресе:

ПровайдерEndpointЧто отдаётОсобенности
AWS IMDSv1http://169.254.169.254/latest/meta-data/IAM-креды, instance ID, security groupsПростой GET, без аутентификации
AWS IMDSv2Тот же адрес, но через session tokenТо жеТребует PUT для получения token - блокирует базовую SSRF
GCPhttp://metadata.google.internal/computeMetadata/v1/Service account tokensТребует заголовок Metadata-Flavor: Google
Azurehttp://169.254.169.254/metadata/instanceManaged identity tokensТребует заголовок Metadata: true

AWS IMDS v1 - самый опасный случай. Запрос http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name> возвращает AccessKeyId, SecretAccessKey и SessionToken без какой-либо аутентификации. Просто GET - и вот тебе ключи от королевства. GCP и Azure требуют специфические заголовки, что затрудняет эксплуатацию SSRF - не каждый серверный HTTP-клиент позволяет устанавливать произвольные заголовки через пользовательский URL.

IMDSv2 требует предварительного PUT-запроса для получения session token. Это серьёзно усложняет эксплуатацию через типовые SSRF-векторы, ограниченные GET-запросами. Обходы возможны через gopher://, HTTP request smuggling и в специфических конфигурациях серверного HTTP-клиента - но это уже не «пять минут и готово». Проблема в том, что IMDSv2 нужно включать вручную - на многих EC2 до сих пор активен IMDSv1. Проверка: если GET к http://169.254.169.254/latest/meta-data/ возвращает ответ - IMDSv1 работает. И вам повезло.

Обход защиты при SSRF: техники и реальные CVE

Альтернативные представления IP-адресов и обход фильтрации​

Большинство защит от SSRF - denylist на regex: блокируются обращения к 127.0.0.1, 10.x.x.x, 192.168.x.x, 172.16-31.x.x. Подход обречён из-за множества альтернативных представлений одного IP:
Код:
http://2130706433/          # decimal = 127.0.0.1
http://0x7f000001/          # hex
http://0177.0.0.1/          # octal (glibc inet_aton: curl, Python requests на Linux; strict parsers - Java, Go - отклоняют)
http://127.1/               # short form (inet_aton-style; strict URL parsers отклоняют)
http://[::1]/               # IPv6 loopback
http://0/                   # Linux: resolves to 127.0.0.1
http://127.0.0.1.nip.io/    # DNS wildcard service
Помимо альтернативных IP, работают redirect-цепочки: атакующий контролирует внешний сервер, который отвечает HTTP 302 на http://169.254.169.254/. Сервер-жертва следует за redirect и попадает на metadata endpoint, хотя изначальный URL прошёл валидацию WAF.

DNS rebinding - техника для modern-инфраструктуры при внешнем пентесте: атакующий контролирует домен, который при первом DNS-запросе резолвится в легитимный IP (проходит проверку), а при втором - в 127.0.0.1 или 169.254.169.254. Работает против валидаторов, которые проверяют IP на этапе DNS-резолва, но делают повторный DNS-запрос при fetch. Классический TOCTOU.

CVE-2024-4084: обход фильтрации в AnythingLLM​

CVE-2024-4084 (CVSS 7.5 HIGH, CWE-918) в mintplex-labs/anything-llm (версии до 1.5.4 включительно) - учебный пример провала denylist-подхода. CVSS-вектор: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - атака по сети, низкая сложность, привилегии не нужны, высокое влияние на конфиденциальность.

Что сделали разработчики: фильтровали IP-адреса regex-ом. Блокировались строки, начинающиеся с 192, 172, 10 и 127, протоколы ограничивались HTTP/HTTPS. Что сделал исследователь: обошёл защиту через decimal и hex представления IP и обращения к другим портам на localhost. Результат: доступ к любому ресурсу внутренней сети, сканирование хостов, потенциальный доступ к SSRF AWS metadata endpoint. Regex-denylist против SSRF - это как замок на калитке при отсутствии забора.

Единственный надёжный подход - allowlist разрешённых доменов/IP или полная изоляция серверного HTTP-клиента через сетевые политики (deny all → allow explicit).

SSRF цепочка атак: от подделки запроса до компрометации

SSRF → IMDS → credential theft: паттерн Capital One​

По данным Gecko Security, взлом Capital One в 2019 году - каноничный пример SSRF to RCE через облачные метаданные. Атакующий эксплуатировал SSRF в WAF-компоненте: сервер выполнил запрос к http://169.254.169.254/latest/meta-data/iam/security-credentials/, вернул временные IAM-креды с чрезмерно широкими привилегиями. Через полученные ключи были прочитаны S3-бакеты с данными более 100 миллионов клиентов. Финансовые последствия - значительный штраф OCC и многомиллионное урегулирование коллективного иска.

Цепочка в ATT&CK: Exploit Public-Facing Application (T1190) → Cloud Instance Metadata API (T1552.005) → Data from Local System (T1005). Одна SSRF уязвимость, один HTTP-запрос - и полный доступ к облачной инфраструктуре. Причина: IAM-роль имела доступ к продакшн-данным, а IMDSv1 не требовал аутентификации. Два фактора, каждый из которых по отдельности - «ну, бывает», а вместе - катастрофа.

CVE-2025-61882: цепочка атак на Oracle E-Business Suite​

В октябре 2025 года зафиксирована активная эксплуатация CVE-2025-61882 (CVSS 9.8 CRITICAL, CWE-287) в Oracle E-Business Suite (версии 12.2.3–12.2.14). Уязвимость в компоненте BI Publisher Integration позволяла неаутентифицированному атакующему через HTTP захватить контроль над Oracle Concurrent Processing. CISA добавила CVE в каталог Known Exploited Vulnerabilities 6 октября 2025 с дедлайном патчинга 27 октября - подтверждённая эксплуатация против критической инфраструктуры. CVE-2025-61882 также отмечена CISA как используемая в ransomware-кампаниях (конкретная группировка не атрибутирована), что повышает приоритет патчинга.

Конкретный вектор атаки не раскрыт - NVD классифицирует уязвимость как CWE-287 (Improper Authentication), CISA KEV описывает её как «unspecified vulnerability». Это пример того, как уязвимость обхода аутентификации в enterprise-системе превращается в катастрофу - особенно если в инфраструктуре присутствуют дополнительные слабости вроде SSRF. Nuclei-темплейт для CVE-2025-61882 уже доступен в публичном репозитории projectdiscovery/nuclei-templates.

Где WAF ловит SSRF и где промахивается​

Большинство WAF (ModSecurity CRS, AWS WAF, Cloudflare) детектируют SSRF по сигнатурам: обращения к 169.254.169.254, localhost, RFC1918-адресам в параметрах. Против базовых payloads это работает. Против всего остального - не очень.

Где WAF стабильно промахивается:

Альтернативные IP - decimal 2130706433, hex 0x7f000001, IPv6 [::1] не покрываются стандартными правилами большинства WAF. ModSecurity CRS v3.x ловит часть, но далеко не все варианты.

Redirect-цепочки - WAF проверяет URL в запросе, но не контролирует, куда сервер уходит после 302. Внешний http://attacker.com/redir выглядит легитимно.

DNS rebinding - домен резолвится в публичный IP при проверке и в приватный при fetch. WAF не перепроверяет DNS.

Protocol smuggling - gopher://, dict:// часто не обрабатываются WAF, но могут поддерживаться серверным HTTP-клиентом. Python urllib поддерживает gopher, Java HttpClient - нет.

Кодирование - URL encoding, double encoding, unicode normalization обходят regex-правила.

Стратегия: начинаем с базовых payloads - если WAF блокирует, переходим к bypass в порядке: альтернативные IP → redirect через контролируемый сервер → DNS rebinding. На каждом шаге фиксируем, что именно детектирует WAF (тело ответа с блокировкой обычно содержит rule ID), и адаптируем payload. Терпение и методичность - WAF рано или поздно пропустит что-то из списка.

Инструменты для поиска SSRF уязвимостей: выбор под задачу

ИнструментПреимуществаОграниченияКогда использоватьКогда не использовать
Burp Suite Pro + CollaboratorИнтеграция с workflow, OOB-детекция blind SSRFPro-лицензия ~$449/год, облачный CollaboratorЛюбой внешний пентест, blind SSRFИзолированные сети без интернета
interactsh (self-hosted)Бесплатный OOB, DNS+HTTP+SMTP, активно поддерживается (2025)Требует настройки DNS-записей и сервераBlind SSRF без Burp Pro, внутренний пентестБыстрые одноразовые проверки
SSRFmapАвтоматизация типовых payloads, протоколы gopher/fileШумный, payloads устаревают (последний коммит: 2023)Внутренний пентест, известная точка входа, legacyStealth, внешний пентест с WAF
GopherusГенерация gopher-payloads для Redis, MySQL, FastCGIТолько gopher, архивный проект (2020)SSRF к Redis/MySQL через gophergopher заблокирован или не поддержан
nuclei (SSRF templates)Масштабное сканирование, CI/CD, community templates (2025)False positives, generic payloadsRecon фаза, mass scanningГлубокая ручная эксплуатация
ffufБыстрый фаззинг параметров для обнаружения SSRF-точекНе эксплуатирует, только обнаружениеНачальный recon, поиск скрытых параметровЭксплуатация подтверждённой SSRF

Мой рабочий стек на внешнем пентесте: ffuf для обнаружения параметров → Burp Repeater для ручного подтверждения → Collaborator для blind SSRF → ручные payloads для bypass и эскалации. SSRFmap и Gopherus подключаю точечно, когда подтверждён gopher-вектор к внутреннему Redis или MySQL. Gopherus, конечно, древний (2020), но gopher-payloads для Redis генерирует исправно - менять его пока не на что.

За последние два года SSRF встречается мне чаще, чем SQLi - особенно в API-first приложениях с микросервисной архитектурой. Webhook-эндпоинты, PDF-генераторы, интеграции с внешними сервисами - везде, где приложение делает исходящий HTTP-запрос по пользовательскому URL, потенциально есть подделка запросов на стороне сервера. При этом разработчики уверены, что regex на 127.0.0.1 - достаточная защита, а тот же 2130706433 проходит незамеченным. CVE-2024-4084 в AnythingLLM - не аномалия, а типовая картина: попытка закрыть SSRF denylist-ом, которая обходится за пять минут. Если на проекте есть облачная инфра с IMDSv1 - вопрос не «будет ли ущерб», а «сколько данных утечёт до детекта».

С ростом LLM-приложений, где пользовательский input уходит в серверные запросы к внешним API и инструментам, количество SSRF-векторов существенно вырастет к концу 2026 - готов поспорить. На HackerLab лежит сценарий, где SSRF-primitive нужно собрать в полную цепочку от обнаружения до эксфильтрации - хороший способ прощупать эти техники до реального проекта.
 
Последнее редактирование:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab