Ataque Retbleed: Spectre contraataca

Examinamos el coste de la seguridad usando como ejemplo un estudio reciente sobre vulnerabilidades de hardware en los procesadores.

A mediados de julio, unos investigadores de la Escuela Politécnica Federal de Zúrich publicaron un estudio que describe un nuevo ataque que aprovecha las vulnerabilidades (o características) de los procesadores modernos. El ataque se denominó Retbleed y es un derivado de Retpoline, un método de defensa contra un tipo de ataque de Spectre. Básicamente, los autores demostraron que su técnica de compilación de programas, que anteriormente se creía que ofrecía una protección eficaz contra el conocido ataque Spectre Variant 2, no funciona o solo funciona de forma ocasional. La investigación es bastante compleja, como ocurre en todos los anteriores estudios sobre vulnerabilidades de hardware en procesadores.  En este artículo, como siempre, intentaremos no profundizar en la complejidad de los artículos científicos más relevantes, sino describir los resultados de forma sencilla. Comencemos con algunos datos para ponernos en contexto:

¿Qué es Spectre v2? Hablemos de la predicción de ramificación

Hace más de cuatro años, a principios de 2018, se publicaron dos trabajos de investigación que describían las vulnerabilidades de Spectre y Meltdown. Estas son vulnerabilidades de hardware: la forma en la que funcionan los procesadores hace posible un ataque de robo de datos potencial. Desde entonces, se han descubierto diversas variantes más de Spectre. Los investigadores han encontrado más formas de atacar una clase de vulnerabilidades comunes; es decir, usar para el ataque la funcionalidad predeterminada del procesador llamada “predicción de ramificación”.

La predicción de ramificación y la ejecución especulativa de instrucciones ayudan a mejorar significativamente el rendimiento del procesador. En cualquier programa, la ejecución de pasos posteriores suele depender del resultado de cálculos previos. El ejemplo más sencillo es cuando un usuario introduce una contraseña para acceder a información confidencial. Si la contraseña es correcta, los datos se muestran al usuario. Si la contraseña es incorrecta, se solicita al usuario que lo intente de nuevo. Con instrucciones simples para la CPU, esto se traduce básicamente en verificar los derechos de acceso a ciertos datos en la RAM: si se confirman los derechos necesarios, se otorga acceso a los datos; si no, el acceso queda denegado.

El procesador puede realizar millones de operaciones de este tipo por segundo, y mientras se verifica una determinada condición, suele estar inactivo (en términos generales, esperando a que un usuario introduzca una contraseña o que se verifiquen los derechos de acceso). Pero ¿y si hacemos que utilice este tiempo de inactividad para realizar por adelantado los cálculos que se realizan tras el resultado más probable de la verificación? Cuando nuestro hipotético usuario introduzca su contraseña hipotética, el resultado del cálculo estará listo y el usuario podrá ver sus datos confidenciales un poco más rápido.

Pero ¿cómo saber qué parte del código es más probable que se ejecute? Mediante estadísticas relacionadas con ejecuciones anteriores de instrucciones similares, por supuesto. Si nuestro usuario introduce la contraseña correcta nueve de cada 10 veces (hay que tener en cuenta que este es un ejemplo teórico y muy simplificado), podemos preparar sus datos confidenciales con antelación. Si la contraseña es incorrecta, simplemente descartaremos los resultados y tardaremos un poco más en mostrar un mensaje de error.

Los autores del artículo de 2018 describieron dos variantes del ataque de Spectre, y la Variante 2 (conocida también como Inyección de destino de rama) entrena a un predictor de ramificación para que realice las instrucciones que necesitamos, como leer datos a los que un atacante no debería tener acceso. Sí, estos cálculos luego se descartan, pero su resultado (los datos extremadamente confidenciales) se almacenan temporalmente en la caché, donde pueden ser robados.

Este es un ataque extremadamente complejo. En primer lugar, el atacante debe poder ejecutar código en el sistema atacado, aunque sin los privilegios deseados, es decir, sin acceso a datos confidenciales. Por ejemplo, se podría persuadir a un usuario para que abra en su navegador una página web que contenga un script malicioso. En segundo lugar, el atacante necesita un software en el sistema de destino que incluya un código idóneo para el ataque. En la jerga de los investigadores, esto se conoce como “gadget”. El código de ataque entrena al sistema de predicción de ramificación para ejecutar especulativamente este dispositivo. Esto hace que acceda a un área de memoria inaccesible para el atacante. Los datos confidenciales se colocan en la caché de la CPU, donde se pueden extraer muy lentamente (no más de decenas de bits por segundo) mediante la lectura del canal lateral.

Tratemos de explicarlo de una forma aún más sencilla. El sistema de predicción de ramificación incorporado en el procesador no separa las instrucciones de diferentes programas, y se puede usar un único programa para hacer que el procesador ejecute especulativamente una instrucción que se supone que no debe ejecutar. Anteriormente, esto no parecía ser un problema, ya que el software no puede acceder en ningún caso directamente a los datos en la caché del procesador. Pero resulta que, se pueden extraer los datos mediante la lectura de canales laterales (que es un mecanismo muy complejo: la reconstrucción de datos basándose únicamente en la información sobre la velocidad de las respuestas a las solicitudes de lectura).

Espera, Spectre fue descubierto en 2018. Seguramente ya lo hayan parcheado, ¿no?

Con las vulnerabilidades de hardware no es tan sencillo. En primer lugar, incluso si nos centramos en esta descripción simplificada, está claro que la vulnerabilidad, aunque esté definitivamente basada en el hardware, requiere que coincidan ciertas condiciones en el software para que pueda ser explotada. Si ese es el caso, ¿por qué no parchear el software? Esto es mucho más sencillo que actualizar el hardware. También es posible reparar parcialmente la vulnerabilidad en los procesadores mediante actualizaciones de microcódigo. Pero solo puede encontrarse una solución definitiva al problema con el lanzamiento de nuevos procesadores con hardware modificado. Mientras tanto, los viejos siguen siendo total o parcialmente vulnerables.

Hay otra pregunta que es extremadamente importante en el contexto de la investigación de Retbleed. ¿Cuál sería el coste de un parche de software o hardware? Cada método para “cerrar” Spectre reduce el rendimiento. Por ejemplo, el bastante obvio sistema de Especulación restringida de rama indirecta (IBRS) introduce verificaciones adicionales de permisos durante la ejecución de código especulativo y evita que los programas con mínimos privilegios accedan a datos altamente confidenciales, haciendo imposible un ataque de Spectre. Pero con cientos de miles o millones de verificaciones de este tipo, el rendimiento de la CPU tiende a disminuir. ¿Pero cuánto? Hay investigaciones que demuestran que un conjunto diverso de parches para Spectre en un sistema provocó una disminución del rendimiento de hasta un 25 %.

Y aquí es donde viene Retpoline, un método de protección contra Spectre relativamente sencillo propuesto por los ingenieros de Google que se ha utilizado durante la compilación de software. Como sugieren los autores del método, reemplazar algunas instrucciones por otras en situaciones típicas de ramificación no afecta a la operatividad del software, pero sí hace imposible un ataque de Spectre. Una ventaja importante de Retpoline frente a IBRS y otros métodos de protección es tan solo un ligero descenso de no más del 5 % del rendimiento.

¿Qué muestra el estudio de Retbleed?

Básicamente, esta nueva investigación ha demostrado que Retpoline… ¡no funciona! Las instrucciones de retorno en las que se basó el método Retpoline también podrían explotarse en un esquema ligeramente modificado para engañar (o entrenar maliciosamente) al predictor de ramificación. Los autores han grabado incluso un vídeo demostrando el ataque:

Una demostración de ataque de Retbleed en un sistema basado en Linux.

El vídeo muestra cómo un programa que no tiene acceso a dichos datos roba una contraseña de superusuario cifrada. Hay que tener en cuenta que el vídeo está muy acelerado: en tiempo real, ¡el robo de la contraseña en un sistema basado en Intel lleva al menos una hora y media! Los resultados se resumen en la siguiente tabla:

Lista resumida de procesadores probados ante la posibilidad de un ataque de Retbleed con la protección Retpoline activada.

Lista resumida de procesadores probados ante la posibilidad de un ataque de Retbleed con la protección Retpoline activada. Fuente

Como muestra la tabla, los procesadores AMD Zen 1 y Zen 2 (2017–2019) y Kaby Lake y Coffee Lake de Intel (2016–2017), que no son completamente nuevos, pero están actualizados, son propensos a un ataque de Retbleed. En los procesadores AMD Zen 3 más modernos y en Intel Alder Lake y los procesadores anteriores de novena generación, no funciona un ataque de Retbleed. Esto también se debe a la implementación de la protección de hardware IBRS mejorado en los procesadores Intel.

Coste de la protección

Si es tan difícil llevar a cabo un ataque de Spectre, ¿por qué defenderse de él? Es verdad que para aplicar Spectre a un caso del mundo real (con daño real a las víctimas), se deben cumplir muchas condiciones: ser capaz de ejecutar código en el sistema atacado, tener instalado un software propenso a ataques y extraer datos de forma fiable de la caché (con bastante probabilidad de una lectura con errores). Anteriormente, comentamos que el ataque más realista se simuló en un navegador Chrome del que un potencial atacante podría, por ejemplo, extraer contraseñas guardadas en la RAM. Pero esto se resolvió con una sencilla mejora de la protección en el propio navegador, como ocurre con cualquier otro pequeño error.

Podría ocurrir que el progreso en la investigación de vulnerabilidades similares a Spectre algún día lleve de forma inesperada a posibilitar un ataque masivo en los ordenadores y servidores de los usuarios. Pero, si hablamos de proteger datos realmente confidenciales, Spectre debe tenerse en cuenta a día de hoy.

La situación más probable es un ataque a través de proveedores de hosting y computación distribuida. Un servidor virtual típico que se puede alquilar por una cantidad de dinero razonable a través de cualquier proveedor es esencialmente un programa que se ejecuta junto a los sistemas operativos virtuales de otros clientes en el mismo servidor de alta potencia. Un suscriptor de servidor virtual puede, por definición, ejecutar programas en él, pero no tiene privilegios para acceder a sus vecinos o al host, es decir, el sistema operativo de control. La separación de los entornos virtuales y la imposibilidad de escapar de su espacio virtual es un requisito de seguridad clave para dichos proveedores de servicios.

A su vez, los proveedores de servicios están interesados ​​en tener tantos sistemas virtuales ejecutándose en el mismo servidor como sea posible sin que surjan problemas entre ellos. Esta es la clave para la recuperación más temprana del hardware más costoso. Dicho esto, todos los parches de Spectre (que realmente funcionan) reducen el rendimiento y, por lo tanto, reducen los ingresos del ISP. Pero los proveedores tampoco pueden ignorar el problema, ¡porque el robo exitoso de datos confidenciales ni siquiera deja rastro!

Entonces, cuando se propuso Retpoline, muchos lo tomaron como un salvavidas para luchar contra el nuevo problema. Pero, en enero de 2018, surgieron dudas sobre la fiabilidad de este método de defensa. Una discusión sobre la lista de correo de los desarrolladores del kernel de Linux muestra una serie de quejas sobre Retpoline (el autor tampoco se deshace en halagos al tratar otros métodos). Al mismo tiempo, Linus Torvalds, el creador y principal guardián de Linux, dejó claro (con el tono tajante que le caracteriza) que Retpoline es en general suficiente.

Los autores de Retbleed critican la forma sentenciosa en la que Torvalds coloca su rotunda cita al comienzo del artículo. Ellos también calcularon el “coste” de la protección en el mundo real para los procesadores vulnerables que no se pueden reparar a nivel de hardware. Los parches en el kernel de Linux han producido caídas de rendimiento de hasta un 39 % en los procesadores Intel y un 14 % en los procesadores AMD.

Los procesadores AMD resultaron ser vulnerables a su manera, y los investigadores descubrieron un fenómeno que llamaron “Phantom JMPs”. Resultó que, bajo ciertas condiciones, es posible hacer que un sistema de predicción de ramificación ejecute una instrucción arbitraria incluso aunque no se encuentre en el código atacado. Como consecuencia de ello, los autores tuvieron que publicar un breve anexo de una página al estudio. Sin embargo, estipulan que explotar esta vulnerabilidad para causar daños reales es aún más difícil que con el Spectre V2 tradicional.

¿Y ahora qué?

Para el común de los usuarios, la amenaza de los ataques de Spectre sigue siendo completamente virtual y será suficiente con aplicar los parches preventivos de los desarrolladores de sistemas operativos. Por cierto, en Windows, la protección IBRS efectiva está habilitada de forma predeterminada. Es posible que los nuevos parches del kernel de Linux provoquen una disminución del rendimiento que puede ser más perceptible en las soluciones empresariales en las que el hardware del dispositivo se exprime al límite.

El problema se complica por el hecho de existir un gran número de variantes de Spectre. Retbleed también podría considerarse una variante separada, que funciona de una forma distinta en procesadores de diferentes fabricantes. AMD e Intel han reconocido a Retbleed como una vulnerabilidad separada y es probable que propongan una solución de hardware para ella. Las empresas cambiarán a un nuevo hardware donde se implementen medidas de protección, encontrando un equilibrio entre rendimiento y seguridad. Por desgracia, todos los parches de software tienen un mayor impacto en el rendimiento de los procesadores relativamente antiguos. Con el tiempo, no solo el software requiere una mayor exigencia, sino que también existe esta “penalización” en la ejecución especulativa.

Si se mira el problema con perspectiva, no se trata de nada nuevo. Los desarrolladores ofrecen una solución para mejorar el rendimiento sin pensar en la seguridad. Tarde o temprano (tarde en este caso, ya que la ejecución especulativa comenzó a mediados de la década de los años 90), vuelve para atormentarnos a todos, y las medidas de seguridad tienen un coste, pero con el tiempo se encuentran nuevas soluciones y la industria de alta tecnología sigue adelante.

La sorpresa fue el descubrimiento del problema en el hardware, algo que no es tan fácil de solucionar como en el software. Y esto no es un simple error, sino un enfoque deficiente (desde la perspectiva de la seguridad) adoptado por la industria hace muchos años. Esperemos que los desarrolladores de procesadores encuentren nuevos métodos para ofrecer una informática segura y potente antes de que la amenaza de un ataque de hardware extremadamente peligroso caiga sobre nosotros, un peligro que nos amenaza a todos, es ya conocido y solo puede resolverse reemplazando el hardware por completo.

 

Consejos