
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.
.
├── 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:
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]:
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
Los subsistemas en la fila "No" usan la API criptográfica del kernel directamente — nunca pasan por
AF_ALG. El rendimiento vuelve a las bibliotecas criptográficas normales del espacio de usuario, que es lo que
casi todo lo demás ya utiliza.
Para comprobar si algo en su sistema usa activamente AF_ALG antes de deshabilitarlo:
lsof | grep AF_ALG
ss -xa | grep alg
Deniegue la creación de socket(AF_ALG, ...) para cargas de trabajo no confiables independientemente del estado del parche. Añada
AF_ALG (familia 38) a su lista de denegación de seccomp, o use una política de AppArmor/SELinux que
restrinja las llamadas socket para procesos sin privilegios.
detect.btImplemente el script de detección incluido en cualquier host que no pueda ser parcheado o bloqueado inmediatamente. Alertará sobre cualquier proceso que ejecute la primitiva de explotación completa de tres pasos.
run-vm.sh automatiza la creación de una máquina virtual QEMU de Ubuntu 24.04 para pruebas en un entorno
controlado. exploit.py y detect.bt se ejecutan directamente en cualquier host vulnerable — QEMU no
es necesario.
| Dependencia | Notas |
|---|---|
qemu-system-x86_64 + KVM | Consulte los comandos de instalación a continuación |
wget o curl | Descarga de la imagen de nube |
cloud-image-utils |
# Ubuntu/Debian
sudo apt install qemu-system-x86 cloud-image-utils wget
# Fedora/RHEL
sudo dnf install qemu-system-x86 wget
# Arch
sudo pacman -Sy qemu
# Alpine
sudo apk add qemu-system-x86 qemu-ui-gtk wget
sh run-vm.sh
1. Iniciar/Crear VM
2. Conectar mediante SSH
3. Subir archivos a la VM (exploit.py, detect.bt)
4. Ejecutar exploit dentro de la VM
5. Ejecutar detect.bt dentro de la VM
6. Comprobar estado de la VM
7. Detener VM
8. Limpiar archivos de la VM
0. Salir
| Campo | Valor |
|---|---|
| Usuario | ubuntu |
| Contraseña | cve123 |
| Puerto SSH | 2222 |
crypto/af_alg.c — código fuente del kernelmm/splice.c — código fuente del kernelEste proyecto está licenciado bajo la GNU General Public License v3.0 o posterior. Consulte LICENSE para el texto completo.
Aviso legal: Este repositorio se proporciona únicamente para investigación de seguridad autorizada, pruebas de penetración y fines educativos. Los autores no aceptan ninguna responsabilidad por el mal uso o los daños causados por este software.
| 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 |
| 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 | — |
| 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 |
| ¿Afectado? | Subsistema/Caso de uso |
|---|
| No | dm-crypt/LUKS, kTLS, IPsec/XFRM, TLS en el kernel |
| No | OpenSSL, GnuTLS, compilaciones predeterminadas de NSS |
| No | SSH, criptografía del keyring del kernel |
| Quizás | OpenSSL con el motor afalg habilitado explícitamente |
| Quizás | Rutas de descarga criptográfica integradas o aplicaciones que enlazan sockets aead/skcipher/hash directamente |
| Generación de la imagen semilla (Docker puede sustituir en hosts que no sean Debian) |