
Uma implementação em Bash do copyfail (CVE-2026-31431)
Sem corrida. Sem offsets. Sem binário pré-compilado para confiar cegamente.
Uma implementação em bash do CVE-2026-31431 (Copy Fail). O script compila um helper mínimo em C inline em tempo de execução. A camada bash trata da detecção de arquitetura, descompressão do payload e seleção do alvo; a camada C faz a interação real com o kernel (sockets AF_ALG, splice, sendmsg) que o bash não consegue alcançar sozinho.
Veja copy.fail para a análise técnica completa.
O bug está em algif_aead, a interface de socket AF_ALG AEAD do kernel. Uma otimização in-place de 2017 permite que páginas do page cache acabem na scatterlist de destino gravável de uma operação de descriptografia authencesn. Alimente-a com a entrada certa via splice() e você obtém uma gravação determinística de 4 bytes no page cache de qualquer arquivo legível, incluindo binários setuid que não são seus.
Sobrescreva /usr/bin/su com shellcode, 4 bytes por vez, execute-o e obtenha um shell root. Sem janela de corrida, sem símbolos específicos do kernel, sem tentativas repetidas.
chmod +x copyfail.sh
# Check if the system is vulnerable before doing anything
./copyfail.sh -c
# Run the exploit (must be non-root)
./copyfail.sh
# Specify a different setuid target
./copyfail.sh -t /usr/bin/passwd
# List all setuid-root candidates on the system
./copyfail.sh -s
O exploit sobrescreve apenas o page cache em memória; o arquivo em disco não é tocado. Uma reinicialização restaura tudo. Se quiser limpar imediatamente:
# Inside your root shell
/usr/bin/su --version # still works from disk if page cache is evicted
# Or just reboot
Se você usou -t com algo diferente de su, é o mesmo esquema. Apenas page cache, disco limpo.
gcc para compilar o helper C inlinepython3 para descomprimir o payload de shellcode (comando de uma linha, sem pacotes necessários)algif_aead, authencesn, hmac, cbcSe o algoritmo não estiver disponível:
sudo modprobe algif_aead authencesn hmac cbc
Algumas distros incluem um bloqueio em /etc/modprobe.d/ como solução temporária. Remova-o se estiver presente:
sudo rm /etc/modprobe.d/disable-algif{_,-}aead.conf 2>/dev/null
floor: torvalds/linux 72548b093ee3 August 2017, v4.14
(AF_ALG iov_iter rework that introduced
the file-page write primitive via splice
into the AEAD scatterlist)
ceiling: torvalds/linux a664bf3d603d April 2026, mainline
(reverts the 2017 in-place optimization;
source and destination scatterlists are
now separate, page-cache pages can no
longer end up as writable crypto output)
Entre esses dois commits: toda grande distro que não aplicou o backport da correção. Ubuntu, RHEL, SUSE, Amazon Linux e Debian foram todos confirmados vulneráveis na época da divulgação. Os backports das distros começaram a chegar por volta de 2026-04-29. Para verificar um kernel específico, procure por a664bf3d603d (ou o backport da distro) no changelog.
| Arquitetura | Status |
|---|---|
| x86_64 | ✓ |
| aarch64 | ✓ |
| i386 / i686 | ✓ |
| armv7l | ✓ |
Permanente: atualize seu kernel.
Solução alternativa (bloqueia o socket AF_ALG; não afeta IPsec/XFRM, que usa a API de criptografia do kernel diretamente):
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null
Contêineres: adicione um perfil seccomp que bloqueie a criação de sockets AF_ALG e defina allowPrivilegeEscalation: false no contexto de segurança do seu pod. Isso ativa o no_new_privs, o que impede o kernel de honrar os bits setuid no execve().
A versão bash não vence em dependências, mas é um único script que você pode ler do início ao fim antes de executar. O helper C é gerado e compilado em tempo de execução a partir de um heredoc, sem blob binário para auditar separadamente.
Apenas para testes de segurança e pesquisa autorizados. Não execute isto em sistemas que você não possui ou para os quais não tem permissão explícita por escrito para testar.
| Python | Go | Bash |
|---|
| Dependência | python3 | nenhum (binário estático) | gcc + python3 |
| Binário pré-compilado | não | sim | não |
| Arquivo único | sim | não | sim |
| Etapa de compilação | não | não | sim (inline, automático) |