
CVE-2026-68398 Escalação local de privilégios por use-after-free no PPPoL2TP do Ubuntu

Este repositório contém um exploit de escalonamento de privilégios local específico para uma build
da CVE-2026-68398, uma condição de corrida do tipo use-after-free entre o processamento de recepção
do PPPoL2TP e a destruição de um canal PPP não anexado. Foi validado em
QEMU contra o pacote oficial do Ubuntu 22.04
linux-image-5.15.0-187-generic (5.15.0-187.197).
O teste final começa como um usuário dedicado com UID 1001, sem grupos
suplementares, sem capabilities e sem acesso sudo, e então obtém o
UID 0 do namespace inicial. KASLR, SMEP, SMAP e AppArmor permanecem ativos. A VM não é iniciada
com nokaslr, nopti, nosmep ou nosmap.
Aviso
Este código corrompe intencionalmente o estado do heap do kernel e está vinculado a uma build exata do kernel Ubuntu. Uma corrida mal-sucedida pode causar pânico ou corromper o sistema. Execute-o somente em uma VM isolada e descartável que você possua.
pppol2tp_recv() é executada no caminho de recepção UDP do L2TP dentro de uma seção crítica
de leitura do RCU e eventualmente chama ppp_input(&po->chan). O socket PPPoX
e seu ppp_channel embutido são seguros para RCU, mas o struct channel interno
usado por ppp_input() é uma alocação separada.
Para um canal vinculado com PPPIOCGCHAN, mas nem anexado a uma unidade PPP nem
em ponte, o caminho de fechamento liberava esse objeto interno imediatamente:
RX: l2tp_udp_encap_recv -> pppol2tp_recv -> ppp_input(channel)
CLOSE: pppol2tp_release -> pppox_unbind_sock
-> ppp_unregister_channel -> ppp_release_channel -> kfree(channel)
O caminho de recepção pode, consequentemente, operar na fila skb e na waitqueue do canal já
liberado. A correção adiciona um callback de RCU ao struct channel e adia a limpeza
da fila e a liberação até que um período de graça do RCU tenha decorrido.
A vulnerabilidade foi descoberta e corrigida upstream por
Norbert Szetei da Doyensec.
A correção na mainline é
ec4215683e47424c9c4762fd3c60f552a3119142.
O registro CNA do Linux identifica a linhagem vulnerável como tendo início no Linux 4.15. Kernels de fornecedores podem trazer a correção com um número de versão diferente, portanto a fonte exata ou o changelog do pacote tem precedência sobre esta tabela.
| Linha do kernel | Primeira versão corrigida | Commit da correção |
|---|---|---|
| 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 |
As linhas de fornecedores mais antigas ainda suportadas exigem um backport. Em 2026-08-12, o
rastreador de CVEs do Ubuntu
marca o pacote linux do Jammy como needs-triage; nenhum pacote corrigido do Ubuntu Jammy
foi identificado. O código-fonte testado 5.15.0-187.197 ainda chama
kfree(pch) diretamente e é vulnerável.
| Propriedade | Valor |
|---|---|
| Distribuição | Ubuntu 22.04.5 LTS (Jammy) |
| Pacote do kernel | linux-image-5.15.0-187-generic / 5.15.0-187.197 |
| Release do kernel | 5.15.0-187-generic #197-Ubuntu |
| Arquitetura | x86-64 |
| VM | QEMU/KVM, -cpu host, quatro vCPUs, 5 GiB de RAM |
| Identidade inicial | uid=1001(poc) gid=1001(poc) groups=1001(poc) |
| Capabilities iniciais | herdáveis, permitidas, efetivas e ambientais todas zeradas |
| Identidade final | uid=0(root) gid=0(root) nos namespaces iniciais |
| Alterações no boot | Nenhuma; linha de comando padrão, KASLR ativado |
O kernel não foi recompilado. A imagem de nuvem mínima não incluía
linux-modules-extra-5.15.0-187-generic, portanto esse pacote oficial do Ubuntu foi
instalado para fornecer l2tp_ppp. Uma instalação normal do Jammy usando o
metapacote linux-generic já depende do pacote modules-extra correspondente.
O módulo do protocolo é carregado automaticamente quando o exploit cria seu socket PPPoL2TP.
| Requisito | Estado no Ubuntu 5.15.0-187 | Uso no exploit |
|---|---|---|
| PPP | CONFIG_PPP=y | Compilado embutido |
| L2TP / PPPoL2TP | CONFIG_L2TP=m, CONFIG_PPPOL2TP=m | Módulo oficial linux-modules-extra |
| User keys | CONFIG_KEYS=y | Recupera o canal kmalloc-256 liberado |
| AppArmor | CONFIG_SECURITY_APPARMOR=y | Permanece ativo; o cred falso inclui um rótulo unconfined válido |
| KASLR | CONFIG_RANDOMIZE_BASE=y | Permanece ativo; o slide é recuperado em tempo de execução |
| SMAP | CONFIG_X86_SMAP=y | Permanece ativo |
| Namespaces de usuário/rede | Ativados pelo Ubuntu, mas não usados | Nenhuma configuração de namespace ou ganho de capability é necessária |
/dev/ppp | Não necessário | O canal é vinculado, mas nunca conectado a uma unidade PPP |
O detector automático de KASLR usa um canal lateral de temporização do prefetch x86 e
exige RDTSCP com KPTI inativo. A CPU do host testado expõe rdtscp,
smep e smap e não é afetada pelo Meltdown, então o Ubuntu deixa o KPTI
inativo sem qualquer alteração no boot. Em uma CPU em que /proc/cpuinfo reporta o
flag pti, o detector se recusa a executar. Essa é uma condição de hardware específica do exploit:
a CVE subjacente permanece alcançável, mas esta versão não afirma um bypass de KASLR em um sistema com KPTI ativo. Um slide fornecido manualmente existe
apenas para diagnósticos controlados.
struct channel liberado. O caminho RX ainda em execução
trata os bytes controlados da chave como sua fila skb e waitqueue.core_pattern como área de escrita temporária para divulgação
e expõe um ponteiro de alocação da chave.override_creds() com a credencial forjada.
Os campos UID/GID, capabilities e os ponteiros necessários de user, namespace, ucount e
group correspondem exatamente à build do Ubuntu testada./proc/self/exe para um
arquivo exclusivo em /tmp, altera-o para propriedade de root com modo 4755 e verifica esses
atributos./usr/bin/id.A última ponte é necessária porque override_creds() altera as credenciais subjetivas
da tarefa ativa do kernel; instalar e executar a cópia SUID verificada
transforma essa primitiva de curta duração em credenciais normais de processo.