
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 / del kernel de Linux
Kernels de Linux 4.14 – 6.18.21 (prácticamente todas las distribuciones desde 2017)
authencesnCVE-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
condition:
// High-confidence: unique algorithm string alone is sufficient
$alg_full
or
// Medium-confidence: socket primitive + option number
($socket_call and $solalg)
or
// Medium-confidence: splice into AEAD socket targeting a setuid path
($aead_bind and $splice and ($target_passwd or $target_su))
or
// PoC hex payload present alongside splice
($key_payload and $splice)
}
rule CVE_2026_31431_CopyFail_Mechanism {
meta:
description = "Behavioral: AF_ALG AEAD + splice combination suggestive of CVE-2026-31431 technique"
author = "Detection Engineering"
reference = "https://xint.io/blog/copy-fail-linux-distributions"
cve = "CVE-2026-31431"
date = "2026-04-30"
severity = "Medium"
note = "Higher false positive rate than HighConfidence rule — review matches in context"
strings:
$authencesn = "authencesn" ascii nocase
$af_alg_num = "socket(38" ascii
$sol_alg_num = "279" ascii
$splice = "splice(" ascii
condition:
($authencesn and $splice)
or
($af_alg_num and $sol_alg_num and $splice)
}
Guardar como /etc/audit/rules.d/cve-2026-31431.rules
Recargar con:
sudo auditctl -R /etc/audit/rules.d/cve-2026-31431.rules
``````bash
sudo augenrules --load
# or on older systems:
sudo auditctl -R /etc/audit/rules.d/cve-2026-31431.rules
Si deseas usar la herramienta con tu propia clave de API, puedes configurar la variable de entorno OPENAI_API_KEY:
export OPENAI_API_KEY="your-api-key-here"
O puedes pasarla directamente al ejecutar la herramienta:
python3 main.py --openai-api-key "your-api-key-here" --provider openai
Para usar Azure OpenAI, debes configurar las siguientes variables de entorno:
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com"
export AZURE_OPENAI_API_KEY="your-api-key-here"
export AZURE_OPENAI_API_VERSION="2023-05-15"
Luego ejecuta la herramienta con el indicador --provider azure:
python3 main.py --provider azure
Para usar un LLM local con Ollama, primero asegúrate de tener Ollama instalado y ejecutándose. Luego, descarga un modelo (por ejemplo, llama3):
ollama pull llama3
Luego ejecuta la herramienta con el indicador --provider ollama:
python3 main.py --provider ollama
Nota: Al usar un LLM local, el rendimiento puede variar según tu hardware. Se recomienda usar un modelo con al menos 7B parámetros para obtener mejores resultados.```bash
-a always,exit -F arch=b64 -S socket -F a0=0x26 -k cve_2026_31431_afalg_socket -a always,exit -F arch=b32 -S socket -F a0=0x26 -k cve_2026_31431_afalg_socket
-a always,exit -F arch=b64 -S splice -k cve_2026_31431_splice -a always,exit -F arch=b32 -S splice -k cve_2026_31431_splice
-w /etc/passwd -p rwa -k cve_2026_31431_passwd_access
-w /usr/bin/su -p xa -k cve_2026_31431_su_exec -w /usr/bin/sudo -p xa -k cve_2026_31431_sudo_exec
-a always,exit -F arch=b64 -S finit_module -S init_module -k cve_2026_31431_module_load -w /etc/modprobe.d -p wa -k cve_2026_31431_modprobe_conf
### Consultando correlaciones
Después de implementar las reglas, use `ausearch` para correlacionar coincidencias entre claves dentro de una ventana de tiempo:```bash
# Find all CVE-2026-31431 related events in the last hour
sudo ausearch -k cve_2026_31431_afalg_socket -k cve_2026_31431_splice \
--start recent -i | aureport --interpret
# Check if a specific PID hit both AF_ALG and splice
sudo ausearch -k cve_2026_31431_afalg_socket --start today -i \
| grep 'pid=' | awk -F'pid=' '{print $2}' | awk '{print $1}' | sort -u \
| while read pid; do
sudo ausearch -k cve_2026_31431_splice --start today -i | grep "pid=$pid" \
&& echo "[!] PID $pid hit both AF_ALG and splice — investigate"
done
Guárdelo como un archivo de reglas local (típicamente /var/ossec/etc/rules/local_rules.xml).
Requisitos previos: Estas reglas dependen de que auditd esté configurado con las reglas anteriores y de que el decodificador de auditd de Wazuh esté activo. Coinciden en el campo
audit.keypoblado por auditd, que es la forma correcta y fiable de conectar los dos sistemas. Las reglas usan<if_group>auditd</if_group>en lugar de un<if_sid>específico para seguir siendo compatibles entre versiones de Wazuh.```xml
Guardar como misp_cve_2026_31431.json e importar a través de MISP → Events → Import.
Nota: Reemplace los UUIDs marcadores de posición a continuación con UUID4 recién generados para su entorno antes de la importación. Los valores de marcador de posición se muestran en un formato coherente para facilitar la lectura.```json { "Event": { "uuid": "7f3a2d1e-8b4c-4f9a-a3e2-6d5c1b8e9f0a", "info": "CVE-2026-31431 Copy Fail — Linux LPE via authencesn page-cache write", "threat_level_id": "2", "analysis": "2", "date": "2026-04-30", "Attribute": [ { "type": "vulnerability", "category": "External analysis", "to_ids": false, "uuid": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "comment": "CVE identifier", "value": "CVE-2026-31431" }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e", "comment": "Vulnerability description", "value": "Logic flaw in Linux kernel authencesn cryptographic template. An unprivileged local user can write 4 attacker-controlled bytes into the page cache of any readable file via AF_ALG + splice(), enabling local privilege escalation. No race condition required. Affects kernels 4.14 through 6.18.21." }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f", "comment": "Attack vector summary", "value": "socket(38, 5, 0) [AF_ALG/SOCK_SEQPACKET] → bind authencesn(hmac(sha256),cbc(aes)) → setsockopt(SOL_ALG/279) → splice() page-cache pages into AEAD socket → 4-byte controlled write into page cache of target file" }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a", "comment": "Affected kernel range", "value": "Linux kernel 4.14 (commit 72548b093ee3) through 6.18.21" }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b", "comment": "Introducing commit (root cause)", "value": "72548b093ee38a6d4f2a19e6ef1948ae05c181f7 — algif_aead in-place AEAD optimization (2017)" }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "6f7a8b9c-0d1e-2f3a-4b5c-6d7e8f9a0b1c", "comment": "Fix commit — kernel 6.18.22 stable", "value": "fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8" }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "comment": "Fix commit — kernel 6.19.12 stable", "value": "ce42ee423e58dffa5ec03524054c9d8bfd4f6237" }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e", "comment": "Fix commit — kernel 7.0 mainline", "value": "a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5" }, { "type": "text", "category": "Other", "to_ids": true, "uuid": "9c0d1e2f-3a4b-5c6d-7e8f-9a0b1c2d3e4f", "comment": "IoC: Socket family (AF_ALG)", "value": "socket family 38 (AF_ALG)" }, { "type": "text", "category": "Other", "to_ids": true, "uuid": "0d1e2f3a-4b5c-6d7e-8f9a-0b1c2d3e4f5a", "comment": "IoC: Socket type (SOCK_SEQPACKET)", "value": "socket type 5 (SOCK_SEQPACKET)" }, { "type": "text", "category": "Other", "to_ids": true, "uuid": "1e2f3a4b-5c6d-7e8f-9a0b-1c2d3e4f5a6b", "comment": "IoC: Socket option (SOL_ALG = 279)", "value": "setsockopt level 279 (SOL_ALG)" }, { "type": "text", "category": "Other", "to_ids": true, "uuid": "2f3a4b5c-6d7e-8f9a-0b1c-2d3e4f5a6b7c", "comment": "IoC: Algorithm string (highest fidelity)", "value": "authencesn(hmac(sha256),cbc(aes))" }, { "type": "text", "category": "Other", "to_ids": true, "uuid": "3a4b5c6d-7e8f-9a0b-1c2d-3e4f5a6b7c8d", "comment": "IoC: Primary PoC target file", "value": "/etc/passwd (UID field offset targeted by PoC)" }, { "type": "text", "category": "Other", "to_ids": true, "uuid": "4b5c6d7e-8f9a-0b1c-2d3e-4f5a6b7c8d9e", "comment": "IoC: Secondary targets (setuid binaries)", "value": "/usr/bin/su, /usr/bin/sudo" }, { "type": "text", "category": "Other", "to_ids": false, "uuid": "5c6d7e8f-9a0b-1c2d-3e4f-5a6b7c8d9e0f", "comment": "Immediate mitigation", "value": "echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif-aead.conf && rmmod algif_aead" }, { "type": "url", "category": "External analysis", "to_ids": false, "uuid": "6d7e8f9a-0b1c-2d3e-4f5a-6b7c8d9e0f1a", "comment": "Official write-up", "value": "https://xint.io/blog/copy-fail-linux-distributions" }, { "type": "url", "category": "External analysis", "to_ids": false, "uuid": "7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b", "comment": "Official PoC repository", "value": "https://github.com/theori-io/copy-fail-CVE-2026-31431" } ], "Object": [ { "name": "vulnerability", "meta-category": "vulnerability", "Attribute": [ { "type": "vulnerability", "object_relation": "id", "value": "CVE-2026-31431" }, { "type": "cvss-score", "object_relation": "cvss-score", "value": "7.8" }, { "type": "text", "object_relation": "summary", "value": "Linux kernel authencesn LPE via AF_ALG + splice() page-cache write" } ] } ] } }
---
## Parche y Remediación
### Parche del Kernel
| Rama | Versión Corregida | Commit de Corrección |
|--------|--------------|------------|
| Stable 6.18.x | 6.18.22 | `fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8` |
| Stable 6.19.x | 6.19.12 | `ce42ee423e58dffa5ec03524054c9d8bfd4f6237` |
| Mainline | 7.0 | `a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5` |
La corrección revierte la optimización AEAD in situ de 2017 en `algif_aead.c` de vuelta a la operación fuera de lugar, asegurando que las páginas de caché de páginas nunca se coloquen en un scatterlist escribible.
### Guía Específica por Distribución
| Distribución | Acción |
|---|---|
| Ubuntu | `apt-get update && apt-get upgrade linux-image-generic`; verifique el aviso USN |
| RHEL / Rocky / Alma | `dnf update kernel`; verifique el aviso RHSB |
| Amazon Linux 2023 | `dnf update kernel`; verifique el aviso ALAS |
| SUSE / openSUSE | `zypper update kernel-default`; verifique el aviso SUSE SA |
| Debian | Verifique el rastreador de seguridad; el parche retroportado puede llegar antes de la actualización del kernel |
| Arch | `pacman -Syu` (rodante; recoja la corrección ascendente cuando llegue) |
### Verificación de Integridad Después de la Exposición
Si sospecha que ocurrió una explotación en un host antes del parche:```bash
# 1. Check if /etc/passwd UID fields have been tampered
# (compare against a known-good backup or secondary host)
awk -F: '$3 ~ /^0+$/ && $1 != "root" {print "SUSPICIOUS UID 0 ENTRY:", $0}' /etc/passwd
# 2. Drop the page cache to flush any in-memory modifications
# WARNING: This impacts performance temporarily
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
# 3. Verify setuid binaries against package manager
rpm -Va --nomtime 2>/dev/null | grep -E '^.{0,8}5.*su$|^.{0,8}5.*sudo$' # RHEL/rpm
debsums -s 2>/dev/null | grep -E 'su|sudo' # Debian/Ubuntu
# 4. Re-examine recently logged su/sudo invocations for unexpected UID transitions
journalctl -u sudo --since "48 hours ago" | grep "session opened for user root"
Importante: Las herramientas estándar de integridad de archivos (AIDE, Tripwire, debsums,
rpm -Va) verifican los hash en disco y mostrarán el binario como no modificado incluso después de la explotación de la caché de páginas. La caché de páginas se limpia de forma natural al reiniciar o condrop_caches. En un sistema reiniciado, la corrupción de la caché de páginas desaparece, pero el atacante puede haber establecido persistencia a través de otros medios.
| Indicador | Valor | Confianza |
|---|---|---|
| Familia de socket AF_ALG | 38 (primer argumento de socket()) | Medio — existen usos legítimos |
| Tipo de socket | 5 (SOCK_SEQPACKET) | Medio |
| Nivel de opción SOL_ALG | 279 (primer argumento de setsockopt()) | Medio |
| Cadena de algoritmo | authencesn(hmac(sha256),cbc(aes)) | Alto — inusual fuera de IPsec ESN |
| Cadena de syscall | socket(38) → setsockopt(279) → splice() | Alto |
| Carga útil clave del PoC | 0800010000000010 (hex, en setsockopt) | Alto para el PoC conocido |
| Objetivo principal del PoC | Campo UID de /etc/passwd | Medio |
| Objetivos secundarios | /usr/bin/su, /usr/bin/sudo | Medio |
| Módulo del kernel | algif_aead | Dependiente del contexto |
Paquete de detección mantenido contra el PoC oficial en theori-io/copy-fail-CVE-2026-31431. Si observa variantes de explotación no cubiertas por estas reglas, por favor abra un issue en el repositorio principal del PoC.