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

sábado, 26 de diciembre de 2015

Servidores DNS Raíz bajo ataque - Root DNS servers under attack

Leyendo algunos mails pendientes me encontré con una de los boletines de SANS que reportaba un ataque de DDOS a los servidores de nombre raíz. Efectivamente, entre el 30 de Noviembre y el 1 de Diciembre último, los servidores raíz fueron víctimas de un número inusual de consultas DNS.

Estos servidores mantienen la zona raíz, donde comienzan todas las consultas DNS recursivas y por lo tanto el correcto funcionamiento de estos servidores es crucial para la salud de Internet.

Podemos obtener la lista de servidores DNS raíz con una simple consulta desde la consola:

juan@juan-VirtualBox:~$ dig +short -t NS .
i.root-servers.net.
j.root-servers.net.
k.root-servers.net.
d.root-servers.net.
e.root-servers.net.
l.root-servers.net.
a.root-servers.net.
h.root-servers.net.
m.root-servers.net.
f.root-servers.net.
c.root-servers.net.
b.root-servers.net.
g.root-servers.net.
juan@juan-VirtualBox:~$


a partir de los nombres queda claro que cada uno de los servidores raíz se identifica por una letra en el abecedario. De momento hay servidores de la A a la M (13 servidores). Vale aclarar que en realidad detrás de cada uno de estos nombres hay en realidad muchas instancias del servidor respondiendo. Según Wikipedia a Octubre de 2014 había unos 504 servidores reales respondiendo consultas.

Horarios del ataque

 
  • El primer ataque comenzó a las 06:50 UTC del 30 de Noviembre y se extendió  hasta aproximadamente las 09:30 UTC.
  • El segundo ataque inició a las 05:10 UTC del 1 de Diciembre y se extendió hasta casi las 06:10 UTC.
Algunos sitios indican, erróneamente, que se trató de un ataque de amplificación y reflexión, sin embargo no parece haberlo sido. Según detalla la propia gente de www.root-servers.org en su informe, el ataque tuvo las siguientes características:
  • Durante el primer ataque, las consultas eran sobre un único dominio.
  • Durante el segundo ataque, las consultas involucraban diferentes dominios.
  • Buena parte de la flota de servidores recibieron este número excesivo de consultas, aunque no todos. Posiblemente por la naturaleza anycast de las direcciones IP de los servidores raíz. 
  • Extrañamente las direcciones origen de las consultas DNS parecían estar distribuidas aleatoriamente dentro del espacio de direcciones IPv4.
  • El pico máximo de consultas fue de alrededor de 5 millones de consultas por servidor raíz. 

Impacto


Afortunadamente el impacto del ataque fue casi nulo. Si confirmaron que algunos de los enlaces que conectan a los servidores raíz se vieron saturados, lo cual generó algunos retardos en las resoluciones destinadas a estos servidores. Una vez mas la robustez del mecanismo de anycast y la simplicidad de UDP mostraron ser un muy buena arquitectura para uno de los servicios mas críticos de Internet.

domingo, 17 de mayo de 2015

UDP en GNU/Linux Parte I

Hace unos días me encontré con un caso interesante de pérdida de paquetes en transferencias utilizando UDP. Como se imaginaran poco me asombro que se perdieran paquetes UDP, ya que por definición se trata de un protocolo de transporte que no es fiable a la hora de entregar la información, una especie de cartero ebrio digamos. El control de flujo, el orden y la re transmisión no forman parte de las especificaciones de UDP [1], ya que fue ideado para ser simple. Meter los paquetes al cable y que la fuerza los acompañe.

Usar UDP como protocolo de transporte suele dar lugar a las siguientes situaciones:
  • Paquetes que nunca alcanzan el destino. Sin control de conexión y re transmisión, básicamente el emisor pone el paquete en el cable y se olvida por completo del mismo, no hay notificación de recepción ni nada que se le parezca.
  • Paquetes que llegan desordenados. Por esas cosas de las redes, los paquetes A y B que fueron enviados en ese orden podrían ser recibidos por el receptor en el orden inverso.
por lo tanto muchas aplicaciones que utilizan UDP deciden lidiar con estos problemas en la capa de aplicación.

En GNU/Linux, haciendo uso del programa netstat podemos ver las estadísticas UDP del sistema, por ejemplo:

root@ubuntu:/home/juan# netstat -su
Udp:
    23 packets received
    0 packets to unknown port received.
    0 packet receive errors
    23 packets sent
...
root@ubuntu:/home/juan#


En esta caso particular vemos que se enviaron 23 paquetes y se recibieron 23, muy probablemente se trate de consultas y respuestas DNS, ya que acabo de iniciar la máquina virtual. En total son 4 los campos disponibles de estadísticas UDP:
  • Packets received: número paquetes recibidos de manera satisfactoria por el sistema. Esto significa paquetes recibidos y pasados a la aplicación correspondiente.
  • Packets to unknown port received: número de paquetes que fueron recibidos pero no eran esperados por el sistema, es decir no había ninguna aplicación escuchando en ese puerto.
  • Packet receive errors: número de paquetes que no pasaron el checksum o que llegaron cuando el buffer de recepción se encontraba lleno y por lo tanto fueron descartados.
  • Packets sent: número de paquetes enviados por el sistema.

Probando Packets received:

Para probar este campo primero debemos identificar algún servicio escuchando en un puerto UDP, y para eso usamos netstat:

root@ubuntu:/home/juan# netstat -plun
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        0      0 0.0.0.0:68              0.0.0.0:*                           558/dhclient   
udp        0      0 0.0.0.0:5113            0.0.0.0:*                           558/dhclient   
udp6       0      0 :::43512                :::*                                558/dhclient   
root@ubuntu:/home/juan#


Podemos ver que el puerto 68, 5113 y 43512 están en uso así que apuntaremos al puerto 68 y enviaremos 5 paquetes. Para generar tráfico UDP sin demasiadas complicaciones vamos a utilizar Hping3 [2] (aquí hay un post en donde lo utilicé para probar DNS Amplification attacks), para entender los parámetros man hping3.

root@moon:/home/juan# hping3 192.168.0.10 -2 -c 5 -p 68 -V
using wlan0, addr: 192.168.0.2, MTU: 1500
HPING 192.168.0.10 (wlan0 192.168.0.10): udp mode set, 28 headers + 0 data bytes

--- 192.168.0.10 hping statistic ---
5 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
root@moon:/home/juan# 


Ahora veamos cómo se manifiesta esto en las estadísticas UDP:

root@ubuntu:/home/juan# netstat -su
Udp:
    28 packets received
    0 packets to unknown port received.
    0 packet receive errors
    23 packets sent

...
root@ubuntu:/home/juan#


Vemos que los paquetes recibidos se incrementaron en 5, como era de esperarse, ya que los paquetes tenían como destino un puerto donde había una aplicación escuchando (mas allá de que la aplicación haya sido capaz de interpretar el contenido de los paquetes o no).

Probando Packets to unknown port received:

Los campos Packets received y Packets sent son bastante simples de comprobar así que vamos a apuntar a este otro que es un poco mas interesante.El tráfico será:
  • Destinado al puerto 5555.
  • Enviaremos 10 paquetes.
 Shoot!

root@moon:/home/juan# hping3 8.8.8.8 -2 -c 10 -p 5555 -V
using wlan0, addr: 192.168.0.2, MTU: 1500
HPING 8.8.8.8 (wlan0 8.8.8.8): udp mode set, 28 headers + 0 data bytes

--- 8.8.8.8 hping statistic ---
10 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
root@moon:/home/juan# hping3 192.168.0.10 -2 -c 10 -p 5555 -V
using wlan0, addr: 192.168.0.2, MTU: 1500
HPING 192.168.0.10 (wlan0 192.168.0.10): udp mode set, 28 headers + 0 data bytes
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1179 seq=0
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1180 seq=1
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1181 seq=2
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1182 seq=3
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1183 seq=4
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1184 seq=5
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1185 seq=6
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1186 seq=7
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1187 seq=8
ICMP Port Unreachable from ip=192.168.0.10 name=UNKNOWN  
status=0 port=1188 seq=9

--- 192.168.0.10 hping statistic ---
10 packets transmitted, 10 packets received, 0% packet loss
round-trip min/avg/max = 3.4/19.6/161.2 ms
root@moon:/home/juan#


Vemos que el destino nos respondió con un mensaje ICMP Port Unreachable por cada paquete que enviamos, lo cuál nos da dos pautas:
  • Los paquetes llegaron al sistema y el kernel reconoció que no tenía a quién entregarlos.
  • El host no tiene un firewall que descarte los paquetes a puertos que no sean necesarios.
Pero bien, ahora veamos qué pasó en los contadores del host destino!!

root@ubuntu:/home/juan# netstat -su
IcmpMsg:
    OutType3: 10
Udp:
    28 packets received
    10 packets to unknown port received.
    0 packet receive errors
    23 packets sent
...

root@ubuntu:/home/juan#

Exacto! Ahora tenemos 10 paquetes reconocidos como "packets to unknown port received" y también vemos los 10 mensajes ICMP enviados como respuesta.

Probando packet receive errors:

Ahora pongamos a prueba el reconocimiento de paquetes con problemas. Por suerte Hping3 nos permite, con el flag -b, enviar paquetes con el checksum corrupto así que usaremos eso para probar. En este punto haremos dos pruebas:

  • Prueba1
    • 5 paquetes con checksum inválido
    • puerto 68
  • Prueba 2
    • 5 paquetes con checksum inválido
    • puerto 5555
Prueba 1:

/root@moon:/home/juan# hping3 192.168.0.10 -2 -c 5 -p 68 -b -V
using wlan0, addr: 192.168.0.2, MTU: 1500
HPING 192.168.0.10 (wlan0 192.168.0.10): udp mode set, 28 headers + 0 data bytes

--- 192.168.0.10 hping statistic ---
5 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
root@moon:/home/juan#



root@ubuntu:/home/juan# netstat -su
IcmpMsg:
    OutType3: 10
Udp:
    28 packets received
    10 packets to unknown port received.
    5 packet receive errors
    23 packets sent
    InCsumErrors: 5
...
root@ubuntu:/home/juan#

Ahora podemos ver que el valor de "packet receive errors" pasó de 0 a 5, también tenemos un nuevo campo llamado InCsumErrors con valor 5.

Prueba 2:

root@moon:/home/juan# hping3 192.168.0.10 -2 -c 5 -p 5555 -b -V
using wlan0, addr: 192.168.0.2, MTU: 1500
HPING 192.168.0.10 (wlan0 192.168.0.10): udp mode set, 28 headers + 0 data bytes

--- 192.168.0.10 hping statistic ---
5 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
root@moon:/home/juan#



root@ubuntu:/home/juan# netstat -su
IcmpMsg:
    OutType3: 10
Udp:
    28 packets received
    10 packets to unknown port received.
    10 packet receive errors
    23 packets sent
    InCsumErrors: 10
...
root@ubuntu:/home/juan#


El número de packet receive errors (y InCsumErrors) volvió a incrementarse en 5. Vale notar que esta vez no recibimos los mensajes ICMP, básicamente porque los paquetes fueron descartados rápidamente por no tener el checksum inválido.

Un detalle llamativo de estas dos últimas pruebas es el siguiente. Viendo los logs escritos en /var/log/syslog, encontré:

May 17 15:08:25 ubuntu dhclient: 5 bad udp checksums in 5 packets
May 17 15:08:34 ubuntu kernel: [ 9005.777840] UDP: bad checksum. From 192.168.0.2:2868 to 192.168.0.10:5555 ulen 8
May 17 15:08:35 ubuntu kernel: [ 9006.776665] UDP: bad checksum. From 192.168.0.2:2869 to 192.168.0.10:5555 ulen 8
May 17 15:08:36 ubuntu kernel: [ 9007.781846] UDP: bad checksum. From 192.168.0.2:2870 to 192.168.0.10:5555 ulen 8
May 17 15:08:37 ubuntu kernel: [ 9008.776246] UDP: bad checksum. From 192.168.0.2:2871 to 192.168.0.10:5555 ulen 8
May 17 15:08:38 ubuntu kernel: [ 9009.779863] UDP: bad checksum. From 192.168.0.2:2872 to 192.168.0.10:5555 ulen 8


La primera línea indica que dhclient (el servicio escuchando en 68/UDP) recibió, o al menos se enteró de, los 5 paquetes con checksum erróneo, lo cual me deja un poco desconcertado. Aparentemente el kernel pasa estos paquetes de todas maneras a la aplicación, probablemente para que la aplicación decida qué medidas tomar. Las siguientes 5 líneas son del kernel indicando que se recibieron 5 paquetes UDP con bad checksum (dirigidos al 5555/UDP).

Otra forma un poco mas complicada de analizar packet receive erors es desde /proc/net/udp. La ventaja de este método es que la información está mas detallada, por ejemplo por puerto. netstat resume esta información.

root@ubuntu:/home/juan# cat /proc/net/udp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops            
   67: 00000000:0044 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 8110 2 caaa82c0 5                
  248: 00000000:13F9 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 8044 2 caaa8000 0                 
root@ubuntu:/home/juan#


En este caso marcado en "negrita" vemos 0044 valor hexadecimal del puerto 68, y por último el número de paquetes descartados para ese puerto 5 (los paquetes enviados con bad checksum). Otros valores importantes que vemos son tx_queue y rx_queue que básicamente indican que las colas están vacías dado que no hay paquetes llegando o saliendo del host.

Cuando describí el campo packet receive errors al comienzo del post, dije que este contador no solo se incrementa por paquetes defectuosos sino también por paquetes que al llegar encuentran el buffer de recepción lleno y son descartados. Esta última condición se genera cuando la tasa de llegada de paquetes es mayor a la tasa de procesamiento de los mismos. Un clásico problema productor-consumidor, si se produce a mayor tasa de la que se consume, el productor debe ser capaz de reconocer la situación y frenar la producción (control de flujo que UDP no posee) o el consumidor debe ser capaz de aumentar su velocidad de consumo o ampliar su capacidad de almacenar productos (incrementar el tamaño de los buffers).

Probar esta última situación resulta un poco mas complicado así que queda pendiente para la próxima publicación :P

Links:

[1] UDP - https://www.ietf.org/rfc/rfc768.txt
[2] Hping3 - http://wiki.hping.org/

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/


jueves, 11 de julio de 2013

"Prueba de concepto" TA13-088A: DNS Amplification Attacks

Para complementar el post anterior voy a hacer una demostración sencilla. La idea es demostrar la facilidad con que se pueden ganar varios Mbytes de tráfico con solo hacer consultas DNS.

Para generar las consultas utilizamos hping3 (http://www.hping.org/), una herramientita muuy interesante que permite generar paquetes de todo tipo, formas, etc, hacer ip spoofing, lanzar enormidad de paquetes por segundo, etc.

Los participantes serán:

IP_victima: la IP que falsificaremos y a donde volverá el tráfico dns amplificado.
IP_dns1, IP_dns2 : las IPs de los servidores de dns que vamos a utilizar para atacar.
IP_atacante: si bien dijimos que lo ideal sería realizar el ataque desde varias PCs, lo vamos a hacer desde solo una para la prueba.

Conseguir la consulta a enviar:

La consulta que vamos a enviar es la misma que mostré en el post anterior, por lo tanto hice una captura con wireshark el envío de la consulta y exporté el contenido del paquete UDP a un archivo llamado "query". Este archivo contiene todo lo respectivo a la consulta DNS


La parte sombreada es lo que exportamos al archivo query en formato binario, podemos ver que son 28 bytes de la consulta.
Podemos ver el tamaño del archivo exportado:

root@corrientes:/home/jpavlik/DoS# ll query 
-rw-r--r-- 1 root root 28 jul  8 17:35 query
root@corrientes:/home/jpavlik/DoS# 

Lanzamos hping contra el primer dns y vemos el efecto en la víctima:

Vamos a lanzar hping de la siguiente manera:

hping3 --faster --udp -p 53 --spoof IP_victima --file query -d 28 IP_dns1
  • Donde el parámetro "--faster" le indica a hping que envíe los paquetes con intervalos de espera de 1 microsegundo (aprox. 1000000 de paquetes por segundo). 
  • Los parámetros "--udp -p 53" indica el protocolo de transporte y el puerto destino al que irán los paquetes generados.
  • El parámetros "--spoof IP_victima" indica la IP de origen que tendrán los paquetes generados.
  • Los parámetros "--file query -d 28" indican por un lado, el archivo de donde se sacará el contenido a enviar en los paquetes y la longitud de este contenido.
  • Por último "IP_dns1" la IP del servidor de nombres recursivo que vamos a utilizar.
Por otro lado, en la víctima mediremos el tráfico con iftop de la siguiente manera:

iftop -f "port 53"
  • Iftop nos permite ver en tiempo real las conexiones y el consumo de estas en una interfaz de red
  • La opción "-f" permite definir un filtro y en nuestro caso filtramos por el puerto 53. 
Vemos que antes de lanzar no tenemos trafico alguno:


Ahora lanzamos el hping con los parámetros correspondientes:


  • Vemos como se generaron unos 47,5 Mb por segundo (solo con 1 máquina y 1 dns).
  • Vemos como solo se registra tráfico RX (entrante), esto se debe principalmente al spoofin, ya que las consultas jamás salieron de esta IP.

Lanzamos hping contra dos dns y vemos el efecto en la víctima:

Esta vez lanzamos una segunda instancia de hping, pero apuntando las consultas a un segundo servidor de dns para "duplicar" el impacto.


  • Con este segundo dns llegamos a un pico de 78Mb por segundo, un poco por debajo del doble.
  • Vemos ahora otro flujo solamente de llegada de paquetes, correspondiente a las respuestas del segundo servidor.

En fin, esto era para mostrarles que no es muy complicado de reproducior el problema de esta manera. Para que realmente el ataque sea exitoso son necesarios varios factores:
  • DNSs recursivos que respondan abiertamente y una tasa alta de respuestas por segundo.
  • Muchos HOSTS desde donde se pueda hacer spoof de la IP de la víctima.
  • Paciencia.

domingo, 7 de julio de 2013

TA13-088A: DNS Amplification Attacks

Hace un par de días recibí un correo de US-CERT con el título "TA13-088A: DNS Amplification Attacks" y me llamó poderosamente la atención que esto siga siendo un problema en la red.

Según el último análisis hecho por la gente de Open Resolver Project (http://openresolverproject.org/ 2013-06-30):


35086838 servers responded to udp/53 probe
30085246 gave the correct answer to the A? for the DNS name queried
30556493 responses had recursion-available bit set


Es decir que existen alrededor de 35 millones de servidores DNS, de los cuales 30 millones responderían consultas recursivas, esto es aproximadamente el 87% del total (bastante, no?). 

A ver..., a priori tener un servidor DNS que responde consultas recursivas no es un pecado capital, de hecho es una gran funcionalidad en casos como el de la siguiente figura:


Un DNS recursivo brinda una serie de ventajas:

  • Permite que las aplicaciones no tengan que cargar con el proceso de resolución de nombres.
  • Definir políticas en cuanto al acceso a determinados dominios.
  • En el caso de tener un firewall principal que controle el tráfico entrante y saliente de la organización, solo sería necesario abrir el puerto 53 (UDP/TCP) para el servidor de DNS y no para todas las IPs.
  • Por lo general los servidores recursivos además son servidores cache, es decir que guardan las respuestas obtenidas por un plazo de tiempo, esto implica reducciones de tiempo y de consumo de ancho de banda.

Entonces cuál es el problema con tener un DNS recursivo?

El problema radica principalmente en la capacidad de un atacante de falsificar la dirección IP de origen (conocido como IP spoofing) en una consulta de dns. Sumado a esto, las consultas DNS tienen una particularidad muy interesante y util en este contexto:

Las respuestas suelen ser mucho mas grandes que las preguntas.

Por ejemplo, una consulta sencilla donde solo queremos los registros NS que corresponden a la raíz del servicio de nombres:


juan@moon:~$ dig -t ns .

; <<>> DiG 9.7.3 <<>> -t ns .
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- 43559="" font="" id:="" noerror="" opcode:="" query="" status:="">
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 15

;; QUESTION SECTION:
;.                              IN      NS

;; ANSWER SECTION:
.                       194627  IN      NS      i.root-servers.net.
.                       194627  IN      NS      j.root-servers.net.
.                       194627  IN      NS      m.root-servers.net.
.                       194627  IN      NS      g.root-servers.net.
.                       194627  IN      NS      k.root-servers.net.
.                       194627  IN      NS      b.root-servers.net.
.                       194627  IN      NS      e.root-servers.net.
.                       194627  IN      NS      l.root-servers.net.
.                       194627  IN      NS      c.root-servers.net.
.                       194627  IN      NS      h.root-servers.net.
.                       194627  IN      NS      f.root-servers.net.
.                       194627  IN      NS      a.root-servers.net.
.                       194627  IN      NS      d.root-servers.net.

;; ADDITIONAL SECTION:
j.root-servers.net.     603710  IN      A       192.58.128.30
m.root-servers.net.     198503  IN      A       202.12.27.33
m.root-servers.net.     254964  IN      AAAA    2001:dc3::35
g.root-servers.net.     603710  IN      A       192.112.36.4
k.root-servers.net.     603710  IN      A       193.0.14.129
b.root-servers.net.     603710  IN      A       192.228.79.201
e.root-servers.net.     603497  IN      A       192.203.230.10
l.root-servers.net.     601827  IN      A       199.7.83.42
l.root-servers.net.     601827  IN      AAAA    2001:500:3::42
c.root-servers.net.     603710  IN      A       192.33.4.12
h.root-servers.net.     603710  IN      A       128.63.2.53
f.root-servers.net.     603710  IN      A       192.5.5.241
a.root-servers.net.     442939  IN      A       198.41.0.4
a.root-servers.net.     599900  IN      AAAA    2001:503:ba3e::2:30
d.root-servers.net.     603710  IN      A       199.7.91.13

;; Query time: 24 msec
;; SERVER: 200.49.130.47#53(200.49.130.47)
;; WHEN: Sun Jul  7 00:25:00 2013
;; MSG SIZE  rcvd: 504

juan@moon:~$ 

Capturando con wireshark la consulta anterior vemos:


La respuesta es casi 10 veces mas grande que la pregunta (podrían existir casos aún peores, pruebe con dig -t ANY . @8.8.8.8 ... 1600 bytes!). Esta particularidad hace al protocolo DNS una potencial herramienta de denegación de servicio muuuuy interesante. 

Si extrapolamos un poco los números:
  • Digamos que podemos hacer 10 consultas por segundo, eso serían 590 bytes, recibiríamos 5460 bytes en respuestas.
  • Digamos que podemos hacer 100 consultas por segundo, eso serían 5900 bytes en consultas y unos 54600 bytes en respuestas.
Dificilmente logremos realizar una DoS realizando 100 consultas por segundo... la amenaza está realmente en el trabajo en equipo, es decir en las Botnets. 

Si un atacante contara con una botnet pequeña de unos 2000 equipos infectados generando unas 10 consultas por segundo, podría generar un bruto de 10920000 (5000*10*546) bytes, aproximadamente 10 Gbytes de tráfico en respuestas!!! Pero todavía queda algo por arreglar, claramente no podríamos exigirle este tráfico a un solo servidor DNS... necesitamos poder distribuir las consultas en mas de un servidor; pero eso no debería ser un impedimento según la gente de OpenResolvers.org, ya que hay millones de servidores DNS recursivos abiertos.

Ahora supongamos que además, el atacante es capaz de cambiar la IP de origen con que salen las consultas DNS de cada uno de los miembros de la botnet, por la IP de la víctima... eso significaría que estos 10 Gbytes estarían volviendo no a los nodos de la botnet sino a la IP víctima, colapsando así su ancho de banda y produciendo una denegación de servicio.

Cómo evitarlo?
Evitar denegaciones de servicio no es un tema sencillo y en la mayoría de los casos lo mejor que podamos hacer solamente reducirá el riesgo de sufrir una o disminuirá un poco su impacto.

Las siguiente medidas son de ayuda:

  • Deshabilitar las consultas recursivas en los servidores que no las precisen, por ejemplo aquellos servidores que solo son autoritativos.
  • Si las consultas recursivas son necesarias, se pueden tomar dos medidas: limitar la funcionalidad a un número acotado de IPs o limitar la cantidad de consultas por segundo permitidas.
  • Verificación de direcciones IP, los ISP deberían combatir el IP spoofing, aca va un RFC que presenta una solución a este problema http://tools.ietf.org/html/bcp38 .
Cómo saber si mi servidor de DNS es vulnerable?

Una buena herramienta para ver si nuestros servidores son vulnerables es la siguiente http://www.dnsinspect.com/ . Con solo introducir nuestro nombre de dominio la aplicación hace una serie de pruebas a los servidores DNS declarados de la zona y prepara un breve informe. Este contiene los resultados de las pruebas junto con una serie de advertencias, sugerencias/recomendaciones para aplicar sobre las configuraciones de los mismos.

sábado, 3 de abril de 2010

Pequeeeeña intro MDNS (Multicast DNS):

Hoy (01/04/2010), mientras preparaba la próxima entrada del blog "casualmente" tenía wireshark corriendo y me encontré con un paquete que me llamó poderosamente la atención. El protocolo es MDNS, lo había visto antes pero siempre creí que se trataba de alguna de las aplicaciones que estaba corriendo.

Intro:

Googleando un poco encontré de que se trata: "Multicast DNS is a way of using familiar DNS programming interfaces, packet formats and operating semantics, in a small network where no conventional DNS server has been installed." (http://www.multicastdns.org/). Es decir, se trata de una implementación del protocolo de resolución de nombres (DNS) para redes de área local, donde no existe un servidor DNS real. Producto de los grupos Zero Configuration Networking y DNS Extensions, creado con el objetivo de facilitar la configuración de redes locales que no cuentan con un servidor de nombres propio.

Según el draft (http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt) "Clients performing DNS-like queries for DNS-like resource records by sending DNS-like UDP query and response packets over IP Multicast to UDP port 5353." se trata de clientes realizando consultas tipo DNS por registros tipo DNS enviando paquetes (tipo DNS) al puerto 5353 UDP  sobre direcciones IP Multicast (JA!, para los que creen que las clase D no se usan jajaaj).

Las direcciones Multicast o clase D van de 224.0.0.0 a 239.255.255.255, y se caracterizan por: una dirección Multicast está asociada con un grupo de receptores interesados, cuando uno de los interesados envía un paquete a una dirección Multicast todos los demás lo reciben, los routers que se encuentren entre estos interesados deben ser capaces de reenviar estos paquetes a cada uno de ellos.

Al tratarse de una dirección Multicast, todos los asociados reciben todos los paquetes, y de esta manera las caches de nombres se mantienen actualizadas. Cada respuesta a una consulta Multicast DNS trae un campo donde se especifica el tiempo de validez que tiene la respuesta, luego de que expire ese tiempo es necesario volver a efectuar la consulta.

Este servicio de DNS cuenta también con un TLD (Top-Level Domain) propio y es ".local.". Todo FQDN (Fully Qualified Domain Name, nombre completo xD) que finalice con ".local." se lo considera de enlace local, es decir... es un análogo a las direcciones IP privadas, que sólo valen en el ámbito local de la red y de nada sirven fuera de ella. Toda consulta DNS que finalice con ".local." debe ser enviada a la dirección 224.0.0.251 (si se trata de IPv4, o FF02::FB si se trata de IPv6).

Existen 3 tipo de consultas: las consultas convencionales 1-consulta->1-respuesta, 1-consulta->N-respuestas y el ultimo tipo que consiste en consultas continuas.

En fin... eso es mas o menos a modo de introducción :D. Si realmente querés saber mas, está el link del borrador mas arriba, de ahora en mas voy a intentar controlar/activar/desactivar este servicio de mi laptop. Resulta ser que en la mayoría de las distribuciones de GNU/Linux viene instalado por defecto un servicio que implementa este protocolo, y se llama Avahi (http://avahi.org/). Avahi es capaz de publicar y descubrir dispositivos, y servicios disponibles en la red local, sin necesidad de realizar configuración alguna.

Veamos si el servicio está corriendo :D  (hagamos de cuenta que nunca vi el paquete con wireshark xD):
"Lo sospeché desde un principio..." asi es, tengo corriendo como demonio a avahi-daemon



Buscando un poco mas se puede ver que escucha en el puerto UDP 5353 de todas las interfaces disponibles, a la espera de consultas/respuestas que pueden provenir de cualquier dirección de red.



Ahora probemos la facilidad de uso de este protocolo. La lan de prueba está compuesta por 2 hosts, la laptop con direccion 192.168.206.1 (nombre moon) y una vm con dirección 192.168.206.134 (nombre ubuntu). Ambos hosts tienen instalado Ubuntu 9.10, que trae por defecto instalado avahi-daemon versión 0.6.25. Ninguno de los host recibió algún tipo de configuración de este servicio, ambos corren como fueron instalados. En el host moon estará nuestro amigo wireshark capturando los paquetes para ver lo que sucede :D.

Buscando a "ubuntu" desde "moon":

Sabemos que está conectadp a la red un host de nombre "ubuntu", pero no sabemos la dirección IP que le fue asignada, y no contamos con un servidor DNS local :D, maldita sea!, pero para eso está corriendo avahi-daemon. Para conocer la dirección de ese host nos basta con hacer un "ping ubuntu.local.", como muestra la imagen



ahora veamos lo que capturó nuestro amigo :D.
Wireshark nos muestra 4 paquetes MDNS, los dos primeros son la resolución directa del nombre de host "ubuntu.local.".
-192.168.206.1 (moon) envía una consulta MDNS a 224.0.0.251 (Multicast IP Address) preguntando por la dirección de "ubuntu.local.".
-192.168.206.134 (ubuntu) envía una respuesta MDNS a 224.0.0.251 (Multicast IP Address) diciendo que 192.168.206.134 corresponde al "host ubuntu.local.".
Los últimos dos paquetes son la resolución inversa, es decir, intenta averiguar el nombre que le corresponde a la dirección 192.168.206.134, esto debe ser una suerte de mecanismo de seguridad, para ver que sean consistentes:
-192.168.206.1 (moon) envía una consulta inversa a la dirección 224.0.0.251, consultando por el nombre que le corresponde a "134.206.168.192.in-addr.arpa.".
-192.168.206.134 (ubuntu) rsponde a la dirección 224.0.0.251, diciendo que esa dirección le corresponde al nombre "ubuntu.local.".



Exáctamente lo mismo podemos observar si ahora realizamos el ping desde ubuntu hacia moon.local.



Publicando y Descubriendo servicios:

Junto con MDNS se puede utilizar algo llamado DNS-SD (DNS-Service Discovery), que consiste en dar a conocer y encontrar servicios locales utilizando MDNS. De nuevo se trata de algo de simple puesta en marcha. Como ejemplo publicaremos dos servicios en el host de nombre moon (FQDN moon.local.), un servidor web en el puerto 80 y un ftp en el puerto 21. El proceso de publicación de los servicios consiste en crear un archivo con sintaxis XML en el directorio /etc/avahi/services/, con la condición que el nombre del archivo debe finalizar en ".service" (sin las comillas :D), como el siguiente:



Para entender bien la sintaxis basta con dar una breve leída a "man avahi.service" :D. Luego de configurar adecuadamente los servicios que querramos reiniciamos el demonio avahi con "avahi-daemon -r" y listo, toda la magia de la publicación de servicios es esa jajaja. Ahora hay que comprobar que los servicios están siendo publicados, para eso instalé dos porgramas mdns-scan y mzclient, NO instalen mdns-scan es DEMASIADO BASICO (ni siquiera recibe parámetros y solo busca types "_workstation"). Primero veamos los hosts que se encuentran utilizando MDNS ejecutamos mzclient como en la próxima imagen (-r se encarga de resolver los nombres de los hosts):



moon tiene 3 direcciones MAC diferentes porque se trata de las 3 interfaces de red, dos virtuales y la eth0 real. Entonces los hosts siguen bien configurados, ahora busquemos los servicios publicados :D. Para eso usamos la opcion -t, que indica la etiqueta type del archivo de servicios, buscamos primero si hay servicios tipo "_http._tcp", incluimos -r para que resuelva nombres:



Ahora busquemos el ftp :D:



Ambos servicios fueron asociados al nombre "moon.local" con dirección 192.168.206.1, como lo configuramos y como debe ser. Eso es gran parte de la publicación de servicios, para mas información http://avahi.org :P.

Deteniendo el demonioooooooo:

Si nos iteresa detener el demonio solo por un momento o reiniciarlo, lo podemos hacer directamente mediante el script ubicado en /etc/init.d. Ejecutamos sudo /etc/init.d/avahi-daemon stop, o mas elegantemente sudo service avahi-daemon stop, para detenerlo, cambiamos stop por restart, para reiniciarlo y start para iniciarlo cuando está detenido.



Deshabilitando temporalmente al demonio:
Si queremos deshabilitarlo temporalmente pero no borrarlo del sistema podemos recurrir a un pequeño truquillo :D. La idea básicamente consiste en que sencillamente el demonio nunca se inicie xD, y esto lo podemos lograr alterando el script de inicio del demonio, ubicado en "/etc/init/avahi-daemon.conf". Como se ve en la imagen hay que comentar la linea de "start".



En definitiva, se trata de un servicio bastante útil, pero que sinceramente no necesito tener activo en este momento. Posiblemente en una LAN donde todo el tiempo entran y salen dispositivos diferentes sea de suma utilidad, pero no lo veo tan así en una LAN chica con poco cambio de los dispositivos.