Перейти к содержимому
← Каталог php SSRF

SSRF через file_get_contents() в загрузке аватара

Приложение загружает аватар по URL без проверки — атакующий может обратиться к внутренним сервисам.

easyphpPro
Задача
# SSRF: запрос к внутреннему эндпоинту через серверный HTTP-клиент ## Сценарий Вы аудируете интернет-магазин **SecureShop**. На странице профиля доступна функция «Fetch Avatar»: пользователь указывает URL изображения, а сервер сам скачивает картинку по этому адресу и сохраняет её локально. Команда уверена, что эндпоинт безопасен — это просто прокси для загрузки внешних ресурсов. По данным внутреннего аудита, в приложении сохранился административный эндпоинт со статистикой и сервисной информацией, доступный только с loopback-интерфейса по проверке `REMOTE_ADDR`. В его ответе раскрывается конфиденциальная метка, которую требуется извлечь. ## Цель 1. Изучите эндпоинт предпросмотра аватара и поведение серверного HTTP-клиента: что именно сервер делает с пользовательским URL. 2. Используя серверный HTTP-клиент как прокси, обратитесь к административному эндпоинту, защищённому проверкой IP источника запроса. 3. Извлеките флаг из ответа административного эндпоинта. ## Теория **Server-Side Request Forgery (SSRF)** — класс уязвимостей, при котором атакующий заставляет сервер выполнить HTTP-запрос по адресу, выбранному атакующим. Запрос исходит **от сервера**, поэтому имеет привилегии серверной сети: проходит файрволы, видит внутренние эндпоинты, использует loopback-интерфейс, а в облачных средах получает доступ к metadata-сервисам. SSRF превращает уязвимое приложение в прокси внутри доверительной границы. **Уязвимый паттерн в PHP:** ```php // Сервер делает запрос по URL, переданному пользователем, без проверки адреса $url = $_POST['url']; $content = file_get_contents($url); // file:// тоже сработает // либо через cURL без CURLOPT_PROTOCOLS: $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $content = curl_exec($ch); ``` Ключевая ошибка — отсутствие проверки destination перед вызовом HTTP-клиента. Многие внутренние эндпоинты доверяют сетевой границе («доступно только с localhost», «доступно только из VPN», «доступно только из k8s-кластера»), но SSRF её обходит, потому что запрос всегда исходит из самой сети — от лица серверного процесса. Классические цели SSRF: loopback (`127.0.0.1`, `::1`, `localhost`) — внутренние админ-панели и debug-эндпоинты; частные сети RFC 1918 (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) — соседние сервисы кластера; cloud metadata (`169.254.169.254`) — IAM-credentials AWS / GCP / Azure; нестандартные схемы (`file://`, `gopher://`, `dict://`) — чтение локальных файлов или взаимодействие с redis/memcached на других портах. ## Точка входа атаки `POST /fetch-url` — обработчик предпросмотра аватара принимает поле `url` и через `file_get_contents()` скачивает содержимое по этому адресу. Никакой валидации хоста и схемы не выполняется. | Параметр | Значение | |----------|----------| | Учётные данные | `demo` / `demo` | | Уязвимый эндпоинт | `POST /fetch-url` (поле `url`) | | Цель | внутренний административный эндпоинт со статистикой | | Где раскрывается флаг | JSON-ответ внутреннего эндпоинта, поле `config.flag` |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru