Desde Linux David Y. Naranjo  

BTR: Una Nueva Amenaza de Ejecución Transitoria en Motores JIT (Ataque Spectre-v2)

vulnerabilidad

Hace poco un equipo de investigadores dieron a conocer información sobre una nueva vulnerabilidad crítica de ejecución especulativa de los procesadores modernos. Denominado «Branch Target Reuse (BTR)», este método de ataque de la clase Spectre-v2 demuestra que es posible evadir los mecanismos de aislamiento de memoria en sistemas con procesadores Intel, AMD y ARM.

La investigación refuta la creencia generalizada de que los ataques de ejecución transitoria basados en código automodificable (Self-Modifying Code, SMC) son poco prácticos en la realidad. BTR logra esto al aprovechar la forma en que los motores de compilación JIT manejan la memoria y cómo las unidades de predicción de bifurcaciones de las CPU gestionan los registros obsoletos.

Sobre la vulnerabilidad Branch Target Reuse (BTR)

Los motores JIT (como el JIT de cBPF en Linux, SpiderMonkey de Firefox o GraalVM de Oracle) generan código máquina en tiempo de ejecución, escribiéndolo en búferes de memoria, haciéndolo ejecutable y, posteriormente, liberando o reescribiendo esas secciones de código. Desde la perspectiva de la CPU, esto es SMC.

Los procesadores modernos cuentan con mecanismos para asegurar que el código sobrescrito no se ejecute, sincronizando las cachés de instrucciones y datos. Sin embargo, la investigación revela un punto ciego crítico a nivel microarquitectónico: «el predictor de bifurcaciones indirectas no invalida necesariamente las entradas obsoletas en su Búfer de Destino de Bifurcación (BTB)».

BTR explota este fallo de sincronización. El proceso se desarrolla en las siguientes etapas:

  1. Entrenamiento: El atacante fuerza al motor JIT a asignar un «bloque de entrenamiento» (training chunk) e induce a una bifurcación indirecta víctima a saltar hacia él, inyectando así una entrada en el BTB.
  2. Reemplazo: El atacante obliga al JIT a liberar ese bloque y reasignar un nuevo «bloque objetivo» (target chunk) que se solapa con la dirección de memoria original.
  3. Ejecución Especulativa (Execute-after-Free): Al forzar de nuevo la bifurcación víctima, la CPU, guiada por el registro obsoleto (stale BTB entry), predice un salto hacia la dirección de memoria antigua, que ahora contiene el nuevo código máquina.

Al saltar a un punto de entrada que ahora es inválido (dado que el código ha cambiado), el atacante logra un «secuestro del flujo de control transitorio». En sistemas con instrucciones de longitud variable como x86, esto permite la ejecución de instrucciones desalineadas (misaligned gadgets). En lugar de ejecutar las instrucciones legítimas del nuevo código (como un salto seguro), la CPU decodifica los valores intermedios (como operandos) como si fueran instrucciones, ejecutando comandos maliciosos diseñados por el atacante para extraer datos.

Evaluación en entornos reales

Los investigadores analizaron la viabilidad de BTR en tres motores JIT del mundo real, encontrando niveles de riesgo variados:

  • Linux cBPF JIT: Identificado como el objetivo más vulnerable y de mayor impacto, ya que permite a usuarios sin privilegios insertar filtros en el kernel (ej. mediante SECCOMP) con un control muy predecible de la asignación de memoria.
  • SpiderMonkey (Firefox): Aunque es vulnerable a la inyección de registros obsoletos (especialmente en x86-64 y ARM64 utilizando literal pools), la recolección de basura (GC) y la actividad en segundo plano de JavaScript reducen significativamente la tasa de supervivencia de las entradas BTB. El ataque requiere afinar el ruido del GC para ser totalmente efectivo.
  • GraalVM (Oracle): Los experimentos mostraron que la intensa actividad del recolector de basura vacía el búfer BTB demasiado rápido, impidiendo la explotación funcional en su estado actual. Sin embargo, los investigadores no descartan que esta limitación sea superable.

Exploits de extremo a extremo: robando la contraseña root

Para demostrar la gravedad de BTR, los investigadores desarrollaron dos exploits de extremo a extremo dirigidos al JIT cBPF del kernel de Linux, ejecutados desde el espacio de usuario hacia el espacio del kernel.

Exploit en configuración por defecto: En Ubuntu 24.04 (kernel 6.14.0-27) con procesadores Intel modernos (Raptor Cove y Lion Cove), el atacante logró inyectar un gadget desalineado mediante operandos de 4 bytes en instrucciones cBPF. Superando la aleatorización de direcciones del kernel (KASLR) y utilizando técnicas de pointer-chasing, el exploit es capaz de localizar la estructura de la utilidad’su’, iterar por sus tablas de memoria y extraer el hash de la contraseña de root almacenada en la memoria en menos de 5 minutos.

Bypass de Constant Blinding: El kernel Linux posee una protección específica contra la inyección de código JIT (JIT spraying) llamada «ceguera de constantes» (constant blinding). Cuando se activa, enmascara (XOR) los valores inmediatos proporcionados por el usuario. Para burlar esta mitigación, los investigadores desarrollaron un segundo exploit que codifica el gadget malicioso no en operandos directos, sino en los desplazamientos de las instrucciones de salto (jump offsets). Lograron extraer el hash en el mismo tiempo (tasa de fuga de 10 B/s), demostrando que BTR es capaz de evadir configuraciones de seguridad avanzadas.

Mitigación y solución

Los ataques de ejecución como BTR son notoriamente difíciles de mitigar. La investigación evaluó posibles defensas:

  • IBT/BTI (Indirect Branch Tracking): Restringir los objetivos de bifurcación mediante hardware ayuda. Sin embargo, en arquitecturas Intel x86, la ventana transitoria previa a la comprobación endbr64 puede ser suficiente para ejecutar el ataque, y en ciertos contextos, los atacantes aún pueden saltar a código alineado en medio de funciones legítimas (ej. RSB-return gadget).
  • Aleatorización (GraalVM): Tras la notificación, Oracle implementó la aleatorización de la ubicación de la caché JIT en GraalVM para dificultar la reasignación predecible de memoria.
  • Barreras IBPB: La solución más robusta (y la adoptada finalmente por los desarrolladores del kernel Linux) es restablecer el estado del bloque de predicción de bifurcaciones utilizando instrucciones IBPB (Indirect Branch Prediction Barriers) cada vez que un programa cBPF/eBPF reutiliza una región de memoria previamente ejecutada. Esta protección ya se ha integrado en versiones recientes del kernel (ej. 7.2-rc2, 7.1.4, etc.). Mozilla y Apple (WebKit), por su parte, continúan priorizando el desarrollo del aislamiento estricto de sitios web como su línea de defensa principal.

Finalmente, si estas interesado en poder conocer mas al respecto, puedes consultar los detalles en el siguiente enlace.

Artículo original

Leave A Comment

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.