
Exploit de escalada de privilegios local para CVE-2026-31431, una sobrescritura de page-cache en el kernel de Linux mediante AF_ALG + splice. Incluye PoC, script de detección BPFtrace y entorno de pruebas QEMU para investigación de seguridad autorizada.
Escalada de privilegios local en el kernel de Linux mediante AF_ALG + sobrescritura de page-cache con splice
Solo para investigación de seguridad autorizada, pruebas de penetración y fines educativos. No lo utilice contra sistemas que no le pertenezcan o para los que no tenga permiso explícito por escrito.
CVE-2026-31431 es una vulnerabilidad de escalada de privilegios local (LPE) en el kernel de Linux. Un
usuario local sin privilegios puede obtener acceso root combinando la interfaz de socket AF_ALG con
splice() para realizar una escritura autenticada directamente en una página de page-cache perteneciente a un
binario setuid.
El exploit sobrescribe el binario su en la caché de páginas sin modificar el inodo en disco,
evadiendo los mecanismos de integridad que dependen únicamente de los metadatos del archivo o de las sumas de verificación a nivel de bloque.
| Campo | Valor |
|---|---|
| ID de CVE | CVE-2026-31431 |
| Tipo | Escalada de privilegios local (LPE) |
| Puntuación CVSS v3.1 | 7.8 Alta — AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (fuente: kernel.org) |
| Subsistemas del kernel | crypto/af_alg.c, mm/splice.c |
| Vector de ataque | Local — se requiere una cuenta de usuario sin privilegios |
| Causa raíz | algif_aead acepta sendfile() sobre un socket AEAD sin imponer semántica de copy-on-write en la página de page-cache mapeada antes de que splice() complete la transferencia |
| Distribución | Versión del kernel | Arquitectura |
|---|---|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws | x86_64 |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 | x86_64 |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 | x86_64 |
| SUSE 16 | 6.12.0-160000.9-default | x86_64 |
| Raspberry Pi OS (Pi 5) | 6.12.75+rpt-rpi-2712 | aarch64 |
.
├── exploit.py # PoC — sobrescritura de page-cache y escalada de privilegios
├── detect.bt # Script de BPFtrace para detección en tiempo real
├── run-vm.sh # Automatización del entorno de prueba QEMU (opcional)
├── PAYLOAD.md # Análisis de codificación del payload (hex → zlib → ELF → shellcode)
└── LICENSE
Ejecute exploit.py como usuario local sin privilegios en cualquier sistema vulnerable — no se necesita sudo:
python3 exploit.py
El script realiza los siguientes pasos:
AF_ALG (algif_aead) y localiza el binario su.su como descriptor de archivo sin procesar y sobrescribe sus páginas de page-cache mediante
AF_ALG + sendfile.Arquitecturas compatibles:
| Arquitectura | Variantes |
|---|---|
| x86_64 | — |
| aarch64 | — |
| riscv64 | — |
| ppc64le | — |
| arm | armv5l, armv6l, armv7l |
| x86 32 bits | i386, i486, i586, i686 |
| MIPS 64 bits | mips64, mips64el |
| LoongArch | loong64, loongarch64 |
| s390x | — |
Supervise los intentos de explotación en tiempo real con detect.bt. Requiere root:
sudo bpftrace detect.bt
# o
doas bpftrace detect.bt
El script rastrea tres indicadores por PID mediante una máscara de bits en @suspect[pid]:
| Bit | Syscall | Indicador |
|---|---|---|
0x1 | socket(AF_ALG, SOCK_SEQPACKET) | Socket AF_ALG creado |
0x2 | setsockopt(SOL_ALG, ...) | Operación criptográfica configurada |
0x4 | sendmsg(MSG_MORE) + splice() | Intento de sobrescritura de page-cache |
Se activa una alerta cuando los tres bits están establecidos (@suspect[pid] == 0x7) en el mismo PID.
exploit.pyAF_ALG/algif_aead cargadodetect.btbpftrace ≥ 0.12# Ubuntu/Debian
sudo apt install bpftrace
# RHEL/CentOS/Fedora
sudo dnf install bpftrace
# Amazon Linux
sudo yum install bpftrace
# SUSE
sudo zypper install bpftrace
# Alpine
sudo apk add bpftrace
Actualice el paquete del kernel de su distribución a uno que incluya el commit de la línea principal
a664bf3d603d,
que revierte la optimización in-place de algif_aead de 2017 para que las páginas de page-cache ya no
puedan terminar en la scatterlist de destino escribible. La mayoría de las distribuciones principales ya
están distribuyendo la corrección.
algif_aead (mientras se espera un parche)blacklist se puede evadir con un modprobe algif_aead explícito. La directiva install .../bin/false
anula por completo el comando de instalación, haciendo que cada intento de carga falle:
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif.conf
sudo rmmod algif_aead 2>/dev/null || true