SSRF к облачным метаданным через обход проверки IP
Приложение блокирует только loopback-адреса, но не link-local 169.254.169.254 — атакующий читает облачные метаданные AWS.
mediumphpPro
Задача
# SSRF к облачным метаданным
## Сценарий
Интернет-магазин SecureShop развёрнут в облачной инфраструктуре. В каталоге реализован удобный для пользователей виджет — предпросмотр внешних URL: вы вводите ссылку, сервер запрашивает её на стороне backend и возвращает содержимое (например, для проверки картинок и описаний партнёрских товаров).
Реализация выглядит безопасной: разработчики добавили фильтр на «локальные» адреса, чтобы запрос изнутри сервера не мог быть направлен на сам сервер. Однако фильтр выполнен наивно — через сравнение hostname со списком из нескольких строковых значений. Это создаёт класс уязвимости **Server-Side Request Forgery (SSRF)**: атакующий заставляет приложение от своего имени обратиться к ресурсу, к которому у него самого сетевого доступа нет.
## Зачем атаковать metadata-сервис
Все крупные облачные провайдеры (AWS, GCP, Azure, Yandex Cloud, Alibaba Cloud) разворачивают на каждом виртуальном инстансе локальный сервис метаданных. Он:
- Привязан к специальному link-local IP-адресу из диапазона 169.254.0.0/16 (RFC 3927).
- Доступен только из самого инстанса по внутренней сети (не маршрутизируется наружу).
- Возвращает информацию об инстансе: образ, тип, регион, теги, user-data.
- Содержит главное — **временные IAM-credentials той роли**, под которой работает инстанс. Эти ключи позволяют выполнять любые AWS API-запросы от имени роли: читать S3, дёргать DynamoDB, поднимать новые EC2 — в зависимости от политики роли.
Захват IAM-credentials через SSRF — один из самых классических облачных эксплойтов: в 2019 году именно так атакующий вытянул 100 миллионов записей клиентов Capital One.
## Почему фильтр обходится
Защита приложения проверяет, что host из URL не совпадает с одной из локальных строк. Реализация работает по строковому совпадению, поэтому пропускает любые **альтернативные текстовые представления** того же адреса:
- Десятичное представление IPv4 как одного 32-битного числа.
- Восьмеричное представление октетов.
- Шестнадцатеричное представление.
- Адрес-агрегатор 0.0.0.0, который на большинстве ОС резолвится в localhost.
- IPv6-mapped IPv4 нотация.
- Имя хоста, резолвящееся в опасный IP только в момент соединения (DNS rebinding).
И, главное, фильтр не охватывает целую категорию опасных адресов — link-local-диапазон, в котором живут metadata-сервисы провайдеров. Это базовое непонимание модели угроз: безопасность SSRF определяется IP-диапазонами после DNS-резолва, а не строкой в URL.
## Цели лабораторной работы
1. Войти в приложение под учётной записью обычного пользователя.
2. Найти эндпоинт предпросмотра URL и убедиться, что он отбрасывает прямой `localhost`.
3. Обнаружить хотя бы одно представление адреса, которое фильтр пропускает.
4. Через найденный обход обратиться к симулятору metadata-сервиса, развёрнутому на стороне backend.
5. Извлечь блок IAM-credentials и найти в нём флаг лаборатории в формате `flag{...}`.
## Данные
| Параметр | Значение |
|----------|----------|
| Учётная запись | `demo` / `demo` |
| Эндпоинт предпросмотра | `POST /preview` |
| Параметр запроса | `url` |
| Эндпоинт metadata-симулятора | путь в RFC-стиле AWS metadata (`/latest/meta-data/...`) |