Suplantando nuestros DNS en la red local

Desde hace un tiempo, es muy común que la gente utilice su teléfono indiscriminadamente a todas horas. Esta mañana cuando desperté me dirigí a la cocina a saludar a mis padres y como es costumbre tras varios minutos apareció mi hermana escuchando un servicio de streaming de audio a todo volumen, le pedí por favor que lo desconectara y como es pasó de mi, así que esto basto para encender mi creatividad. Como no tengo el hardware necesario para montar un Firewall + Squid para que me aplique control parental, he decidido montar un aproximación con mi Raspberry (Ya os aviso de que es muy rudimentario, pero de momento efectivo). La finalidad de este post es poder bloquear el acceso a una serie de dominios en determinadas horas del día.

Evidentemente, para alguien que sepa algo de redes este procedimiento no sirve de nada, bastaría con forzar los dns de la máquina en la que se está trabajando a los de nuestro ips/google/opendns para que nos sirviera las entradas reales, pero creo que para mi propósito me sirve sobrado.

Antes de empezar supondremos que tenemos una RED de área local que corresponde con el rango 192.168.22.0/24 dónde

	192.168.22.1  --> Gateway
	192.168.22.2  --> Equipo Windows con reserva de DHCP
	192.168.22.11 --> DNS + DHCP.

En la siguiente imagen os presento una aproximación (en este caso no sería ROGUE DNS porque nosotros lo permitimos con nuestro servidor DHCP, ya que es nuestra red, pero si montáramos este escenario intentando suplantar el DHCP real se podría considerar un ataque) de lo que realizaremos:

Rogue DNS

En mi caso el Router del ISP no me permite configurar que servidores DNS serán servidos con este protocolo por lo que tendré que instalar un servidor de DHCP en la Raspberry y desactivar el propio del router.


El primer paso consiste en instalar Raspbian en nuestro dispositvo, acto seguido instalaremos el servidor DNS (bind9) y DHCP (isc-dhcp-server):

sudo apt-get install bind9 dnsutils
sudo apt-get install isc-dhcp-server 

Una vez se han terminado de instalar estos paquetes, debemos configuramos servidor DNS para hacer de relay (El relay permite resolver Zonas DNS que no son nuestras. P.E google.es). Para ello debemos editar:

	
sudo vi /etc/bind/named.conf.options

Dentro de la sección options añadimos los forwarders esto permite utilizar DNS externos para que nos resuelvan consultas que no tenemos en cache ni somos maestros de la zona. En este ejemplo se añadirán los un servidor de nombres de Opendns (Cisco) y un servidor de nombres de Google (en la práctica son muy utilizados). Notad que utilizo vi para editar el archivo si no estáis acostumbrados a este editor quizá sea mejor que utilicéis nano.

forwarders {
       208.67.222.222;
       8.8.8.8;
};
dnssec-enable yes;
dnssec-validation no;
dnssec-lookaside auto;

Una vez hemos terminado de hacer cambios, reiniciamos el servicio:

sudo service bind9 restart

Para probar si los cambios se han aplicado bien, utilizaremos la utilidad nslookup para resolver direcciones en nuestro servidor de DNS, para ello es necesario especificar que el server que usaremos es el 127.0.0.1.

$ nslookup 
> server 127.0.0.1
Default server: 127.0.0.1
Address: 127.0.0.1#53
> google.es
Server:         127.0.0.1
Address:        127.0.0.1#53
Non-authoritative answer:
Name:   google.es
Address: 216.58.201.131

Si resuelve correctamente significa, que los forwarders de dns se han configurado correctamente.

El siguiente paso es crear una zona maestra para hacer un “override” de un dominio determinado. Como el servidor de nombres DNS primero revisa si tiene una zona (un dominio y todas sus entradas asociadas) y si no la tiene la pregunta a los forwarders, podemos aprovechar este comportamiento para sobrescribir el dominio que no queremos que sea accesible desde la red.

Cuando estás realizando un ataque, este montaje es muy común en redes en la que los elementos de red no controlan por donde les debe venir la información del servidor DHCP, esto se conoce como suplantación de DHCP y rogue/suplantación de DNS.

Para hacer esta configuración, lo primero que hay que hacer es editar el archivo:

sudo vi /etc/bind/named.conf.local

Y crear la zona para la web que queremos servir. En mi caso me interesa bloquear/suplantar la web: “miwebbloqueada.com”

zone "miwebbloqueada.com" {
	type master;
	file "/etc/bind/db.miwebbloqueada.com";
};

El siguiente paso es crear la base de datos de información del dominio. Este fichero contendrá todas los “Resource Records” (entradas del DNS asociadas a un dominio). Estas entradas nos facilitan información sobre los servidores de nombre de un dominio, la dirección ip que debe resolver un subdominio de ese dominio, los servidores de correo de un dominio, y mucha más información que no viene al caso.

	
sudo cp /etc/bind/db.local /etc/bind/db.miwebbloqueada.com

Editamos el archivo para que quede con la información mínima para que resuelva una ip distinta a la original (como localhost), con esto podríamos hacer un ataque de “fishing” o un bloqueador de publicidad, o de servicios molestos por la mañana…

	
sudo vi /etc/bind/db.miwebbloqueada.com
	;
	; BIND data file for local loopback interface
	;
	$TTL    604800
	@       IN      SOA     ns.miwebbloqueada.com root.localhost. (
								  2         ; Serial
							 604800         ; Refresh
							  86400         ; Retry
							2419200         ; Expire
							 604800 )       ; Negative Cache TTL
	;
	@   IN  NS  ns.miwebbloqueada.com.
	ns      IN      NS      192.168.22.11
	@       IN      A       127.0.0.1

Una vez configurado debemos reiniciar el servicio de DNS.

sudo service bind9 restart

Si todo ha ido bien deberíamos ver en el syslog que la zona ha sido cargada correctamente

$ tail -f /var/log/syslog 
Apr 28 20:39:11 raspberrypi named[15686]: managed-keys-zone: loaded serial 2
Apr 28 20:39:11 raspberrypi named[15686]: zone 0.in-addr.arpa/IN: loaded serial 1
Apr 28 20:39:11 raspberrypi named[15686]: zone 127.in-addr.arpa/IN: loaded serial 1
Apr 28 20:39:11 raspberrypi named[15686]: zone 255.in-addr.arpa/IN: loaded serial 1
Apr 28 20:39:11 raspberrypi named[15686]: zone miwebbloqueada.com/IN: ns.miwebbloqueada.com/NS '192.168.22.11.miwebbloqueada.com' has no address records (A or AAAA)
Apr 28 20:39:11 raspberrypi named[15686]: zone miwebbloqueada.com/IN: loaded serial 2
Apr 28 20:39:11 raspberrypi named[15686]: zone localhost/IN: loaded serial 2
Apr 28 20:39:11 raspberrypi named[15686]: all zones loaded

Sale una advertencia que no es del todo correcta, nos viene a decir que solo hay configurado el subdominio “.” y no hay ninguno más por lo que todos los subdominios se resolverían igual. La prueba de fuego igual que antes, es ejecutar nslookup. Con esta utilidad, deberíamos poder ver la web en cuestión apuntando a la IP que hayamos puesto

$ nslookup 
> server 127.0.0.1
Default server: 127.0.0.1
Address: 127.0.0.1#53
> miwebbloqueada.com
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   miwebbloqueada.com
Address: 127.0.0.1

Si resuelve bien, aquí termina la configuración del DNS.

Como ya os comenté antes, mi router no me permite modificar las propiedades básicas del protocolo DHCP por lo que tendré que desactivarlo y montar mi propio server. Si vuestro router lo permitiese, bastaría con cambiar los DNS por defecto y poner que resuelva la IP de vuestra Raspberry. Dicho esto, pasamos a la configuración del DHCP.

Editamos configuración para poner la IP de la Raspberry manualmente para que sea estática ya que el servidor DHCP será la propia Raspberry (cuidado cuando se edite esta configuración, si no es correcta o acorde con vuestra red puede dejar inaccesible por red la raspberry en el próximo reinicio). Para ello debemos editar el archivo:

sudo vi /etc/network/interfaces

Una vez abierto debemos comentar la linea

#iface eth0 inet manual

Y a continuación escribir (adaptando las ips a vuestra red):

	allow-hotplug eth0
	iface eth0 inet static
	address 192.168.22.11
	netmask 255.255.255.0
	gateway 192.168.22.1
	nameserver 8.8.8.8

Creamos una copia de seguridad de la configuración inicial del DHCP:

cp /etc/default/isc-dhcp-server  /etc/default/isc-dhcp-serverold
cp /etc/dhcp/dhcpd.conf  /etc/dhcp/dhcpd.confold

Editamos el server DHCP para que escuche en eth0 que, es la única interfaz de la Raspberry:

sudo vi /etc/default/isc-dhcp-server

Y buscamos la línea:

INTERFACES=”″

Y la reemplazamos por esta otra:

INTERFACES=”eth0″

Una vez hemos hecho que el server escuche en eth0 hay que indicarle el comportamiento que debe tener el DHCP:

sudo vi /etc/dhcp/dhcpd.conf

A continuación os pego una copia de mi configuración del DHCP, lo importante aquí es configurar el campo “option domain-name-servers 192.168.22.11;” para que apunte a la raspberry y los rangos de IPs. Adicionalmente, he creado un elemento con IP reservada, en este caso mi equipo, os será útil cuando tengáis que abrir los puertos. Como punto extra, os diré que tener reservada la IP en este DHCP me permite llevar un control de mis dispositivos ya que en el router no podía ponerles nombres. Cuando vayáis a configurar vuestro DHCP aseguraos de que dentro de subnet esté la “option routers” apuntando a vuestro Gateway, sino perderéis conectividad con Internet.

#Configuracion del servifor DHCP
ddns-update-style none;
option domain-name "micasa";
option domain-name-servers 192.168.22.11;
default-lease-time 7200;
max-lease-time 21600;
authoritative;
log-facility local7;

# Rangos
subnet 192.168.22.0 netmask 255.255.255.0 {
      range 192.168.22.15 192.168.22.200;
      option routers 192.168.22.1;
      option subnet-mask 255.255.255.0;
}


# ASIGNACIONES ESTATICAS  #
host mipc {
   hardware ethernet 00:11:22:33:44:55;
   fixed-address 192.168.22.2;
}

Una vez hemos hecho estos cambios, para que surjan efecto, debemos reiniciar el server dhcp:

sudo service dhcpcd restart

Pasados unos segundos, podemos comprobar si el servicio haya arrancado sin errores en los eventos del sistema:

tail -20f /var/log/daemon.log  
Apr 28 21:22:33 raspberrypi dhcpcd[1021]: sending signal TERM to pid 991
Apr 28 21:22:33 raspberrypi dhcpcd[991]: received signal TERM from PID 1021, stopping
Apr 28 21:22:33 raspberrypi dhcpcd[991]: eth0: removing interface
Apr 28 21:22:33 raspberrypi dhcpcd[1021]: waiting for pid 991 to exit
Apr 28 21:22:33 raspberrypi dhcpcd[1021]: dhcpcd[1021]: waiting for pid 991 to exit
Apr 28 21:22:33 raspberrypi dhcpcd[991]: exited
Apr 28 21:22:33 raspberrypi systemd[1]: dhcpcd.service: main process exited, code=exited, status=1/FAILURE
Apr 28 21:22:33 raspberrypi systemd[1]: Unit dhcpcd.service entered failed state.
Apr 28 21:22:33 raspberrypi systemd[1]: Starting dhcpcd on all interfaces...
Apr 28 21:22:33 raspberrypi dhcpcd[1025]: version 6.7.1 starting
Apr 28 21:22:33 raspberrypi dhcpcd[1025]: dev: loaded udev
Apr 28 21:22:33 raspberrypi dhcpcd[1025]: DUID 00:01:00:01:20:7e:13:db:b8:27:eb:e4:b0:68
Apr 28 21:22:33 raspberrypi dhcpcd[1025]: eth0: IAID eb:e4:b0:68
Apr 28 21:22:34 raspberrypi dhcpcd[1025]: eth0: soliciting an IPv6 router
Apr 28 21:22:34 raspberrypi dhcpcd[1025]: eth0: rebinding lease of 192.168.22.11
Apr 28 21:22:34 raspberrypi dhcpcd[1025]: eth0: changing route to 192.168.22.0/24
Apr 28 21:22:34 raspberrypi dhcpcd[1025]: eth0: changing default route via 192.168.22.1
Apr 28 21:22:34 raspberrypi dhcpcd[1025]: forked to background, child pid 1040
Apr 28 21:22:34 raspberrypi systemd[1]: Started dhcpcd on all interfaces.
Apr 28 21:22:46 raspberrypi dhcpcd[1040]: eth0: no IPv6 Routers available

El siguiente paso es desactivar el dhcp del router principal y renovar las IPs en nuestros dispositivos para ver que nos nos sirve nuestro DHCP:

Adaptador de Ethernet Ethernet:

   Sufijo DNS específico para la conexión. . : micasa
   Descripción . . . . . . . . . . . . . . . : Realtek PCIe GBE Family Controller
   Dirección física. . . . . . . . . . . . . : 00-11-22-33-44-55
   DHCP habilitado . . . . . . . . . . . . . : sí
   Configuración automática habilitada . . . : sí
   Vínculo: dirección IPv6 local. . . : fe80::bc04:e853:fee7:e419%26(Preferido)
   Dirección IPv4. . . . . . . . . . . . . . : 192.168.22.2(Preferido)
   Máscara de subred . . . . . . . . . . . . : 255.255.255.0
   Concesión obtenida. . . . . . . . . . . . : viernes, 28 de abril de 2017 19:54:24
   La concesión expira . . . . . . . . . . . : sábado, 29 de abril de 2017 1:38:34
   Puerta de enlace predeterminada . . . . . : 192.168.22.1
   Servidor DHCP . . . . . . . . . . . . . . : 192.168.22.11
   IAID DHCPv6 . . . . . . . . . . . . . . . : 253521765
   DUID de cliente DHCPv6. . . . . . . . . . : 00-01-00-01-1A-ED-3C-DE-1C-6F-65-90-30-42
   Servidores DNS. . . . . . . . . . . . . . : 192.168.22.11
   NetBIOS sobre TCP/IP. . . . . . . . . . . : habilitado

Como podéis observar, el servidor DHCP y el servidor DNS apuntan a nuestra Raspberry Pi por lo que entrada de DNS que no queramos entrada que podemos bloquear.

Ya solo quedaría crear un cron para que copie una config con las db que queremos y lo restablezca pasado X tiempo. Por ejemplo, a mi solo me interesa que esto este activo de 7:00-9:00.

Así que crearé 2 archivos:

/etc/bind/named.conf.local.block
/etc/bind/named.conf.local.noblock

El archivo block contendrá las entradas a las zonas bloqueadas mientras que el noblock no contendrá ninguna zona. Además crearé un pequeño script en bash para hacer el cambio de archivos (como root debemos ejecutar):

touch /root/change-dns.sh
chmod +x /root/change-dns.sh
vi /root/change-dns.sh

Y pegamos el siguiente código:

#!/bin/bash
if [ -f "/etc/bind/named.conf.local.$1" ]; then
        cp -f "/etc/bind/named.conf.local.$1" /etc/bind/named.conf.local
        /usr/sbin/service bind9 restart
else
        echo "File doesn't exist"
fi

Guardamos los cambios y ejecutamos

crontab -e

Dentro del crontab podemos añadir las siguentes lineas:

0 7 * * * bash /root/change-dns.sh "block" > /tmp/block 2>  /tmp/block.err
0 9 * * * bash /root/change-dns.sh "noblock" > /tmp/block 2>  /tmp/block.err

3 pensamientos en “Suplantando nuestros DNS en la red local

  1. En el script de change-dns deberías verificar el argumento antes de aplicarlo 😉
    Code safely, muy friend.

    Sabes que te harán mirar porqué falla el streaming de audio cada mañana, ¿verdad? 😎😎

  2. Pingback: Actualizar DNS con DHCP | BitsDeLocos

Deja un comentario