
Repositorio de investigación para CVE-2026-68121, un use-after-free en PPPoE del kernel de Linux en pppoe_sendmsg() que permite escalada local de privilegios, con PoC, análisis de causa raíz y configuración de laboratorio.
PPPoEject
Una vulnerabilidad de corrupción de memoria en el kernel de Linux en la ruta de transmisión PPPoE,
causada por un puntero obsoleto a una cabecera sk_buff después de que un callback de cabecera de dispositivo
reubique la cabecera del skb.
Este repositorio está destinado únicamente a investigación de seguridad autorizada, análisis de vulnerabilidades del kernel, entornos CTF y pruebas defensivas.
No ejecute código de prueba de concepto contra sistemas sin autorización explícita.
El registro CVE identifica la vulnerabilidad como un puntero de cabecera PPPoE obsoleto que
puede volverse inválido cuando dev_hard_header() reubica la cabecera del skb.
La vulnerabilidad existe en:
drivers/net/ppp/pppoe.c
dentro de:
pppoe_sendmsg()
La secuencia vulnerable es conceptualmente:
pppoe_sendmsg()
│
▼
Guardar puntero de cabecera PPPoE
│
▼
dev_hard_header()
│
▼
la cabecera del skb puede reubicarse
│
▼
El puntero antiguo queda obsoleto
│
▼
PPPoE escribe a través del puntero obsoleto
│
▼
Use-After-Free
│
▼
Corrupción de memoria del kernel
El código de red de Linux permite que los callbacks de cabecera de dispositivo reubiquen la
cabecera del sk_buff. Por lo tanto, un puntero a la cabecera antigua no puede reutilizarse de forma segura
después de que dev_hard_header() retorne.
El problema central es una violación del tiempo de vida.
pppoe_sendmsg() obtiene un puntero a la cabecera PPPoE antes de invocar:
dev_hard_header()
Sin embargo, ese callback puede provocar que la cabecera del skb se mueva.
Conceptualmente:
Antes del callback:
skb
┌──────────────────────────────┐
│ Ethernet │ PPPoE │ Payload │
└──────────┴───────┴───────────┘
▲
│
puntero obsoleto
Después de la expansión del skb:
cabecera antigua del skb ──X──► liberada
nueva cabecera del skb
┌────────────────────────────────────┐
│ Ethernet │ PPPoE │ Payload │
└──────────┴───────┴─────────────────┘
▲
│
ubicación válida
El puntero antiguo sigue referenciando la asignación liberada.
Cuando PPPoE posteriormente escribe la cabecera a través de ese puntero, el kernel realiza una escritura use-after-free.
El disparador documentado implica una condición de carrera en torno a copy_from_user() y cambios
en las operaciones de cabecera de un dispositivo team.
Una secuencia descrita es:
PPPoE sendmsg()
│
▼
copy_from_user() se bloquea
│
│
├───────────────┐
│ │
▼ ▼
El dispositivo team cambia Se añade el primer puerto
las operaciones de cabecera no Ethernet
│
▼
Callback GRE delegado
│
▼
Expansión de la cabecera del skb
│ │
└───────────────┘
│
▼
puntero PPPoE obsoleto
│
▼
escritura use-after-free
El registro CVE señala que esto puede ocurrir cuando el primer puerto no Ethernet se añade a un dispositivo team vacío y el callback de cabecera GRE delegado expande la cabecera del skb.
La vulnerabilidad puede provocar:
El vector CVSS publicado del CVE es:
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
con una puntuación base de 7.8 Alta.
Los componentes relevantes son:
PF_PPPOX / PPPoE socket
│
▼
pppoe_sendmsg()
│
▼
sk_buff (skb)
│
▼
dev_hard_header()
│
▼
Callback de cabecera del dispositivo de red
│
▼
Potencial expansión de la cabecera del skb
│
▼
Puntero de cabecera PPPoE obsoleto
│
▼
Escritura UAF
Por lo tanto, el código vulnerable no es simplemente un analizador genérico de paquetes PPPoE; la condición crítica es la interacción entre la transmisión de sockets PPPoE y la reubicación dinámica de la cabecera del skb.
La corrección upstream se titula:
pppoe: reload header pointer after dev_hard_header()
La corrección recarga la cabecera PPPoE a través del offset de cabecera de red del skb después de la creación de la cabecera del dispositivo.
La propiedad importante es:
Antes:
puntero de cabecera
│
▼
dev_hard_header()
│
▼
el skb se mueve
│
▼
puntero = obsoleto ❌
Después:
dev_hard_header()
│
▼
el skb puede moverse
│
▼
recargar cabecera usando el offset del skb
│
▼
puntero = válido ✅
pskb_expand_head() actualiza el offset relevante del skb cuando la cabecera del skb se
reubica, haciendo que la búsqueda basada en offset sea segura después de la reubicación.
Un laboratorio controlado puede estructurarse como:
┌───────────────────────────────────────────────┐
│ Linux VM │
│ │
│ ┌───────────────┐ │
│ │ PPPoE Socket │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ pppoe_sendmsg │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Team │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ GRE │ │
│ └───────────────┘ │
│ │
└───────────────────────────────────────────────┘
Herramientas útiles de depuración del kernel:
gdb
pwndbg
gef
crash
objdump
readelf
pahole
Monitorizar mensajes del kernel:
sudo dmesg -w
Inspeccionar el soporte PPPoE:
lsmod | grep pppoe
Comprobar los módulos PPP disponibles:
find /lib/modules/$(uname -r) -iname '*pppoe*'
Comprobar el kernel en ejecución actualmente:
uname -r
Comprobar la configuración relacionada con PPPoE:
grep -E 'CONFIG_PPP|CONFIG_PPPOE' \
/boot/config-$(uname -r)
Las opciones relevantes típicas incluyen:
CONFIG_PPP
CONFIG_PPP_ASYNC
CONFIG_PPP_SYNC_TTY
CONFIG_PPPOE
Para investigación controlada del kernel:
01. Compilar kernel vulnerable
↓
02. Arrancar VM aislada
↓
03. Habilitar soporte PPPoE
↓
04. Crear topología de red controlada
↓
05. Configurar interacción team/GRE
↓
06. Ejercitar PPPoE sendmsg()
↓
07. Monitorizar el tiempo de vida del skb
↓
08. Capturar diagnósticos del kernel
↓
09. Aplicar el parche upstream
↓
10. Repetir y comparar
El objetivo es reproducir la violación del tiempo de vida de la memoria de forma segura y comparar el comportamiento vulnerable y el parcheado.
CVE-2026-68121-PPPoEject/
│
├── README.md
│
├── exploit/
│ ├── poc.c
│ └── Makefile
│
├── analysis/
│ ├── root-cause.md
│ ├── pppoe-sendmsg.md
│ ├── skb-lifetime.md
│ └── patch-analysis.md
│
├── kernel/
│ ├── vulnerable/
│ └── patched/
│
├── lab/
│ ├── setup.sh
│ ├── cleanup.sh
│ └── topology.md
│
├── screenshots/
│
├── docs/
│ └── research-notes.md
│
└── LICENSE
La mitigación recomendada es actualizar a un kernel de Linux que contenga la corrección upstream o un backport apropiado de la distribución.
Para Debian/Kali:
sudo apt update
sudo apt full-upgrade
Luego reiniciar:
sudo reboot
Verificar el kernel en ejecución:
uname -r
Los backports de las distribuciones pueden usar números de versión diferentes, por lo que los administradores deberían verificar su paquete instalado contra el aviso de seguridad de la distribución. Debian actualmente enumera versiones corregidas que incluyen 6.1.187-1 para Bookworm y 6.12.101-1 para Trixie.
Los árboles estables de Linux contienen la corrección en múltiples ramas mantenidas. El registro CVE enumera los commits estables correspondientes e identifica el archivo fuente afectado como:
drivers/net/ppp/pppoe.c
El historial vulnerable comienza con la implementación PPPoE del kernel de Linux y
la serie de commits corregidos termina en la corrección upstream representada por
7a56e7c9b08e08fd55a1bcada24cf4fe3782b722 en los datos del CVE.
No se puede asumir que un puntero a un skb sea válido después de un callback capaz de reubicar la cabecera del skb.
Los callbacks de red pueden cambiar la disposición subyacente de la memoria.
El parche demuestra por qué un offset relativo al skb es más seguro que retener un puntero sin procesar a través de una operación que potencialmente reubica memoria.
El estado vulnerable depende de actividad concurrente en torno a la transmisión de paquetes y la configuración del dispositivo de red.
Un puntero obsoleto en el código de red del kernel puede convertirse en una primitiva de corrupción de memoria con consecuencias para la confidencialidad, integridad y disponibilidad.
drivers/net/ppp/pppoe.cpppoe_sendmsg()pppoe: reload header pointer after dev_hard_header()Linux Kernel · PPPoE · Use-After-Free · Kernel Security · LPE
Investigar • Analizar • Reproducir • Asegurar
| Campo | Detalles |
|---|
| CVE | CVE-2026-68121 |
| Nombre en clave | PPPoEject |
| Componente | Linux Kernel |
| Subsistema | PPPoE / Networking |
| Archivo afectado | drivers/net/ppp/pppoe.c |
| Función principal | pppoe_sendmsg() |
| Clase de bug | Use-After-Free |
| Impacto | Corrupción de memoria del kernel |
| Impacto potencial | Escalada de privilegios local |
| CVSS v3.1 | 7.8 — Alta |
| Vector de ataque | Local |
| Complejidad del ataque | Baja |
| Privilegios requeridos | Bajos |
| Interacción del usuario | Ninguna |
| Estado | Parcheado |
| Propiedad de seguridad | Vulnerable | Parcheado |
|---|
| Puntero de cabecera guardado antes del callback | ✅ | — |
| La cabecera del skb puede moverse | ✅ | ✅ |
| Puntero actualizado después del callback | ❌ | ✅ |
| Desreferencia de puntero obsoleto | Posible | Prevenido |
| Escritura use-after-free | Posible | Mitigado |
| Corrupción de memoria del kernel | Posible | Mitigado |