La carrera en el kernel de Linux que Claude convirtió en una shell como root (CVE-2026-98432)

Anthropic publicó cinco cadenas de exploit escritas por un modelo interno de Claude. Una explota una carrera en el stack TCP de Linux (CVE-2026-98432, CVSS 9.8) para ejecutar comandos como root sin credenciales.

Anthropic publicó el 27 de octubre los detalles de cinco cadenas de exploit construidas por un modelo de investigación interno no publicado. La quinta es la que más ruido ha dejado en el sector: una ejecución remota de código sin clics en el kernel de Linux, puntuada con un 9,8 sobre 10 en la escala CVSS, que permite ejecutar comandos arbitrarios como root en servidores remotos sin credenciales y sin ninguna interacción del usuario. El identificador es CVE-2026-98432 y el fallo está en el subsistema de red IPv4 del kernel.

Lo relevante no es solo que un modelo de IA encontrara un fallo. Es que llegó al final: escribió el exploit completo, lo dejó reproducible y obtuvo una shell como root. En su prueba de concepto, el atacante tarda 48 minutos en filtrar un puntero del kernel y cinco minutos más en alcanzar la ejecución del comando. Poco más de una hora de cómputo para convertir una condición de carrera de más de una década en ejecución remota privilegiada.

El fallo lo reportó Xinyang Ge, de Anthropic, y lo corrigió Eric Dumazet en el kernel upstream el 5 de octubre con el commit e3f33b0a1d89, que cambia la liberación de memoria con kfree() por kfree_rcu() en la ruta de destrucción del socket. El arreglo ya está en las ramas estables mantenidas, pero la distribución del parche entre Ubuntu, Red Hat y el resto de proveedores va por detrás: el aviso de Red Hat, a fecha de 29 de octubre, señala que no hay mitigación disponible todavía.

Este post mira por debajo del titular: qué es exactamente la condición de carrera, por qué se puede repetir hasta que sale, cómo se consigue leer un puntero del kernel a distancia para desactivar KASLR y qué significa, para quien opera sistemas, que un modelo pueda cerrar la cadena completa de forma automática.

El fallo: qué se libera antes de tiempo

Todo ocurre en la creación de un socket TCP sobre IPv4. Cuando llega un SYN y el servidor responde con el saludo, la función tcp_v4_syn_recv_sock() crea el socket hijo y le cede la propiedad del bloque de opciones de IP, el campo ireq_opt, sin copiarlo y sin limpiar el puntero del socket de petición original.

El problema aparece en la concurrencia. Un SYN retransmitido que llega en ese instante lo procesa otra CPU en tcp_check_req(), que acaba llamando a tcp_v4_send_synack(). Esa ruta lee ireq_opt protegida solo con rcu_read_lock(). En paralelo, el socket hijo puede destruirse: inet_sock_destruct() libera ese bloque con un kfree() normal, sin esperar el periodo de gracia de RCU. Cuando la construcción del SYNACK invoca ip_options_build(), el bloque ya está liberado. Es un use-after-free.

Y hay un segundo escenario, más difícil de esquivar: la migración de sockets de petición. Con net.ipv4.tcp_migrate_req=1, o con un programa BPF_SK_REUSEPORT_SELECT_OR_MIGRATE, el socket de petición se clona y el clon y el original comparten el mismo bloque de opciones. Una CPU que todavía sostiene una referencia al socket antiguo puede estar usándolo cuando el clon se libera, y ahí también se recurre a un kfree() sin RCU.

Lo que convierte este defecto en algo explotable de forma masiva es un detalle de diseño: perder la carrera no tumba el sistema. Un fallo en la carrera solo aborta el handshake. El atacante puede reintentar indefinidamente hasta que la sincronización salga. En un kernel de producción, eso convierte un fallo intermitente en una ventana de tiro ilimitada.

La lectura en ip_options_build() es además un patrón TOCTOU: lee opt->optlen dos veces. Si entre la primera y la segunda lectura el contenido cambia, la segunda ya no describe lo que se va a copiar. Esa lectura doble es la bisagra del exploit: convierte un use-after-free en una operación controlada por el atacante.

El exploit en dos fases

La primera fase consiste en tumbar KASLR a distancia. El atacante provoca la carrera y consigue que el kernel lea un campo de longitud controlado, de modo que copie bytes de más y los devuelva al atacante dentro de la respuesta. Si al menos una de esas lecturas de más contiene un puntero del kernel, el atacante deja de adivinar direcciones: conoce el mapa del espacio de memoria del kernel y puede calcular dónde está aquello que le interesa.

La segunda fase consiste en secuestrar el flujo de control. Con el mismo use-after-free, el atacante desborda un búfer y sobrescribe un puntero de callback con la dirección de una carga útil que ya ha colocado en memoria del kernel mediante una función de protocolo ordinaria. Cuando el kernel invoca ese callback, la carga encadena una serie de llamadas a funciones que ya existían en el kernel y termina ejecutando el comando elegido por el atacante, como root.

Conviene detenerse en ese último detalle, porque es el que cambia la naturaleza del problema. No hizo falta introducir código nuevo ni una primitiva de explotación exótica: se encadenaron funciones que el kernel ya tenía. La parte difícil, leer memoria ajena, calcular direcciones y alinear escrituras, es exactamente la que un modelo puede automatizar.

La reproducción independiente

Pocos días después, el equipo de Innora Security Research publicó su propia reproducción del CVE-2026-98432, con el kernel instrumentado y KASAN activado. Su lectura del fallo coincide con la del parche upstream y añade el detalle fino de la cadena de primitivas.

  • La UAF se dispara de forma determinista en tcp_v4_syn_recv_sock(): KASAN la señala en el 100 por ciento de las rondas de handshake.
  • La ruta real de carrera se confirma en inet_csk_route_req, vía inet_rtx_syn_ack, tcp_v4_send_synack e ip_options_build.
  • Aplicando el cambio a kfree_rcu(), el informe desaparece. Ese es el grupo de control.
  • La recuperación del bloque se consigue con un heap spray: los 72 bytes liberados, en un objeto kmalloc-96, son recuperados por el primer kmalloc de 72 bytes del spray, con un 100 por ciento de aciertos.
  • Con optlen igual a 48, la lectura se sale ocho bytes del campo __data de 40 bytes: una marca colocada en la cola del objeto slab se lee de vuelta intacta, byte a byte. Esa es la fuga de información.
  • La ruta srr permite una escritura de cuatro bytes en un offset arbitrario más allá del área de datos del skb.
  • Esa escritura aterriza sobre skb_shared_info->nr_frags, y el kernel recorre entonces fragmentos no inicializados: de ahí al pánico y, con la alineación correcta, a una desreferencia controlada.
  • Con 173 rondas consecutivas, la cadena se completa sin pánico.

Conviene ser precisos con los límites de esta reproducción. El trabajo de Innora documenta las primitivas y su encadenamiento sobre un kernel instrumentado; no es un exploit de root listo para usar contra producción, y el propio repositorio lo dice: los experimentos se ejecutan sobre un kernel 6.12.112 en QEMU, con instrumentación y spray forzado. Lo que aporta es la confirmación pública de que la cadena es real y de que la ruta de corrupción está donde decía el parche.

Qué dicen los avisos oficiales

El aviso de Red Hat describe el fallo en el subsistema de red IPv4 del kernel: una carrera durante el procesamiento concurrente de peticiones de conexión TCP retransmitidas o de migraciones de socket, que permite liberar las opciones del socket mientras todavía se están usando. Un atacante remoto puede provocarlo enviando peticiones de red cronometradas, y el resultado principal es el cierre del sistema, es decir, una denegación de servicio, o una corrupción de memoria.

La misma página muestra una divergencia habitual en las puntuaciones: Red Hat, que actúa como autoridad de certificación del CVE, asigna un 8,1 con complejidad de ataque alta, mientras que cve.org publica un 9,8 con complejidad baja. No es un error de uno de los dos, es una diferencia de criterio sobre lo que cuesta ganar la carrera de forma fiable. Tratar el 9,8 como "crítico, hay que parchear ya" y el 8,1 como "menor, puede esperar" es un error de lectura en las dos direcciones.

La reproducción de Innora concreta las versiones corregidas: 6.12.113, 6.18.56, 6.6.159, 6.1.190, 5.15.223 y 5.10.272, además del backport que aplica la misma semántica kfree_rcu. Y es tajante en un punto: no existe ningún ajuste de configuración que evite el problema. La única mitigación es actualizar el kernel.

El resto de las cadenas y lo que tienen en común

El kernel es el titular, pero el mismo post describe cinco cadenas distintas y el patrón que las une importa más que cualquiera de ellas.

La primera es una ejecución remota con un solo clic en Chrome. Claude encontró un fallo en V8, el motor de JavaScript, que permitía corromper el heap. Después encontró un segundo fallo que rompía el sandbox de memoria y anulaba ASLR, localizando el código de Chrome en memoria y construyendo una cadena de programación orientada a retorno que tomaba el control del proceso de render. El renderer seguía confinado por el sandbox de procesos, así que el modelo encontró una condición de carrera en CacheStorage que leía memoria fuera del sandbox y revelaba el layout del proceso privilegiado. El último eslabón era un use-after-free en FedCM, el inicio de sesión federado de Chrome, que ya ejecutaba código fuera del sandbox. Google asignó 62 CVE a los hallazgos, todos parcheados en Chrome 156 y todos de severidad crítica o alta: 13 escapes de sandbox y 21 vulnerabilidades capaces de comprometer el renderer.

En Safari la cadena es más elegante porque no llega a ejecutar código. Un use-after-free en JavaScriptCore, con operaciones de TypedArray escribiendo a través de punteros obsoletos, permite leer y escribir fuera de la región donde WebKit tiene aislado ese tipo de datos, el Gigacage. Un fallo en el mecanismo de IPC del sandbox WebContent permite leer del disco el historial, las cookies y las bases de datos de sesión. Y el paso final es tan simple como sobrescribir una variable en memoria para desactivar la política de mismo origen. Apple recibió el informe el mismo día en que se envió y publicó la corrección.

En Android, el objetivo era extraer fotos y datos personales de un teléfono robado sin desbloquearlo. El modelo combinó análisis del código abierto, ingeniería inversa y desofuscación de los binarios de Google Play services y pruebas sobre un Pixel 9 físico. Logró saltarse la prohibición de transferir datos por USB, la autorización del par en el protocolo de transferencia entre dispositivos, la verificación del código de seis dígitos y el chequeo interno que impedía enviar el contenido. Google corrigió el problema.

En Windows, el hallazgo fue más discreto y más peligroso por escala: una lectura fuera de límites en HTTP.sys, el componente del kernel que sirve HTTP y también HTTP/3, que permite tumbar cualquier servidor que atienda peticiones de ese protocolo. Anthropic la describe en su texto como una lectura fuera de límites en la implementación de QUIC del kernel de Windows, y el registro oficial la sitúa en HTTP.sys. Lo excepcional aquí no estaba en el exploit, sino en el descubrimiento: el modelo recibió el binario de Windows y lo reversó con Ghidra, escribió un programa en C anotado que reproducía el comportamiento, comparó la reproducción con el binario para validar su comprensión y solo entonces buscó fallos. El CVE asignado es CVE-2026-33096, publicado en el registro oficial el 14 de abril de 2026, y Anthropic estima que hay varios millones de servidores expuestos en internet.

La lista incluye además escalada local de privilegios en OpenBSD, FreeBSD y Linux, escapes de sandbox en infraestructura de contención habitual y varios fallos en aplicaciones web. Y hay un detalle que importa más que los recuentos: algunos de los eslabones no son vulnerabilidades por sí mismos, sino comportamientos previstos que se vuelven explotar cuando se combinan.

Cómo lo hicieron: la parte que no sale en el titular

Anthropic explica en su propio texto cómo repetir el proceso, y es la parte más transferible de todo el trabajo.

  • El escalado de cómputo en el momento de la inferencia y la diversidad de escáneres aumentan de forma sustancial el número de hallazgos. Construyeron una plataforma que ejecuta muchos agentes de escaneo en paralelo, mide cada escáner por cuántos fallos adicionales aporta al conjunto y lleva un control dinámico de cobertura para que los escáneres recorran todo el código.
  • Las estrategias de escaneo van desde la cobertura pura, es decir, ¿hay un fallo en esta función?, hasta la basada en objetivo, ¿esta aplicación expone algo que pueda comprometer los datos de un cliente?, pasando por la basada en modelo de amenazas, ¿este camino se salta el modelo de amenazas documentado?
  • Sobre cada hallazgo confirmado ejecutaron análisis de variantes automatizado. Todos los hallazgos pasan por una canalización estandarizada de verificación y de puntuación de riesgo, de modo que se puede experimentar libremente con escáneres nuevos sin bajar la barra de calidad.
  • La conclusión operativa de Anthropic es que arreglar el trabajo pendiente existente solo resuelve la mitad del problema: la otra mitad es cortar el ritmo de entrada de fallos nuevos. Para eso recomiendan escanear en el momento del pull request, y publican un plugin de guía de seguridad para Claude Code que ya está disponible en su repositorio público.
  • El marco de divulgación fue de 90 días para el proveedor más 45 días adicionales antes de hablar de lo que no esté ya en un aviso público.

Qué significa para quien opera sistemas

  • Actualiza el kernel y comprueba la versión exacta. El arreglo está publicado desde el 5 de octubre y la corrección es semántica kfree_rcu, no un rediseño. Las versiones reparadas son 6.12.113, 6.18.56, 6.6.159, 6.1.190, 5.15.223 y 5.10.272.
  • Revisa la superficie concreta. La prueba de concepto de Anthropic apunta a servidores con un oyente de TCP multipath. Merece la pena saber si tus máquinas exponen TCP multipath y si el kernel que corre detrás está dentro del rango afectado.
  • No busques un ajuste de configuración que te salve. No existe. Entre el kfree() y el kfree_rcu() no hay ninguna bandera que desactive el fallo.
  • Prepara la detección. En kernels de depuración, KASAN canta a la primera. En producción, el patrón a vigilar son cierres inesperados en ip_options_build bajo la combinación de inundación SYN y carreras de handshake.
  • No leas el CVSS como una excusa. Si Red Hat dice que no hay mitigación disponible, tu posición depende de la fecha, no del número. Entre el 8,1 y el 9,8 no cambia nada en tu servidor.
  • Cuenta los días, no los meses. El investigador tenía 90 días por política de divulgación coordinada. Para el atacante, la ventana la marcan los tiempos de publicación de tu distribución y de tu ventana de mantenimiento.
  • Del lado ofensivo, el modelo deja de ser un copiloto. La diferencia entre un hallazgo y un exploit funcional es ahora una tarde de trabajo de un modelo, no una carrera de diez años de un especialista. Cualquier planificación de defensa que asuma ese tiempo de razonamiento tiene que revisarse.

Lo que deja el caso

El dato relevante no es que Claude encontrara un CVE. Es que la distancia entre "hay un fallo" y "tengo una shell como root en tu servidor" se haya convertido en una hora de cómputo y un commit de unas pocas líneas.

Durante más de una década, este defecto estuvo en el árbol del kernel, a un clic de cualquier atacante con tiempo y conocimientos. La diferencia con entonces no es que el fallo sea más difícil de encontrar: es que ahora hay un modelo que lo encuentra, lo entiende y entrega la explotación completa, con un exploit que cualquiera puede ejecutar y verificar. La misma capacidad que Anthropic pone a disposición de los defensores a través de su programa de verificación está, por supuesto, al alcance de quien tenga acceso al modelo.

La consecuencia operativa es incómoda y no admite matices: la defensa ya no consiste en encontrar antes que el atacante, sino en parchear antes de que el atacante convierta el fallo en un exploit. El resto es teatro.

Fuentes

Read more