Esta semana en seguridad: soluciones confusas, fuentes incorrectas, ataques de tiempo de TPM y más.

Se descubrió una aventura en libarchive a través del proyecto ClusterFuzz de Google. Libarchive es una biblioteca de compresión y descompresión, ampliamente utilizada en utilidades. El problema aquí es cómo se recupera la biblioteca después de un archivo con formato incorrecto. Al golpear un título no válido, se libera la memoria utilizada. El problema es que es posible seguir procesando archivos incluso después de liberar esa memoria de trabajo, lo que provoca todo tipo de problemas. Hasta ahora no se ha revelado la explotación real, pero probablemente sea posible. El problema se solucionó en mayo, pero el problema se anunció recientemente para dar tiempo a que esa actualización se extendiera a los usuarios.

Es de destacar el hecho de que este número se encontró gracias a los esfuerzos difusos de Google. Google está lanzando el proyecto oss-fuzz, que automáticamente consume compilaciones nocturnas de unos 200 proyectos de código abierto y lanza ClusterFuzz contra ellos. Este proceso de lanzar datos aleatorios a programas y funciones reveló más de 14.000 errores.

Documentos PDF y fuentes incrustadas

Adobe lanzó recientemente una actualización de seguridad para Reader. Hay muchas vulnerabilidades en esta actualización, pero la que me llamó la atención fue CVE-2019-8196. Esto también se descubrió mediante fuzzing, aunque en este caso manipuló accidentalmente un documento PDF válido que produjo el archivo con formato incorrecto. Los cambios en la fuente incrustada llevaron a la lectura de la ubicación de la memoria no inicializada. Es preocupante que después de casi diez años de las típicas vulnerabilidades relacionadas, aún sean posibles bloqueos como estos.

Ataque de tiempo modular de plataforma confiable

El Reliable Platform Module es una pieza de hardware integrada en muchas placas base que le permite descargar operaciones criptográficas. El propósito de mover tareas como firmar y encriptar la CPU no apunta a ventajas rápidas, en este caso. En cambio, el TPM apunta a ser una plataforma confiable incluso si el sistema operativo se ha visto comprometido. Un nuevo estudio, acertadamente llamado TPM Fail, ilustró un ataque de tiempo que revela una de las claves secretas incrustadas en el TPM.

Los ataques de tiempo se convierten en paradigmas de programación normales. Por ejemplo, cuando usa grep para buscar el primer caso de una cadena en un archivo grande, desea que la operación finalice lo antes posible. Si los datos que está buscando se encuentran en el 10% superior del archivo, es obvio que el programa de búsqueda debe dejar de buscar y devolver una respuesta tan pronto como se encuentre. Lo que es menos obvio es la información filtrada por el tiempo que necesita grep encuentra tu plantilla. Imagine realizar varias búsquedas de este tipo en el mismo archivo, todas buscando cadenas diferentes. Teniendo en cuenta los datos de tiempo y el archivo de origen, sería posible hacer una suposición informada sobre las cadenas de búsqueda.

Un ejemplo típico de esto en el mundo real es una comparación de rutina. Si los primeros caracteres de dos cadenas son diferentes, la rutina puede regresar inmediatamente, pero si los primeros 10 caracteres son iguales y las cadenas no difieren hasta el undécimo carácter, esa rutina tardará mucho más en iniciar la comparación. Con el tiempo suficiente para observar las comparaciones, un atacante podría resolver la cadena secreta de una en una. Cuanto mayor sea el tiempo de comparación, más signos serán correctos. La solución estándar a este dilema utiliza funciones de tiempo constante. En nuestro ejemplo de comparación de combinación, esto significaría comparar cada carácter de las cadenas, independientemente de cuán diferentes sean.

Los investigadores interesados ​​descubrieron que algunas implementaciones de TPM 2.0 no usaron algoritmos de tiempo constante al realizar rutinas de curvas elípticas. Entonces, ¿qué tan malo es el resultado? En un sistema vulnerable, la clave secreta de TPM se puede extraer lo más rápido posible en 20 minutos, asumiendo que el atacante podría lanzar código en esa máquina. Peor aún, en el caso de una VPN como StrongSwan con tecnología TPM, la clave secreta podría extraerse en 5 horas de tráfico de red.

Las implementaciones de software se pueden parchear, pero los TPM de dispositivos son mucho más difíciles de arreglar porque no son defectuosos por diseño. La matemática sobre cómo las claves secretas mapean las variaciones de tiempo es un poco complicada, pero todo está en el periódico, así que eche un vistazo.

Zombieload regresa de los muertos

Muy apropiadamente, considerando el nombre, Zombieload ha vuelto a subir en forma de Zombieload V2. Esta vez, el problema son las extensiones de sincronización transaccional (TSX) en los procesadores Intel modernos. Las mitigaciones existentes no fueron suficientes para prevenir la vulnerabilidad de TSX Asynchronous Abort (TAA), por lo que este ataque no se reveló con el resto de los detalles de Zombieload. Lo que hace que TAA sea particularmente problemático es que un proceso no necesita usar las instrucciones TSX, todo lo que se necesita es que un atacante tenga acceso a ellas. Para un procesador vulnerable, la solución final es desactivar completamente las instrucciones TSX. La documentación del kernel de Linux tiene parte de la información más útil que he encontrado.

Ataques de Windows

Recientemente han aparecido un par de ataques contra sistemas Windows. Primero está Ghost Potato, un ataque reflejo de NTLM. NTLM es la solución de autenticación introducida en Windows. Ha habido varios ataques contra NTLM a lo largo de los años y mitigaciones contra esos ataques. Uno de los efectos secundarios del código cerrado de Windows es que no siempre está claro cómo funcionan exactamente esas mitigaciones. Ghost Potato es un ejemplo de lo triviales que se pueden eludir estas mitigaciones, una vez que un atacante comprende cómo funcionan.

La esencia de los ataques reflectantes NTLM es que si un atacante puede engañar a un usuario para que intente realizar la verificación NTLM con una máquina maliciosa. Esta autenticación luego se repite en la máquina que se conecta en tiempo real, lo que esencialmente hace que la víctima se autentique con su propia máquina. Una vez que se completa la autenticación, el atacante puede hacerse cargo de la sesión y actuar como el usuario autenticado. Una de las formas de mitigar este ataque fue registrar los desafíos criptográficos. Los mensajes de desafío entrantes se comparan con los enviados recientemente, y es probable que una colisión sea un ataque. El problema es qué tan rápido envejecen los desafíos de esa caché: 5 minutos. Es posible extender una sesión auténtica NTLM más allá de esa marca de 5 minutos. En ese momento, enviar un segundo intento de conexión falso empujará el mensaje deseado desde el final de la caché y el intento de reflexión tendrá éxito. Está listo y se corrigió en la actualización de Windows Patch Tuesday para Windows.

Bitlocker es la solución de cifrado de disco / carpeta que se ha creado en Windows desde Windows Vista. Un grupo de investigadores publicó recientemente un artículo que detalla las técnicas más modernas de descifrado de contraseñas aplicadas a Bitlocker. Su programa Bitcracker contiene algunas mejoras de rendimiento nuevas. Al principio se dieron cuenta de que parte del algoritmo de descifrado de Bitlocker podía calcularse previamente parcialmente. Se ha creado una tabla de búsqueda de 256 Mb, que en cierto modo elimina todos los intentos de contraseña.

La segunda mejora es una forma de determinar rápidamente si la prueba de descifrado fue exitosa antes de hacer todos los cálculos necesarios. El descifrado de Bitlocker generalmente termina con el cálculo y la comparación del código de autenticación masiva. Si la MAC calculada coincide con la esperada, entonces la contraseña era correcta. Se observó que la salida de un descifrado adecuado era reconocible sin contar el MAC. Básicamente, pudieron determinar rápidamente si el resultado de una prueba de contraseña dada dio un resultado creíble sin completar el proceso. Este atajo puede resultar en algunos falsos positivos, pero el número de falsos positivos es lo suficientemente bajo como para que el enfoque valga la pena.

Cuando utilizaron GPU habilitadas para CUDA de alta calidad, pudieron probar más de 100 millones de contraseñas al día. Esto no es suficiente para reforzar una buena contraseña, pero sin duda hace que un gran ataque de diccionario sea trivial. Su conclusión fue que sigue siendo importante utilizar buenas contraseñas que no aparecen en las listas de contraseñas.

  • BT dice:

    Siempre espero con ansias esta rúbrica, por supuesto, no torcida, ¡gracias!

    • Lobo dice:

      ¿Estás esperando que se revele tu vector de ataque? ; D

  • Alexander Wikström dice:

    Ah, el venerable ataque basado en los viejos tiempos.

    Otra solución para los ataques de tiempo es tener un sistema secundario que agregue una cantidad de tiempo desconocida y aleatoria a cada solicitud, esto técnicamente no “detendría” los ataques de tiempo, solo haría que las respuestas de este ataque fueran “un poco” más confusas.

    Sin embargo, agregar un retraso aleatorio no es una solución "perfecta", sino que se deben usar funciones que siempre terminen en un tiempo constante. Y esto es ridículamente fácil. Simplemente haga que un temporizador se ejecute en paralelo a la tarea, el temporizador siempre es lo suficientemente largo para que la tarea finalice y la respuesta nunca se devuelve antes de que finalice el temporizador. Y en ASIC, esto es realmente fácil de implementar.

    Pero si la tarea puede llevar desde un momento hasta muchas horas para trabajar, entonces tal vez un poco de espera siempre espere horas ...

    Otra mitigación de los ataques de tiempo es disminuir la resolución del tiempo en sí. Por ejemplo, si enviamos respuestas solo una vez cada milisegundo, entonces no podemos saber si la tarea tardó 1.2 ms o 1.8 ms en completarse, ya que ambas se devuelven después de 2 ms. Sin embargo, esta no es una solución “ideal” porque aún filtra información, solo filtra información menos precisa.

    Para mejorar esta funcionalidad y aún menos agotar, podemos hacer que nuestras funciones (tanto como sea posible) atraviesen los datos en orden aleatorio. Por ejemplo, si uno compara cadenas con una lista de cadenas, entonces no necesitamos comenzar con la primera cadena, o explorar la lista de forma secuencial, podemos saltar un poco. Esto significa efectivamente que "apresuramos" el pedido de los artículos enumerados, excepto sin perder el orden real. Y sí, tendremos que rastrear qué partes de la lista escaneamos para no perder el tiempo comparándolas de nuevo ...

    Esto significa que el tiempo que realiza una función no se rige por la entrada y la longitud de una lista estática, sino también por la salida de un generador de números aleatorios. (Y el tiempo promedio requerido para encontrar un artículo específico en realidad no se verá afectado, estadísticamente hablando).

    Al final, si la función siempre puede completar la tarea con la suficiente rapidez, utilice un temporizador para devolver respuestas dentro de un tiempo constante.

    Si el tiempo de finalización puede variar con una cantidad excepcionalmente grande y desea al menos algo de rendimiento, tenga cuidado de eliminar las fuentes de ataques de tiempo. Solo enviar respuestas en intervalos de tiempo específicos es una solución, agregar algo de tiempo adicional arriba es otra solución que funciona bien junto con la anterior. (a menos que su generación de números aleatorios produzca patrones claros. Pero debido a que el atacante probablemente no sepa la hora original, estos patrones deberían ser mucho más difíciles de ver). Y si incluye algo de aleatoriedad en el orden en el que está ejecutando, entonces el tiempo . los ataques están empezando a ser bastante duros.

    • MagicLant3rn dice:

      Tener un tiempo de respuesta fijo es una buena defensa contra ataques remotos, pero el método que mencionó el autor de hacer siempre una comparación completa es mejor contra ataques locales, ya que el consumo de energía y las fugas de RF también pueden filtrar este mismo tiempo sobre la información de ramificación debido a las diferencias. al hacer una comparación y simplemente esperar sin rumbo fijo a que expire un temporizador para poder devolver los resultados cuando expire.

      • Alexander Wikström dice:

        De hecho, esto también es un problema considerable. Y si hay bastantes perturbaciones eléctricas en la parte de la red eléctrica de alguien, entonces estas poderosas variaciones / ruido pueden viajar muy lejos, pero con un equipo bastante bueno, siempre es posible una tormenta.

        Sin embargo, el TPM generalmente no consume grandes cantidades de energía y hay un chip separado en el circuito base, "lejos" de las CPU, en un servidor cerrado, en un armario de acero en un centro de datos lleno de otras computadoras. Por lo tanto, es bastante difícil para las CPU de ese servidor saber a qué carga está el TPM en algún momento. Y algo las entidades externas fuera del centro de datos tendrán mucho ruido para mirar ...

        Entonces, usar una calculadora simple debería ser suficiente, en última instancia, la diferencia en el consumo de energía es ligeramente leve.

        Para sistemas más codiciosos, o cosas que se ejecutan localmente en la misma CPU, entonces sí, esperar inútilmente un temporizador ya no protege tanto las cosas como el código malicioso que se ejecuta en la misma CPU.

    • Harrison Grundy dice:

      Pensé que podría descubrir cómo alguien que ha trabajado en algunos de estos ... en resumen, son mucho más difíciles de mitigar de lo que parecen.

      Agregar un retardo o ruido aleatorio no cambia la exposición tanto como parece, solo requiere que el atacante recolecte más muestras para promediarlo, algo que hacen de todos modos para calcular la aleatoriedad introducida por los cachés, la programación, etc. A menudo, ya está recolectando miles o millones de muestras por un bit recolectado.

      Incluso las versiones de tiempo constante de las funciones no oscurecen de manera confiable la clave, ya que cosas como la aceleración térmica de la CPU expondrán cuán duro “trabajó” durante la operación a un nivel bastante granulado.

      Las mejores soluciones son escribir la función de tal manera que requiera el mismo "trabajo" sin importar cuál sea el resultado, pero eso puede ser increíblemente difícil de hacer sin afectar el rendimiento de manera terrible.

      • Alexander Wikström dice:

        Sí, para las cosas que se ejecutan en la misma CPU se vuelve mucho más difícil.

        Pero para un sistema en particular, en su propio chip, entonces la CPU no presta suficiente atención a los esfuerzos de ese otro chip.

        • Harrison Grundy dice:

          Siempre pensé que se trataba de un entorno común ... cuanto más compartes, más fácil es comunicarte. Suponiendo que un proceso desea monitorear otro:

          Dos procesos segmentados en dos CPU con un circuito base tendrán canales ocultos de gran ancho de banda y ataques de tiempo utilizando todas las NIC, hasta acceder a la memoria en un dominio NUMA separado. El ancho de banda entre ellos puede ser gigabits por segundo.

          Dos máquinas físicas independientes que comparten un bastidor pueden comunicarse más lentamente, utilizando elementos como el sonido, la temperatura y la unidad. Ahora el ancho de banda cae a decenas de bps.

          Dos máquinas contra los lados de la misma cámara pueden comunicarse por carga térmica y eléctrica ... ingresando bits por minuto o bits por hora.

          ¡Habilitar el control de acceso obligatorio y la seguridad alta / baja es difícil!

  • Ren dice:

    "Este proceso de enviar datos aleatorios a programas y funciones ha revelado más de 14.000 errores".

    Que Google registró inmediatamente como propiedad intelectual.
    B ^)

  • Tim dice:

    Buen articulo informativo!

  • daedlanth dice:

    Siempre sonrío cuando se menciona a Storm.

Alberto Gimenez
Alberto Gimenez

Deja una respuesta

Tu dirección de correo electrónico no será publicada.