Logotipo de Zephyrnet

Zenbleed: cómo la búsqueda del rendimiento de la CPU podría poner en riesgo sus contraseñas

Fecha:

¿Recuerdan Heartbleed?

Ese fue el error, allá por 2014, que introdujo el sufijo -sangrar por vulnerabilidades que filtrar datos al azar forma que ni el atacante ni la víctima pueden controlar de forma fiable.

En otras palabras, un ladrón no puede usar un error tipo sangrado para un ataque de precisión, como "Encuentre el archivo de contraseña en la sombra en el /etc directorio y cárguemelo”, o “Busque hacia atrás en la memoria hasta la primera ejecución de 16 dígitos ASCII consecutivos; ese es un número de tarjeta de crédito, así que guárdelo para más tarde”.

En Heartbleed, por ejemplo, podría engañar a un servidor sin parches para que envíe un mensaje que se suponía que tenía una longitud máxima de 16 bytes, pero que incluía incorrectamente hasta aproximadamente 64,000 bytes adicionales agregados al final.

No podías elegir qué había en esos 64,000 bytes saqueados; simplemente obtuvo lo que sucedió que estaba adyacente en la memoria al mensaje genuino que se suponía que debía recibir.

A veces, obtendría fragmentos de ceros o datos cifrados desconocidos para los que no tenía la clave de descifrado...

…pero de vez en cuando obtendría fragmentos de texto sin cifrar sobrantes de una página web que el visitante anterior descargó, o partes de un correo electrónico que otra persona acaba de enviar, o incluso bloques de memoria con las propias claves criptográficas privadas del servidor.

Agujas abundantes en montones de heno sin fin

Los atacantes generalmente explotan los errores basados ​​en sangrado simplemente activándolos una y otra vez automáticamente, recopilando una gran cantidad de datos no autorizados y luego analizándolos más tarde en su tiempo libre.

Las agujas son sorprendentemente fáciles de extraer de los montones de heno si (a) puede automatizar la búsqueda mediante el uso de un software que haga el trabajo duro por usted, (b) no necesita respuestas de inmediato y (c) tiene muchas y muchos montones de heno, por lo que puede darse el lujo de perder muchas o incluso la mayoría de las agujas y aún así terminar con un alijo considerable.

Otros errores con nombre de sangrado incluyen divagando, que provocó deliberadamente errores de memoria temporales para adivinar qué estaba almacenado en partes cercanas de un chip RAM, y Opcionessangrado, donde podías preguntarle a un servidor web una y otra vez qué opciones HTTP admitía, hasta que te envió una respuesta con los datos de otra persona por error.

En analogía, un error de estilo de sangrado es un poco como una lotería discreta que no tiene ningún premio mayor garantizado, pero donde tienes la oportunidad furtiva de comprar 1,000,000 de boletos por el precio de uno.

Bueno, el famoso cazador de errores de Google, Tavis Ormandy, acaba de informó un nuevo error de este tipo que él ha apodado Zenbleed, porque el error se aplica a la última versión de AMD Zen 2 gama de procesadores de alto rendimiento.

Desafortunadamente, puede explotar el error de casi cualquier proceso o subproceso en una computadora y eliminar datos de forma pseudoaleatoria de casi cualquier lugar de la memoria.

Por ejemplo, un programa que se ejecuta como un usuario sin privilegios dentro de una máquina virtual invitada (VM) que se supone que debe estar aislada del resto del sistema podría terminar con datos de otros usuarios en esa misma VM o de otras VM en el mismo computadora, o desde el programa host que se supone que controla las máquinas virtuales, o incluso desde el kernel del propio sistema operativo host.

Ormandy pudo Para crear código de prueba de concepto que filtró alrededor de 30,000 bytes de datos de otras personas por segundo por núcleo de procesador, 16 bytes a la vez.

Puede que no parezca mucho, pero 30 KB/s es suficiente para exponer la friolera de 3 GB en el transcurso de un día, con datos a los que se accede con mayor frecuencia (incluidas contraseñas, tokens de autenticación y otros datos que se supone que deben mantenerse en secreto) posiblemente apareciendo repetidamente.

Y con los datos expuestos en fragmentos de 16 bytes, es probable que los atacantes encuentren una gran cantidad de fragmentos reconocibles en la información capturada, lo que les ayudará a tamizar y clasificar los montones de heno y concentrarse en las agujas.

El precio del rendimiento

No vamos a tratar de explicar la falla de Zenbleed aquí (consulte el artículo de Tavis Ormandy propio artículo para más detalles), pero nos centraremos en la razón por la que apareció el error en primer lugar.

Como probablemente haya adivinado, dado que ya hemos aludido a procesos, subprocesos, núcleos y administración de memoria, este error es un efecto secundario de las "características" internas que los procesadores modernos incluyen para mejorar el rendimiento tanto como sea posible. , incluido un truco ingenioso pero propenso a errores conocido en el comercio como ejecución especulativa.

Hablando en términos generales, la idea detrás de la ejecución especulativa es que si un núcleo de procesador estaría inactivo, tal vez esperando para saber si se supone que debe dejar de funcionar. THEN o de ELSE ruta de una decisión if-then-else en su programa, o esperar una verificación de control de acceso de hardware para determinar si realmente está permitido usar el valor de datos que está almacenado en una dirección de memoria específica o no...

…entonces vale la pena continuar de todos modos y calcular con anticipación (esa es la parte de la “ejecución especulativa”) en caso de que la respuesta sea útil.

Si la respuesta especulativa resulta innecesaria (porque resolvió el THEN resultado cuando el código bajó el ELSE path en su lugar), o termina fuera de los límites del proceso actual (en el caso de una verificación de acceso fallida), simplemente puede descartarse.

Puede pensar en la ejecución especulativa como un presentador de un programa de preguntas y respuestas que mira la respuesta en la parte inferior de la tarjeta mientras hace la pregunta actual, suponiendo que el concursante intentará responder y tendrá que consultar la respuesta directamente. lejos.

Pero en algunos concursos, el concursante puede decir "Aprobado", omitiendo la pregunta para volver a ella más tarde.

Si eso sucede, el anfitrión debe olvidarse de la respuesta no utilizada y continuar con la siguiente pregunta, y la siguiente, y así sucesivamente.

Pero si la pregunta "aprobada" vuelve a surgir, ¿cuánto afectará el hecho de que ahora saben la respuesta de antemano cómo la preguntan la segunda vez?

¿Qué pasa si sin darse cuenta leen la pregunta de manera diferente o usan un tono de voz diferente que podría darle al concursante una pista no deseada?

Después de todo, la única forma verdadera de "olvidar" algo por completo es nunca haberlo sabido en primer lugar.

El problema con los vectores

En el error Zenbleed de Ormandy, ahora conocido oficialmente como CVE-2023-20593, el problema surge cuando un procesador AMD Zen 2 ejecuta una instrucción especial que existe para configurar varios de los llamados registros vectoriales a cero al mismo tiempo.

Los registros vectoriales se utilizan para almacenar datos utilizados por instrucciones especiales de procesamiento de datos y numéricos de alto rendimiento, y en la mayoría de los procesadores Intel y AMD modernos tienen un ancho de 256 bits, a diferencia de los 64 bits de los registros de propósito general de la CPU que se utilizan para fines de programación tradicionales. .

Estos registros de vectores especiales normalmente se pueden operar en 256 bits (32 bytes) a la vez, o solo 128 bits (16 bytes) a la vez.

De hecho, por razones históricas, las CPU de hoy en día tienen dos conjuntos completamente diferentes de instrucciones de código de máquina de estilo vectorial: un grupo más nuevo conocido como AVX (extensiones vectoriales avanzadas), que puede funcionar con 128 o 256 bits, y un grupo de instrucciones más antiguo y menos potente llamado SSE (transmisión de extensiones SIMD, donde SIMD a su vez significa instrucción única/múltiples datos), que solo puede funcionar con 128 bits a la vez.

De manera molesta, si ejecuta un código AVX de nuevo estilo, luego un código SSE de estilo antiguo y luego más código AVX, las instrucciones SSE en el medio estropean los 128 bits superiores de los nuevos registros AVX de 256 bits, a pesar de que las instrucciones SSE, al menos en papel, solo hacen sus cálculos en los 128 bits inferiores.

Por lo tanto, el procesador guarda silenciosamente los 128 bits superiores de los registros AVX antes de cambiar al modo SSE compatible con versiones anteriores, y luego restaura esos valores guardados la próxima vez que comience a usar las instrucciones AVX, evitando así efectos secundarios inesperados al mezclar código vectorial antiguo y nuevo. .

Pero este proceso de guardar y restaurar perjudica el rendimiento, que tanto Intel y AMD guías de programación le advierten fuertemente.

AMD dice:

Hay una penalización significativa por mezclar instrucciones SSE y AVX cuando los 128 bits superiores de los registros YMM [de 256 bits de ancho] contienen datos distintos de cero.

La transición en cualquier dirección provocará que una microfalla derrame o llene los 128 bits superiores de los dieciséis registros YMM.

Habrá una penalización de aproximadamente 100 ciclos para señalar y manejar esta falla.

E Intel dice algo similar:

El hardware guarda el contenido de los 128 bits superiores de los registros YMM [de 256 bits de ancho] cuando se hace la transición de AVX a SSE, y luego restaura estos valores cuando se hace la transición […]

Las operaciones de guardar y restaurar provocan una penalización que asciende a varias decenas de ciclos de reloj para cada operación.

Para salvar el día, hay una instrucción de vector especial llamada VZEROUPPER que pone a cero los 128 bits superiores de cada registro vectorial de una sola vez.

Llamando VZEROUPPER, incluso si su propio código realmente no lo necesita, le indica al procesador que ya no le importan los 128 bits superiores de esos registros de 256 bits, por lo que no es necesario guardarlos si llega una instrucción SSE de la vieja escuela a lo largo del siguiente.

Esto ayuda a acelerar su código, o al menos le impide ralentizar el código de otra persona.

Y si esto suena como un poco de kludge...

…Bueno, lo es.

Es un truco a nivel de procesador, si lo desea, solo para asegurarse de no reducir el rendimiento al intentar mejorarlo.

¿Dónde entra CVE-2023-20593?

Toda esta fijación en el rendimiento llevó a Ormandy a su agujero de fuga de datos de Zenbleed, porque:

  • El código AVX se usa con mucha frecuencia para fines no matemáticos, como trabajar con texto. Por ejemplo, la popular biblioteca de programación de Linux glibc utiliza instrucciones y registros AVX para acelerar la función strlen() que se usa para encontrar la longitud de las cadenas de texto en C. (En términos generales, strlen() usar el código AVX le permite buscar a través de 16 bytes de una cadena a la vez buscando el byte cero que indica dónde termina, en lugar de usar un bucle convencional que verifica byte por byte).
  • Los procesadores Zen 2 de AMD no se deshacen de manera confiable VZEROUPPER cuando falla una ruta de código de ejecución especulativa. Al "quitar a cero" los 128 bits superiores de un registro de 256 vectores porque el procesador adivinó incorrectamente y el VZEROUPPER la operación debe revertirse, el registro a veces termina con 128 bits (16 bytes) "restaurados" del código AVX de otra persona, en lugar de los datos que realmente estaban allí antes.

En la vida real, parece que los programadores rara vez usan VZEROUPPER en formas que deben revertirse, de lo contrario, este error podría haberse encontrado hace años, tal vez incluso durante el desarrollo y las pruebas en AMD.

Pero al experimentar cuidadosamente, Ormandy descubrió cómo crear bucles de código AVX que no solo activaban repetidamente la ejecución especulativa de un VZEROUPPER instrucción, pero también obligó regularmente a revertir esa instrucción y el AVX registra "sin cero".

Desafortunadamente, muchos otros programas convencionales usan mucho las instrucciones AVX, incluso si no son el tipo de aplicaciones como juegos, herramientas de representación de imágenes, descifradores de contraseñas o criptomineros que esperaría que necesitaran un código de estilo vectorial de alta velocidad.

Su sistema operativo, cliente de correo electrónico, navegador web, servidor web, editor de código fuente, ventana de terminal (prácticamente todos los programas que usa de forma rutinaria) casi con certeza usa una parte justa del código AVX para mejorar el rendimiento.

Entonces, incluso en condiciones muy típicas, Ormandy a veces terminaba con los restos fantasmales de los datos de otros programas mezclados con sus propios datos AVX, que podía detectar y rastrear.

Después de todo, si sabe lo que se supone que debe estar en los registros AVX después de un VZEROUPPER la operación se revierte, es fácil detectar cuándo los valores en esos registros van mal.

En las propias palabras de Ormandy:

[B] operaciones básicas como strlen(), memcpy() y strcmp() [encontrar la longitud de la cadena de texto, copiar la memoria, comparar cadenas de texto] utilizará los registros vectoriales, ¡así que podemos espiar de manera efectiva las operaciones que ocurren en cualquier parte del sistema!

No importa si están ocurriendo en otras máquinas virtuales, sandboxes, contenedores, procesos, lo que sea.

Como mencionamos anteriormente, si tiene un grupo diario de 3 GB de datos fantasma no estructurados y seleccionados de forma pseudoaleatoria por núcleo de CPU, es posible que no obtenga el equivalente de la lotería a un premio mayor de varios millones de dólares.

Pero es casi seguro que ganará el equivalente a miles de premios de $ 1000, sin arriesgarse a meter la nariz en los procesos y páginas de memoria de otras personas como lo hace el malware tradicional de "espionaje de RAM".

¿Qué hacer?

CVE-2023-20593 fue divulgado responsablemente, y AMD ya ha producido un parche de microcódigo para mitigar el defecto.

Si tiene una CPU de la familia Zen 2 y le preocupa este error, hable con el proveedor de su placa base para obtener más información sobre cómo obtener y aplicar las correcciones pertinentes.

En los sistemas operativos con herramientas de software que admiten el ajuste de los llamados MSR (registros específicos del modelo) en su procesador que controla su configuración de bajo nivel, hay un indicador no documentado (bit 9) que puede configurar en un registro de modelo mal documentado (MSR 0xC0011029) que aparentemente desactiva el comportamiento que causa el error.

Se hace referencia a MSR 0xC0011029 en la lista de correo del kernel de Linux archivo como el DE_CFG registro, aparentemente abreviatura de configuración de decodificación, y otros bits conocidos de este registro se utilizan para regular otros aspectos de la ejecución especulativa.

Por lo tanto, estamos suponiendo que DE_CFG[9], que es la abreviatura de "bit 9 de MSR 0xC0011029", decide si permite instrucciones con efectos secundarios complejos como VZEROUPPER ser probado especulativamente en absoluto.

Obviamente, si nunca permite que el procesador ponga a cero los registros vectoriales a menos que ya esté seguro de que nunca necesitará "quitar a cero" esos registros y revertir los cambios, este error nunca se puede desencadenar.

El hecho de que este error no se haya detectado hasta ahora sugiere que la ejecución especulativa en el mundo real de VZEROUPPER no sucede muy a menudo y, por lo tanto, es poco probable que este hack/fix de bajo nivel tenga un impacto notable en el rendimiento.

El artículo de Ormandy incluye una descripción de cómo reconfigurar el bit MSR relevante en su procesador Zen 2 en Linux y FreeBSD.

(Ya verás DE_CFG[9] descrito como un bocado de pollo, jerga para un ajuste de configuración que activa on girar off una característica que te da miedo.)

OpenBSD, escuchamos, estará obligando DE_CFG[9] encendido automáticamente en todos los procesadores Zen 2, suprimiendo así este error por defecto en busca de seguridad sobre el rendimiento; en Linux y otros BSD, puede hacerlo con herramientas de línea de comando (se necesita raíz) como wrmsr y cpucontrol.

Mac los usuarios pueden relajarse porque todas las Mac que no son ARM tienen chips Intel, hasta donde sabemos, en lugar de AMD, y no se sabe que los procesadores Intel sean vulnerables a este error en particular.

Windows Es posible que los usuarios deban recurrir a hacks de controladores del kernel no oficiales (evítelos a menos que realmente sepa lo que está haciendo, debido a los riesgos de seguridad de arrancar en el modo "permitir cualquier controlador antiguo"), o para instalar el depurador oficial de WinDbg, habilite la depuración del kernel local y use un script WinDbg para modificar el MSR relevante.

(Admitimos que no hemos probado ninguna de estas mitigaciones, porque no tenemos una computadora basada en AMD a mano en este momento; ¡háganos saber cómo le va si la tiene!)


punto_img

Información más reciente

punto_img