
Laboratorio controlado de inyección de tramas HTTP/2 en NGINX para validación de parches e investigación defensiva de CVE-2026-42926
Un laboratorio controlado de ciberseguridad para validar y comparar el comportamiento relacionado con CVE-2026-42926, un problema de inyección de tramas HTTP/2 que afecta versiones específicas de NGINX cuando se utiliza una configuración proxy vulnerable.
Este repositorio está destinado exclusivamente a investigación defensiva, validación de parches, auditoría de configuración y reproducción controlada en laboratorio.
Clasificación: Inyección de tramas HTTP/2
Versiones afectadas: NGINX1.29.4a1.30.0
Versiones corregidas: NGINX1.30.1+/1.31.0+
Utilice este proyecto únicamente en un entorno de laboratorio aislado que sea de su propiedad o para el cual tenga autorización explícita para realizar pruebas.
No lo ejecute contra sistemas de terceros, infraestructura pública, entornos compartidos o servicios de producción sin autorización por escrito.
Aislamiento recomendado:
El laboratorio comprueba si un binario y configuración de NGINX objetivo cumplen las condiciones necesarias para reproducir el problema, envía una solicitud manipulada a la ubicación de prueba e inspecciona un registrador ascendente controlado para detectar evidencia de que bytes similares a tramas HTTP/2 inyectadas llegaron al lado ascendente.
El patrón de validación normal es:
Resultado esperado:
| Archivo | Descripción |
|---|---|
README.md | Documentación del proyecto. |
LICENSE | Licencia MIT. |
Dockerfile | Construye una imagen de laboratorio autónoma con NGINX 1.29.4, PHP CLI/cURL, Python y los scripts del proyecto. |
docker-compose.yml | Inicia el servicio NGINX vulnerable, el registrador de tramas ascendente y un ejecutor de validación opcional. |
cve_2026_42926_lab.php | Script principal de validación del laboratorio. Verifica las condiciones previas de versión/configuración, envía la solicitud manipulada, inspecciona los registros ascendentes y devuelve un veredicto. |
nginx_vulnerable.conf | Configuración de NGINX de ejemplo que contiene el patrón proxy vulnerable utilizado tanto para las ejecuciones de comparación vulnerables como parcheadas. |
docker/nginx_vulnerable.docker.conf | Configuración de NGINX específica de Docker que utiliza el mismo patrón vulnerable y descubrimiento de servicios de Compose. |
nginx_config_verify.sh | Helper que verifica si una configuración de NGINX objetivo contiene el patrón proxy vulnerable requerido. |
upstream_frame_logger.py | Registrador ascendente HTTP/2 sin procesar controlado utilizado para capturar e inspeccionar las tramas recibidas de NGINX. |
run_lab_comparison.sh | Orquesta ejecuciones de comparación vulnerable vs parcheada. |
.dockerignore | Mantiene los registros generados y los metadatos del IDE fuera del contexto de construcción de Docker. |
bashpython3phpPara el flujo de trabajo contenerizado:
La configuración de ejemplo escucha en el puerto 80, que comúnmente requiere privilegios de root. Para un laboratorio local sin privilegios, cambie listen 80; en nginx_vulnerable.conf a un puerto alto disponible como 8080, luego use la URL objetivo correspondiente en el comando PHP.
Haga ejecutables los scripts de shell:
chmod +x nginx_config_verify.sh run_lab_comparison.sh
Confirme que PHP tiene soporte para cURL:
php -m | grep -i curl
Confirme que cada binario de NGINX puede imprimir su versión:
/path/to/nginx -V
El archivo nginx_vulnerable.conf proporcionado contiene el patrón de prueba requerido:
location /exploit {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 2;
proxy_set_body $request_body;
proxy_set_header Host $host;
proxy_set_header Content-Length $content_length;
}
Detalles importantes:
proxy_http_version 2 habilita el proxy HTTP/2 hacia el registrador ascendente.proxy_set_body $request_body utiliza un cuerpo de solicitud controlado por el cliente.client_max_body_size 20m permite el cuerpo de solicitud manipulado de 16 MiB utilizado por el script de validación.127.0.0.1:8081 de forma predeterminada.La configuración específica de Docker en docker/nginx_vulnerable.docker.conf mantiene el mismo patrón proxy vulnerable pero escucha en el puerto del contenedor 8080 y hace proxy al nombre de servicio de Compose upstream:8081.
El Dockerfile compila NGINX 1.29.4 desde el código fuente e instala las herramientas PHP/Python necesarias para el laboratorio. Compose ejecuta tres servicios desde la misma imagen:
upstream: registrador de tramas HTTP/2 sin procesarnginx: NGINX 1.29.4 vulnerable usando docker/nginx_vulnerable.docker.confrunner: comando de validación PHP de una sola ejecuciónConstruir la imagen de laboratorio:
docker compose build
Iniciar el registrador ascendente y NGINX vulnerable:
docker compose up -d upstream nginx
Confirmar la versión de NGINX incluida:
docker compose exec nginx nginx -V
Ejecutar el script de validación dentro de la red de Compose:
docker compose --profile run run --rm runner
El ejecutor utiliza estos argumentos dentro del contenedor:
php /lab/cve_2026_42926_lab.php \
http://nginx:8080/exploit \
/lab/upstream_logs \
/lab/nginx_config_verify.sh \
/usr/local/nginx/sbin/nginx \
/lab/docker/nginx_vulnerable.docker.conf \
/exploit
Los registros ascendentes generados se escriben en el directorio del host:
./upstream_logs/
El servicio NGINX también está expuesto al host en:
http://localhost:8080/version
Detener y eliminar los contenedores del laboratorio:
docker compose down
Iniciar el registrador ascendente controlado:
python3 upstream_frame_logger.py 8081 ./upstream_logs
En otra terminal, iniciar NGINX con la configuración de ejemplo:
/path/to/nginx -c "$PWD/nginx_vulnerable.conf"
Ejecutar el script de validación:
php cve_2026_42926_lab.php \
http://localhost/exploit \
./upstream_logs \
./nginx_config_verify.sh \
/path/to/nginx \
"$PWD/nginx_vulnerable.conf" \
/exploit
Detener NGINX después de la ejecución:
/path/to/nginx -s stop
Si cambió NGINX para que escuche en otro puerto, actualice el primer argumento. Por ejemplo:
php cve_2026_42926_lab.php http://localhost:8080/exploit ./upstream_logs ./nginx_config_verify.sh /path/to/nginx "$PWD/nginx_vulnerable.conf" /exploit
Establezca las rutas a los dos binarios de NGINX y ejecute el harness de comparación:
VULNERABLE_NGINX=/usr/local/nginx_1.29.4/sbin/nginx \
PATCHED_NGINX=/usr/local/nginx_1.30.1/sbin/nginx \
bash run_lab_comparison.sh
Anulaciones de configuración opcionales:
VULNERABLE_NGINX=/path/to/vulnerable/nginx \
PATCHED_NGINX=/path/to/patched/nginx \
VULNERABLE_CONFIG="$PWD/nginx_vulnerable.conf" \
PATCHED_CONFIG="$PWD/nginx_vulnerable.conf" \
bash run_lab_comparison.sh
El script de comparación escribe:
vulnerable_result.txtpatched_result.txtupstream_logs_vulnerable/upstream_logs_patched/Utilice nginx_config_verify.sh directamente cuando solo desee inspeccionar si una configuración contiene el patrón vulnerable:
./nginx_config_verify.sh /path/to/nginx "$PWD/nginx_vulnerable.conf" /exploit
El helper verifica:
proxy_http_version 2proxy_set_body con una variableclient_max_body_size de al menos 16 MiBcve_2026_42926_lab.php acepta argumentos posicionales:
php cve_2026_42926_lab.php <target_url> <upstream_log_dir> <config_script> <nginx_binary> <nginx_config> <location> [version_url]
Valores predeterminados:
| Argumento | Valor predeterminado |
|---|---|
target_url | http://localhost/exploit |
upstream_log_dir | ./upstream_logs |
config_script | ./nginx_config_verify.sh |
nginx_binary | nginx |
nginx_config | /etc/nginx/nginx.conf |
location | /exploit |
version_url | http://localhost/version |
cve_2026_42926_lab.php devuelve uno de tres veredictos:
| Veredicto | Significado | Código de salida |
|---|---|---|
positivo | Se observó evidencia de inyección de tramas correlacionada con la ejecución. | 0 |
negativo | Se cumplieron las condiciones previas y no se observó evidencia de inyección. | 1 |
no concluyente | Una o más condiciones previas o comprobaciones de evidencia fallaron. | 2 |
La evidencia positiva requiere que el script correlacione el marcador de ejecución, el encabezado de trama ascendente observado, el indicador de trama inyectada y la versión afectada de NGINX.
El registrador ascendente escribe archivos JSON con nombres como:
frames_<timestamp>.json
Cada registro contiene metadatos de trama HTTP/2 analizados, extractos de carga útil, desplazamientos de bytes, indicadores de detección de inyección y campos de correlación de ejecución.
El harness de comparación almacena directorios de registro separados para las ejecuciones vulnerable y parcheada para que la evidencia de las dos ejecuciones no se mezcle.
Si el script PHP informa que el helper de configuración no es ejecutable, ejecute:
chmod +x nginx_config_verify.sh
Si la solicitud devuelve 413 Request Entity Too Large, aumente client_max_body_size al menos a 16m; la configuración de ejemplo usa 20m.
Si no se crean registros ascendentes, verifique que:
upstream_frame_logger.py esté en ejecución.127.0.0.1:8081./exploit.Si NGINX no puede vincularse al puerto 80, ejecútelo con los privilegios adecuados en un entorno de laboratorio o cambie la configuración a un puerto alto como 8080.
Si el resultado de la comparación no es concluyente, inspeccione vulnerable_result.txt, patched_result.txt y los directorios de registro ascendente correspondientes para la condición previa fallida.
Este proyecto está licenciado bajo la Licencia MIT. Consulte LICENSE para más detalles.