22 octubre 2008

Creación de laboratorios virtuales con Netkit (II)

En el anterior artículo sobre Netkit vimos un ejemplo sencillo de sus posibilidades para simular una red con varios dispositivos. Las posibilidades son casi infinitas, pero es cierto que necesitamos algún tipo de automatización si queremos simular topologías complejas, con muchos nodos y sobre todo si queremos pasarle estas topologías a otros investigadores para que experimenten con ellas. Netkit aporta este nivel de automatización mediante laboratorios, estructuras de directorios que contienen ficheros para configurar cada uno de los nodos de manera automática. Lo bueno es que podemos comprimir este árbol de directorios y pasárselo a otros investigadores los cuales podrán arrancar el laboratorio y tener todos los nodos configurados y funcionando con apenas un único comando. Además, este fichero comprimido no ocuparía practicamente nada ya que los ficheros de configuración de cada nodo son sólo texto.

Vamos a preparar como ejemplo un laboratorio en el que simularemos un escenario en el que Alice se conecta a Internet desde la red conmutada de su organización. Lo que ella no sabe es que un intruso ha conseguido acceso a la red y pretende lanzar un ataque de arp-spoofing contra Alice para averiguar qué páginas de internet visita.

Antes de nada debemos configurar Netkit para que funcione correctamente en nuestro sistema operativo en modo laboratorio. Lo primero son las variables globales que usa Netkit. En el artículo anterior las configuramos correctamente, el problema es que cuando arrancamos un laboratorio en el que uno de los equipos se conecta a Internet tenemos que usar sudo el cual ignora por seguridad la mayor parte de las variables globales, entre ellas las que nosotros configuramos y usamos como usuarios normales. Para solucionarlo hay que configurar el sudo para que no ignore las variables de Netkit editando el fichero /etc/sudoers. En la sección "Default" de este fichero hay que poner:

Defaults:dante env_keep+="NETKIT_HOME", env_keep+="MANPATH"

Por supuesto en vez de dante hay que poner nuestro nombre de usuario. Faltaría la variable PATH y el sentido común dice que se debería poder configurar en el sudoers como las otras dos... el problema es que no es así y sudo sigue ignorando la variable PATH del usuario por mucho que nosotros configuremos en sudoers lo contrario. Es algo que de hecho ya está reportado en el Launchpad de Ubuntu como un bug largamente arrastrado. La solución es crear un alias que incluya el PATH de usuario cada vez que usemos sudo. Para ello editamos el fichero .bash_aliases de nuestro home e introducimos:

#Para que funcione el NETKIT.
alias sudo="sudo env PATH=$PATH"

Con eso Netkit cuenta con todas las variables necesarias, tanto si usamos sudo como si lo arrancamos como usuario normal.

Por otro lado, la versión 2.6 tiene un bug que hace que no se levante bien la salida a Internet de la máquina virtual, la solución es un patch que sacó uno de los autores de la aplicación en la lista de correo:
======================================================== diff -Naur netkit-old/bin/script_utils netkit-new/bin/script_utils --- netkit-old/bin/script_utils 2007-12-19 10:55:58.000000000 +0100 +++ netkit-new/bin/script_utils 2008-02-02 12:48:46.000000000 +0100 @@ -317,8 +317,8 @@ # This function starts all the hubs inside a given list runHubs() { local HUB_NAME BASE_HUB_NAME ACTUAL_HUB_NAME TAP_ADDRESS GUEST_ADDRESS - HUB_NAME="$1" while [ $# -gt 0 ]; do + HUB_NAME="$1" BASE_HUB_NAME="`varReplace HUB_NAME \".*_\" \"\"`" if [ "${BASE_HUB_NAME#tap${HUB_SOCKET_EXTENSION},}" != "$BASE_HUB_NAME" ]; then # This is an Internet connected hub @@ -328,7 +328,7 @@ startInetHub "$ACTUAL_HUB_NAME" "$TAP_ADDRESS" "$GUEST_ADDRESS" else # This is a normal hub - startHub "$1" + startHub "$HUB_NAME" fi shift done ========================================================
Una manera de aplicar este patch es crear un fichero de texto en $NETKIT_HOME/bin/ llamado patch2_6_bug con el texto del patch y acto seguido hacer:

dante@Hades:/usr/share/netkit/bin$ sudo patch script_utils patch2_6_bug patching file script_utils dante@Hades:/usr/share/netkit/bin$

Con esto se acaba la peor parte: la configuración previa de Netkit. Lo bueno es que sólo hay que hacerlo una vez, a partir de ahora sólo tendremos que preocuparnos de crear buenos laboratorios.

Para empezar con el nuestro, tendremos que crear una carpeta para contener el árbol de directorios y los ficheros de configuración. En esa carpeta crearemos el fichero principal de configuración del laboratorio: lab.conf. Ese fichero podemos meter todos aquellos parámetros que usaríamos con vstart para definir una máquina individual. Podemos definir cuantos interfaces tendrá cada nodo y a qué dominio de colisión pertenecerá cada uno (hay que recordar que, a diferencia de los hubs, los switches definen un dominio de colisión diferente para cada uno de sus puertos). Otro elemento que se puede definir es la memoria RAM que usará cada máquina. También se puede incluir información para catalogar el laboratorio como su autor, una sinopsis, versión, etc. En nuestro caso, el fichero lab.conf será el siguiente:

dante@Hades:~/netkit_labs/lab_sniffing_sw$ cat lab.conf LAB_DESCRIPTION="Laboratorio para simular un ataque de ARP-Spoofing" LAB_VERSION="0.1" LAB_AUTHOR="Dante" LAB_EMAIL="dante.signal31@gmail.com" LAB_WEB="http://danteslab.blogspot.com/" PC-Alice[mem]=100 PC-Sniffer[mem]=100 Router[mem]=100 Switch[mem]=100 PC-Alice[0]=CD-A Switch[1]=CD-A PC-Sniffer[0]=CD-C Switch[2]=CD-C Router[1]=CD-B Switch[0]=CD-B Router[0]=tap,192.168.10.1,192.168.10.2

La última línea configura el interfaz eth0 del Router como tap. Eso equivale a establecer una línea punto a punto entre la máquina virtual Router (192.168.10.2) y nuestro PC real (192.168.10.1 ) a través de la cual Router podrá salir a Internet utilizando nuestro PC como puerta de enlace. De hecho si cuando arranquemos el laboratorio hacemos un ifconfig en nuestro PC veremos que se ha creado un interfaz llamado nk_tap_root con la IP 192.168.10.1. En cuanto a la ruta por defecto, Netkit se encarga de meter una ruta estática en Router apuntando a la 192.168.10.1. Todo esto permite que el Router salga a Internet normalmente pero si además queremos que salgan el resto de los PCs de la red virtual (utilizando a Router y a nuestro PC como saltos hacia Internet) tendremos que añadir una ruta en nuestro PC real hacia la red virtual:


dante@Hades:~$ sudo route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.10.2

Ahora, dentro de la carpeta del laboratorio crearemos un subdirectorio por cada máquina virtual que vaya a utilizarse.

dante@Hades:~/netkit_labs$ mkdir lab_sniffing_sw dante@Hades:~/netkit_labs$ cd lab_sniffing_sw/ dante@Hades:~/netkit_labs/lab_sniffing_sw$ mkdir Routerdante@Hades:~/netkit_labs/lab_sniffing_sw$ mkdir Switch dante@Hades:~/netkit_labs/lab_sniffing_sw$ mkdir PC-Alice dante@Hades:~/netkit_labs/lab_sniffing_sw$ mkdir PC-Snifferdante@Hades:~/netkit_labs/lab_sniffing_sw$ ls PC-Alice PC-Sniffer Router dante@Hades:~/netkit_labs/lab_sniffing_sw$

Los subdirectorios de las máquinas virtuales pueden quedarse vacíos o utilizarse para depositar ficheros que luego aparecerían en la máquina virtual. Por ejemplo si quisieramos que PC-Alice contase con el script X en /usr/bin, crearíamos la carpeta "/netkit_labs/lab_sniffing_sw/PC-Alice/usr/bin" y depositaríamos ahí una copia del script. En nuestro caso lo que haremos será poner en el directorio /etc/ de cada equipo los ficheros necesarios para que se configuren los recursos de red de manera adecuada.
Para el caso de Alice, quedará de la siguiente manera:

dante@Hades:~/netkit_labs/lab_sniffing_sw$ cat ./PC-Alice/etc/network/interfaces auto lo eth0 iface lo inet loopback address 127.0.0.1 netmask 255.0.0.0 iface eth0 inet static address 192.168.0.2 netmask 255.255.255.0 gateway 192.168.0.1


El PC-Sniffer tendrá la siguiente configuración de red:


dante@Hades:~/netkit_labs/lab_sniffing_sw $ cat ./PC-Sniffer/etc/network/interfaces auto lo eth0 iface lo inet loopback address 127.0.0.1 netmask 255.0.0.0 iface eth0 inet static address 192.168.0.3 netmask 255.255.255.0 gateway 192.168.0.1

El Router tendrá la siguiente configuración de red:


dante@Hades:~/netkit_labs/lab_sniffing_sw $cat ./Router/etc/network/interfaces auto lo eth1 iface lo inet loopback address 127.0.0.1 netmask 255.0.0.0 iface eth1 inet static address 192.168.0.1 netmask 255.255.255.0

Además, si queremos que nuestras máquinas virtuales puedan hacer resoluciones DNS (indispensable si queremos instalar paquetes con apt o navegar con lynx), tendremos que incluir un fichero /etc/resolv.conf en cada una de las máquinas virtuales igual que hicimo s con /etc/network/interfaces. Una copia del contenido del fichero /etc /resolv.conf de nuestro PC real valdrá.

Por último queda configurar el switch y decidir qué servicios se van a arrancar en cada máquina virtual. Precisamente para eso, Netkit permite definir qué comandos se ejecutarán durante el arranque y el apagado de las máquinas virtuales mediante los scripts startup y shutdown respectivamente. Para nuestro laboratorio crearemos los siguie
ntes scripts:

dante@Hades:~/netkit_labs/lab_sniffing_sw$ cat Switch.startup ifconfig eth0 up ifconfig eth1 up ifconfig eth2 up brctl addbr br0 brctl addif br0 eth0 brctl addif br0 eth1 brctl addif br0 eth2 brctl stp br0 on ifconfig br0 up

Este script configura un bridge tras el arranque de la máquina Switch incorporando a dicho bridge los puertos eth0, eth1 y eth2 y activando también el
spanning-tree (innecesario en este caso porque sólo hay un switch pero se trata de una costumbre que deberíamos adquirir).

Los comandos de startup del resto de las máquinas son más sencillos ya que lo único que hacen es iniciar el servicio de red:


dante@Hades:~/netkit_labs/lab_sniffing_sw$ cat Router.startup /etc/init.d/networking start dante@Hades:~/netkit_labs/lab_sniffing_sw$ cat PC-Alice.startup /etc/init.d/networking start dante@Hades:~/netkit_labs/lab_sniffing_sw $ cat PC-Sniffer.startup /etc/init.d/networking start

Este ejemplo es muy sencillo, pero gracias a estos scripts podemos hacer que un laboratorio se configure sólo sin que el usuario final que lo pruebe tenga que molestarse en tocar o instalar nada. De hecho lo más cómodo es configurar las direcciones IP de los interfaces y las rutas a través de estos scripts en vez de copiando los ficheros de configuración en la carpeta /etc de cada máquina, pero dar ese rodeo me ha permitido explicar la posibilidad de introducir archivos en el árbol de directorios de las máquinas virtuales.

Ahora, por fin, ha llegado el momento de arrancar nuestro laboratorio. Los laboratorios se arrancan con la orden lstart y se paran con lhalt. Veamos lo que pasa en nuestro caso:
dante@Hades:~/netkit_labs/lab_sniffing_sw$ sudo lstart [sudo] password for dante: 033[1m======================== Starting lab ===========================033[0m Lab directory: /home/dante/netkit_labs/lab_sn iffing_sw Version: 0.1 Author: Dante Email: dante.signal31@gmail.com Web: http://danteslab.blogspot.com/ Description: Laboratorio para simular un ataque de ARP-Spoofing 033[1m=================================================================033[0m 033[1mStarting "PC-Alice" with options "-q --mem=100 --eth0 CD-A --hostlab=/home/dante/netkit_labs/lab_sniffing_sw --hostwd=/ho me/dante/netkit_labs/lab_sniffing_sw"... 033[0m 033[1mStarting "PC-Sniffer" with options "-q --mem=100 --eth0 CD-C --hostlab=/home/dante/netkit_labs/lab_sniffing_sw --hostwd=/hom e/dante/netkit_labs/lab_sniffing_sw"... 033[0m 033[1mStarting "Router" with options "-q --mem=100 --eth1 CD-B --eth0 tap,192.168.10.1,192.168.10.2 --hostlab=/home/dante/netkit_labs/lab_sniffing_sw --hostwd=/home/dante/netkit_labs/lab_sniffing_sw"... 033[0m 033[1mStarting "Switch" with options "-q --mem=100 --eth1 CD-A --eth2 CD-C --eth0 CD-B --hostlab=/home/dante/netkit_labs/lab_sniffing_sw --hostwd=/home/dante/netkit_labs/lab_sniffing_sw"... 033[0m 033[1mThe lab has been started.033[0m 033[1m===================== ============================================033[0m dante@Hades:~/netkit_labs/lab_sniffing_sw$

Para comprobar que la red resultante funciona podemos probar a navegar por Internet con el lynx desde PC-Alice:




Ahora que hemos comprobado que nuestra red funciona vamos darle un uso a nuestro laboratorio realizando el experimento que mencionábamos al comienzo del artículo: un ataque de ARP-Spoofing contra Alice desde PC-Sniffer.

Como se puede ver en la foto anterior
, PC-Sniffer tiene activado un tcpdump, pero sólo ve el tráfico de spanning tree (STP) emitido por el switch. A diferencia de la red del artículo anterior en la que se simulaba un hub, en esta el switch no replica el tráfico por todos sus puertos sino sólo en el puerto al que se conecta el destinatario de los datos.

Para espiar el tráfico habrá que situarse entre Router y PC-Alice haciendoles creer que hablan entre sí cuando en realidad su interlocutor es PC-Sniffer.


Usaremos la herramienta Ettercap, que ya viene instalada por defecto en el Debian que trae Netkit (si no, podríamos haberla instalado con un simple "#aptitude install ettercap", como haríamos en nuestro PC real). Ettercap permite hacer intercepciones en redes conmutadas. En realidad es una pequeña maravilla que merece un artículo para ella sola. Aquí usaremos Ettercap desde el PC-Sniffer para espiar el tráfico web de Alice. Para activar un ataque de ARP-Spoofing (también llamado ARP-Poisoning) con Ettercap la orden sería:

PC-Sniffer# ettercap -M arp:remote -T /192.168.0.1/ /192.168.0.2/

Inmediatamente la pantalla de PC-Sniffer empieza a sacar el contenido de los datos que PC-Alice intercambia con su puerta de enlace, Router, mientras navega por Internet:




Para parar el laboratorio sólo tenemos que hacer "sudo lhalt" desde el directorio raíz del laboratorio (donde lanzamos antes el lstart). Si quisieramos relanzar el laboratorio debemos tener en cuenta que hay que volver a meter la ruta hacia la red virtual ya que la que dimos de alta antes desapareció cuando lhalt desactivó el interfaz tap. Por otro lado, el lstart creo ficheros .disk en la carpeta del laboratorio para que no se pierdan los programas que hayamos instalado en las máquinas virtuales o cualquier otra modificación que hayamos hecho, eso quiere decir que las carpetas donde pusimos los ficheros de configuración dejan de tener efecto por lo que si queremos poner nuevos ficheros allí primero tendremos que borrar los ficheros .disk y hacer un lstart para que Netkit vuelva a leer esas carpetas. Existe otra opción más útil para transferir ficheros a las máquinas virtuales y es mediante la carpeta /hosthome que hay en todas las máquinas virtuales y que monta el home del usuario que lanzó el Netkit.

En otro artículo explicaré qué es lo que hace Ettercap entre bastidores y cómo funcionan esta y otras técnicas de interceptación. Este artículo lo que ha servido es para demostrar la utilidad de Netkit a la hora de simular redes complejas con las que hacer experimentos de seguridad informática con un ahorro considerable tanto en esfuerzo, como en dinero y espacio. Supone también una ayuda valiosísima para los que pretendemos divulgar el arte de la seguridad informática, ya que nos permite ofrecer a nuestros lectores laboratorios preconfigurados que les permitirán concentrarse exclusivamente en las técnicas explicadas sin que tengan que perder el tiempo montando una red de prueba propia. Por ello, mis artículos futuros incluirán enlaces a laboratorios de Netkit especialmente diseñados para probar de una manera rápida y sencilla lo que se explique en ellos.