Script de detecção para CVE-2026-31431 (Copy Fail) que verifica a versão do kernel, presença de patch, configurações do kernel, disponibilidade de socket AF_ALG, binários setuid e mitigações para determinar o status de vulnerabilidade em sistemas Linux.
Apenas detecção. Um PoC funcional já existe em copy.fail/#exploit. Este script é para administradores de sistemas e equipes de segurança determinarem onde estão vulneráveis — ou ainda vulneráveis após a aplicação de patches.
Em 29 de abril de 2026, uma vulnerabilidade chamada Copy Fail (CVE-2026-31431) foi divulgada publicamente pela Xint Code Research Team. É um bug lógico que está silenciosamente presente no kernel Linux desde aproximadamente 2017 — quase uma década — e permite que qualquer usuário local sem privilégios obtenha root.
Não é "obter root sob condições específicas com um pouco de sorte e vento a favor." Apenas... obter root. De forma confiável. Em praticamente todas as principais distribuições Linux.
Afeta Ubuntu, Amazon Linux, RHEL, SUSE e qualquer outra coisa que execute um kernel mainstream dos últimos ~8 anos. Mesmo script, sem recompilação, sem ajustes por distribuição.
Sim, é tão grave quanto parece.
O kernel Linux possui um subsistema criptográfico acessível a usuários sem privilégios via sockets AF_ALG. Existe um mecanismo chamado splice() que pode alimentar dados de arquivos diretamente nesse subsistema sem copiá-los — o que significa que a cópia em cache na memória do kernel de um arquivo (o "page cache") acaba dentro de uma operação criptográfica.
Um algoritmo específico — authencesn, usado para Números de Sequência Estendidos do IPsec — tem uma peculiaridade: ele usa o buffer de saída como espaço de rascunho e escreve 4 bytes ligeiramente além do que deveria. Normalmente inofensivo. Mas quando páginas do page cache de um binário setuid como /usr/bin/su acabam encadeadas nesse buffer de saída (graças a uma "otimização" de 2017 em algif_aead.c), esses 4 bytes caem diretamente na cópia em cache do binário no kernel.
A operação falha com um erro. O kernel nunca marca essa página como suja. O arquivo no disco permanece intacto. Ferramentas de integridade de arquivos que verificam checksums no disco não veem nada errado.
Mas o page cache é o que é executado. E su é setuid root.
O artigo técnico completo está em xint.io e vale genuinamente a pena ler.
Sete da versão original, mais seis novas verificações adicionadas para fechar lacunas de detecção:
| # | Verificação | O que procura |
|---|---|---|
| 1 | Versão do kernel | Este kernel está na faixa afetada (4.10–6.14)? |
| 2 | Presença do patch | O commit da correção está realmente no kernel em execução? |
| 3 | Módulo algif_aead | O módulo vulnerável está carregado ou pode ser carregado? |
| 4 | CONFIG_CRYPTO_AUTHENC (novo) | CONFIG_CRYPTO_AUTHENC está embutido (=y) ou como módulo (=m)? Esta única opção compila tanto authenc quanto authencesn. Embutido significa que a mitigação de blacklist do modprobe não faz nada. |
| 5 | CONFIG_CRYPTO_USER_API_AEAD (novo) | A interface de usuário AEAD do AF_ALG está sequer compilada? Se não, todo o caminho do exploit está fechado em tempo de compilação. |
| 6 | Socket AF_ALG | Um usuário sem privilégios pode abrir um agora? |
| 7 | Python os.splice | O caminho do exploit em Python puro está disponível? |
| 8 | Binários setuid | Lista estendida de alvos setuid-root legíveis presentes no sistema. |
| 9 | Mitigações | AppArmor, SELinux, seccomp — o que está em vigor? |
| 10 | Namespaces de usuário (novo) | Namespaces de usuário sem privilégios estão habilitados? (Não bloqueia o Copy Fail diretamente, mas afeta a superfície mais ampla de escalonamento local de privilégios.) |
| 11 | Transparent hugepages (novo) | Status do THP — pode afetar o alinhamento do page cache e a confiabilidade do exploit. |
| 12 | Detecção de ambiente (novo) | Contexto Docker/container/VM — containers compartilham o kernel do host; o host é o que precisa de patch. |
| 13 | Aviso de usuário root (novo) | Avisa se estiver executando como root, pois várias verificações dão falsos positivos para root independentemente das restrições de não privilegiados. |
O script Bash cobre a mesma lógica central de detecção, mas omite três itens específicos do Python:
| # | Verificação | Notas |
|---|---|---|
| 1 | Versão do kernel | |
| 2 | Presença do patch | |
| 3 | Módulo algif_aead | |
| 4 | Socket AF_ALG | Usa Python como auxiliar se disponível; recorre à inferência da configuração do kernel |
| 5 | Binários setuid | Lista estendida, igual à versão Python |
| 6 | Mitigações | AppArmor, SELinux, seccomp |
| 7 | CONFIG_CRYPTO_AUTHENC | |
| 8 | Namespaces de usuário | |
| 9 | Transparent hugepages | |
| 10 | Detecção de ambiente |
Não presente no script shell (em comparação ao Python):
| Verificação ausente | Motivo |
|---|---|
| CONFIG_CRYPTO_USER_API_AEAD | Ainda não implementado — planejado |
| Disponibilidade do Python os.splice | Não se aplica a um script shell |
| Aviso de usuário root | Ainda não implementado — planejado |
Nenhum dos scripts corrige ou explora nada. Eles dizem a verdade sobre o seu sistema para que você possa agir.
# Clone ou baixe o script e então:
python3 cve-2026-31431-detect.py
É isso. Relatório codificado por cores com um resumo no final.
O script sai com código não zero em achados vulneráveis, tornando-o adequado para uso em pipelines:
| Código | Significado |
|---|---|
0 | Nenhuma condição vulnerável encontrada |
1 | Uma ou mais condições vulneráveis encontradas |
# Exemplo: falhar uma etapa de CI se o host estiver vulnerável
python3 cve-2026-31431-detect.py
rc=$?
if [ $rc -eq 1 ]; then
echo "VULNERÁVEL — bloquear deploy"
elif [ $rc -ne 0 ]; then
echo "ERRO — script falhou ao concluir (exit $rc)"
fi
CVE-2026-31431 'Copy Fail' — Detecção de Vulnerabilidade
Corrupção do page cache do authencesn / escalonamento local de privilégios
Executando como uid=1001, euid=1001
=== Versão do Kernel ===
[VULNERÁVEL] Versão do kernel
Motivo : Kernel está na faixa vulnerável (4.10 – 6.14)
Detalhe : Release: 6.12.0-124.45.1.el10_1 — status do patch deve ser confirmado
=== CONFIG_CRYPTO_AUTHENC (Configuração do Kernel) ===
[VULNERÁVEL] CONFIG_CRYPTO_AUTHENC
Motivo : Compilado como módulo (=m): carrega automaticamente no bind() do AF_ALG; blacklist do modprobe é a mitigação correta
=== CONFIG_CRYPTO_USER_API_AEAD (Configuração do Kernel) ===
[VULNERÁVEL] CONFIG_CRYPTO_USER_API_AEAD
Motivo : A interface AEAD do AF_ALG é um módulo carregável — usuários sem privilégios podem acessar o subsistema criptográfico via sockets AF_ALG
...
O SISTEMA PROVAVELMENTE ESTÁ VULNERÁVEL AO CVE-2026-31431
Ações recomendadas:
1. Aplique a atualização de kernel da sua distribuição para o CVE-2026-31431
2. Até aplicar o patch, coloque o módulo na blacklist:
echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null
NOTA: isso é EFICAZ apenas quando CONFIG_CRYPTO_AUTHENC=m (módulo).
Se CONFIG_CRYPTO_AUTHENC=y (embutido), aplicar o patch é a única correção.
Um script Bash complementar (cve-2026-31431-detect.sh) está disponível para ambientes onde Python não está presente ou onde ferramentas nativas de shell são preferidas. Ele executa 10 das 13 verificações — veja a tabela de comparação de verificações acima para detalhes do que difere.
# Execução básica
bash cve-2026-31431-detect.sh
# Saída JSON — adequada para ingestão em SIEM, facts do Ansible, agregação de logs
bash cve-2026-31431-detect.sh --json > scan-results.json
# Modo silencioso — apenas imprime o resumo (útil em logs de CI)
bash cve-2026-31431-detect.sh --quiet
# Desabilitar cor ANSI (para arquivos de log)
bash cve-2026-31431-detect.sh --no-colour
O script shell usa os mesmos códigos de saída (0 = OK, 1 = vulnerável) e produz saída JSON equivalente para consumo em pipelines. Onde Python 3 está disponível no sistema, o script shell o usa para executar o teste ao vivo do socket AF_ALG; caso contrário, recorre à inferência da configuração do kernel.
A correção real é aplicar patch no kernel. Verifique os avisos de segurança da sua distribuição.
| Distribuição | Onde procurar |
|---|---|
| Ubuntu | ubuntu.com/security/CVE-2026-31431 |
| RHEL / Amazon Linux | dnf update kernel |
| SUSE | zypper update kernel-default |
| Debian | apt update && apt upgrade |
Se a verificação CONFIG_CRYPTO_AUTHENC reportar =m (compilado como módulo, não embutido), você pode colocá-lo na blacklist:
echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null
Importante: esta mitigação não tem efeito se
CONFIG_CRYPTO_AUTHENC=y(embutido). Nesse caso, aplicar patch no kernel é a única correção. A verificação CONFIG_CRYPTO_AUTHENC no script informa em qual situação você está. Observe queCONFIG_CRYPTO_AUTHENCé a chave correta de configuração do kernel — ela compila tanto os módulosauthencquantoauthencesna partir de uma única opção.
Isso pode afetar o IPsec se você o estiver usando — verifique antes de implantar em toda a frota.
A correção upstream é este commit — ele reverte a otimização AEAD in-place de 2017 em algif_aead.c, separando as scatterlists de origem e destino para que páginas do page cache não possam mais acabar no destino gravável.
Se você estiver executando isso dentro de um container Docker, pod Kubernetes ou outro ambiente de container, o script avisará: containers compartilham o kernel do host. A vulnerabilidade vive no kernel, não na imagem do container. Você deve avaliar e aplicar patch no host.
# GitHub Actions
# A etapa falhará naturalmente e bloqueará o pipeline quando o script sair com 1.
# Nenhuma configuração extra necessária — códigos de saída não zero falham etapas por padrão.
- name: Verificar CVE-2026-31431
run: |
python3 cve-2026-31431-detect.py
rc=$?
if [ $rc -eq 1 ]; then
echo "VULNERÁVEL — pipeline bloqueado"
exit 1
elif [ $rc -ne 0 ]; then
echo "ERRO — script de detecção falhou ao concluir (exit $rc)"
exit $rc
fi
# Ansible
# Usa playbook_dir para garantir que o caminho do script seja resolvido corretamente.
# failed_when verifica qualquer saída não zero (vulnerabilidade OU erro do script).
- name: Verificar CVE-2026-31431
script: "{{ playbook_dir }}/cve-2026-31431-detect.py"
register: cve_check
failed_when: cve_check.rc != 0
# Verificação Nagios / monitoramento (script shell — suporta códigos de saída nativamente)
bash cve-2026-31431-detect.sh --quiet
# exit 0 = OK, exit 1 = CRÍTICO (vulnerável)
# Saída JSON para SIEM / agregação de logs (script shell)
bash cve-2026-31431-detect.sh --json --quiet > /var/log/cve-2026-31431-$(hostname)-$(date +%Y%m%d).json
| Data | Evento |
|---|---|
| 2026-03-23 | Reportado à equipe de segurança do kernel Linux |
| 2026-03-24 | Reconhecido |
| 2026-03-25 | Patches propostos e revisados |
| 2026-04-01 | Correção commitada no kernel mainline |
| 2026-04-22 | CVE-2026-31431 atribuído |
| 2026-04-29 | Divulgação pública |
Créditos a Taeyang Lee na Theori pela percepção original da pesquisa, e à Xint Code Research Team pelo artigo completo de divulgação.
Encontrou um falso positivo? Uma distribuição que isso não detecta? Uma configuração de kernel que deveria ser verificada? PRs são bem-vindos. O objetivo é sinal preciso, não apenas texto vermelho assustador.
Esta ferramenta é fornecida como está para fins de segurança defensiva. Aponte-a para sistemas que você está autorizado a avaliar. Não seja estranho com isso.