El proyecto OpenSSL acaba de liberar una nueva versión de la librería
que corrige una muy curiosa y relativamente grave vulnerabilidad. La han
llamado "Heartbleed", algo así como corazón desangrado, el motivo es
que el fallo se encuentra en una extensión denominada "Heartbeat" y
obviamente los que la han descubierto no han dejado pasar el juego de palabras,
veremos la razón.
Heartbeat es una funcionalidad
añadida a TLS/DTLS que básicamente permite refrescar una sesión segura sin
necesidad de efectuar una renegociación. Entre cliente y servidor se envían
mensajes en forma de estructuras muy básicas para asegurarse que el cliente va
a seguir enviando peticiones o el servidor sigue ahí para seguir
respondiéndolas.
Cuando OpenSSL se decidió a
implementar el RFC correspondiente, introdujo un bug en la implementación.
Dicho fallo permite leer partes de la memoria del proceso, hasta 64k, tanto en
el cliente como en el servidor, dependiendo del punto de vista del atacante.
Ese es el motivo del apodo con el que han bautizado la vulnerabilidad.
El problema reside en la función
'dtls1_process_heartbeat' de 'ssl/di_both.c' al no validar correctamente la
longitud de la estructura 'ssl3_record_st'. Dicha longitud puede ser manipulada
a un valor de 65535 bytes y la parte de datos mucho menor o simplemente 0.
Cuando se reserva memoria para construir la respuesta, se hace teniendo en
cuenta la longitud indicada por la petición. Posteriormente cuando los datos
(que recordemos pueden estar a 0) sean copiados a la respuesta, mediante la
función 'memcpy', lo que se van a copiar son datos de la memoria cercana a
dicha estructura pero no relacionados con la misma.
Esto es así porque se le está
indicando que nuestros datos son de 65535 cuando en realidad hemos enviado una
cantidad muchísimo menor o 0. Obviamente, el receptor de la respuesta recibirá
los datos en bruto de ese trozo de memoria.
Solo pueden ser leídos 64k como
máximo, pero tal y como advierten en la web dedicada al fallo
(http://heartbleed.com/) es posible renegociar la conexión una y otra vez y
volver a obtener otros 64k reiterativamente aunque de manera no controlada, es
decir, no sabemos que parte de la memoria "tocará". Según los
descubridores esto les permitió efectuando pruebas de concepto extraer las
claves privadas del servidor y diversa información sensible.
Recordemos que OpenSSL es una
librería usada en multitud de proyectos y es distribuida en múltiples versiones
de Linux, etc. Es decir, actualmente existe un número astronómico de equipos y
servidores que podrían estar expuestos a esta vulnerabilidad. Hay que
actualizar la librería OpenSSL a la última versión no vulnerable o compilar las
fuentes descartando el soporte Heartbeat definiendo la opción
-DOPENSSL_NO_HEARTBEATS.
Esta vulnerabilidad está
presente desde la versión de OpenSSL que introdujo la implementación con el
bug, desde la versión 1.0.1. El fallo fue descubierto por investigadores de la
empresa Codenomicon en colaboración con Neel Mehta del equipo de seguridad de
Google e independientemente por el equipo de seguridad de la empresa
Codenomicon. Tiene asignado el CVE-2014-0160. Podemos leer un análisis técnico
(en inglés) aquí y el commit al repositorio Git de OpenSSL del parche en este
enlace . El parche se encuentra incluido en la última versión de OpenSSL, la
1.0.1g.
Más información:
- The Heartbleed Bug http://heartbleed.com/
- Existential type crisis : Diagnosis of the OpenSSL Heartbleed Bug http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html
- Projects / openssl.git / commitdiff http://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=96db9023b881d7cd9f379b0c154650d6c108e9a3
- Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) Heartbeat Extension http://tools.ietf.org/html/rfc6520