
CVE-2026-68398 Escalada de privilegios local por use-after-free en Ubuntu PPPoL2TP

Este repositorio contiene un exploit de escalada de privilegios local específico de una compilación para CVE-2026-68398, una condición de carrera de tipo use-after-free entre el procesamiento de recepción de PPPoL2TP y la destrucción de un canal PPP no asociado. Fue validado en QEMU contra el paquete oficial de Ubuntu 22.04 linux-image-5.15.0-187-generic (5.15.0-187.197).
La prueba final comienza como un usuario dedicado con UID 1001, sin grupos suplementarios, sin capacidades y sin acceso sudo, y después obtiene UID 0 en el espacio de nombres inicial. KASLR, SMEP, SMAP y AppArmor permanecen habilitados. El invitado no se inicia con nokaslr, nopti, nosmep ni nosmap.
Advertencia
Este código corrompe intencionalmente el estado del heap del kernel y está ligado a una compilación exacta del kernel de Ubuntu. Una condición de carrera fallida puede provocar un pánico del kernel o corromper el sistema. Ejecútalo solo en una máquina virtual aislada y desechable de tu propiedad.
pppol2tp_recv() se ejecuta en la ruta de recepción UDP de L2TP dentro de una sección crítica de lectura de RCU y finalmente llama a ppp_input(&po->chan). El socket PPPoX y su ppp_channel incorporado son seguros para RCU, pero la struct channel interna usada por ppp_input() es una asignación separada.
Para un canal vinculado con PPPIOCGCHAN pero que no está asociado a una unidad PPP ni puenteado, la ruta de cierre liberaba ese objeto interno inmediatamente:
RX: l2tp_udp_encap_recv -> pppol2tp_recv -> ppp_input(channel)
CLOSE: pppol2tp_release -> pppox_unbind_sock
-> ppp_unregister_channel -> ppp_release_channel -> kfree(channel)
En consecuencia, la ruta de recepción puede operar sobre la cola skb y la waitqueue del canal liberado. El parche añade una devolución de llamada (callback) de RCU a struct channel y difiere el vaciado de la cola y la liberación hasta que haya transcurrido un período de gracia de RCU.
La vulnerabilidad fue descubierta y corregida upstream por Norbert Szetei, de Doyensec. La corrección en mainline es ec4215683e47424c9c4762fd3c60f552a3119142.
El registro CNA de Linux identifica el linaje vulnerable como comenzando con Linux 4.15. Los kernels de los proveedores pueden incluir la corrección con un número de versión diferente, por lo que la fuente exacta o el changelog del paquete tienen prioridad sobre esta tabla.
| Línea del kernel | Primera versión corregida | Commit de corrección |
|---|---|---|
| 6.6.y | 6.6.148 | 4bb84e964ff0 |
| 6.12.y | 6.12.101 | 3ab32218d718 |
| 6.18.y | 6.18.42 | c9574b8a8ede |
| 7.1.y | 7.1.6 | 06213c85d8c0 |
| Mainline | 7.2-rc4 | ec4215683e47 |
Las líneas de kernel de proveedores más antiguas requieren un backport. A fecha de 2026-08-12, el rastreador de CVE de Ubuntu marca el paquete linux de Jammy como needs-triage; no se identificó ningún paquete corregido de Ubuntu Jammy. La fuente probada 5.15.0-187.197 todavía llama a kfree(pch) directamente y es vulnerable.
| Propiedad | Valor |
|---|---|
| Distribución | Ubuntu 22.04.5 LTS (Jammy) |
| Paquete del kernel | linux-image-5.15.0-187-generic / 5.15.0-187.197 |
| Versión del kernel | 5.15.0-187-generic #197-Ubuntu |
| Arquitectura | x86-64 |
| VM | QEMU/KVM, -cpu host, cuatro vCPUs, 5 GiB de RAM |
| Identidad inicial | uid=1001(poc) gid=1001(poc) groups=1001(poc) |
| Capacidades iniciales | heredables, permitidas, efectivas y ambientales, todas a cero |
| Identidad final | uid=0(root) gid=0(root) en los espacios de nombres iniciales |
| Cambios de arranque | Ninguno; línea de comandos estándar, KASLR habilitado |
El kernel no fue recompilado. La imagen mínima de nube carecía de linux-modules-extra-5.15.0-187-generic, por lo que se instaló ese paquete oficial de Ubuntu para proporcionar l2tp_ppp. Una instalación normal de Jammy que use el metapaquete linux-generic ya depende del paquete modules-extra correspondiente. El módulo del protocolo se carga automáticamente cuando el exploit crea su socket PPPoL2TP.
| Requisito | Estado en Ubuntu 5.15.0-187 | Uso en el exploit |
|---|---|---|
| PPP | CONFIG_PPP=y | Integrado |
| L2TP / PPPoL2TP | CONFIG_L2TP=m, CONFIG_PPPOL2TP=m | Módulo oficial de linux-modules-extra |
| Claves de usuario | CONFIG_KEYS=y | Recupera el canal liberado de kmalloc-256 |
| AppArmor | CONFIG_SECURITY_APPARMOR=y | Permanece activo; la credencial falsa incluye una etiqueta unconfined válida |
| KASLR | CONFIG_RANDOMIZE_BASE=y | Permanece activo; el slide se recupera en tiempo de ejecución |
| SMAP | CONFIG_X86_SMAP=y | Permanece activo |
| Espacios de nombres de usuario/red | Habilitados por Ubuntu, pero no utilizados | No se requiere configuración de espacios de nombres ni obtención de capacidades |
/dev/ppp | No es necesario | El canal está vinculado pero nunca se conecta a una unidad PPP |
El detector automático de KASLR usa un canal lateral de temporización por prefetch x86 y requiere RDTSCP con KPTI inactivo. La CPU del host probado expone rdtscp, smep y smap y no está afectada por Meltdown, por lo que Ubuntu deja KPTI inactivo sin ninguna anulación en el arranque. En una CPU donde /proc/cpuinfo reporte el flag pti, el detector se niega a ejecutarse. Esa es una condición de hardware específica del exploit: la CVE subyacente sigue siendo alcanzable, pero esta versión no afirma un bypass de KASLR en un sistema con KPTI activo. Existe un slide suministrado manualmente únicamente para diagnósticos controlados.