Español | English
rss facebook linkedin Twitter

Drown a fondo: Un nuevo ataque al SSL. (PARTE I)


A lo largo de las últimas semanas se ha hablado mucho de un nuevo ataque dirigido contra el protocolo SSL/TLS. Este ataque, conocido como DROWN, acrónimo en inglés de "Descifrado de RSA con cifrado débil y obsoleto", permite atacar y descifrar comunicaciones que utilizan incluso la versión más actual de este protocolo, TLSv1.2.

A lo largo de los siguientes posts intentaremos desgranar por qué y cómo funciona este ataque y, lo que es más importante, qué podemos hacer para protegernos contra él. El artículo en el que se describe este ataque en profundidad puede verse en https://drownattack.com/drown-attack-paper.pdf

Para entender DROWN es importante comprender cómo funciona SSL/TLS. Mucha gente sabe que este protocolo se basa en criptografía asimétrica, de tal modo que el servidor dispone de una clave formada por una parte pública (que se presenta al cliente en forma de certificado) y una parte privada, que (idealmente) sólo conoce el servidor. Cualquier dato cifrado con la clave pública debe descifrarse con la clave privada y viceversa. Sin embargo, lo que ya menos gente conoce es que, en general, los algoritmos asimétricos son, para proporcionar un nivel de protección similar, considerablemente más lentos que los algoritmos simétricos. Por ello, cliente y servidor utilizan la criptografía asimétrica únicamente para identificarse entre ellos e intercambiarse información suficiente para generar una serie de claves simétricas, que serán las utilizadas posteriormente durante la comunicación en sí.

El proceso de determinar estas claves simétricas e intercambiarlas de forma segura se conoce como "handshake", y tiene la misma estructura para las versiones SSLv3 y TLS del protocolo. Se muestra de forma esquemática (en su caso más sencillo, en que el cliente no se autentica mediante certificado, y para intercambio de claves mediante RSA) en la siguiente figura:


El cálculo de las claves simétricas se realiza a partir de tres valores que se intercambian durante este proceso:
  • Un número aleatorio enviado por el cliente en el mensaje ClientHello
  • Un número aleatorio enviado por el servidor en el mensaje ServerHello
  • Un tercer código de 48 bytes conocido como pre-master-secret, generado aleatoriamente por el cliente y enviado al servidor en el mensaje ClientKeyExchange, cifrado con la clave pública del servidor.


Si un atacante consigue hacerse con estos tres valores, será capaz de obtener las claves de cifrado de la comunicación y por tanto descifrar todos los datos intercambiados posteriormente entre ambos. Suponiendo que fuese capaz de capturar el tráfico entre cliente y servidor, y teniendo en cuenta que los paquetes ClientHello y ServerHello se envían sin cifrar, toda la seguridad recae en el pre-master-secret, enviado en el paquete ClientKeyExchange.  Esto en cuanto a la negociación de SSLv3 y TLS.

¿Cómo funciona la negociación de SSLv2? Conceptualmente es muy parecida, aunque tiene algunas diferencias importantes:

A primera vista puede verse que en la negociación SSLv2 faltan varios paquetes (en realidad se envía información parecida pero condensada en menos mensajes). En cuanto a las claves simétricas, en el caso de SSLv2, su cálculo requiere de los siguientes datos:

  • Un valor denominado "challenge" enviado por el cliente en ClientHello
  • El identificador de la conexión, enviado por el servidor en ServerHello
  • Un valor llamado master-key, que es generado aleatoriamente por el cliente y se envía en ClientMasterKey. Se envía cifrado total o parcialmente (volveremos sobre esto más adelante en el proceso) con la clave pública del servidor.
De nuevo la situación es parecida. Utilizando estos tres valores se calculan las claves simétricas con las que se encriptan el resto de mensajes. Dos de estos tres valores se envían en claro y el tercero se envía cifrado con la clave pública del servidor.

En este punto comienza a tomar forma la base del ataque DROWN. Si conseguimos encontrar un servidor SSLv2 que utilice como clave RSA, la misma que utiliza el servidor SSLv3/TLS, ¿Qué ocurre si en la negociación de SSLv2 enviamos como master-key cifrado exactamente el mismo valor que teníamos como pre-master-secret cifrado en la negociación de TLSv1? ¿Podríamos obtener información sobre cuál es el valor sin cifrar del pre-master-secret? Desgraciadamente, la respuesta es que no. La longitud del pre-master-secret es de 48 bytes, mientras que la del master-key tiene la misma longitud que la clave simétrica que se usará posteriormente (por ejemplo, para el caso de triple-des con clave de 192 bits, el master-key es de 24 bytes). Ningún algoritmo soportado por SSLv2 usa un master-key de 48 bytes, por lo que no se puede pasar directamente el pre-master-secret. Ahora bien, ¿Se puede generar un valor que sea un master-key  válido y que a la vez dé información sobre el pre-master-secret que se busca?

La primera idea que puede venir a la cabeza es que si tenemos un pre-master-secret demasiado largo, ¿no podríamos simplemente cortar a medida el mensaje cifrado y usar los N bytes cifrados que nos pide el master-key? La respuesta es que no. El mensaje cifrado RSA no es divisible, ya que en este caso ha sido cifrado como un bloque entero (técnicamente se pueden concatenar varios mensajes cifrados con RSA de forma independiente, pero no es el caso).

Entonces, ¿es posible transformar un pre-master-secret de SSLv3/TLS cifrado mediante RSA, en un master-key de SSLv2 cifrado con RSA, sin necesidad de descifrarlo?

Esto es algo que os contaremos en el próximo post.


Ion Larrañaga 
Software Innovation S21sec

(+34 902 222 521)


24 horas / 7 días a la semana



© Copyright S21sec 2013 - Todos los derechos reservados


login