- En una auditoría de ksmbd, la implementación del servidor SMB3 del kernel de Linux, se encontró la vulnerabilidad remota de use-after-free CVE-2025-37899 usando únicamente la API de o3 de OpenAI, sin frameworks de agentes, scaffolding ni herramientas adicionales
- La vulnerabilidad surge durante el procesamiento del comando SMB
logoff, donde otros hilos pueden seguir accediendo asess->userdespués de que fue liberado; solo se hace visible al considerar tanto conexiones concurrentes como el estado de sesión compartida - En un benchmark basado en CVE-2025-37778, una vulnerabilidad encontrada manualmente, o3 detectó la falla 8 veces de 100, Claude Sonnet 3.7 la encontró 3 veces y Claude Sonnet 3.5 no la detectó ninguna vez
- Bajo una condición ampliada de 12k LoC / 100k tokens de entrada, que incluía todos los handlers de comandos SMB y el código de manejo de conexiones, la tasa de detección de la vulnerabilidad conocida cayó a 1 de 100, pero en esos mismos resultados apareció la nueva vulnerabilidad CVE-2025-37899
- Aunque siguen existiendo muchos falsos positivos y salidas poco útiles, la probabilidad de obtener una respuesta correcta ya subió lo suficiente como para que valga la pena la revisión y validación humana en investigación real de vulnerabilidades
Experimento para encontrar una vulnerabilidad en ksmbd con o3
- El objetivo de la auditoría fue ksmbd, que implementa el protocolo de compartición de archivos SMB3 en el espacio del kernel de Linux
- Se invocó el modelo o3 de OpenAI mediante la
o3 API, sin usar scaffolding, frameworks de agentes ni herramientas adicionales - La vulnerabilidad descubierta es CVE-2025-37899, y su corrección está en este commit del kernel de Linux
- El problema central es un use-after-free en el handler del comando SMB
logoff, donde un objeto sin conteo de referencias se libera mientras sigue siendo accesible desde otro hilo - Para encontrar esta vulnerabilidad hay que entender a la vez las conexiones concurrentes hacia el servidor y los objetos compartidos en ciertas condiciones
- Se incluye la valoración de que, entre los casos discutidos públicamente, este parece ser el primer caso en que un LLM encuentra una vulnerabilidad de esta naturaleza
Vulnerabilidad de referencia CVE-2025-37778
- Primero se usó CVE-2025-37778, encontrada manualmente, como benchmark para evaluar el rendimiento de o3
- Esta vulnerabilidad es un use-after-free que ocurre al procesar una solicitud
session setupde un cliente remoto en la ruta de autenticación Kerberos krb5_authenticateliberasess->usersisess->state == SMB2_SESSION_VALID- Después, el código depende del supuesto de que
ksmbd_krb5_authenticatelo volverá a inicializar con un nuevo valor válido, o de que si devuelve-EINVAL, entoncessess->userya no será usado - En la práctica, es posible hacer que
ksmbd_krb5_authenticateno vuelva a inicializarsess->user, y aun sikrb5_authenticatedevuelve-EINVAL,sess->userpuede seguir siendo accedido
Configuración del benchmark y prompt
- CVE-2025-37778 se usó como benchmark porque está en una superficie de ataque remota y exige razonar tanto sobre cómo inducir la condición
sess->state == SMB2_SESSION_VALID, como sobre una ruta sin reinicialización y otra de acceso después de liberar - Se calculó que el código mínimo necesario para explicar la ruta vulnerable era de aproximadamente 3.3k LoC
- La entrada del experimento incluía el handler del comando
session setupy las funciones que llama hasta una profundidad de llamadas de 3 - También se añadieron la recepción de paquetes, el parseo de solicitudes, la selección del handler del comando y el código de limpieza de la conexión al terminar el handler, para reducir conjeturas sobre cómo se inicializan las estructuras de datos
- La entrada final fue de aproximadamente 3.3k LoC / 27k tokens, y el archivo analizado se publicó como session_setup_code.prompt
- El prompt incluía las siguientes condiciones
- Indicaba que debía buscar vulnerabilidades use-after-free
- Proporcionaba una descripción de alto nivel del rol, la arquitectura y el modelo de amenazas de ksmbd
- Lo inducía con fuerza a preferir omitir un hallazgo antes que reportar un falso positivo
- El archivo completo del prompt está en el repositorio o3_finds_cve-2025-37899
- Para la ejecución se utilizó la herramienta
llmde Simon Willison
Resultados del benchmark de CVE-2025-37778
- El harness del experimento ejecutó la misma consulta 100 veces y guardó los resultados
- o3 encontró CVE-2025-37778 8 veces de 100
- En 66 ocasiones de 100 concluyó que no había bug, lo que produjo falsos negativos
- Las 28 restantes fueron falsos positivos
- Los resultados comparativos fueron los siguientes
- Claude Sonnet 3.7: 3 hallazgos de 100
- Claude Sonnet 3.5: 0 hallazgos de 100
- En este benchmark, o3 mostró un resultado entre 2 y 3 veces mejor que Claude Sonnet 3.7
- Se publicaron ejemplos de reportes en resultado de o3 y resultado de Sonnet 3.7
- La salida de o3, por su estructura y enfoque, se lee como un reporte de bug resumido escrito por una persona, aunque a veces puede ser demasiado breve y perder claridad
- La salida de Sonnet 3.7 aparece más como un flujo de razonamiento o un registro de trabajo
Experimento ampliado a todos los handlers de comandos
- En el siguiente experimento, se le dio a o3 no solo el handler de
session setup, sino el código de todos los handlers de comandos SMB - Los handlers están en
smb2pdu.c, y el archivo tiene un tamaño aproximado de 9k LoC - Sumando todos los handlers, el código de establecimiento y limpieza de conexiones, y la rutina de dispatch de handlers, la entrada llegó a unas 12k LoC / 100k tokens de entrada
- Bajo esta condición, el experimento también se ejecutó 100 veces
- o3 solo encontró la vulnerabilidad ya conocida de autenticación Kerberos CVE-2025-37778 1 vez de 100, mostrando una degradación clara del rendimiento al aumentar el número de tokens de entrada
- En ese mismo conjunto de resultados apareció un reporte de una vulnerabilidad nueva y antes desconocida: CVE-2025-37899
Ruta vulnerable de CVE-2025-37899
- La nueva vulnerabilidad también está relacionada con la liberación de
sess->user, pero esta vez ocurre en el handler de session logoff smb2_session_logofffunciona en el siguiente orden- Llama a
ksmbd_close_session_fds(work) - Llama a
ksmbd_conn_wait_idle(conn) - Establece el estado de la sesión en
SMB2_SESSION_EXPIRED - Si existe
sess->user, lo libera conksmbd_free_user(sess->user)y luego establecesess->user = NULL
- Llama a
- El escenario vulnerable del reporte de o3 es el siguiente
- En SMB 3.0 o superior, una segunda conexión de transporte se vincula a una sesión existente y
conn->binding == true - Worker-A procesa una solicitud normal, como WRITE, en otra conexión C2
smb2_check_user_session()guarda enwork->sessel puntero existente astruct ksmbd_sessiony aumenta el conteo de referencias de la sesión, pero no toma una referencia separada sobresess->user- Worker-B procesa un SMB2 LOGOFF para esa misma sesión en la primera conexión C1 y ejecuta
smb2_session_logoff() ksmbd_conn_wait_idle(conn)solo espera las solicitudes en ejecución de esa conexión, no las solicitudes de otras conexiones que usan la misma sesión- Worker-A sigue ejecutándose y puede hacer accesos como
user_guest(sess->user),ksmbd_compare_user(sess->user, …)osess->user->uid
- En SMB 3.0 o superior, una segunda conexión de transporte se vincula a una sesión existente y
- Según el momento, esto puede convertirse en un use-after-free que apunta a un objeto slab ya liberado, o en un DoS por desreferencia NULL si la lectura ocurre después de
sess->user = NULL
Corrección errónea y valor de los resultados de o3
- La primera corrección propuesta para CVE-2025-37778 consistía en agregar
sess->user = NULLdespués deksmbd_free_user(sess->user) - Tras leer el reporte de CVE-2025-37899, quedó claro que esa corrección era insuficiente
- El handler de
logoffya hacesess->user = NULL, pero sigue siendo vulnerable porque el protocolo SMB permite vincular dos conexiones distintas a la misma sesión - En la ruta de autenticación Kerberos también existe una ventana breve en la que otro hilo puede acceder a
sess->userjusto después de que se libera y antes de que se establezca en NULL - Algunos reportes de o3 cometieron el mismo error, pero otros sí captaron que
sess->user = NULLpor sí solo no era suficiente debido a la posibilidad de session binding - Como la proporción de verdaderos positivos frente a falsos positivos no es alta, existe la limitación de no saber con certeza si todos los reportes fueron revisados con el suficiente cuidado
Lugar práctico en la investigación de vulnerabilidades
- En creatividad, flexibilidad y generalidad, los LLM están más cerca de un auditor humano de código que de las técnicas tradicionales de análisis de programas
- Como puntos de comparación se mencionan symbolic execution, abstract interpretation y fuzzing
- Desde GPT-4 ya existía la posibilidad de usar LLM para investigación de vulnerabilidades, pero en problemas reales los resultados habían sido peores de lo esperado
- o3 funciona lo bastante bien en razonamiento sobre código, preguntas y respuestas, programación y resolución de problemas como para mejorar el desempeño de investigadores reales de vulnerabilidades
- Sigue estando lejos de ser perfecto y puede generar resultados inútiles que frustren al usuario
- Lo que cambió es que, por primera vez, se considera que la probabilidad de obtener una respuesta correcta ya es lo suficientemente alta como para justificar probarlo en problemas reales
1 comentarios
Opiniones de Hacker News
Es un detalle pequeño, pero la forma en que el autor organiza el proyecto parece útil. Crea archivos
.promptseparados para el prompt del sistema, la información de contexto y las instrucciones auxiliares [1], y los ejecuta conllm.Muestra que un buen uso de los LLM, como cualquier otra herramienta de ingeniería, requiere un pensamiento de ingeniería sistemático, centrado en especificaciones cuidadosas y que equilibre bien las restricciones de diseño.
[1] https://github.com/SeanHeelan/o3_finds_cve-2025-37899
Todo parece una especie de conjuro basado en corazonadas. Frases como “eres un experto en encontrar vulnerabilidades”, “reporta solo vulnerabilidades reales, sin falsos positivos”, o formas de organizarlo con etiquetas HTML falsas porque al modelo aparentemente le gustan. No veo dónde está la ingeniería en eso.
A esos prompts habría que llamarlos pistas, no instrucciones. Todos los LLM actuales ignoran el prompt cuando entra en conflicto con su único objetivo superior: producir una respuesta, sea verdadera o no.
Pedirle a un LLM que te ayude a escribir prompts también es sorprendentemente efectivo. Todos mis fragmentos de prompt los diseñé con ayuda de un LLM.
Personalmente, los guardo todos en archivos org-mode y los copio y pego en conversaciones de ChatGPT cuando los necesito. Prefiero una interacción más “de debate”, pero el enfoque es el mismo.
El artículo dice que la relación señal-ruido es de aproximadamente 1:50. El autor conoce muy bien esta base de código, así que está en una buena posición para separar la señal del ruido.
El verdadero avance vendrá de automatizar esa parte, así que pienso seguirlo de cerca.
Cada vez que sale un nuevo LLM de frontera, pruebo esos ejercicios, excluyendo los modelos que usan las entradas como datos de entrenamiento. Me sorprendió que la proporción de respuestas que funcionan al primer intento se mantuviera de forma constante alrededor de 1:10, y que muchas veces hicieran falta más de 10 rondas de insistirle para que encontrara sus propios errores.
Así que una relación señal-ruido de ese nivel en temas más difíciles me parece razonable.
Los resultados fueron bastante variados y los voy a publicar todos en una próxima presentación en una conferencia, así que pueden estar atentos. Va a mostrar bastante bien el estado actual del área.
Edit: la redacción era confusa.
Un LLM así podría ser una versión sintética de alguien que trabajó durante años en la base de código y aprendió todo tipo de particularidades.
Se puede meter muchísimo en un contexto largo, pero algunas bases de código ya tienen 200 mil tokens solo de código, así que no estoy seguro.
Especialmente si se usa un esquema de torneo binario como RAInk, que apareció aquí hace unas semanas, y también se puede usar consenso entre distintos LLM. Me sorprende que aquí no hayan usado Gemini 2.5 PRO; en mi experiencia, es el LLM más potente para este tipo de tareas.
La parte más interesante e importante del artículo fue que el autor ejecutó la búsqueda de vulnerabilidades 100 veces por cada modelo.
Es mucho más cómputo del que yo habría pensado usar para la mayoría de los problemas que he probado con modelos de lenguaje grandes, pero quizá simplemente haya que dejar que el modelo siga corriendo.
No sé qué pasará con el mundo de la ciberseguridad cuando el costo de inferencia se acerque a cero, pero será un espacio muy distinto al actual.
Más bien se acerca a celebrar el lujo y el desperdicio. Aunque enfrentamos el cambio climático global, seguimos quemando recursos en cosas triviales como si estuviéramos en los años 50.
O tuvo muchísima suerte o, como se sospecha, Gemini 2.5 PRO parece encontrar esta vulnerabilidad con más facilidad. La tasa de éxito fue alta, así que bastó con ejecutar unas cuantas veces el siguiente prompt: https://gist.github.com/antirez/8b76cd9abf29f1902d46b2aed3cd...
Últimamente se está repitiendo este patrón
Si hay un problema con una definición clara y una función de evaluación, se hace que el LLM reduzca el espacio de soluciones. Los LLM son muy fuertes para reconstruir patrones, y pueden funcionar bien si la respuesta se parece a patrones ya conocidos
En este caso, el problema es un tipo específico de vulnerabilidad de seguridad, y el evaluador es un experto. Aunque la escala es distinta, en espíritu se parece a los intentos recientes de usar LLM para optimización genética
“Mathematical discoveries from program search with large language models” también es una lectura interesante, y recuerdo que antes también apareció en HN
https://www.nature.com/articles/s41586-023-06924-6
Aun así, personalmente creo que es un poco excesivo concluir, solo con base en este experimento, que los LLM razonan sobre el código
Espero que esto sea real, y que no sea como lo que sigue pasando con curl
[1] https://daniel.haxx.se/blog/2024/01/02/the-i-in-llm-stands-f...
No estoy seguro de la afirmación de que esta sea la primera vulnerabilidad descubierta con un LLM. Por ejemplo, OSS-Fuzz [0] encontró varias mediante fuzzing, y Big Sleep también encontró una con un enfoque de agente [1]
[0] https://security.googleblog.com/2024/11/leveling-up-fuzzing-...
[1] https://googleprojectzero.blogspot.com/2024/10/from-naptime-...
Lo que decía el artículo era: “Para entender la vulnerabilidad, hay que razonar sobre conexiones simultáneas al servidor y sobre cómo se comparten varios objetos en determinadas circunstancias. o3 entiende esto y encontró el punto en el que un objeto específico, no contado por referencias, se libera mientras sigue siendo accesible desde otro hilo. Hasta donde sé, esta es la primera discusión pública sobre un LLM encontrando una vulnerabilidad de esta naturaleza”
Lo que quería decir es que, hasta donde sé, es la primera documentación pública de un LLM encontrando ese tipo de bug: uno que surge de una cantidad no trivial de código y de acceso concurrente a recursos compartidos. Al menos para mí, es una señal interesante del avance de los LLM
Si pensamos en el valor de descubrir zero-days, si se pudieran encontrar de forma confiable con solo unos cientos de llamadas a una API, casi todas las agencias de inteligencia del mundo invertirían dinero en esto
Especialmente si se pudiera afinar el modelo con muchos ejemplos; y no creo que lugares como OpenAI ofrezcan algo así mediante una API pública
Para agencias gubernamentales u otras organizaciones, estas restricciones obviamente no son un problema. Solo se aplican a todos los demás. Por eso la gente va a usar otros modelos y agentes sin esas limitaciones
Es seguro asumir que hay muchas vulnerabilidades en todo tipo de software crítico. Ahora se pueden encontrar. Empezará a aplicarse una teoría de juegos de carrera armamentista a la seguridad informática y al hacking. Probablemente llegue antes de lo esperado
Entiendo que algunos desarrolladores del kernel “verificaron” este bug, pero me pregunto si alguien realmente creó y probó una prueba de concepto
Es una parte tan central del proceso y, sin embargo, la prueba de concepto está completamente ausente. Sin una prueba de concepto, no se sabe qué problemas pueden aparecer en el camino y, por lo tanto, no se puede juzgar la posibilidad de explotación ni el impacto. Al menos el autor no lo llamó ejecución remota de código sin verificación
Pero ¿qué pasaría si hubiera una pieza del rompecabezas que el autor y los desarrolladores pasaron por alto, o que asumieron que o3 había manejado, pero que en realidad estaba fuera del contexto de o3, y eso invalidara la vulnerabilidad en sí?
No digo que exista algo así, ni que vaya a dedicar tiempo a hacer el trabajo del autor. Solo digo que este reporte no está completamente verificado y, considerando que podría convertirse en una publicación de blog influyente para el futuro de la investigación de vulnerabilidades con LLM, me parece un precedente peligroso
Personalmente, creo que a cualquier reporte de vulnerabilidad generado por un modelo se le debería aplicar PoC || GTFO con más rigor que nunca
Sigue siendo válida la idea de que o3 es mucho mejor que modelos anteriores u otros modelos actuales, y la metodología también es interesante. Entiendo el deseo y la necesidad de redactarlo así para hacer que la gente preste atención a algo específico. Ese es el problema del clickbait. Pero, por favor, hay que hacerlo mejor. Hay que crear una prueba de concepto y verificar las afirmaciones; no hay que ser flojos. Si vas a escribir una publicación de blog que puede influir en la forma en que los investigadores de vulnerabilidades hacen su trabajo, deberías fomentar la verificación, no las suposiciones teóricas. De lo contrario, en vez de profundizar la comprensión de los sistemas con reportes verificables y demostrados, reportes falsos pero plausibles terminarán difundiendo ignorancia
Hay un pequeño y hermoso pasaje que captura perfectamente cómo se desarrollan la mayoría de mis sesiones de desarrollo de prompts