¿Cómo es posible incluso la explotación de Heartbleed?

122

He leído acerca de la vulnerabilidad OpenSSL de Heartbleed y entiendo el concepto. Sin embargo, lo que no entiendo es la parte en que pasamos 64k como la longitud y el servidor devuelve 64kb de datos aleatorios porque no verifica si realmente pasamos 64kb de mensaje de eco o 1 byte.

Pero, ¿cómo es posible que un proceso en un servidor devuelva 64kb de datos aleatorios desde la RAM?

¿No se supone que el sistema operativo impide el acceso a la RAM real y solo permite el acceso a la memoria virtual cuando un proceso no puede acceder al contenido de la memoria de otros procesos?

¿Se ejecuta OpenSSL en modo kernel y, por lo tanto, tiene acceso a toda la RAM?

Esperaría un error de segmentación si un proceso intentara acceder a alguna memoria que no asignó explícitamente. Puedo entender que se obtengan 64kb de datos aleatorios del proceso que ejecuta el programa OpenSSL, pero no veo cómo se puede ver la memoria RAM completa del servidor para poder enviarlo de vuelta al cliente.

ACTUALIZACIÓN: El comentario de @ paj28, sí, fue precisamente la información falsa lo que me llevó a preguntarme sobre esto. Como usted dijo, incluso el asesor oficial de heartbleed.com lo expresa de manera engañosa (aunque yo diría que lo hicieron porque está destinado a una audiencia mucho más amplia que solo nosotros, los técnicos y ellos querían que sea sencillo)

Para referencia, aquí está cómo lo dice heartbleed.com (énfasis mío):

  

El error Heartbleed permite que cualquier persona en Internet lea la memoria de los sistemas protegidos por las versiones vulnerables del software OpenSSL.

Para cualquier persona técnica que implique la RAM completa de la máquina virtual / física.

    
pregunta Talha Sayed 10.10.2016 - 22:03
fuente

2 respuestas

207
El comentario de

@ paj28 cubre el punto principal. OpenSSL es una biblioteca compartida, por lo que se ejecuta en el mismo espacio de direcciones en modo usuario que el proceso que lo usa. No puede ver la memoria de otro proceso en absoluto; cualquier cosa que sugiera lo contrario estaba mal.

Sin embargo, la memoria utilizada por OpenSSL, el material probablemente cerca del búfer desde el que Heartbleed lee en exceso, está llena de datos confidenciales. Específicamente, es probable que contenga tanto el texto cifrado como el texto plano de cualquier transmisión reciente o futura. Si ataca un servidor, esto significa que verá mensajes enviados al servidor por otros y respuestas del servidor a esos mensajes. Esa es una buena manera de robar tokens de sesión e información privada, y probablemente también obtendrá las credenciales de inicio de sesión de alguien. Otros datos almacenados por OpenSSL incluyen claves de cifrado simétricas (utilizadas para el cifrado y la integridad de datos masivos a través de TLS) y claves privadas (utilizadas para probar la identidad del servidor). Un atacante que roba esos puede espiar (e incluso modificar) la comunicación TLS comprometida en tiempo real, o suplantar con éxito el servidor, respectivamente (asumiendo una posición de hombre en el medio en la red).

Ahora, hay algo extraño en Heartbleed que lo hace peor de lo que podrías esperar. Normalmente, existe una gran posibilidad de que, si intenta leer 64k de datos a partir de una dirección de pila arbitraria dentro de un proceso, se encuentre con una dirección de memoria no asignada (memoria virtual no respaldada por nada y, por lo tanto, inutilizable). con rapidez. Estos agujeros en el espacio de direcciones de un proceso son bastante comunes, porque cuando un proceso libera memoria que ya no necesita, el sistema operativo reclama esa memoria para que otros procesos puedan usarla. A menos que su programa pierda memoria como un tamiz, por lo general no hay muchos datos en la memoria que no sean los que se utilizan actualmente. Intentar leer la memoria no asignada (por ejemplo, intentar acceder a la memoria que se ha liberado) provoca una infracción de acceso de lectura (en Windows) / falla de segmentación (en * nix), lo que provocará un bloqueo del programa (y se bloquea antes de que pueda hacerlo) nada como enviar datos de vuelta). Todavía es explotable (como un ataque de denegación de servicio), pero no es tan malo como permitir que el atacante obtenga toda esa información.

Con Heartbleed, el proceso casi nunca se estrelló. Resulta que OpenSSL, aparentemente decidiendo que las bibliotecas de administración de memoria de la plataforma eran demasiado lentas (o algo así, no voy a intentar justificar esta decisión), preasigna una gran cantidad de memoria y luego usa sus propias funciones de administración de memoria. dentro de eso Esto significa algunas cosas:

  • Cuando OpenSSL "libera" la memoria, en realidad no se libera en lo que concierne al sistema operativo, por lo que la memoria sigue siendo utilizable por el proceso. El administrador de memoria interna de OpenSSL podría pensar que la memoria no está asignada, pero en lo que respecta al sistema operativo, el proceso de uso de OpenSSL todavía posee esa memoria.
  • Cuando OpenSSL "libera" la memoria, a menos que borre explícitamente los datos antes de llamar a su función free , esa memoria retiene los valores que tenía antes de ser "liberada". Esto significa que se pueden leer muchos datos que aún no están en uso.
  • El montón de memoria utilizado por OpenSSL es contiguo; no hay vacíos dentro de él en lo que se refiere al sistema operativo. Por lo tanto, es muy poco probable que la lectura en exceso del búfer se ejecute en una página no asignada, por lo que no es probable que se bloquee.
  • El uso de la memoria de OpenSSL tiene una ubicación muy alta, es decir, se concentra dentro de un rango relativamente pequeño de direcciones (el bloque asignado previamente), en lugar de extenderse por el espacio de direcciones en el capricho del asignador de memoria del sistema operativo. Como tal, la lectura de 64 KB de memoria (que no es mucho, incluso al lado del rango típico de 2 GB de un proceso de 32 bits, y mucho menos del enorme rango de un proceso de 64 bits) es probable que obtenga una gran cantidad de datos actualmente (o estuvo recientemente) en uso, a pesar de que los datos residen en el resultado de un conjunto de asignaciones supuestamente separadas.
respondido por el CBHacking 10.10.2016 - 22:44
fuente
6
  

Esperaría un error de segmentación si un proceso intentara acceder a alguna memoria que no asignó explícitamente

Aquí es donde se encuentra el concepto erróneo.

Cualquier acceso de memoria roto podría provocar una falla de segmentación, pero en realidad si la dirección de memoria solicitada se encuentra dentro del espacio de direcciones del proceso actual (por ejemplo, una variable que acaba de liberar), esto es altamente improbable.

¡Es por eso que no debe confiar en fallas de segmentación para encontrar errores de acceso a la memoria!

    
respondido por el Lightness Races in Orbit 13.10.2016 - 11:05
fuente

Lea otras preguntas en las etiquetas