
Implementações educacionais de exploits em vários idiomas para CVE-2026-31431, uma escalada local de privilégios no kernel Linux por meio do módulo algif_aead, com um detector seguro e orientação de uso para CTF.
Repositório educacional com implementações em múltiplas linguagens do exploit Copy Fail.
Criado e mantido por @shotafry — porque ler o CVE não é suficiente. É preciso reproduzi-lo.
Copy Fail é uma vulnerabilidade de escalada de privilégios local (LPE) no kernel do Linux, catalogada como CVE-2026-31431. Afeta o subsistema criptográfico do kernel, concretamente o módulo algif_aead que gerencia operações de criptografia autenticada (AEAD) através de sockets AF_ALG.
A falha foi introduzida em 2017 numa otimização do módulo authencesn e permaneceu sem detecção por quase 9 anos, presente em praticamente todas as distribuições Linux modernas.
O que torna Copy Fail especial em relação a outros LPEs históricos:
| Característica | Copy Fail | LPE típico |
|---|---|---|
| Precisa de race condition | ❌ Não | ✅ Sim |
| Precisa de offset específico do kernel | ❌ Não | ✅ Sim |
| Funciona em todas as distros | ✅ Sim | ❌ Normalmente não |
| Confiabilidade | 100% determinística | Variável |
| Modifica o disco | ❌ Não (apenas RAM) | Depende |
A vulnerabilidade foi descoberta por Taeyang Lee da equipe de pesquisa da Theori. A cadeia de exploit completa foi desenvolvida pela equipe Xint Code Research, que documentou o processo usando análise assistida por IA sobre o subsistema crypto/ do kernel do Linux.
A divulgação pública inclui PoC funcional, análise técnica completa e documentação em copy.fail.
CVE: CVE-2026-31431
CVSS: 7.8 — ALTA
Vetor: Local
Impacto: Escalada de privilégios completa (root)
Distros: Todas as distribuições Linux com kernel >= 2017 sem patch
O CVSS é 7.8 e não chega a crítico (9+) apenas porque requer acesso local prévio — o atacante já deve ter uma sessão no sistema. Em ambientes cloud e com contêineres Docker, esse requisito é consideravelmente mais fácil de cumprir do que parece.
O kernel do Linux guarda em RAM os arquivos que leu recentemente. Isso é chamado de page cache. Quando um processo lê /etc/passwd, o kernel não vai ao disco — serve a cópia em RAM. Isso é mais rápido, mas cria uma superfície de ataque: se você puder modificar essa cópia em RAM sem tocar no disco, o sistema verá dados falsos.
O módulo algif_aead permite fazer operações AEAD a partir do espaço do usuário através de sockets AF_ALG. O bug está na otimização introduzida em 2017: quando se usa splice() para passar páginas de um arquivo ao socket, essas páginas da page cache acabam na lista de dispersão destino (gravável) da operação criptográfica.
Resultado: qualquer usuário sem privilégios pode escrever 4 bytes controlados em qualquer arquivo que possa ler, sem tocar no disco.
Usuário sem privilégios
│
▼
Abre socket AF_ALG (authencesn)
│
▼
sendmsg() — parâmetros AEAD com nossos 4 bytes em seqno_lo
│
▼
splice() — arquivo → pipe → socket op
[BUG] A page cache do arquivo fica no scatterlist destino
│
▼
recv() dispara a operação AEAD
A auth falha (EBADMSG) mas o scratch-write já ocorreu
│
▼
/etc/passwd (page cache) agora diz: usuário → UID 0
│
▼
su <usuário> → PAM valida senha real → setuid(0) → ROOT
Imagine que o kernel tem um livro de registros do castelo (/etc/passwd). Copy Fail é como descobrir que, se você abrir a oficina de magia do castelo numa ordem muito específica, o livro de registros acidentalmente fica sobre sua mesa de trabalho — e você pode mudar seu posto de "soldado raso" para "rei" com uma caneta. O arquivista (PAM) verifica sua senha, mas não verifica o livro original, apenas a cópia que está à sua frente. Você é rei.

>= ~2017 sem o patch de CVE-2026-31431algif_aead disponível e carregávelIsso pode realmente ser pulado e você pode testar diretamente um dos exploits, mas também é válido se não quisermos arriscar enviar ou criá-los e apenas quisermos ver se funciona, mas os exploits têm sua função para verificar se o sistema em questão é vulnerável.
# Ver versão do kernel
uname -a
# Verificar se o algoritmo está disponível
grep -i authencesn /proc/crypto
# Verificar se o módulo está carregado
lsmod | grep alg
Se grep -i authencesn /proc/crypto retornar authencesn(hmac(sha256),cbc(aes)), o sistema é vulnerável.
| Linguagem | Requisito no alvo | Compilação prévia |
|---|---|---|
| C | Nenhum (binário estático) | gcc na máquina de compilação |
| Python | Python 3.10+ | Não |
| Rust | Nenhum (binário estático) | rustc na máquina de compilação |
| Go | Nenhum (binário estático) | go na máquina de compilação |
| Ruby | Ruby + gem fiddle (incluída por padrão) | Não |
| Perl | Perl 5 (incluído em praticamente todo Linux) | Não |
Este repositório contém o exploit implementado em 6 linguagens, todas funcionalmente equivalentes, com comentários educacionais em português.
copy_fail_exploit.c → C — binário estático, zero dependências
copy_fail_exploit.py → Python — mais legível, ideal para aprender
copy_fail_exploit.rs → Rust — a ironia: linguagem "segura" explora kernel
copy_fail_exploit.go → Go — binário estático, muito portátil
copy_fail_exploit.rb → Ruby — onipresente em servidores Rails
copy_fail_exploit.pl → Perl — o mais silencioso, está em todo Linux
test_cve_2026_31431.py → Detector — verifica vulnerabilidade sem explorar nada
python3 test_cve_2026_31431.py
# Compilar
gcc copy_fail_exploit.c -o copy_fail_c
# Dry-run (limpa ao sair, não deixa rastro)
./copy_fail_c
# Exploit completo
./copy_fail_c --shell
# Dry-run
python3 copy_fail_exploit.py