Shopping cart

Subtotal $0.00

View cartCheckout

Building better devs

TnewsTnews
  • Home
  • Notícias
  • Copy Fail: O Exploit de 732 Bytes que Hackeia Qualquer Linux Desde 2017
Notícias

Copy Fail: O Exploit de 732 Bytes que Hackeia Qualquer Linux Desde 2017

Email : 16

Um script Python de 732 bytes. Sem race condition. Sem offset de kernel. Root em qualquer distro Linux mainstream dos últimos 9 anos.

Parece exagero? Eu também achei — até ler o disclosure completo do Copy Fail, publicado em 29 de abril de 2026 e já com mais de 1.000 pontos no Hacker News. O CVE-2026-31431 é o tipo de bug que faz engenheiro de segurança perder o sono: uma falha de lógica pura no kernel Linux que existe desde 2017 e que ninguém percebeu por quase uma década.

Diferente do Dirty Cow ou do Dirty Pipe, que dependiam de race conditions ou de versões específicas do kernel, o Copy Fail funciona de forma determinística. Você roda o script, ele escreve 4 bytes na page cache de qualquer arquivo legível pelo usuário, e pronto — game over.

Vamos entender como isso funciona, por que demorou tanto para ser encontrado, e o que você precisa fazer agora para se proteger.

A cadeia de ataque: três subsistemas, um bug

O Copy Fail não é um buffer overflow clássico nem uma race condition. É o que o pesquisador chamou de “straight-line logic flaw” — um erro na lógica do código que se manifesta de forma confiável, sem precisar “ganhar” nenhuma corrida contra o kernel.

A cadeia de ataque encadeia três subsistemas do kernel Linux:

Subsistema Papel no ataque
AF_ALG (socket interface) Expõe operações criptográficas para userspace sem privilégios
splice() Transfere dados entre file descriptors usando referências diretas à page cache — sem copiar os dados
algif_aead.c (crypto template) Operação in-place que aponta req->src = req->dst, colocando páginas da page cache no scatterlist de destino

A mágica (ou o horror, dependendo da perspectiva) acontece quando esses três se encontram.

Como o kernel acabou escrevendo onde não devia

Para entender o bug, preciso explicar um pouco de história.

2011 — O algoritmo authencesn foi adicionado ao kernel (commit a5079d084f8b) para suportar IPsec ESP com Extended Sequence Numbers. Ele usa o buffer de destino como scratch space temporário para rearranjar bytes do AAD (Associated Authenticated Data). Nessa época, source e destination eram scatterlists separados, então nenhum dado externo era afetado.

2015 — O algif_aead.c ganhou suporte a AEAD via AF_ALG com path de splice(), mas manteve a operação out-of-place. Scatterlists separados. Tudo seguro.

2017 — Aqui o bicho pegou. O commit 72548b093ee3 adicionou uma otimização de operação in-place. A ideia era simples: por que manter dois scatterlists separados se podemos usar um só? O código passou a fazer req->src = req->dst, combinando tudo em um único scatterlist.

O problema? Quando dados chegam via splice(), as páginas do scatterlist de destino são referências diretas à page cache do arquivo-alvo. E o authencesn faz uma escrita de 4 bytes nesse scatterlist como parte do processamento criptográfico.

Em código simplificado, a sequência fatal é:


// authencesn rearranges AAD bytes using destination as scratch
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);           // lê AAD
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);           // sobrescreve dst[4..7]
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1);  // BOOM

A terceira escrita — dst[assoclen + cryptlen] — cruza a fronteira do buffer de output e atinge a page cache do arquivo-alvo. E o authencesn nunca restaura os bytes originais. A escrita é permanente.

Por que isso é diferente do Dirty Cow e do Dirty Pipe

Característica Dirty Cow (2016) Dirty Pipe (2022) Copy Fail (2026)
Tipo de bug Race condition Inicialização incorreta de pipe flags Falha de lógica no crypto path
Precisa de race? Sim Não Não
Precisa de offsets? Sim Parcialmente Não
Determinístico Não Sim Sim
Tamanho do exploit ~2KB+ ~1KB 732 bytes
Escrita controlada Parcial Parcial Total (4 bytes, offset e valor controlados)
Detecção por HIDS Sim Sim Não (page cache, disco inalterado)

Essa última linha é a que tira o sono. O Copy Fail corrompe a page cache — a cópia em memória do arquivo — mas nunca marca a página como “dirty” para writeback. O arquivo no disco permanece intacto. Ferramentas de integridade como AIDE, Tripwire ou OSSEC que comparam checksums no disco não vão detectar nada.

O exploit de 732 bytes: passo a passo

O atacante controla três variáveis:

  1. Arquivo-alvo: qualquer arquivo legível pelo usuário corrente
  2. Offset: determinado pelos parâmetros de splice offset, splice length e assoclen
  3. Valor: os 4 bytes escritos derivam das posições 4-7 do AAD, construído via sendmsg()

O ataque em si é assustadoramente simples:


import socket

# Step 1: Abre socket AF_ALG — sem privilégios
a = socket.socket(38, 5, 0)  # AF_ALG, SOCK_SEQPACKET
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))

# Step 2: Configura a chave e parâmetros
# ... (setup do algoritmo AEAD)

# Step 3: sendmsg() com AAD contendo o payload nos bytes 4-7
# Step 4: splice() do arquivo-alvo (ex: /usr/bin/su)
# Step 5: recv() dispara a operação de decriptação
# authencesn escreve seqno_lo na page cache do arquivo
# A operação falha (ciphertext fabricado), mas a escrita persiste

Para cada chunk de 4 bytes de shellcode, o atacante repete o ciclo sendmsg + splice + recv. O HMAC falha porque o ciphertext é fabricado, recvmsg() retorna erro, mas a escrita na page cache já aconteceu.

No final, o atacante executa execve("/usr/bin/su"). Como o su é setuid-root, o kernel carrega o binário da page cache corrompida, e o shellcode injetado roda como UID 0.

Root. Em qualquer distro. Sem precisar de nada além de um terminal e Python.

Quem está vulnerável

A resposta curta? Basicamente todo mundo que roda Linux e não atualizou o kernel nos últimos dias.

O disclosure confirmou exploits funcionando em:

  • Ubuntu 24.04 LTS (kernel 6.17.0-1007-aws)
  • Amazon Linux 2023 (kernel 6.18.8-9.213.amzn2023)
  • RHEL 10.1 (kernel 6.12.0-124.45.1.el10_1)
  • SUSE 16 (kernel 6.12.0-160000.9-default)

O mesmo script Python de 732 bytes funciona em todas, sem modificação. Nada de compilar exploit para cada distro, nada de ajustar offsets.

Ambientes mais críticos:

  • Cloud multi-tenant (EC2, GCP, Azure) — um container ou VM comprometida dá root no host
  • CI/CD runners — código não confiável rodando em pipelines pode escalar privilégios
  • Servidores compartilhados — hosting, universidades, qualquer ambiente com múltiplos usuários

A furtividade que assusta: por que ninguém detecta

Vou repetir porque vale: o Copy Fail não altera o arquivo no disco. Ele corrompe apenas a cópia em memória (page cache). Isso significa que:

  • sha256sum /usr/bin/su retorna o hash correto (lê do disco)
  • cat /usr/bin/su | sha256sum pode retornar o hash corrompido (lê da page cache)
  • Ferramentas como AIDE, Tripwire e OSSEC que fazem verificação periódica de integridade não vão acusar nada
  • Reboots “limpam” a corrupção porque a page cache é descartada e recarregada do disco

Isso cria um cenário perverso para incident response. Um atacante pode obter root, fazer o que quiser, e depois reiniciar o serviço afetado. A page cache é recarregada do disco limpo, e qualquer evidência forense baseada em integridade de arquivos desaparece.

Em ambientes de cloud, a situação é ainda pior. Containers compartilham o kernel do host. Se um processo dentro de um container sem privilégios executa o exploit, ele ganha root no host — não só dentro do container. Kubernetes, Docker, LXC — todos afetados da mesma forma.

Como o bug foi encontrado

Aqui tem um detalhe interessante: a vulnerabilidade foi identificada com assistência de IA. Segundo o disclosure, pesquisadores da Xint Code usaram modelos de linguagem guiados por contexto específico — focando na interação entre splice() e scatterlists criptográficos — e o scan identificou o bug em aproximadamente uma hora.

Isso levanta uma questão que a comunidade de segurança vai mastigar por meses: se uma IA encontrou esse bug em uma hora, quantos outros bugs similares existem esperando para serem encontrados da mesma forma? O kernel Linux tem milhões de linhas de código e interações complexas entre subsistemas que humanos simplesmente não conseguem auditar na mesma velocidade.

Já vimos essa tendência se acelerando. O Claude encontrou um bug de 23 anos no Linux no início de abril, e a DARPA financiou projetos de IA para bug hunting com milhões de dólares. O Copy Fail é mais um sinal de que a era da auditoria manual de segurança está chegando ao fim.

O fix é simples (e meio óbvio)

O patch (commit a664bf3d603d) reverteu a otimização de 2017. Em vez de operação in-place, o kernel volta a usar scatterlists separados:

Antes:


req->src = req->dst;  // combined scatterlist, page cache pages writable

Depois:


req->src = sgl->src;  // TX SGL (input only)
req->dst = sgl->dst;  // RX SGL (user's buffer, no page cache pages)

Páginas da page cache ficam apenas no scatterlist de origem (leitura), nunca no de destino (escrita). A otimização de 2017 se foi — e com ela, o vetor de ataque.

O que fazer agora

Se você administra servidores Linux — e se está lendo isso, provavelmente administra — aqui vai o plano de ação:

Passo 1: Atualize o kernel

Verifique se sua distro já lançou o patch:


# Ubuntu/Debian
sudo apt update && sudo apt upgrade linux-image-$(uname -r)

# RHEL/CentOS/Fedora
sudo dnf update kernel

# SUSE
sudo zypper update kernel-default

# Após atualizar, reinicie
sudo reboot

Passo 2: Mitigação imediata (se não pode reiniciar agora)

Desabilite o módulo vulnerável:


# Blacklist do módulo algif_aead
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf

# Se o módulo já está carregado, remova
sudo rmmod algif_aead 2>/dev/null

# Alternativa: bloqueie AF_ALG via seccomp
# (requer configuração específica por aplicação)

Passo 3: Verifique se o módulo está carregado


lsmod | grep algif_aead

Se não retornar nada, o módulo não está carregado e a superfície de ataque é menor (mas não zero — qualquer processo pode carregar o módulo via socket).

Passo 4: Monitore

Ferramentas tradicionais de integridade de arquivos não detectam corrupção de page cache. Se você precisa de garantia, considere:

  • Reiniciar serviços críticos (força reload da page cache do disco limpo)
  • Verificar binários setuid comparando com pacotes da distro: rpm -V ou debsums
  • Monitorar logs de AF_ALG socket creation via auditd

# Auditd rule para detectar uso de AF_ALG
sudo auditctl -a always,exit -F arch=b64 -S socket -F a0=38 -k af_alg_usage

Timeline do disclosure

O processo de responsible disclosure seguiu o protocolo padrão do kernel:

Data Evento
23/03/2026 Vulnerabilidade reportada ao Linux kernel security team
24/03/2026 Acknowledgment inicial
25/03/2026 Patches propostos e revisados
01/04/2026 Patches commitados no mainline
22/04/2026 CVE-2026-31431 atribuído
29/04/2026 Disclosure público

Foram 37 dias entre o report e o disclosure público. As distros tiveram quase um mês para preparar patches — e a maioria já tem atualizações disponíveis. Se você ainda não aplicou, o exploit já é público e qualquer pessoa pode reproduzi-lo.

O contexto maior

O Copy Fail é o terceiro grande exploit de page cache/pipe do Linux em quatro anos, depois do Dirty Pipe (2022) e do Wall Escape (2024). E cada um é mais elegante que o anterior.

A comunidade no Hacker News já está debatendo se o modelo de segurança do kernel Linux precisa de uma revisão fundamental. O AF_ALG em particular é um subsistema que expõe operações criptográficas complexas para userspace sem privilégios — uma superfície de ataque enorme que poucos olhos realmente auditam. Quantos outros subsistemas obscuros do kernel têm problemas similares? O io_uring já deu dor de cabeça suficiente. O eBPF vive sendo alvo. E agora o AF_ALG entra na lista.

O CVSS score de 7.8 pode parecer “alto” mas não “crítico” — até você perceber que a exploração é trivial, determinística, e funciona em qualquer distro. Na prática, o impacto real é muito maior do que o score sugere.

Enquanto isso, a IA está acelerando a descoberta de vulnerabilidades em ritmo exponencial. Se o Copy Fail foi encontrado em uma hora com assistência de modelos de linguagem, estamos entrando numa era onde o “security through obscurity” dos subsistemas menos populares do kernel simplesmente não funciona mais.

A corrida agora é entre pesquisadores e atacantes — ambos com acesso às mesmas ferramentas de IA. E o kernel Linux, com seus 30+ milhões de linhas de código e décadas de otimizações acumuladas, é o campo de batalha perfeito.


Fonte de inspiração: Copy Fail — CVE-2026-31431 | Xint Code Blog

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts