
Detector + PoC para vulnerabilidades de escritura en el page-cache de Linux: Copy Fail (CVE-2026-31431) y Dirty Frag (CVE-2026-43284/43500). Solo para investigación de seguridad autorizada.
Un detector unificado y un banco de pruebas de PoC para las familias de vulnerabilidades de escritura en caché de páginas de Linux Copy Fail y Dirty Frag.``` ██████╗ ██╗██████╗ ████████╗██╗ ██╗███████╗ █████╗ ██╗██╗ ██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗ ██╔╝██╔════╝██╔══██╗██║██║ ██║ ██║██║██████╔╝ ██║ ╚████╔╝ █████╗ ███████║██║██║ ██║ ██║██║██╔══██╗ ██║ ╚██╔╝ ██╔══╝ ██╔══██║██║██║ ██████╔╝██║██║ ██║ ██║ ██║ ██║ ██║ ██║██║███████╗ ╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝
DIRTYFAIL es una herramienta C pequeña y bien documentada para investigadores de seguridad.
Detecta si un host Linux es vulnerable a los tres CVE de esta familia y — con
confirmación explícita y escrita — ejecuta una prueba de concepto real que deja
al llamador en un shell root en un sistema vulnerable.
| CVE / variante | Nombre | Cobertura de DIRTYFAIL |
|---|---|---|
| **CVE-2026-31431** | Copy Fail (escritura de page-cache `authencesn` de algif_aead) | Detección + PoC completa |
| **CVE-2026-43284 v4** | Dirty Frag — escritura de page-cache xfrm-ESP IPv4 | Detección + PoC completa |
| **CVE-2026-43284 v6** | Dirty Frag — escritura de page-cache xfrm-ESP IPv6 (`esp6`) | Detección + PoC completa |
| **CVE-2026-43500** | Dirty Frag — escritura de page-cache RxRPC | Detección + PoC completa |
| Variante GCM de Copy Fail | escritura de page-cache xfrm-ESP `rfc4106(gcm(aes))` | Detección + PoC completa |
**Modos adicionales:**
- **`--scan --active`** — sondas activas de STORE en archivo centinela. Por
defecto, `--scan` informa de las precondiciones por CVE (kernel, módulos,
estado del LSM) además de una sonda activa de la primitiva Copy Fail. Añadir
`--active` extiende la sonda STORE de archivo centinela a las otras cuatro
primitivas (ESP v4, ESP v6, RxRPC, GCM): cada una dispara el trigger del
kernel contra un centinela en `/tmp` e informa VULNERABLE solo si los bytes
de marcador aterrizan realmente. Esta es la única forma de distinguir un
kernel con parche backportado (las precondiciones dicen vulnerable pero la
sonda dice intacto) de uno sin parchear sin ejecutar el exploit completo.
`/etc/passwd` nunca se toca. Auto-calibra el desplazamiento V6 STORE por
compilación de kernel.
- **`--exploit-backdoor`** — backdoor persistente uid-0: sobrescritura de
longitud coincidente de una línea `nologin`/`false`/`sync` de `/etc/passwd`
con `dirtyfail::0:0:<pad>:/:/bin/bash`. Sobrevive a la salida del shell hasta
que la página se desaloja. El estado se guarda en `/var/tmp/.dirtyfail.state`
para `--cleanup-backdoor`. El nombre de usuario `dirtyfail` está
deliberadamente emparejado con este proyecto para que sea identificable al
instante en cualquier auditoría — cambia `NEW_USER` en `src/backdoor.c` si
necesitas un identificador distinto para un compromiso red team autorizado.
- **Bypass de AppArmor** — vence la política
`apparmor_restrict_unprivileged_userns=1` de Ubuntu mediante una re-ejecución
`change_onexec("crun")` de un solo salto hacia un perfil no confinado que
conserva las capacidades de userns. Cada modo de exploit lo maneja
internamente mediante un fork: el padre permanece en el namespace init, el
hijo hace el baile del bypass, el padre lee el page-cache global y ejecuta
`su` para obtener root REAL del init-ns. La bandera heredada `--aa-bypass`
sigue existiendo para depurar la mecánica del bypass de forma aislada. Ver
[§8.5 Arquitectura](#85-architecture-outerinner-fork-based-bypass).
## Verificado en
DIRTYFAIL ha sido **validado empíricamente de extremo a extremo** en múltiples
distros y versiones de kernel. La siguiente matriz refleja los resultados de
pruebas por modo al ejecutar cada modo `--exploit-*` contra una instalación
limpia de cada distro.
| Distro | Kernel | LSM | Copy Fail | xfrm-ESP v4 | xfrm-ESP v6 | RxRPC | GCM | Backdoor | Shellcode SU |
|---|---|---|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| Ubuntu 24.04 LTS | `6.8.0-111-generic` | AppArmor | 🛡² | ✅ | ✅ | ✅ | ✅¹ | ✅¹ | (no probado) |
| Debian 13.4 | `6.12.86+deb13` | none | 🛡 | 🛡 | 🛡 | 🛡 | 🛡 | 🛡 | 🛡⁵ |
| AlmaLinux 10.1 | `6.12.0-124.8.1.el10_1` | SELinux | ✅ | ✅ | ✅ | ⏭³ | ✅ | ✅ | ✅ |
| Fedora 44 (Server) | `6.19.10-300.fc44` | SELinux | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Ubuntu 26.04 LTS | `7.0.0-15-generic` | AppArmor (endurecido) | 🛡 | 🛡⁴ | 🛡⁴ | 🛡⁴ | 🛡⁴ | 🛡⁴ | 🛡⁵ |
**Leyenda:** ✅ el exploit aterrizó y produjo root real del init-ns · 🛡 mitigado — el exploit no puede alcanzar el bug del kernel (kernel parcheado O el LSM bloquea la ruta no privilegiada) · ⏭ no aplicable (precondición ausente)
### Validación de sonda activa (`--scan --active`)
La bandera `--active` añade una sonda STORE de archivo centinela por CVE
durante la detección. Validamos las salidas de la sonda contra las mismas 4
distros de arriba (Debian, Fedora, AlmaLinux, Ubuntu 26.04) — la matriz
siguiente muestra el veredicto de sonda por modo y coincide uno a uno con la
verdad de campo del exploit completo:
| Distro | Sonda Copy Fail | Sonda ESP v4 | Sonda ESP v6 | Sonda RxRPC | Sonda GCM |
|---|:-:|:-:|:-:|:-:|:-:|
| Debian 13.4 | intacto 🛡 | intacto 🛡 | intacto 🛡 | intacto 🛡 | intacto 🛡 |
| Fedora 44 | marcador @0 ✅ | STORE @0 ✅ | STORE @8 ✅ | cambio de byte ✅ | sentinel[0] 0x41→0x27 ✅ |
| AlmaLinux 10.1 | marcador @0 ✅ | STORE @0 ✅ | STORE @8 ✅ | precondiciones ⏭ | centinela cambiado ✅ |
| Ubuntu 26.04 | intacto 🛡 | bloqueado por LSM 🛡 | bloqueado por LSM 🛡 | bloqueado por LSM 🛡 | bloqueado por LSM 🛡 |
El desplazamiento de aterrizaje STORE de la sonda V6 (8 en Fedora y Alma)
coincide con el `V6_STORE_SHIFT` empírico que `calibrate_v6_shift()` descubre
en tiempo de ejecución — lo que confirma que la auto-calibración reemplaza
correctamente la constante antes hardcodeada a través de las compilaciones de
kernel.
¹ GCM y Backdoor requieren que `algif_aead` sea cargable. Ubuntu 24.04 incluye
`/etc/modprobe.d/disable-algif_aead.conf` que lo bloquea (blacklisting) como
mitigación de Copy Fail. Con la lista negra eliminada (p. ej. en un kernel
anterior a la mitigación), ambos modos funcionan de extremo a extremo.
² La ruta algif_aead de Copy Fail está mitigada por la lista negra de modprobe;
la primitiva CVE subyacente en el kernel es la misma tanto si `authencesn` es
alcanzable como si no. xfrm-ESP, RxRPC y la variante GCM aterrizan en el mismo
kernel porque no pasan por algif_aead.
³ El paquete `kernel-modules-extra` de AlmaLinux 10 no se instala por defecto
en una instalación Mínima, por lo que `rxrpc.ko` falta en disco. Instalar
`kernel-modules-extra-$(uname -r)` desde EPEL o el repositorio extras de
AlmaLinux devuelve el módulo; en una instalación mínima estándar RxRPC es
inalcanzable.
⁴ **Ubuntu 26.04 LTS bloquea exhaustivamente la explotación no privilegiada.**
El kernel incluido `7.0.0-15.15` (publicado el 2026-04-22) **es anterior al
parche mainline `f4c50a4034e6` (fusionado el 2026-05-07) por ~2 semanas** — así
que el bug SIGUE presente en el kernel. La defensa de Ubuntu es **defensa en
profundidad mediante endurecimiento de AppArmor**, no un parche de kernel: