Espectro (vulnerabilidad)

Spectre : un grupo de vulnerabilidades  de hardware , un error en la mayoría de los procesadores modernos que tienen ejecución de instrucción especulativay predicción avanzada de bifurcaciones , lo que permite que los datos se lean a través de un canal de terceros en forma de una jerarquía de caché común . Afecta a la mayoría de los microprocesadores modernos, en particular las arquitecturas x86/x86_64 (Intel y AMD) y algunos núcleos de procesadores ARM [1] .

La vulnerabilidad permite potencialmente que las aplicaciones locales (un atacante local, cuando ejecuta un programa especial) accedan al contenido de la memoria virtual de la aplicación actual u otros programas [2] [3] [4] . A la amenaza se le han asignado dos identificadores CVE: CVE -2017-5753 y CVE-2017-5715 .

Historia

Spectre fue descubierto de forma independiente por investigadores de la corporación norteamericana Google ( Project Zero ) y un grupo colaborador de Paul Kocher, con la participación de empleados de la Universidad Tecnológica de Graz . La vulnerabilidad se encontró a mediados de 2017 y estuvo bajo discusión cerrada y corrección durante varios meses. La publicación de detalles y correcciones estaba programada para el 9 de enero de 2018, pero los detalles de la vulnerabilidad se hicieron públicos el 4 de enero de 2018 al mismo tiempo que el ataque Meltdown , debido a publicaciones de los periodistas de The Register [5] que se enteraron de las correcciones de KAISER/KPTI para combatir Meltdown desde la lista de correo del kernel de Linux [6] .

Significado

El error de Spectre permite que las aplicaciones de usuarios maliciosos que se ejecutan en una computadora determinada obtengan acceso de lectura a ubicaciones arbitrarias en la memoria de la computadora utilizada por el proceso de la víctima, como otras aplicaciones (es decir, romper el aislamiento de memoria entre programas). El ataque de Spectre afecta a la mayoría de los sistemas informáticos que utilizan microprocesadores de alto rendimiento, incluidos ordenadores personales, servidores, portátiles y una serie de dispositivos móviles [7] . En particular, el ataque de Spectre se demostró en procesadores fabricados por las corporaciones Intel y AMD y en chips que utilizan núcleos de procesador ARM .

Existe una variante del ataque Spectre que utiliza programas JavaScript para acceder a la memoria de los navegadores (leyendo datos de otros sitios o datos guardados en el navegador) [8] .

Implementación utilizando predicción errónea de rama

Supongamos que el fragmento de código del proceso víctima

si ( x < array1_size ) y = matriz2 [ matriz1 [ x ] * 256 ];

es parte de una función que recibe un entero sin signo x de una fuente que no es de confianza, y el proceso que ejecuta este código tiene acceso a una matriz de enteros de 8 bits sin signo matriz1 de tamaño matriz1_tamaño y una segunda matriz de enteros de 8 bits sin signo matriz2 de tamaño 64 kb.

Este fragmento comienza comprobando que x es un valor válido. Y este control es fundamental desde el punto de vista de la seguridad. En particular, evita leer información más allá de los límites de array1 . En su ausencia, los valores x no válidos pueden generar una excepción al intentar leer datos fuera de la memoria disponible del proceso o leer información confidencial accesible al proceso especificando x = <secret_byte_address> - <array1_address_array1> .

Desafortunadamente, la predicción errónea de una rama condicional en la ejecución especulativa de instrucciones puede conducir a la ejecución de una rama del código del programa que, en condiciones normales, nunca se ejecutaría [9] .

Por ejemplo, el fragmento de código anterior podría ejecutarse bajo las siguientes condiciones:

  • el valor x se elige para estar fuera de los límites de array1 , y el valor array1[x] apunta al byte k de datos secretos en la memoria del proceso víctima,
  • los valores array1_size y array2 no están en el caché del procesador, y el byte secreto k está en el caché,
  • las llamadas anteriores a este fragmento de código se realizaron con valores x válidos (es decir, se cumplió la condición x < array1_size ).

Tales condiciones pueden surgir espontáneamente, sin embargo, también pueden formarse a propósito, por ejemplo, al leer una gran cantidad de datos extraños para llenar el caché del procesador con estos datos y, en consecuencia, eliminar array1_size y array2 del caché, y luego llame a la función del kernel que usa el byte secreto k , para almacenarlo en caché. Sin embargo, si se conoce la estructura de la memoria caché o si el procesador proporciona voluntariamente una instrucción de restablecimiento de la memoria caché (por ejemplo, la instrucción cflush para los procesadores de la familia x86 ), la tarea de crear las condiciones necesarias para ejecutar un fragmento de código se simplifica enormemente.

El fragmento de código comienza comparando el valor de x con el valor de array1_size . La lectura del valor de array1_size en las condiciones descritas anteriormente dará como resultado una pérdida de memoria caché, lo que a su vez provocará la espera de que el valor de array1_size se obtenga de la RAM. Debido a la presencia de un mecanismo de ejecución de instrucción especulativa en el procesador, durante el tiempo de espera el procesador no estará inactivo, sino que intentará ejecutar una de las ramas del código del programa siguiendo la instrucción de rama.

Dado que los accesos anteriores al fragmento se realizaron con valores válidos de x , el predictor de bifurcación asumirá que esta vez el predicado (x < array1_size) será verdadero, y el procesador intentará ejecutar la secuencia de instrucciones correspondiente. Es decir, leerá el byte en <array1_address> + x , es decir, el byte secreto k , que, gracias a condiciones especialmente formadas, ya está en el caché. Luego, el procesador usa el valor resultante para evaluar la expresión k * 256 y lee el elemento de array2[k * 256] , lo que resultará en una segunda falla de caché, y espera a que el valor de array2[k * 256] sea recuperado de la RAM. En este momento, el valor de array1_size se obtendrá de la RAM , el procesador reconocerá el error del predictor de rama y restaurará el estado arquitectónico al momento anterior al inicio de la ejecución de la rama incorrecta del código del programa.

Sin embargo, en procesadores reales, una lectura especulativa de array2[k * 256] afectará el estado de la memoria caché del procesador, y este estado dependerá de k . Para completar el ataque, solo es necesario detectar este cambio mediante un ataque de canal lateral (el atacante debe tener acceso a la memoria caché del procesador compartido y la fuente de tiempo exacta) y, en base a ello, calcular el byte secreto k . Esto es fácil de hacer, ya que leer los elementos de array2[n * 256] será rápido para n = k y lento para otros valores.

Uso de predicciones erróneas de saltos indirectos

Una sucursal indirecta puede usar más de dos direcciones para ramificar. Por ejemplo, las instrucciones del procesador de la familia x86 pueden saltar usando un valor de dirección en un registro ( jmp eax ), en la memoria ( jmp [eax] o jmp dword ptr [0xdeadc0de] ) o en la pila ( ret ). Las instrucciones de salto indirecto también se encuentran en ARM ( mov pc, r14 ), MIPS ( jr $ra ), SPARC ( jmpl %o7 ), RISC-V ( jarl x0,x1,0 ) y muchos otros.

Si la determinación de una dirección de rama indirecta se retrasa debido a una falta de memoria caché, y el predictor de rama indirecta se "entrena" con direcciones especialmente elegidas, puede ocurrir la ejecución especulativa de instrucciones en la dirección proporcionada por el atacante. Comandos que de otro modo nunca se habrían ejecutado. Si tal actuación deja efectos secundarios medibles , entonces su uso se convierte en una poderosa herramienta en manos del atacante.

Correcciones

Actualmente, no existen tecnologías de software preparadas para proteger contra el ataque de Spectre, aunque se está trabajando [10] . Según un sitio web dedicado a promover el ataque, "no es tan fácil de solucionar y (el error) nos perseguirá durante mucho tiempo".

Una solución de software puede incluir volver a compilar el software utilizando nuevos compiladores para reemplazar las secuencias de código de máquina vulnerables (el llamado mecanismo "retpoline", implementado en GCC y Clang / LLVM ) [11] .

Los fabricantes de procesadores han propuesto varias correcciones, algunas que requieren actualizaciones del microcódigo del procesador, otras que requieren que se agreguen nuevas instrucciones a los procesadores futuros. Las correcciones deben combinarse con la recompilación del software [11] .

En las primeras versiones del aviso de Spectre CVE, el CERT sugirió reemplazar los procesadores como respuesta a la vulnerabilidad: “La vulnerabilidad es causada por elecciones en el diseño del microprocesador. La eliminación completa de la vulnerabilidad requiere el reemplazo de los microprocesadores afectados”. Sin embargo, en textos posteriores ya no se menciona esta versión de la corrección [11] .

Véase también

Notas

  1. Greenberg, Andy Una falla crítica de Intel rompe la seguridad básica para la mayoría de las computadoras . Wired (revista) (3 de enero de 2018). Consultado el 3 de enero de 2018. Archivado desde el original el 3 de enero de 2018.
  2. Personal. Fusión y Espectro . Universidad Tecnológica de Graz (2018). Consultado el 3 de enero de 2018. Archivado desde el original el 3 de enero de 2018.
  3. Metz, Cadé . Los investigadores descubren dos fallas importantes en las computadoras del mundo  , The New York Times  (3 de enero de 2018). Archivado desde el original el 3 de enero de 2018. Consultado el 3 de enero de 2018.
  4. Warren, Tom . Los procesadores de Intel tienen un error de seguridad y la solución podría ralentizar las PC , The Verge  (3 de enero de 2018). Archivado desde el original el 3 de enero de 2018. Consultado el 3 de enero de 2018.
  5. Copia archivada . Consultado el 6 de enero de 2018. Archivado desde el original el 7 de abril de 2018.
  6. Comprensión de Meltdown & Spectre: Qué saber sobre los nuevos exploits que afectan a prácticamente todas las CPU . Consultado el 6 de enero de 2018. Archivado desde el original el 6 de enero de 2018.
  7. Actualizaciones de seguridad de Arm - Desarrollador de Arm . Consultado el 4 de enero de 2018. Archivado desde el original el 4 de abril de 2018.
  8. Ataque de canal lateral de ejecución especulativa ("Spectre") - Mozilla . Consultado el 6 de enero de 2018. Archivado desde el original el 16 de mayo de 2018.
  9. Artículo " Spectre Attacks: Exploiting Speculative Execution Archivado el 3 de enero de 2018 en Wayback Machine "  .
  10. Copia archivada . Fecha de acceso: 4 de enero de 2018. Archivado desde el original el 3 de enero de 2018.
  11. 1 2 3 Copia archivada . Consultado el 6 de enero de 2018. Archivado desde el original el 7 de enero de 2018.

Enlaces