Diecinueve años. Un hook de validación faltante. Cualquier usuario local se convierte en root. CIFSwitch es la prueba de que la infraestructura legítima (keyrings, namespaces, NSS) se convierte en arma cuando el límite de confianza no se aplica. Descubierta por Asim Manizada, security engineer en SpaceX, con asistencia de IA mediante razonamiento en grafos. Divulgada el 28 de mayo tras un embargo coordinado. CVE pendiente. PoC público. Servidores enterprise expuestos. En Tech86 auditamos infraestructura Linux con foco en superficies de ataque del kernel, y esta vulnerabilidad confirma algo que sabemos por experiencia: el mayor riesgo no es el bug zero-day, es el bug que estuvo ahí durante casi dos décadas sin que nadie lo notara.
El mecanismo: request_key confía sin validar
El kernel Linux usa keyrings para gestionar credenciales Kerberos en mounts CIFS/SMB. Cuando un mount necesita autenticación, el kernel invoca request_key("cifs.spnego", descripción). Esa llamada dispara el helper cifs.upcall, que corre como root. El problema: el kernel nunca validó el origen de la solicitud. Cualquier usuario, sin ningún privilegio, puede llamar request_key() con una descripción falsificada. El helper se ejecuta como root y confía en los campos como si vinieran del kernel. No hay verificación de que el solicitante tenga permiso para pedir esa key. No hay validación de que los campos de la descripción sean legítimos. El upcall ocurre antes de cualquier comprobación. Cuando el kernel rechaza la key, ya es tarde: el helper ya se ejecutó como root dentro del namespace del atacante.
Ese bug existe desde 2007. El código vulnerable estuvo en el kernel durante casi dos décadas. La cadena completa de explotación, sin embargo, solo se volvió viable en 2013, cuando los user namespaces no privilegiados llegaron con Linux 3.8. El bug permaneció latente durante 6 años, esperando la pieza que faltaba: la capacidad de crear un namespace sin privilegios para controlar el entorno donde el helper se ejecuta.
La cadena de explotación: 6 pasos hasta root
El exploit sigue una cadena precisa y determinística:
- El atacante crea un user namespace con un
nsswitch.conffalso y un módulo NSS malicioso - Llama
request_key("cifs.spnego", descripción_falsificada)con pid, uid yupcall_targetcontrolados cifs.upcallcorre como root y entra al namespace del atacante víaupcall_target=app- Antes del drop de privilegios, el lookup NSS carga el módulo del atacante como root
- El módulo escribe en
/etc/sudoers.d/conNOPASSWD: ALL sudo. Shell root.
El punto central es que el kernel no necesita devolver la key para que el helper sea invocado. El upcall ocurre primero. Cuando el kernel rechaza la solicitud, el código malicioso ya se ejecutó como root. El límite de confianza entre el espacio de usuario y el helper privilegiado nunca se aplicó, y 19 años de kernel releases no lo corrigieron.
Quién está expuesto: el mapa de vulnerabilidad
La superficie de exposición de CIFSwitch es amplia y desigual. Algunas distribuciones son vulnerables con la configuración por defecto: el paquete cifs-utils viene instalado y la regla request-key está activa sin necesidad de acción del administrador. Es el caso de Linux Mint 21.3/22.3, CentOS Stream 9, Rocky Linux 9, Kali 2021.4-2026.1, AlmaLinux 9.7 (incluyendo imágenes en Azure) y SLES 15 SP7/SAP.
Otras distribuciones son vulnerables de forma condicional: si el administrador instaló cifs-utils, la cadena se vuelve viable. Ubuntu 18.04 a 24.04, Debian 11/12/13, openSUSE Leap 15.6, Oracle Linux 8/9 y Amazon Linux 2023 están en esa categoría. El paquete no viene por defecto, pero es una instalación común en servidores que montan shares SMB.
Están también las distribuciones donde SELinux o AppArmor con la configuración por defecto bloquean la explotación: Ubuntu 26.04, Fedora 40-44, CentOS Stream 10, Rocky Linux 10 y AlmaLinux 10. Pero esa protección es condicional: políticas relajadas, comunes en entornos legacy y configuraciones personalizadas, eliminan la barrera. En Tech86 vimos repetidamente que "el MAC protege" es una premisa que dura hasta que alguien necesita una excepción y relaja la política sin documentarlo.
Descubrimiento asistido por IA y el fix de 4 líneas
Asim Manizada usó agentes de IA con razonamiento en grafos para encontrar la vulnerabilidad. No fue fuzzing bruto, fue razonamiento estructurado sobre el grafo de confianza entre componentes del kernel. La IA mapeó las relaciones de confianza entre request_key, cifs.upcall, namespaces y NSS, identificó dónde el límite de confianza no se aplicaba y señaló el gap. Esto es significativo: la vulnerabilidad existía desde hacía 19 años y resistió auditorías humanas, code reviews y fuzzers. La IA la encontró porque razonó sobre el modelo de confianza, no sobre el código aislado.
El fix upstream son 4 líneas. Commit 3da1fdf. La corrección agrega la validación que faltaba: verificar si el solicitante de request_key() tiene permiso para invocar el helper privilegiado. Diecinueve años de exposición, millones de servidores vulnerables, y la corrección cabe en un tweet. No es una anomalía: es la naturaleza de las vulnerabilidades de límite de confianza. El bug no es complejidad, es la ausencia de una comprobación en la que nadie pensó agregar.
La lección: la infraestructura legítima se convierte en arma
Los keyrings son legítimos. Los namespaces son legítimos. NSS es legítimo. Cada componente individualmente funciona como fue diseñado. El problema emerge en la composición: cuando el kernel invoca un helper privilegiado dentro de un namespace controlado por el atacante, y ese helper confía en datos que no fueron validados, la infraestructura legítima se convierte en el vector de compromiso.
En Tech86, esa es la lente que usamos en auditorías de seguridad ofensiva. No basta con verificar componentes aislados: hay que mapear los límites de confianza entre ellos. CIFSwitch no es un bug de memoria, no es un overflow, no es una race condition. Es un gap de validación en una cadena de confianza que nadie auditó como conjunto. Si sus servidores corren CIFS, si usan contenedores rootless, si tienen cifs-utils instalado, necesita saber si está expuesto. Diecinueve años es demasiado tiempo para un bug que da root con un syscall.
Conozca nuestra Seguridad Ofensiva y entienda cómo auditamos superficies de ataque del kernel con la profundidad que esta realidad exige.