viernes, 30 de octubre de 2015

Sincronización de tiempos en Microsoft

Pégale un vistazo a otros posts de esta serie:

[6] Atacando la Infraestructura de Clave Pública (PKI)
[7] Otros ataques
[8] Herramientas de ayuda

Por supuesto, no podría acabar mis ejemplos sin hablar de Microsoft. De los sistemas operativos de escritorio con los que he estado haciendo pruebas, Microsoft tiene el sistema de sincronización de tiempos más segudo. Funciona de manera diferente en sistemas "standalone" que en miembros de un dominio, así que veamos ambas circunstancias.

En un Windows "standalone" la sincronización tiene lugar cada 7 días (domingos de madrugada para ser exactos) así que la única opción de interceptar las peticiones NTP es estar presentes el domingo o el lunes cuando el usuario arrnca el sistema por primera vez después de la hora de sincronización. Además, Windows tiene un límite de 15 horas para el cambio de la fecha, con lo que no podemos cambiar el reloj más de esas 15 horas para cada sincronización, lo cual es un verdadero problema para la mayoría de los ataques que veremos en los próximos artículos.

Esas 15 horas no son un valor escrito a fuego en el código, sino que está guardado en el registro de Windows, en las llaves "MaxPosPhaseCorrection" y "MaxNegPhaseCorrection", y pueden ser diferentes en diferentes sistemas, por ejemplo, en Windows 7/8 son 15 horas, pero en un Windows Server 2012 son 48 horas, y en servidores más antiguos será diferente también. También puede cambiar cuando se dan ciertos cambios en el sistema, por ejemplo cuando el equipo se une a un dominio Microsoft.


La combinación de ambas protecciones hace a los sistemas Windows bastante seguros en lo que a sincronización de tiempos se refiere. Sin embargo, si cualquiera de ellos es cambiado por el usuario, habría algunos vectores de ataques posibles. Por ejemplo, hay muchos tutoriales en internet explicando como cambiar la frecuencia de la sincronización de la hora, porque piensas (y probablemente están en lo cierto) que una vez a la semana no es suficiente para conseguir una buena precisión de reloj.


Bajo estas circunstancias, se me ocurrió un nuevo vector de ataque ¿Qué ocurre si un usuario configura su sistema para sincronizar la hora con más frecuencia que el limite que comentábamos antes? La respuesta es que un atacante podría interceptar la petición y cambiar la hora del equipo a unos pocos segundos antes de la próxima sincronización. Tras esos segundos interceptaría otra vez la petición y haría lo propio, y así sucesivamente hasta llegar a la fecha deseada. Llamé a este ataque "Time Skimming" porque es similar a un "Stone Skimming", que en Inglés es como se llama al efecto de tirar una piedra en un lago y que vaya saltando sobre la superficio, recorriendo grandes distancias. Este ataque también está implementado en Deloran:



Hay otra manera más de forzar la sincronización, pero requiere utilizar técnicas de ingeniería social. Cuando un usuario solicita una sincronización de hora manualmente usando el menú "Internet Time Settings" la hora se sincroniza sin ninguna restricción, pero no es tan fácil como en Mac OS X, ya que llegar a esta ventana requiere varios clicks.

Los miembros de un dominio funcionan de manera diferente. Los valores de Max[Pos|Neg]PhaseCorrction pasan a ser 0xFFFFFFFF que quiere decir "aceptar cualquier hora". Esto es un riesgo, pero han incluido firma en los paquetes para autenticar el origen de la respuesta:


Microsoft usa el estándar NTP de una forma creativa. El "Key ID" debería ser un valor que identificara qué clave debe ser usada para autenticar la respuesta. En una petición NTP normal debería tenr un valor 1 o 2, dependiendo de la cantidad de claves disponibles. Sin embargo, lo que hace Microsoft es identificar el sistema dentro del directorio activo que está realizando esta petición. Por ejmplo, si tenemos un KeyID 0x5e040000 necesitamos cambiar el orden de los bytes (endianess) y tendríamos 0x0000045e. El primer bit es un selector de clave (0 o 1), y el resto es el Relative ID (RID) del equipo.


Como probablemente sepais, tanto los equipos como los usuarios son objetos en un dirctorio activo. Los equipos son un tipo espcial de usuario. Ellos mismos crean una contraseña compartida para su usuario cuando se unen a un dominio, y esta contraseña se cambia automáticamente de forma periódica. Un controlador de dominio guarda los dos últimos  hashes de las contraseñas utilizadas, que es lo que selecciona el selector de clave que comentabamos antes.

/* Sign the NTP response with the unicodePwd */
MD5Init(&ctx);
MD5Update(&ctx, nt_hash->hash, sizeof(nt_hash->hash));
MD5Update(&ctx, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length);
MD5Final(signed_reply.signed_packet.data + sign_request.packet_to_sign.length + 4, &ctx);


Las respuestas son firmadas usando MD5 ( md5(hashed_password+response_body) ), que no es el algoritmo de hashing más robusto del mundo, pero al menos yo no pude encontrar un ataque factible para un mensaje tan pequeño, así que en este momento opino que la sincronización de tiempos de un dominio Microsoft es la más robusta de las que he analizado.

miércoles, 28 de octubre de 2015

Sincronización de tiempos en Fedora / Ubuntu

Pégale un vistazo a otros posts de esta serie:

[6] Atacando la Infraestructura de Clave Pública (PKI)
[7] Otros ataques
[8] Herramientas de ayuda

Ayer estabamos hablando de como funciona la sincronización de tiempos en Mac OS X y de como es diferente en las versiones pre-Mavericks que en las más modernas. Hoy vamos a pegar un vistazo a GNU/Linux. Por supuesto, hay un montón de sabores de Linux disponibles, y no hubiera podido revisarlos todos, así que me quedé con los dos que yo creo que están más extendidos en los usuarios de escritorio (Ubuntu y Fedora), ya que ellos serían los objetivos principales en caso de un ataque.

Descargo de responsabilidad: Toda la información se ha obtenido de una forma empirica, realizando pruebas, y en un periodo de tiempo concreto, con lo que puede haber cambiado en el momento de leer este artículo.
Ubuntu Linux es el único sistema de los que he visto que no sincroniza su reloj de forma periódica, por lo que no es tan simple como esperar la cantidad de tiempo suficiente e interceptar la petición NTP. En Ubuntu, la sincronización se produce cada vez que un interface de red se levante (y, por supuesto, cada vez que el sistema arranca). Pegémosle un vistazo a los scripts que el sistema ejecuta cuando ésto ocurre:

$ ls /etc/network/if-up.d/
000resolvconf  avahi-daemon  ntpdate  wpasupplicant
avahi-autoipd   ethtool             upstart

No hay ninguna restricción en cuanto a grandes cambios de hora, con lo que podríamos interceptar la petición y cambiar la hora local de forma sencilla, usando Delorean. Hay dos posibles escenarios: Interceptar cuando el equipo arranca o se conecta a la red, o simplemente denegarle el servicio a la red y esperar a que vuelva a conectar, deautenticando en una red Wifi, por ejemplo.

Por otro lado, Fedora Linux usa una aproximación similar a Mac OS X. En versiones anteriores, simplemente sincronizaba la hora cada minuto sin ninguna restricción de seguridad, así que resultaba sencillo y rápido usar Delorean y manipular ele reloj:

$ tcpdump -i eth0 -nn src port 123
12:43:50.614191 IP 192.168.1.101.123 > 89.248.106.98.123: NTPv3, Client, length 48
12:44:55.696390 IP 192.168.1.101.123 > 213.194.159.3.123: NTPv3, Client, length 48
12:45:59.034059 IP 192.168.1.101.123 > 89.248.106.98.123: NTPv3, Client, length 48

En algún momento cambiaron la manera en la que hacían esta sincronización. En este momento hay un servicio llamado "chrony" que funciona de manera similar a "pacemaker" en Mac OS X. Sin embargo, Chrony está configurado de una forma más segura que Pacemaker, ya que por defecto no acepta grandes cambios de hora. Solo acepta este tipo de cambios en las tres primeras sincronizaciones tras el arranque o reinicio, así que sí que podremos usar Delorean si el sistema arranca o si somos capaces de realizar una denegación de servicio de chrony.

Probablemente es muy pronto para enseñar este video, porque aún no hemos hablado de HSTS y como puede ser evadido usando ataques de sincronización, pero tomadlo como un mero ejemplo de como podemos manipular la hora de un Linux Ubuntu usando Delorean:

martes, 27 de octubre de 2015

Sincronización de tiempos en Mac OS X

Pega un vistazo a los otros posts de esta serie:

[4] Sincronización de tiempos en Microsoft
[6] Atacando la Infraestructura de Clave Pública (PKI)
[7] Otros ataques
[8] Herramientas de ayuda

La semana pasada mostrabamos como funcionaba Delorean y como podría ser usado para manipular respuestas NTP. Sin embargo, los diferentes sistemas operativos sincronizan su reloj de forma ligeramente diferente.

Descargo de responsabilidad: Toda la información se ha obtenido de una forma empirica, realizando pruebas, y en un periodo de tiempo concreto, con lo que puede haber cambiado en el momento de leer este artículo.

Los Mac OS X anteriores a Mavericks usaban una sincronización de reloj muy sencilla. Un servicio NTPd se ejecuta y sincroniza el tiempo cada 9 minutos. Ninguna restricción de seguridad se aplica en este servicio, con lo que sería posible atacarlo usando Delorean.

$ tcpdump -i eth0 -nn src port 123
09:02:18.166708 IP 192.168.1.100.123 > 17.72.148.53.123: NTPv4, Client, length 48
09:11:20.059792 IP 192.168.1.100.123 > 17.72.148.53.123: NTPv4, Client, length 48
09:20:17.951361 IP 192.168.1.100.123 > 17.72.148.53.123: NTPv4, Client, length 48


Sin embargo, Apple cambio la manera de funcionar de este servicio. En la actualidad, NTPd aún es utilizado en las versiones modernas de Mac OS X, pero ya no cambia la hora por si mismo. En su lugar, la diferencia de tiempo se guarda en /var/db/ntp.drift , y hay otro servicio llamado "pacemaker" que debería comprobar su valor y cambiar el reloj si es necesario.
Este servicio tiene algunas ventajas. Por ejemplo, adapta la cantidad de peticiones NTP en función de si el equipo está conectado a corriente o funciona con baterías. Otra diferencia importante es que los cambios de reloj no se aplican en un solo paso. El reloj se acelera o se ralentiza para corregir la fecha, pero sin grandes saltos. No implementa tampoco ningún otra función de seguridad, con lo que también podría ser atacado utilizando Delorean.

Aunque no debería ser un problema, nos dimos cuenta que NTPd no estaba funcionando correctamente en éstas últimas versiones de Mac OS X, con lo que la sincronización de tiempos nos estaba funcionando. Podemos encontrar gente comentando este tema en Internet ¿Quiere esto decir que los Mac OS X modernos no son vulnerables al ataque con Delorean? La respuesta es NO. Peguemos un vistazo al script /usr/libexec/ntpd-wrapper :


Como podéis ver, Mac OS X ejecuta el comando sntp (simple NTP) en el arranque, antes de ejecutar el servicio NTPd. Este comando no está afectado por el mismo fallo, con lo que podríamos interceptar la sincronización y realizar un ataque con Delorean cuando Mac OS X arranca,

Existe otra manera de explitar este mecanismo de sincronización que implementa Mac OS X. Cuando un usuario abre el menú "Date & Time Preferences", el sistema operativo sincroniza automáticamente la hora sin el conocimiento del usuario, con lo que también podríamos usar Delorean en este escenario.


En los proximos artículos mostraremos como podemos utilizar esta vulnerabilidad para interceptar comunicaciones SSL, tal y como presentamos en DEF CON recientemente.

miércoles, 21 de octubre de 2015

NTP MitM con Delorean

Hace alrededor de un año y medio empecé una investigación sobre como los ordenadores sincronizaban sus relojes internos, y como esto podría usarse para atacar protocols o servicios conocidos que se ejecutan en los sistemas operativos. Como resultado, presente mis hallazgos en varias conferencias de seguridad como BlackHat Europe 2014, RootedCON 2015, DEF CON 23 y Navaja Negra / ConectaCON 2015.


Hoy, 21 de Octubre de 2015, es la fecha en la que Marty McFly fue al futuro en la segunda parte de la alucinante saga "Regreso al Futuro", así que no creo que haya una fecha mejor para empezar a publicar todos los detalles de la investigación.

[6] Atacando la Infraestructura de Clave Pública (PKI)
[7] Otros ataques
[8] Herramientas de ayuda

Como veremos en los sucesivos artículos, todos los fabricantes de sistemas operativos que he probado utilizan el protocol NTP (Network Time Protocol) para mantener su reloj interno actualizado a una hora correcta, lo cual es muy importante para algunos protocolos de autenticación entre otros. La mayoría de ellos no despliegan el servicio de forma segura, haciendo vulnerable a ataques de Man-in-the-Middle.

Para explotar esta vulnerabilidad, desarrollé una herramienta a la que llamé DELOREAN. Delorean es un servidor NTP escrito en python, de código abierto y  disponible en GitHub (toda contribución es bienvenida). Tomé prestadas algunas lineas de código de la herramienta ntpserver de kimifly y, por supuesto, ha sido incluido en los créditos como correspondía.

Lo que hace a Delorean diferente y útil es que podemos configurar sus flags para hacer que funcione de una manera diferente a como lo haría un servidor NTP tradicional. Básicamente, podemos configurarlo para que mande respuestas manipuladas, de forma similar a como hace el módulo de Metasploit fakedns.

$ ./delorean.py -h
Usage: delorean.py [options]

Options:
-h, --help show this help message and exit
-i INTERFACE, --interface=INTERFACE Listening interface
-p PORT, --port=PORT Listening port
-n, --nobanner Not show Delorean banner
-s STEP, --force-step=STEP Force the time step: 3m (minutes), 4d (days), 1M (month)
-d DATE, --force-date=DATE Force the date: YYYY-MM-DD hh:mm[:ss]
-x, --random-date Use random date each time


Tenemos los típicos flags para el interface (-i) y puerto (-p), que nos ayudarán a poner a la escucha el servicio exactamente donde queramos. El flag -n simplemente esconde el Delorean ASCII del banner :)
                                    _._                                          
                               _.-="_-         _                                 
                          _.-="   _-          | ||"""""""---._______     __..    
              ___.===""""-.______-,,,,,,,,,,,,`-''----" """""       """""  __'   
       __.--""     __        ,'                   o \           __        [__|   
  __-""=======.--""  ""--.=================================.--""  ""--.=======:  
 ]       [w] : /        \ : |========================|    : /        \ :  [w] :  
 V___________:|          |: |========================|    :|          |:   _-"   
  V__________: \        / :_|=======================/_____: \        / :__-"     
  -----------'  ""____""  `-------------------------------'  ""____""  

Podemos user Delorean de varias formas, pero vamos a centrarnos en las más útiles. Hay algunas ataques que han resultado no ser muy interesantes después de desarrollarlos, pero todavía están implementados. Quizá los acabe quitando en el futuro, ya que requieren algunas dependencias como scapy que de otro modo podríamos ahorrarnos.

Todavía es pronto para hablar de como sincronizan los sistemas operativos, así que de momento probaremos Delorean utilizando la herramienta "ntpdate":

$ ntpdate -q 192.168.1.2
server 192.168.1.2, stratum 2, offset 97372804.086845, delay 0.02699
20 Oct 06:05:45 ntpdate[881]: step time server 192.168.1.2 offset 97372804.086845 sec


Por defecto (sin flags), Delorean responde con una fecha en la que coincida el mismo día del mes y de la semana que hoy, pero al menos 1000 días en el futuro. Esto es debido a que era útil para los ataques contra HSTS, tal y como veremos en próximos artículos.

# ./delorean.py -n
[19:44:42] Sent to 192.168.10.113:123 - Going to the future! 2018-08-31 19:44
[19:45:18] Sent to 192.168.10.113:123 - Going to the future! 2018-08-31 19:45


Podemos configurar un salto relativo desde la fecha actual usando el flag "step" (-s). Los saltos relativos pueden ser definidos como 10d (diez días en el futuro), -2y (dos años en el pasado), etc:

# ./delorean.py -s 10d -n
[19:46:09] Sent to 192.168.10.113:123 - Going to the future! 2015-08-10 19:46
[19:47:19] Sent to 192.168.10.113:123 - Going to the future! 2015-08-10 19:47


También podemos configurar una fecha específica, y Delorean responderá siempre con la misma fecha:

# ./delorean.py -d ‘2020-08-01 21:15’ -n
[19:49:50] Sent to 127.0.0.1:48473 - Going to the future! 2020-08-01 21:15
[19:50:10] Sent to 127.0.0.1:52406 - Going to the future! 2020-08-01 21:15


Hay otro ataque llamado "Skimming Attack" que puede ser utilized en ciertas configuraciones, pero lo veremos en profundidad cuando hablamos sobre como los sistemas operativos de Microsoft sincronizan, aunque también podrían resultar útiles en ciertas configuraciones de otras plataformas.