
Comprobador de exposición y laboratorio seguro de VM desechables para CVE-2026-23111 (escalada de privilegios local por use-after-free en nf_tables de Linux). Defensivo: detección, mitigación, laboratorio multi-distro. Sin exploit.
Herramientas defensivas y un laboratorio de máquina virtual reproducible para CVE-2026-23111, la escalada de privilegios local por use-after-free en nf_tables del kernel de Linux (una comprobación invertida de actividad de elementos en nft_map_catchall_activate(), el error «off by !»). Un usuario local sin privilegios puede escalar a root y escapar de un contenedor mediante espacios de nombres de usuario sin privilegios.
Este repositorio no incluye ningún exploit. Contiene un comprobador de exposición de solo lectura, un script para crear un usuario genuinamente sin privilegios y definiciones de VM para que puedas alcanzar el fallo de forma segura y estudiar la investigación pública. La cadena completa hasta root está en los avisos enlazados abajo, no aquí.
Análisis completo: https://techearl.com/cve-2026-23111-nftables-lpe
check-exposure.sh — detector de solo lectura: versión del kernel frente a la compilación corregida, presencia de nf_tables, la condición previa de userns sin privilegios y las firmas de caída del registro del kernel.setup-unprivileged-user.sh — crea un labuser sin sudo y demuestra que no tiene privilegios. El objetivo de una prueba de LPE es partir de un usuario que todavía no pueda convertirse en root.Vagrantfile — VMs desechables de Debian 12 y AlmaLinux 10 (las distros que Multipass no puede lanzar).Un contenedor comparte el kernel del host. Ejecutar un exploit de kernel dentro de un contenedor lo ejecuta contra el kernel real de tu host, por lo que una «prueba» puede comprometer la máquina real. Usa una VM desechable con su propio kernel.
| Distro | Lanzar con | Por qué |
|---|---|---|
| Ubuntu 24.04 / 22.04 | Multipass (solo Ubuntu) | Exodus lo reprodujo en ambas; 24.04 trae la restricción de userns de AppArmor activada por defecto, por lo que muestra la mitigación. |
| Debian 12 | Vagrant (vagrant up debian) | Exodus lo reprodujo en ella; userns sin privilegios abiertos por defecto. |
| AlmaLinux / Rocky 10.1 | Vagrant (vagrant up alma) | Coincide con el kernel objetivo 6.12.0-124.x.el10 de FuzzingLabs, por lo que su trigger público se reproduce tal como se publicó. |
Multipass solo lanza Ubuntu, por eso las demás usan Vagrant.
Cada distro necesitó un truco distinto para arrancar un kernel genuinamente anterior al parche que aún tuviera red funcionando en una VM en la nube:
linux-aws antiguo, no linux-generic. El kernel genérico carece del driver de NIC ENA de AWS y pierde SSH en una instancia Nitro. sudo apt install -y linux-image-6.8.0-1028-aws (por debajo del corregido 6.8.0-1051), establécelo como predeterminado en GRUB y reinicia. En virtualización local el kernel genérico funciona bien.cloud (conserva ENA): deb [check-valid-until=no trusted=yes] https://snapshot.debian.org/archive/debian/20251201T000000Z/ bookworm main, y luego apt install -y linux-image-6.1.0-39-cloud-amd64=6.1.148-1 (por debajo del corregido 6.1.164-1, DSA-6163-1).el10_1 están en la vault de 10.1. Apunta dnf a https://vault.almalinux.org/10.1/BaseOS/x86_64/os/ y ejecuta dnf install kernel-6.12.0-124.38.1.el10_1, luego grubby --set-default.# 1. Create a real unprivileged user and prove it cannot sudo.
# (useradd, not Debian's adduser, so it works on RHEL too.)
sudo bash setup-unprivileged-user.sh labuser
# 2. Exposure verdict.
sudo ./check-exposure.sh
# 3. As labuser, the precondition, then the public nft trigger inside a netns.
sudo -u labuser unshare -Ur id # uid=0 in a new userns = precondition open
# (denied on stock Ubuntu 24.04 = mitigation working)
# The public FuzzingLabs trigger (catchall GOTO + aborted batch). Inlined here as
# documentation; this repo does not ship an executable exploit/trigger file.
sudo -u labuser unshare -Urn bash -c '
nft add table inet t; nft add chain inet t c
nft add map inet t m "{ type ipv4_addr : verdict; }"
nft add element inet t m "{ * : goto c }"
printf "delete element inet t m { * }\ndelete element inet t m { 1.2.3.4 }\n" > /tmp/b.nft
nft -f /tmp/b.nft; nft flush ruleset'
Esa secuencia ejecuta la ruta de aborto con el fallo; no incluye una cadena de escalada de privilegios y, en un kernel estándar, es silenciosa (ver abajo).
| Distro | Kernel vulnerable arrancado | userns por defecto | Veredicto |
|---|---|---|---|
| Ubuntu 24.04 | 6.8.0-1028-aws | restringido (AppArmor) | MITIGADO, no corregido |
| Debian 12 | 6.1.0-39-cloud (6.1.148-1) | abierto | EXPUESTO |
| AlmaLinux 10.1 | 6.12.0-124.38.1.el10_1 | abierto | EXPUESTO |
La conclusión honesta sobre el trigger: en un kernel de producción estándar es silencioso. Ejecuta la ruta de aborto con el fallo sin caída ni salida en dmesg, incluso en bucle con liberación y reutilización. La salida KASAN: slab-use-after-free de los análisis proviene de un kernel con KASAN/debug; convertir el use-after-free latente en un arma requiere el heap spray del exploit (que no está en este repositorio). El laboratorio demuestra que el usuario sin privilegios alcanza el fallo, muestra que la restricción de AppArmor por defecto de Ubuntu bloquea esa ruta y ofrece un veredicto claro de EXPUESTO / MITIGADO / corregido. No te entrega una shell de root, por diseño.
Restringe los espacios de nombres de usuario sin privilegios (cierra la vía realista para los exploits públicos) y luego parchea el kernel.
# Ubuntu 23.10+ (AppArmor-based, keeps legitimate userns users working):
echo "kernel.apparmor_restrict_unprivileged_userns=1" | sudo tee /etc/sysctl.d/99-restrict-userns.conf
sudo sysctl --system
# Elsewhere (blanket disable; set both on Debian/Ubuntu):
printf 'kernel.unprivileged_userns_clone=0\nuser.max_user_namespaces=0\n' | sudo tee /etc/sysctl.d/99-restrict-userns.conf
sudo sysctl --system
# Patch (Ubuntu 24.04 generic fixed at 6.8.0-107.107):
sudo apt update && sudo apt install --only-upgrade linux-image-generic && sudo reboot
MIT. Uso defensivo y educativo.