Un fallo crítico de 9 años en el kernel de Linux que permite obtener acceso root en segundos
| Atributo | Detalles |
|---|---|
| CVE | CVE-2026-31431 |
| Apodo | Copy Fail |
| Tipo | Escalamiento de Privilegios Local (LPE) |
| CVSS | 7.8 (High) |
| Descubierto por | Theori (Xint Code) |
| Divulgación | 29 de abril de 2026 |
| Componente | Subsistema algif_aead del kernel de Linux |
Fallo en la optimización de "operación en el lugar" (in-place) introducida en 2017 (commit 72548b093ee3). Permite a un usuario local realizar una escritura controlada de 4 bytes directamente en la caché de páginas del kernel.
AF_ALG para acceder a algoritmos criptográficos del kernel/usr/bin/su) o archivos sensibles (/etc/passwd)Es un bug lógico de diseño, no un desbordamiento de memoria. Requería análisis profundo del subsistema criptográfico para detectarlo.
# Ubuntu/Debian
sudo apt update
sudo apt upgrade
sudo reboot
# RHEL/AlmaLinux/Rocky
sudo dnf update kernel
sudo reboot
# Verificar versión del kernel
uname -r
⚠️ El reinicio es obligatorio para activar el nuevo kernel.
# Deshabilitar la carga del módulo vulnerable
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/copyfail_mitigation.conf
# Descargar el módulo si ya está en uso
sudo rmmod algif_aead
# El módulo suele estar integrado en el kernel
# Añadir parámetro de arranque para deshabilitarlo
sudo grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init"
# Reiniciar para aplicar cambios
sudo reboot
# Purgar la caché de páginas en caliente
sudo sysctl -w vm.drop_caches=3
⚠️ Nota: Esto no reemplaza el parche. Es solo una medida complementaria.
| Fecha | Evento |
|---|---|
| 29 de abril | Divulgación pública por Theori |
| 1 de mayo |
# Obtener versión del kernel
uname -r
# Vulnerable si es:
# - v4.14 a v7.0-rc (lanzado entre 2017 y abril 2026)
# - Contiene el commit 72548b093ee3
# Verificar si el módulo algif_aead está cargado
lsmod | grep algif_aead
# Si aparece en la lista, tu sistema es vulnerable
Una IA identificó este fallo que pasó desapercibido para los desarrolladores durante 9 años. Esto marca un antes y un después:
# 1. Detect
python3 prueba.py
# exit 0 = not vulnerable, 2 = vulnerable, 1 = test error
# 2. Exploit (interactive — su will prompt for your own password)
python3 exploit.py --shell
python3 prueba.py
Qué hace:
Confirma que AF_ALG y el algoritmo authencesn(hmac(sha256),cbc(aes))
sean accesibles desde un proceso sin privilegios.
Crea un archivo centinela de 4 KiB en un directorio temporal y rellena la caché de páginas.
Envía 8 bytes de AAD en línea mediante sendmsg+cmsg con seqno_lo establecido en
el marcador PWND, y luego copia 32 bytes de la página de la caché de páginas del centinela en el socket de operación AF_ALG mediante os.splice().
Llama a recv() para iniciar el descifrado. La comprobación de autenticación falla con
EBADMSG; la escritura temporal se ejecuta de todos modos.
Vuelve a leer el archivo (caché de páginas, no el disco) y busca el marcador.
Clases de salida:
Condición previa no cumplida: AF_ALG o authencesn no disponibles. Salida 0.VULNERABLE a CVE-2026-31431: el marcador PWND se insertó en la página modificada.Salida 2.
Caché de página MODIFICADA mediante una ruta de inserción AEAD in situ: se escribió en la página,
pero el marcador no se insertó en la posición esperada.
Tratar como vulnerable. Salida 2.Caché de página intacta: parcheada. Salida 0.El detector nunca modifica /usr/bin/su, /etc/passwd ni ningún otro archivo fuera del directorio temporal que crea, y dicho archivo se elimina al finalizar.
Salida. ## Uso de LPE
python3 exploit_cve_2026_31431.py # Solo parchea, imprime los siguientes pasos
python3 exploit_cve_2026_31431.py --shell # Parchea y ejecuta `su <usuario>`
Función:
/etc/passwd y encuentra eldesplazamiento de bytes del campo UID de 4 caracteres.
write4 sobre ese desplazamiento, reemplazando el UID con0000.
pwd.getpwnam(usuario) para confirmar que libc ahora informa UID 0.--shell, ejecuta execvp("su", ["su", usuario]). Introduce tu propia
contraseña. PAM valida contra /etc/shadow (sin modificar), luegosetuid(getpwnam(user).pw_uid) se establece en 0.
requieren escrituras de múltiples disparos; extienda write4 según corresponda.
Ningún demonio de caché NSS (nscd, sssd, systemd-userdbd) está enmascarando
las lecturas de /etc/passwd. Si getpwnam aún devuelve el UID real después de
la aplicación del parche, reinicie o ignore la caché, o seleccione un usuario diferente.
La página /etc/passwd debe permanecer en la caché entre la aplicación del parche y la
ejecución de su. En la práctica, esto es fiable en cualquier sistema con una presión de memoria normal.
El archivo /etc/passwd en disco permanece sin cambios.
La ejecución en seco (exploit_cve_2026_31431.py sin --shell) elimina automáticamente
la página corrupta al salir mediante POSIX_FADV_DONTNEED, por lo que las búsquedas de UID → nombre
vuelven a la normalidad inmediatamente.
Tras usar --shell**, la página permanece corrupta hasta que se borra.
Mientras esté corrupta, cualquier operación que resuelva UID 1000 → nombre (por ejemplo, ls,
administradores de archivos, comprobaciones de propiedad de scp/sftp) fallará o mostrará identificadores numéricos. Para borrarlo:
# Sin privilegios: solicita la eliminación de la caché de páginas de /etc/passwd:
python3 -c "import os; fd=os.open('/etc/passwd', os.O_RDONLY); \
os.posix_fadvise(fd, 0, 0, os.POSIX_FADV_DONTNEED); os.close(fd)"
# Desde la consola de root:
echo 3 > /proc/sys/vm/drop_caches
Un reinicio también lo borra.
write4sendmsg([AAD de 8 bytes], cmsg=[ALG_SET_OP=DECRYPT, ALG_SET_IV, ALG_SET_AEAD_ASSOCLEN=8],
flags=MSG_MORE)
splice(target_fd, pipe_w, 32, offset_src=file_offset)
splice(pipe_r, op_fd, 32)
recv(op_fd) # EBADMSG; la escritura temporal ya se ha realizado
Los 4 bytes de las posiciones 4 a 7 del AAD (seqno_lo) son escritos por
authencesn en la lista de dispersión de destino, que en esta ruta de código
es la página de caché de páginas que extrajimos de target_fd. El desplazamiento de aterrizaje
dentro de la página corresponde al offset_src que pasamos a splice().
Hasta que el kernel parcheado llegue a tu distribución:
sudo tee /etc/modprobe.d/disable-algif-aead.conf <<<'install algif_aead /bin/false'
sudo rmmod algif_aead 2>/dev/null
Tras aplicar el parche, test_cve_2026_31431.py debería mostrar el mensaje «Precondición
no cumplida» y salir con código 0.
La corrección original revierte las operaciones AEAD in situ a operaciones fuera de lugar, manteniendo las páginas de la caché de páginas fuera de las listas de dispersión modificables.
algif_aeadalgif_aead en logs de auditoríaÚltima actualización: 3 de mayo de 2026
Estado: 🔴 CRÍTICO - Acción inmediata requerida
| Primeros intentos de explotación activa detectados |
| 2 de mayo | CISA ordena a agencias federales de EE.UU. parchear antes del 15 de mayo |
| 3 de mayo | Parches disponibles en Ubuntu, RHEL, AlmaLinux, Debian |
| Distribución | Estado | Referencia |
|---|
| Ubuntu | ✅ Parcheado | USN-8226-1 (20.04, 22.04, 24.04) |
| RHEL/AlmaLinux/Rocky | ✅ Disponible | Desde 1 de mayo |
| Debian | ✅ En repositorios de seguridad | Actualización disponible |
| Android | ⏳ Próximamente | Boletín de seguridad de junio 2026 |