
Reglas de detección, firmas YARA, reglas auditd/Wazuh y plantillas de eventos MISP para la vulnerabilidad LPE CVE-2026-31431 del kernel Linux (Copy Fail). Incluye IoCs, pasos de mitigación y análisis de exploits.
Publicado: 2026-04-30
CVSSv3: 7.8 (Alta)
Tipo: Escalada Local de Privilegios (LPE)
Subsistema: Plantilla criptográfica algif_aead / authencesn del kernel de Linux
Afecta: Kernels de Linux 4.14 – 6.18.21 (prácticamente todas las distribuciones desde 2017)
Referencias:
CVE-2026-31431 es un fallo lógico introducido en el kernel 4.14 (2017) en la intersección de tres cambios independientes:
authencesn (añadida en 2011 para soporte ESN en IPsec) escribe 4 bytes de datos de prueba más allá del límite de su búfer de salida.AF_ALG obtuvo soporte AEAD en 2015, permitiendo que el espacio de usuario envíe datos mediante splice() desde archivos en caché de páginas.algif_aead.c fue optimizado para operar in-situ (req->src == req->dst), colocando páginas activas de la caché de páginas en una lista de dispersión escribible.El resultado: un usuario sin privilegios puede escribir exactamente 4 bytes controlados por el atacante en la copia de la caché de páginas del kernel de cualquier archivo legible, incluidos binarios setuid y /etc/passwd, sin tocar el archivo en disco. El PoC funcional es un script Python de 732 bytes. Sin condición de carrera. Sin offsets específicos por distribución. Fiable en Ubuntu, RHEL, Amazon Linux y SUSE.
Attacker opens AF_ALG socket (family 38, type 5) └─ Binds to "authencesn(hmac(sha256),cbc(aes))" └─ Sets SOL_ALG (279) options including key and authsize └─ Accepts a connection socket
Attacker opens target file (e.g., /etc/passwd) read-only └─ Uses splice() to feed page-cache pages into the AEAD socket's RX buffer └─ Sends crafted AAD via sendmsg() — bytes 4–7 of AAD = attacker-controlled write value
authencesn performs in-place decryption: └─ scatterwalk_map_and_copy writes seqno_lo into the chained page-cache page └─ recvmsg() returns an error (HMAC fails — expected), but the write already happened
Page-cache now contains attacker-modified copy of the file └─ Kernel executes from page-cache, not disk └─ On-disk file is UNCHANGED — file integrity tools see nothing
El PoC apunta a `/etc/passwd`: encuentra el desplazamiento del campo UID del usuario en ejecución y lo sobrescribe con `0000`, luego invoca `su` para obtener un shell de root.
---
## Limitaciones de detección
> **Lee esta sección antes de implementar cualquier regla más abajo.**
Este exploit tiene dos propiedades que limitan significativamente la cobertura de detección:
**1. La escritura va a la caché de páginas, no al sistema de archivos.**
Cualquier herramienta de detección que monitoree eventos del sistema de archivos — `inotify`, `fanotify`, AIDE, Tripwire, watches de rutas de auditd — **no** observará la modificación. El archivo en disco nunca se escribe. Esto significa que las banderas `-p w` (escritura) en los watches de rutas de auditd para `/usr/bin/su` o `/etc/passwd` no capturarán la escritura real de explotación.
**2. El mecanismo utiliza interfaces legítimas del kernel.**
Los sockets `AF_ALG`, `splice()` y `authencesn` tienen usos legítimos (IPsec, autopruebas del kernel, E/S estilo sendfile). La detección debe centrarse en la *combinación* de estas primitivas en lugar de una sola aislada, y se deben esperar falsos positivos en sistemas que ejecuten IPsec o realicen pruebas criptográficas del kernel.
**Lo que la detección PUEDE capturar:**
- La llamada al sistema `socket(AF_ALG, SOCK_SEQPACKET, 0)`
- La llamada al sistema `splice()` correlacionada con la anterior, especialmente cerca del acceso a binarios setuid
- El script PoC en sí (mediante YARA)
- La cadena de algoritmo específica `authencesn(hmac(sha256),cbc(aes))` en la memoria del proceso o archivos de script
**Lo que la detección NO PUEDE capturar:**
- La escritura real en la caché de páginas (en memoria, sin evento del sistema de archivos)
- El uso posterior a la explotación de la entrada modificada de la caché de páginas (parece una llamada normal a `su` o `passwd`)
- Variantes que evitan Python o la cadena de algoritmo específica
---
## Mitigación inmediata
Antes de implementar reglas de detección, aplica esta mitigación en cualquier host sin parche:```bash
# Disable algif_aead kernel module — blocks the exploit primitive entirely
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null || true
Verifica que la mitigación esté activa usando el detector oficial:```bash
python3 test_cve_2026_31431.py
> **Nota:** El comando `rmmod` fallará si el módulo no está cargado actualmente; esto es aceptable. La configuración de `modprobe.d` evita cargas futuras. Esta mitigación no tiene impacto en cargas de trabajo estándar de TLS, SSH o cifrado de sistemas de archivos — solo afecta a IPsec con Números de Secuencia Extendidos usando la plantilla `authencesn`, lo cual es poco común fuera de puertas de enlace VPN dedicadas.
---
## Regla YARA
Guardar como `cve_2026_31431.yar`
> **Alcance de escaneo:** Esta regla está diseñada para escanear archivos de script Python en disco o extraídos de volcados de memoria. Coincidirá con el PoC conocido y variantes cercanas. NO detectará la actividad del exploit a nivel de syscall — use las reglas de auditd/Wazuh para eso.```yara
rule CVE_2026_31431_CopyFail_PoC_HighConfidence {
meta:
description = "High-confidence match: CVE-2026-31431 Copy Fail PoC or close variant"
author = "Detection Engineering"
reference = "https://xint.io/blog/copy-fail-linux-distributions"
cve = "CVE-2026-31431"
date = "2026-04-30"
severity = "High"
cvss = "7.8"
strings:
// Algorithm string unique to this exploit path — very high fidelity
$alg_full = "authencesn(hmac(sha256),cbc(aes))" ascii
// Specific socket call signature from PoC: AF_ALG=38, SOCK_SEQPACKET=5
$socket_call = "socket(38,5,0)" ascii
// SOL_ALG socket option (decimal 279)
$solalg = "setsockopt(279" ascii
// Hex key/iv payload written via setsockopt in PoC
$key_payload = "0800010000000010" ascii
// splice() usage in context of AEAD operations
$splice = "splice(" ascii
// Target indicators from PoC (page-cache corruption targets)
$target_passwd = "/etc/passwd" ascii
$target_su = "/usr/bin/su" ascii
// AF_ALG aead bind strings
$aead_bind = "\"aead\"" ascii