Ataque de transferencia de zona DNS en Linux

Publicado el 20 enero 2017 por Drassill
En anteriores ocasiones ya he hablado sobre la importancia del DNS (Domain Name Service), y su configuración, pues se tratan de un servicio de una enorme relevancia que hace que Internet sea lo que hoy en día todos conocemos; basta con escribir un nombre de dominio para poder acceder a una web; evitándonos tener que memorizar las IPs de los sitios. Hoy quiero hablaros de una configuración especifica que tienen estos servidores; una configuración que puede convertirse en un arma de doble filo si no tenemos cuidado: Se trata de la transferencia de zona.

Lo más común en los entornos empresariales y/o pensados para dar servicio a un gran número de personas, es que los servidores DNS estén compuestos por varios equipos físicos: Un maestro y varios esclavos que estarían para ayudar a distribuir el tráfico y para que en caso de que el maestro se cayese, no nos quedásemos tirados. Para que no haya problemas con la información, cuando un DNS secundario es arrancado para convertirse en el DNS principal se realiza una transferencia de zona; transferencia que replicaría la "base de datos" del DNS y que, para bien o para mal, está activada por defecto. Veamos un sencillo ejemplo basado en el archivo de configuración named.conf.local de bind9.
  1. zone "pruebaivan2.net" {
  2.         type master;
  3.           file "/etc/bind/db.pruebaivan2";
  4. };
  5. zone "1.168.192.in-addr.arpa" {
  6.         type master;
  7.         file "/etc/bind/db.192";
  8. };

Esta configuración es una muy típica en los servidores DNS, con la diferencia de que obviamente las IPs serán distintas; pero lo importante no son los datos sino el concepto en sí. Si os fijáis bien, no hay ningún parámetro que haga referencia a la transferencia de zona; dicho concepto ya está por defecto activado. Esto está pensado para que así no haya restricción alguna para realizar la transferencia y que no haya ningún impedimento a la hora de pasar la información desde el servidor primario a algún secundario. El problema está en que dicha transferencia es abierta; es decir que se puede realizar la transferencia a cualquier destino; y he ahí el problema.
Todo sistema informático, tan pronto como está expuesto al público, es susceptible de ser hackeado; y el DNS, obviamente, no es una excepción; más aún cuando éste servicio es de vital importancia para evitar tener que memorizar direcciones IP.
Para hacer la prueba usaremos un comando muy conocido pero que cuyo uso no es tan extendido como otros comandos de red, tales como traceroute o nmap. Sería el comando dig, cuyo proposito es recavar información sobre un host en concreto o, en este caso, recabar y transferir dicha información. Hay que recalcar que dig en sí no es una herramienta con fines malignos; la cuestión está que toda herramienta puede tener diferentes usos dependiendo de quien la use.
Para realizar una transferencia de zona usaríamos la siguiente estructura del comando dig:
dig @host_origen axfr host_destino
El comando en sí haría lo siguiente: Mediante el @host_origen, haríamos referencia al DNS al que queremos realizar la transferencia de zona; el parámetro axfr especifica que la acción que se quiere realizar es la transferencia de zona; mientras que el host_destino sería el DNS al que queremos realizar la transferencia. Por ejemplo:
dig@pruebaivan2.net axfr pruebaivan2.net
Lo más impactante es que ni siquiera es necesario tener otro host propio; el propio host suyo puede darnos la información al realizar la transferencia de zona, ya que lo que estamos haciendo al realizar dicha transferencia sería actualizar y sincronizar los datos DNS existentes. Mirad este pequeño ejemplo:

Como podéis ver estaríamos viendo el contenido de la base de datos, cosa muy peligrosa ya que vemos qué información maneja, y la información es poder...
Afortunadamente tenemos una solución a dicho problema; una solución muy simple que no conlleva apenas esfuerzo por nuestra parte. Limitar la transferencia de zona para que haga las transferencias a unas IPs en concreto; IPs que nosotros conozcamos y que sepamos que son de "confianza". Para aquello editaremos el fichero named.conf.local y usaremos el parámetro allow-transfer. Dicho parámetro especificará qué IPs en concreto queremos que puedan realizar la acción de transferencia; cualquiera que lance la petición de transferencia que no tenga una de las IPs mostradas en dicho parámetro, simplemente no tendrá éxito.
  1. zone "pruebaivan2.net" {
  2.         type master;
  3.           file "/etc/bind/db.pruebaivan2";
  4.           allow-transfer {192.168.1.7; localhost; };
  5. };
  6. zone "1.168.192.in-addr.arpa" {
  7.         type master;
  8.         file "/etc/bind/db.192";
  9.         allow-transfer {192.168.1.7; localhost; };
  10. };

Obviamente, para aplicar los cambios habría que reiniciar el servidor DNS; es decir:
/etc/init.d/bind9 restart
Por último, para comprobar si en efecto la transferencia de zona está "capada"; tendríamos que, por un lado, ejecutar el comando dig a nivel local para ver que efectivamente todavía funciona la transferencia; y por otro lado ejecutar edig desde una IP no autorizada. En caso de realizar la petición de transferencia desde una IP inadecuada obtendríamos un mensaje de respuesta tal como el siguiente:

Como veis, una configuración descuida del servidor DNS puede resultar fatal, ya que podríamos estar dejando "abiertos" varios parámetros que por defecto están pensados para darnos flexibilidad, pero que pueden ser aprovechados por personas malintencionadas para obtener información de nuestros servicios.
Espero que os haya resultado útil.
Saludos.