Ya no te puedes fiar de nadie…

El año 2008 fue el año de la “vulnerabilidad crítica que pone en compromiso toda la seguridad de Internet”. Hemos visto varios casos de estos, primero la vulnerabilidad del DNS, luego algunas otras vulnerabilidades en los protocolos de enrutamiento, y alguna otra cosa de menor importancia.

En todos ellos, al final, la solución siempre ha sido la misma: apoyarnos en el uso de certificados digitales (clave pública y privada) para garantizar que estamos conectando donde realmente queremos conectar, y que toda la comunicación entre ambos extremos va a permanecer cifrada, no legible e inalterable por agentes externos a nuestra comunicación.

El gran problema del cifrado de comunicaciones mediante certificados es la distribución de las claves públicas, debemos encontrar alguna manera de poder obtener las claves públicas de nuestros sites web preferidos de tal manera que estos no puedan ser alterados, puesto que en ese caso no existiría ningún impedimento para que un intruso creara un certificado falso y nos lo hiciera llegar al realizar contra nosotros un ataque de Man-in-the-Middle.

Para solucionar este problema entraron en juego las CA (Certification Authority). Las autoridades de certificación son entidades a priori confiables por todo el mundo cuya misión es FIRMAR estos certificados digitales. Podriamos decir que son el equivalente a los Notarios en el “mundo real” (que me perdonen los notarios por la comparación), son entidades confiables que se encargan de “dar Fe” de que la persona que ha firmado un documento es quien dice ser. Las CA funcionan igual, disponen de su propia clave pública y su clave privada, y firman con su clave privada los certificados de las entidades que se lo solicitan.

Por poner un ejemplo para que quede la cosa más clara, pongamos que soy el administrador de www.mibanco.es y que he configurado el acceso por HTTPS con mis claves pública y privada para garantizar la seguridad de mis usuarios. Si no acudo a una CA para que firme mi certificado, los usuarios al conectar a mi web recibirán el mensaje de “este certificado no está firmado por una CA de confianza”, exactamente el mismo mensaje que les daría si un intruso realizara un ataque de Man-in-the-Middle (nos dará un certificado firmado por si mismo). Como no queremos que peligre la seguridad de nuestros usuarios, acudimos a una de las CAs reconocidas, la cual verifica nuestra identidad como administrador del host www.mibanco.es y firma con su clave privada nuestro certificado.

Al poner nuestro nuevo certificado firmado en nuestra web, a partir de ahora nuestros usuarios ya dispondrán de la diferencia entre conectar a la web auténtica (certificado firmado por la CA) y conecter a una web que intenta suplantar a la auténtica (certificado firmado por alguien que no es de confianza).

Como podeis imaginar, de esta manera, el problema de distribución de claves públicas de las webs se reduce al problema de distribución de claves públicas de las CAs, pero este es mucho menos debido a que, evidentemente, hay muchas menos CAs reconocidas que sitios webs en Internet. La solución es, sencillamente, incluir las claves públicas de las CAs más relevantes en el propio navegador web.

Después de todas esta no-breve introducción a las CAs, volvemos al problema que nos ocupa: ¿Nos fiamos de nuestras CAs?

El pasado 30 de Diciembre, en el 25th Chaos Communication Congress (25C3) en Berlín, un grupo internacional de investigadores (principalmente Estadounidenses, Holandeses y Suizos) anunciaron que habían conseguido explotar la conocida debilidad ante colisiones del algoritmo de Hash MD5 para realizar un ataque real contra la infraestructura de PKIs.

Como ya es sabido desde hace algún tiempo, el algoritmo MD5 es susceptible de presentar colisiones, es decir, es posible encontrar dos textos de entrada diferentes que sin embargo produzcan el mismo Hash resultado. Esto supone un verdadero problema para los algurirmos o sistemas que se apoyen en Hash MD5, puesto que para toda operación que se realice con este Hash, las dos entradas serán completamente indistinguibles.

Es el caso de las CAs, existen algunas CAs que a día de hoy siguen utilizando MD5 como Hash cuando firman certificados, ya que no firman el certificado entero por una cuestión de eficiencia, sino que calculan el MD5 de los parámetros más significativos del certificado y luego firman dicho Hash.

Como podeis imaginar, ahí es donde está el problema, ya que debido a la vulnerabilidad del algoritmo MD5, es posible encontrar 2 certificados diferentes cuyo Hash sea idéntico, y por lo tanto, el Hash firmado por la CA será igualmente idéntico. Este problema puede ser usado para usurpar la identidad de un host y realizar ataques Man-in-the-Middle, puesto que nuestro navegador reconocerá el certificado malicioso como firmado por una CA de confianza.

Volviendo al ejemplo de www.mibanco.es ,supongamos que un intruso quiere usurpar la identidad del sitio web, solo tiene que descargar el certificado con la clave pública del host (que se puede descargar desde el propio host) y calcular un certificado (con su clave pública y privada) cuyo contenido tenga como resultado el mismo Hash MD5 que el certificado original. Una vez conseguido esto (algo nada sencillo, los investigadores han tenido que usar un cluster compuesto por 200 Playstation 3 durante 3 días) lo único que hay que hacer es aplicar el Hash firmado original al certificado malicioso, que efectivamente será perfectamente válido, por lo que cuando el usuario acceda al sitio malicioso este aceptará el certificado ya que lo reconocerá como firmado por una CA reconocida.

En realidad, el ataque mostrado por los investigadores es un poco más complicado, ellos lo que hacen es conseguir que una CA reconocida firme el certificado de otra CA propia, una rogueCA, a partir de lo cual cualquier cosa que firmen con esa CA (que es de la propiedad de los atacantes) será automáticamente aceptado por todos los navegadores, lo cual es aún más terrorifico si cabe. Podeis acudir a la web original de los investigadores para más detalles.

Las CAs afectadas por esta vulnerabilidad ya han anunciado que están corrigiendo este problema, pero por el momento, la única medida efectiva con la que nos podemos quedar tranquilos es eliminar los certificados públicos de las CAs que aún utilizan MD5 de nuestro navegador/sistema operativo, ya que si no confiamos en la CA, no vamos a “tragarnos” la suplantación basada en la firma de esa CA.

Para no tener que comprobar uno a uno los certificados, podemos usar esta herramienta aunque sólo funciona en entornos Windows, según se lee en la propia web.

Si es que al final no podremos confiar en nadie…

Comments

  1. http://José%20Selvi says

    También podemos usar esta herramienta: http://codefromthe70s.org/sslblacklist.aspx

    Es un plugin para Firefox que detecta tanto los certificados débiles debido a la archiconocida vulnerabilidad de Debian como los certificados firmados mediante MD5 y que por tanto pueden ser susceptibles de realizar sobre ellos un MitM sobre el que forzar la instalación de un RogueAP.

  2. Cuanta razón tienes, finalemnte hemos llegado al punto de que no podemos fiarnos de nadie, y lamentablemente esto seguirá siendo así ahora y en mucho tiempo más. ¿Porqué? Simplemente por el hecho de sea cual fuere el certificado el mismo será susceptible a colisiones (¿acaso hay un metodo que este libre de ellas? _pregunto desde mi ignorancia quizá_) y es por ello que solo podremos sentirnos seguros unos breves instantes hasta darnos cuenta que otra vez lo han logrado y el ciclo comenzará nuevamente.

    Saludos, muy interesante tu página :)

  3. http://José%20Selvi says

    Hola Ariel, gracias por tu comentario.

    No soy un experto en criptología y criptoanálisis, pero la lógica me dice que cualquier método que nos podamos inventar que pase de un mensaje de tamaño N a un mensaje de tamaño menor que N va a sufrir siempre de este tipo de problemas.

    Como esta es la naturaleza de los algoritmos de Hash (sirven precisamente para verificar el contenido de un mensaje sin tener que manejar el mensaje entero, cuyo tamaño puede ser variable), supongo que siempre existirán matematicamente las colisiones.

    La fortaleza del algoritmo de Hash radica en la dificultad para encontrar estas colisiones, es decir, precisamente por tratarse de un algoritmo de “cifrado en un sentido” (One-Way Encryption), si un algoritmo de Hash fuera “perfecto” (si es que eso existe) tendriamos que recorrer todos los posibles mensajes de entrada, de todas las longitudes posibles, y al final podriamos encontrar dos mensajes que tuvieran el mismo resultado al aplicarles el algoritmo de Hash. Sin embargo, como te puedas imaginar, recorrer todos los posibles mensajes de entrada es imposible, puesto que son infinitos.

    Si el algoritmo tiene alguna debilidad, pues se podría acortar el espacio de posibilidades.

    Cuando se estima que en el momento actual es posible comprobar todas las posibilidades en un tiempo razonable, bien porque la potencia de los procesadores ahora lo permite, bien porque se ha descubierto una vulnerabilidad en el algoritmo que permite reducir el espacio de búsqueda hasta una cantidad manejable de pruebas, entonces se dice que “se ha roto” un algoritmo de Hash.

    De hecho, probablemente, dado un algoritmo de Hash, existan estudios matemáticos que definan cual es el tamaño del espacio de entradas que asegura que exista al menos una colisión entre ellas.

    Como ya he dicho, no soy experto en criptología, por lo que mi respuesta puede no ser 100% precisa. Si alguno de nuestros lectores es experto en criptología, por favor, que nos escriba :)

  4. Parece que se lo come por un signo menor que. Pego de nuevo:

    ———-

    Hola,

    Yo no me considero un experto en criptografía, pero algún conocimiento al respecto sí tengo. Esto viene de mi cabeza directamente sin verificación, así que puede haber algún error. Si es así agradecería que me lo comentarais :)

    Es evidente que cualquier método que pase de N bits a k menor que N bits va a tener colisiones. De hecho, si pruebas 2^k+1 combinaciones, seguro que 2 de ellas tienen el mismo hash. O lo que es lo mismo, hablando de md5 (128 bits), si pruebas 2^128 combinaciones seguramente dos de ellas tengan el mismo resultado. Obviamente, si tienes 128 bits no puedes tener más de 2^128 salidas distintas, así que con ese número de entradas va a haber una colisión.

    El truco está en que por una parte 2^128 es muy costoso de probar, y por otra las colisiones además deben tener sentido (meaningful collisions). Para atacar estos algoritmos no nos vale en encontrar ‘una colisión’ sino que necesitamos que el destinatario ‘se lo trague’.

    Que por cierto, un algoritmo de hashing se suele considerar roto cuando se conoce un ataque mejor que un ‘birthday attack’, que en teoría necesita de 2^(n/2) ejecuciones del algoritmo de hash para obtener una colisión, con n igual al número de bits de salida. De ahí que en general los algoritmos de hash usen el doble de bits que los cifrados de bloques.

    Si imaginamos una colisión en una firma de un ejecutable, debemos no solo conseguir MD5 idénticos, sino que el resultado de la colisión tenga el formato adecuado (PE o ELF o lo que sea) y además funcione de la manera que el atacante quiere.

    El ataque del que hablamos se basa en el método de ‘chosen-prefix collisions’. El atacante puede elegir el principio de los dos mensajes arbitrariamente, luego en uno de los mensajes necesita 728 bits (si no me falla la memoria) que crean un ‘bloque de colisión’, en el segundo necesita más bytes para forzar la colisión, y finalmente detrás de esos bloques viene el resto del mensaje, que debe ser idéntico en ambos casos.

    También quería comentar que la parte donde dice “descargar el certificado con la clave pública del host (que se puede descargar desde el propio host) y calcular un certificado (con su clave pública y privada) cuyo contenido tenga como resultado el mismo Hash MD5 que el certificado original” no es del todo cierta.

    Lo que se hace es hacer una petición de un certificado a una CA online, que tras haberla estudiado sabían que los IDs, la fecha de creación y de expiración eran predecibles. De esta forma, conocían toda la información de la parte que la CA iba a firmar, y podían modificar a su antojo la clave pública RSA. Por tanto, esa petición tenía una clave RSA en la que se había añadido ese ‘bloque de colisión’.

    Luego, con 3 días de antelación realizaban los cálculos de la colisión y generaban el nuevo certificado ‘mágico’. Cuando la CA les devolvía el certificado, si su predicción de fecha y números de serie se había cumplido ganaban la partida, si no perdían. Esto les costó 4 peticiones, hechas durante 4 fines de semanas consecutivos, y menos de 700$ si no me falla la memoria.

    Respecto a descartar certificados firmados con MD5, realmente no es esa la solución. Teniendo una CA que cuyo certificado es de confianza para los navegadores (valida toda la jerarquía de certificados hasta una CA raiz), el atacante podría firmar el certificado final con lo que le diera la gana.

    Tampoco resuelve nada quitar la confianza en las CAs cuyo certificado esté firmado con MD5, ya que en ese certificado el atacante no ha podido incluir esos ‘pocos’ bytes necesarios para ayudar a forzar la colisión.

    La solución aquí pasa por que las CAs lo arreglen, y esperar que nadie haya hecho esto antes ;)

    De todas formas, no creo que nadie se haya preocupado demasiado de realizar este ataque porque el 90% de los usuarios ‘tragan’ ante un certificado inválido con un mitm. La gente no lee los mensajes de alerta y le da a aceptar y se queda tan ancha.

    Por lo que a mí respecta, parafraseo una de las últimas transparencias de la presentación de este ataque: “Don’t panic, the Internet is not *completely* broken”.

    Ah, hay un video de la presentación en el FTP del CCC. En los videos la han titulado ‘Making the theoretical possible’. Podeis ver esta y las otras charlas en: http://ftp.ccc.de/congress/25c3/video_h264_720x576/

    Saludos

  5. http://José%20Selvi says

    Hola TuXeD, muchas gracias por tu aportación, como ya he comentado mi aportación sobre criptografía era “desde el sentido común”, así que agradezco mucho que aportes una información más precisa, y totalmente de acuerdo con que realmente muy pocos usuarios vigilan los certificados que aceptan ;)

    Evidentemente, ya comento en el post que el ataque es algo más complicado, puesto que intervienen una rogueCA y el tema que comentas de la predecibilidad del número de certificado (ayudado por ser secuencial y porque fueron capaces de estimar que si hacían coincidir los 3 días que requería el cálculo con un fin de semana solo se firmaban aproximadamente 1000 certificados). Se ha intentado explicar “el concepto” de forma simplificada para que resultara más didáctico, pero agradecemos igualmente tu aportación dando detalles más precisos.

    Sólo una puntualización con la que no estoy completamente de acuerdo: “Tampoco resuelve nada quitar la confianza en las CAs cuyo certificado esté firmado con MD5, ya que en ese certificado el atacante no ha podido incluir esos ‘pocos’ bytes necesarios para ayudar a forzar la colisión”

    Más que las que está firmadas utilizando Hash MD5 serían aquellas que firman sus certificados utilizando un Hash MD5. El éxito del ataque es conseguir, de alguna manera, instalar el certificado de la rogueCA en la base de datos de certificados de confianza del navegador, porque a partir de ahí se puede generar certificados para cualquier web, firmarlos con esta CA, y eso será automáticamente aceptado como válido por el navegador. Para ello, lo que hacen es utilizar el Hash firmado por la CA de confianza X de un certificado especialmente preparado para aplicarlo al certificado de un rogueCA, cuyo contenido ha sido ya calculado para que sea coherente y además para que su hash colisione con el del certificado “legítimo” que ha firmado la CA de confianza. Una vez hecho esto, se dispone de una CA propia con la que podemos firmar cualquier certificado, y que además, a ojos de todos, es de confianza para la CA X. Por eso, la primera vez que nuestro navegador visitara una web con un certificado firmado por esta CA, este comprobaría que CA lo ha firmado, encontraría la rogueCA, que desconoce, pero cuyo certificado está a su vez firmado por una CA que sí que es de confianza, por lo que “los amigos de mis amigos son mis amigos” y la incluye en su base de datos de CAs de confianza (visita la prueba de concepto modificando el reloj de tu equipo y luego mira tu lista de certificados de confianza, verás como ha aparecido el rogueCA que ellos han generado como prueba de concepto entre ellos).

    ¿En que solucionaría retirar de nuestra base de datos de CAs de confianza a las CAs que firmen certificados con MD5? Pongamonos en el ejemplo anterior, sé que la CA X firma certificados usando Hash MD5, y por lo tanto la elimino de mi base de datos. ¿Que pasará cuando alguien intente suplantar una web legítima mediante un certificado firmado por la rogueCA? En primer lugar desconocerá la CA que ha firmado el certificado de la web, verá que esta a su vez está firmado por otra CA llamada CA X, con lo que comprobará en su base de datos si esa CA X es de confianza y por tanto si esa rogueCA también lo es. Tras buscarla, no la encontrará (la hemos eliminado), por lo que rechazará el certificado de la CA rogueCA, y por tanto el certificado de la web que intenta suplantar.

    Saludos y muchas gracias por tu comentario TuXeD, y perdona lo del símbolo menor, ya sabes, la seguridad es la seguridad :P

  6. Totalmente de acuerdo con la puntualización :)

    Lo que pasa es que creía haber visto una herramienta que te decía qué CAs tenían un certificado firmado usando MD5… por eso decía que eso no ayudaba. Sí ayuda lo que tu comentas, no fiarte de los que firmen en MD5.

    Espero que pronto sean pocos y que no se pasen a SHA-1… que busquen algo mejor pues ‘los expertos’ opinan que SHA-1 sufrirá de problemas similares en poco tiempo. Yo lo he oído decir a uno de los autores de este ataque ( Benne de Weger ) en clase en Eindhoven el año pasado, y creo recordar que dijo que su opción en ese momento sería usar SHA-256. Quizás SHA-512 sea ser un poco bestia :D

    Saludetes!