⏱️ Lectura: 8 min

El 29 de abril de 2026, el equipo Xint Code de Theori publicó los detalles técnicos de CVE-2026-31431, apodada Copy Fail: una falla en el subsistema de criptografía del kernel Linux que permite a cualquier usuario local sin privilegios ganar root mediante un exploit de 732 bytes en Python puro, sin race conditions, sin offsets específicos por distribución y con el mismo script funcionando idéntico en Ubuntu, RHEL, SUSE, Amazon Linux, Debian, Arch, Fedora, Rocky, Alma y Oracle Linux. La vulnerabilidad estuvo dormida en el código del kernel desde 2017, con CVSS asignado de 7.8 (alta).

📑 En este artículo
  1. Línea de tiempo
  2. Qué falla por dentro
  3. La cadena de explotación
  4. Lo que lo hace especialmente preocupante
  5. Versiones de kernel testeadas vulnerables
  6. Cómo mitigarlo ya
  7. Qué deja este caso
  8. Fuentes

Línea de tiempo

Fecha Evento
2017 Commit 72548b093ee3 introduce la optimización “in-place” en algif_aead, momento en que el bug nace.
23 mar 2026 Xint Code reporta la vulnerabilidad al kernel team.
22 abr 2026 Asignación oficial de CVE-2026-31431.
29 abr 2026 Disclosure coordinada. Distros principales sacan parches en simultáneo.

El bug fue encontrado por una herramienta de IA: Xint Code, el escáner que Theori desarrolló internamente. Según The Hacker News, el descubrimiento principal lo hizo el investigador Taeyang Lee con asistencia del scanner, lo que reduce el tiempo de hallazgo a aproximadamente una hora desde el momento que la herramienta se lanzó sobre el subsistema crypto.

Qué falla por dentro

El componente vulnerable es algif_aead, la implementación dentro del kernel que expone los algoritmos AEAD (Authenticated Encryption with Associated Data) hacia userspace mediante el socket family AF_ALG. El template específico que rompe todo es authencesn, que combina autenticación HMAC con cifrado AEAD usando un Extended Sequence Number.

La cadena tiene tres piezas:

  1. AF_ALG: un socket legítimo del kernel que da acceso a primitivas crypto desde userspace, pensado originalmente para que aplicaciones aprovechen aceleración hardware o para herramientas de bajo nivel.
  2. splice(): la syscall que mueve datos entre file descriptors por referencia, sin copiar. En este exploit, transfiere páginas del page cache al socket AF_ALG, manteniendo punteros directos a las páginas físicas que respaldan read(), mmap() y execve().
  3. El bug en authencesn: durante la operación, escribe 4 bytes en el offset assoclen + cryptlen, más allá del tag AEAD, usando el buffer destino como scratch space para reordenar bytes del Extended Sequence Number.

El resultado es una primitiva limpia: el atacante puede escribir 4 bytes controlados (seqno_lo, los bytes 4 a 7 del AAD) en cualquier offset del page cache de cualquier archivo que pueda leer. Y como el HMAC al final falla, la página queda corrupta pero no marcada como dirty, así que el kernel nunca la sincroniza al disco; la corrupción solo vive en memoria, donde la siguiente lectura o execve() la consume sin sospechar.

La cadena de explotación

El PoC oficial condensa todo en cinco pasos:

# 1. Abrir socket AF_ALG y bindear al template vulnerable
sock = socket.socket(AF_ALG, SOCK_SEQPACKET, 0)
sock.bind(b"aead", b"authencesn(hmac(sha256),cbc(aes))")

# 2. Por cada chunk de 4 bytes a escribir:
#    - sendmsg() lleva el valor a inyectar
#    - splice() pasa páginas del page cache del archivo target
sendmsg(payload_4bytes)
splice(target_file_page_cache_pages)

# 3. recv() dispara el decrypt; kernel escribe 4 bytes en page cache
# 4. HMAC falla; página corrupta pero NO dirty (no va al disco)
# 5. execve() del binario target carga código corrupto → shellcode con root

Theori cita el ejemplo más obvio: sobreescribir bytes en /usr/bin/su (o cualquier binario setuid root) con shellcode propio. Cuando otro proceso ejecuta ese binario, el kernel sirve la versión corrupta desde el page cache, el shellcode corre con privilegios elevados, y el atacante obtiene una shell de root.

Una cita literal de los investigadores recogida por The Hacker News resume el alcance: “An unprivileged local user can write four controlled bytes into the page cache of any readable file on a Linux system, and use that to gain root”.

Lo que lo hace especialmente preocupante

Tres cosas separan a Copy Fail de otros LPE recientes como Dirty Cow o Dirty Pipe:

  • Sin race conditions. El bug es un error de lógica lineal (“straight-line logic flaw”, según Xint), no una condición de carrera. No hay que ganarle a nada: el exploit es determinista.
  • Cero offsets específicos por distribución. En palabras del propio reporte de Xint Code: “the same exact script works on every tested distribution and architecture”. No hay que recompilar para Ubuntu vs Fedora vs Arch.
  • Container escape primitive. El page cache de Linux es host-wide, no está namespaced. Un pod malicioso en Kubernetes con kernel compartido (la configuración por defecto en la mayoría de clusters) puede modificar binarios que el host lee, escapando la frontera del contenedor sin tocar runtime ni kernel modules. Bugcrowd lo describe directamente como un vector de escape para nodos Kubernetes, mientras que The Register advierte que la mitigación arquitectural real pasa por microVM (Firecracker, gVisor) en lugar de aislamiento por namespaces.

Por sí solo no es remotamente explotable. Pero si un atacante ya consiguió RCE como usuario sin privilegios (vía un servicio web vulnerable, un parser de archivos, etc.), Copy Fail le entrega root local en milisegundos.

Versiones de kernel testeadas vulnerables

Xint confirmó la explotación con el mismo script en estos sistemas:

Distribución Kernel testeado
Ubuntu 24.04 LTS 6.17.0-1007-aws
Amazon Linux 2023 6.18.8-9.213.amzn2023
RHEL 10.1 6.12.0-124.45.1.el10_1
SUSE 16 6.12.0-160000.9-default

Por la naturaleza del bug (introducido en 2017 y que toca código que casi no cambió en 9 años), prácticamente cualquier kernel mainline desde 4.x hasta 6.x está afectado, incluyendo Debian, Arch, Fedora, Rocky, Alma y Oracle Linux. Si tu kernel es anterior al parche del distro, asumí que estás vulnerable.

Cómo mitigarlo ya

Opción 1 — actualizar el kernel (recomendada). Las distribuciones principales liberaron parches el día de la disclosure. Debian, Ubuntu y SUSE empujaron el fix de inmediato; Red Hat inicialmente difirió pero terminó publicando el parche en cuestión de horas tras la presión pública. El parche upstream es el commit a664bf3d603d del mantenedor crypto Herbert Xu, que revierte la optimización in-place de 2017 y vuelve algif_aead a operación out-of-place, separando req->src (TX scatterlist) de req->dst (RX scatterlist).

# Debian / Ubuntu
sudo apt update && sudo apt upgrade linux-image-generic && sudo reboot

# RHEL / Rocky / Alma
sudo dnf upgrade kernel && sudo reboot

# Arch
sudo pacman -Syu linux && sudo reboot

Opción 2 — mitigación interina sin reboot. Si no podés rebootear ya, deshabilitá el módulo vulnerable. algif_aead solo lo usan herramientas crypto explícitas (cierta integración con strongSwan, algunos benchmarks): para la gran mayoría de servidores no romper nada:

echo "install algif_aead /bin/false" | \
  sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null || true

Opción 3 — política seccomp para workloads no confiables. En entornos donde corren cargas de terceros (CI, Kubernetes multi-tenant, sandboxes), bloqueá la creación de sockets AF_ALG directamente vía seccomp, denegando socket(AF_ALG, ...) a procesos hijos del runtime.

Qué deja este caso

Copy Fail funciona como recordatorio de tres cosas:

  • Las “optimizaciones” en código de seguridad son cuchillos de doble filo. La mejora de 2017 que eliminó una copia de buffer ahorró ciclos pero abrió una primitiva de escritura cross-tenant. Cuando el código vive 9 años sin que nadie audite la asunción original, el costo termina siendo desproporcionado al beneficio.
  • El page cache compartido sigue siendo el talón de Aquiles del kernel multi-tenant. Es el mismo patrón que Dirty Cow (2016) y Dirty Pipe (2022) en distintas formas. Cualquier modelo de aislamiento basado solo en namespaces sigue corriendo el riesgo de un próximo “Dirty X” emergiendo de una superficie inesperada del kernel.
  • El descubrimiento por IA acelera el ciclo de hallazgo. Xint Code encontró el bug en aproximadamente una hora con un único prompt al scanner. Si herramientas así están disponibles para defensores también lo están para atacantes: el ciclo de divulgación coordinada se va a acortar, y los attackers que mantengan herramientas privadas similares van a tener ventana cada vez más estrecha contra el blue team.

Para administradores de Linux la lectura es directa: parchá hoy. Si gestionás un cluster Kubernetes con kernel compartido, asumí que cualquier pod no confiable puede escapar al host hasta que todos los nodos estén actualizados, y considerá reconsiderar el modelo de aislamiento si manejás cargas multi-tenant de verdad.

Fuentes

Categorías: Seguridad

Clara Vásquez

Analista de ciberseguridad enfocada en vulnerabilidades críticas, zero-days y amenazas emergentes. Cubre CVEs de alto impacto, análisis de malware, incidentes de ransomware y tendencias de seguridad para LATAM.

0 Comentarios

Deja un comentario

Marcador de posición del avatar

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.