
Copy Fail - CVE-2026-31431 - Implementação em C fortalecida para operações de red team e testes de penetração autorizados. ⚠️ Aviso Legal: Esta ferramenta destina-se exclusivamente a pesquisas de segurança autorizadas, testes de penetração autorizados e análises defensivas. Use em sistemas próprios ou para os quais você tenha permissão explícita por escrito para testar. O acesso não autorizado a sistemas de computador é ilegal.
Implementação C endurecida para operações de redteam e testes de penetração autorizados.
⚠️ Aviso Legal: Esta ferramenta destina-se exclusivamente a pesquisas de segurança autorizadas, testes de penetração autorizados e análises defensivas. Utilize apenas em sistemas que você possui ou para os quais tenha permissão explícita por escrito para testar. O acesso não autorizado a sistemas de computador é ilegal.
🚀 Desenvolvimento primário movido para GitLab.
Este repositório é mantido ativamente aqui. Para problemas e contribuições, use o GitLab.
Este projeto é uma porta C endurecida e pronta para produção do exploit de escalonamento de privilégio local CVE-2026-31431 ("Copy Fail"), originalmente divulgado por Theori e Xint em 29 de abril de 2026.
O proof-of-concept original foi escrito em Python e projetado para demonstração de pesquisa. Esta implementação o transforma em um kit de ferramentas de nível redteam com:
| Atributo | Valor |
|---|---|
| Data de Divulgação | 29 de abril de 2026 |
| Pesquisadores | Theori (Jinoh Kang, Yonghwi Jin, Seunghyun Lee), Xint |
| Artigo | https://copy.fail/ |
| PoC Original | theori-io/copy-fail-CVE-2026-31431 (Python) |
| Porta C (Base) | tgies/copy-fail-c por Tony Gies |
| Kernels Afetados | Linux 4.14 -- 6.14 (antes do commit de correção a664bf3d603d) |
| Severidade | CVSS 7,8 (Alta) -- Escalonamento de Privilégio Local |
A vulnerabilidade reside no subsistema criptográfico AF_ALG do kernel Linux. O template AEAD authencesn implementa uma otimização in-place para descriptografia: quando o texto cifrado é fornecido via splice() a partir do cache de páginas de um arquivo, o kernel reutiliza a mesma página como fonte e destino.
O fluxo de ataque:
/usr/bin/su) como somente leituraauthencesn(hmac(sha256),cbc(aes)) via AF_ALGsplice() a partir do cache de páginas do arquivo alvoexecve() no alvo -- o kernel carrega as páginas mutadas do cache, concede credenciais setuid-rootInsight chave: O inode no disco nunca é modificado. Apenas o cache de páginas na memória é mutado, tornando a detecção forense significativamente mais difícil do que exploits tradicionais de sobrescrita de arquivos.
Este projeto estende a pesquisa original com endurecimento orientado a redteam em nove módulos.
patch_chunk.c)| Característica | Original | Nossa Implementação |
|---|---|---|
| Gerenciamento de sockets | Socket novo por chunk | Reuso de socket (~60% menos syscalls) |
| Verificação | Nenhuma | mmap + memcmp com repetição automática (3 tentativas) |
| Escrita paralela | Sequencial apenas | Paralela baseada em fork (até 16 processos) |
| Códigos de erro | Sucesso/falha binário | Granulares: 0=verificado, 1=kernel corrigido, -1=fatal |
| Alocações de heap | malloc no caminho crítico | Apenas pilha (sem jitter de alocação) |
target_discovery.c)su, sudo, passwd, pkexec, mount, ping, etc./snap (setuid não tradicional)anti_forensics.c)| Técnica | Propósito |
|---|---|
posix_fadvise(POSIX_FADV_DONTNEED) | Evicção do cache de páginas por arquivo |
echo 3 > /proc/sys/vm/drop_caches | Limpeza global de cache (pós-root) |
utimensat() timestomp | Restaura atime/mtime original |
| Autodestruição | Sobrescreve o binário dropper com zeros antes do exec |
| Limpeza de memória | volatile zerando buffers sensíveis |
memfd_exec.c)kworker, anon_inode, eventfd (se mistura em /proc/$pid/fd/)stage1.c)| Canal | Furtividade | Velocidade | Prioridade de Fallback |
|---|---|---|---|
| Embutido | Máxima | Instantâneo | Último (airgap) |
| HTTP direto | Médio | <1s | Primeiro |
| System curl/wget | Baixo | 1-3s | Segundo (suporte HTTPS) |
| DNS TXT | Alto | Lento | Terceiro (bypass de firewall) |
stage2_template.c)SIGUSR1 (acionar), SIGUSR2 (status), SIGTERM (desligar)[kworker/N:0] no ps/topproc_hide.c)/proc/$pid/cmdlineSSH_*, AWS_*, TOKEN*, etc.setsid() + setpgid() para independência do terminalsignal_trigger.c)| Modo | Comportamento | Caso de Uso |
|---|---|---|
trigger_oneshot() | Dormir → acionar → executar → sair | Bate-e-corre |
trigger_daemon() | Dormir → acionar → executar → loop | Implante persistente |
trigger_auto() | Dormir com fallback de timeout | Operações não supervisionadas |
Espera com zero CPU: sigsuspend() em vez de loops de polling.
sleep_jitter.c)getrandom(2), /dev/urandom, fallback rdtscsleep_scheduled() mantém intervalo médio apesar do jittercheck_sandbox_acceleration() detecta sleep() corrigida