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-98432 — PoC de solo prueba para CVE-2026-98432, un use-after-free de ireq_opt en IPv4/TCP de Linux: disparador de condición de carrera y oráculo de reutilización de heap que confirma el UAF sin ejecución de código. | Kitploit
Herramientas/GitHubGitHub/alucard0x1/cve-2026-98432
Herramientas DefensivasAnálisis de VulnerabilidadesExplotaciónFuzzingSeguridad de RedesPapers e Investigación
GitHubalucard0x1/cve-2026-98432

cve-2026-98432

PoC de solo prueba para CVE-2026-98432, un use-after-free de ireq_opt en IPv4/TCP de Linux: disparador de condición de carrera y oráculo de reutilización de heap que confirma el UAF sin ejecución de código.

Ver Repositorio
1745hace 6 díasAú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

CVE-2026-98432 — PoC de use-after-free en ireq_opt de IPv4/TCP de Linux

Prueba de concepto únicamente demostrativa para CVE-2026-98432 (CVSS 9.8): un use-after-free activable de forma remota en la pila IPv4/TCP de Linux.

Solo para pruebas de seguridad autorizadas. Ejecútalo contra sistemas que sean de tu propiedad o para los que tengas permiso explícito de probar.


Qué demuestra

El PoC activa la carrera y detecta cuándo el kernel copia bytes de un objeto ip_options_rcu liberado a un SYN-ACK. No crea usuarios ni archivos, y no implementa una cadena de ejecución de código.

Un acierto significa que el servidor devolvió el marcador de otra asignación dentro de su SYN-ACK — un kernel correcto no puede hacer eso. En una prueba controlada en Ubuntu 24.04.5 con kernel 6.8.0-147-generic (marcado como vulnerable por Ubuntu; corrección en cola en 6.8.0-149), una ejecución en loopback de 180 segundos produjo 21 aciertos en 320.829 intentos, y una ejecución de 300 segundos produjo 22 aciertos en 616.911 intentos. El kernel permaneció limpio (tainted=0, sin oops).

No se incluyen aquí capturas de paquetes ni registros de ese host; la propia salida del PoC es la evidencia.


1. El fallo

Un SYN que transporta opciones IPv4 hace que el kernel construya un ip_options_rcu (72 bytes, kmalloc-96) para el request socket. Cuando el handshake se completa, tcp_v4_syn_recv_sock() entrega ese objeto al socket hijo sin copiarlo, y luego borra el puntero en el request socket. Una segunda CPU que ya haya consultado el request socket puede seguir dentro de tcp_check_req() → tcp_v4_send_synack() → ip_build_and_send_pkt() → ip_options_build(), leyendo el mismo objeto. Los sockets hijos no son SOCK_RCU_FREE, e inet_sock_destruct() libera inet_opt con un simple kfree(), así que si el hijo se destruye en esa ventana, el lector desreferencia memoria liberada.

Existe una segunda variante con migración de request socket (net.ipv4.tcp_migrate_req=1 o un programa BPF de reuseport); la corrección usa kfree_rcu() tanto en inet_sock_destruct() como en tcp_v4_reqsk_destructor().

Introducido en Linux 4.4 (079096f103fa); corregido en mainline 7.3 y retroportado a 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56 y 7.2.10. Afectados: Linux 4.4 y posteriores, sin parchear.

El impacto va desde un cierre remoto (DoS) hasta la divulgación de memoria del kernel y, con una cadena de explotación completa, la ejecución de código. Este repositorio se limita a demostrar el use-after-free.


2. Cómo funciona el PoC

Por intento:

  1. SYN con una opción IPv4 Timestamp de 40 bytes (o Record Route) → request socket con ireq_opt; el objetivo refleja la opción en su SYN-ACK.
  2. SYN puro duplicado enviado justo antes del ACK del handshake, para que una segunda CPU ejecute la ruta del SYN-ACK contra el request socket.
  3. ACK completa el handshake; el hijo hereda inet_opt, el request socket descarta su puntero.
  4. RST (con ACK, para que sobreviva al filtro RST local) destruye el hijo, liberando el objeto mientras el lector del SYN duplicado puede seguir usándolo.

Oráculo. Cada intento incrusta un magic único de 32 bits más una etiqueta de comprobación en los offsets 16..23 de la opción. Se producen tres reescrituras antes de que un lector en espacio de usuario vea la opción:

etaparanura
ip_options_compile() del servidor sobre el SYN4..7 (TS) / 3..6 (RR)
ip_options_build() del servidor para el SYN-ACK8..11 (TS) / 7..10 (RR)
ip_options_compile() del host receptor sobre el SYN-ACK12..15 (TS) / 11..14 (RR)

El marcador queda más allá de las tres. Un SYN-ACK que refleja el magic de una asignación diferente (con tag == magic ^ 0x5a5a5a5a) demuestra que el lector copió de un objeto liberado y reutilizado.


3. Requisitos

  • Linux, root o CAP_NET_RAW; el filtro RST automático necesita CAP_NET_ADMIN (root).
  • Objetivo: Linux sin parchear con un listener TCP IPv4 que haga accept().
  • Python 3.8+ (probado en 3.12), solo biblioteca estándar.
  • iptables/nftables para el filtro de RST puro.

--proof es autocontenido en un solo host: inicia un listener en loopback y compite contra él.


4. Inicio rápido

4.1 Autoprueba sin conexión (cualquier SO, sin sockets)

python3 poc_cve_2026_98432.py --selftest

4.2 Comprobación del kernel (ejecutar en el host bajo prueba)

sudo python3 poc_cve_2026_98432.py --check

Imprime el kernel en ejecución, la tabla de versiones corregidas y los sysctls relevantes.

4.3 Prueba con un solo comando (recomendado)

sudo python3 poc_cve_2026_98432.py --proof 9000 \
     --duration 180 --workers 6 --spray 2 --spray-rate 1000 \
     --pcap /tmp/proof.pcap

Inicia un listener en 127.0.0.1:9000, ejecuta la carrera, imprime un veredicto, detiene el listener y elimina la regla de firewall temporal. No se crea nada en el host — solo estado TCP transitorio.

4.4 Sondear un listener remoto

sudo python3 poc_cve_2026_98432.py --probe <TARGET>:<PORT>

Un SYN: informa si el objetivo es un listener MPTCP y si refleja la opción IPv4 (requerida por el oráculo).

4.5 Carrera remota (LAN de laboratorio)

sudo python3 poc_cve_2026_98432.py <TARGET>:<PORT> \
     --workers 16 --spray 4 --duration 600 --pcap hits.pcap

Las direcciones públicas se rechazan a menos que se especifique --allow-public. El filtro de RST sin procesar se instala automáticamente y se elimina al salir.

4.6 Listener de laboratorio independiente

python3 poc_cve_2026_98432.py --listen 9000 --mptcp

Se vincula a 127.0.0.1; añade --listen-any solo para un host atacante remoto. El listener acepta y cierra inmediatamente cada conexión con SO_LINGER(0), liberando el hijo rápidamente.


5. Lectura de la salida

camposignificado
attemptshandshakes iniciados
synacksSYN-ACKs observados (aproximadamente dos por intento)
hitsel SYN-ACK llevaba el marcador de otra asignación → UAF confirmado
anomaliesmarcador analizado pero etiqueta no coincidente (corrupción parcial)
leaksvalor con aspecto de puntero del kernel en los bytes devueltos
nooptSYN-ACK sin la opción devuelta (syncookies/cola llena/eliminación)
staleretransmisión tardía de SYN-ACK filtrada (no es un hit)
malformedSYN-ACK con ihl < 5 (firma de underflow de optlen obsoleto)
timeoutssin SYN-ACK dentro de --timeout
spraySYNs de heap-spray enviados

Ejemplo de hit:

[!] UAF ORACLE HIT #1 at attempt sport=63042 (expected magic f815ca68 tag a24f9032)
    tcp <TARGET>:9000 -> <CLIENT>:63042 seq=c20ed8ef ack=d212b2b1 flags=0x12
    SYN-ACK echoed magic d4bcdcc7 tag 8ee6869d, belongs to another allocation
    ip options:
    44 28 11 00 03 71 b0 b5 03 71 cc 73 03 71 cc 73
    d4 bc dc c7 8e e6 86 9d 00 00 00 00 00 00 00 00

0x8ee6869d == 0xd4bcdcc7 ^ 0x5a5a5a5a: la relación de etiquetas demuestra que los bytes devueltos son un marcador válido de una asignación diferente.

Códigos de salida: 0 = evidencia observada, 3 = ninguna, 2 = error de configuración, 1 = error de uso/ejecución.


6. Ajuste

La carrera es probabilística. En el host de prueba, --workers 6 --spray 2 --spray-rate 1000 durante al menos 3 minutos la reprodujo; una ejecución de 60 segundos con --workers 4 --spray 1 --spray-rate 500 produjo cero aciertos en el mismo host. No concluya "no vulnerable" a partir de una ejecución corta.

Descargar herramienta