Hasta ahora, hemos estudiado y trabajado con herramientas que, gracias a sus interfaces gráficas, nos ayudaron a entender mejor sus resultados y forma de uso. En otros casos, como Tshark, Windump o Tcpdump, si bien no poseen GUI alguno, no son herramientas complicadas de usar.
En esta serie de artículos (ya disponible la Parte 2: Scapy. Manipulación avanzada e interactiva de paquetes. Parte 2 ), comenzamos a estudiar una herramienta (Win32 / Linux) muy poderosa: Scapy. Scapy es una utilidad escrita en Python que nos servirá para crear y manipular paquetes, escanear, funciones de sniffer, creación de gráficas 2D / 3D / Pdf, passive OS fingerprinting, tracers gráficos, ……. Además, podemos crear utilidadades escritas en Python usando scapy. Posee funciones similares a ttlscan, nmap, hping, queso, p0f, xprobe, arping, arp-sk, ARPSpoof, firewalk, etc. Todo mediante línea de comandos, es integrable en Python, programable, versátil y flexible. Obtendremos solo los datos que queramos y todo lo complejo que deseemos.
En esta primera parte haremos una referencia a su instalación en Windows, comenzaremos a trabajar extrayendo datos de los paquetes, captura de paquetes, lectura de archivos pcap, etc.
Instalando Scapy en Windows.
Scapy es un script de Python, por tanto, lo primero que vamos a instalar es Python 2.5. Una vez instalado, los pasos a seguir, y en este mismo orden, son los siguientes:
- Versión windows de Scapy. Lo descargamos y ubicamos en C:\Python25\Lib\site-packages\scapy.py
- Pywin32
- WinPcap 4.1.1
- Pypcap
- Libdnet
- Pyreadline
La instalación de cada uno de los paquetes no tiene complicación alguna.
Añadimos en variables del sistemas las siguientes rutas PATH:
- C:\Python25
- C:\Python25\Scripts
- Si no lo tenemos añadimos C:\Archivos de programa\WinPcap
De forma opcional, tenemos una serie de paquetes para añadir funcionalidades a Scapy. Instalamos dichos paquetes que nos servirán más adelante.
Sistema de Plotting.
Descargamos e instalamos:
- Gnuplot. Es un .zip, descomprimimos e ubicamos en c:\gnuplot
- Numeric Es un .exe, lo ejecutamos e instalamos.
- Gnuplot-py Es un .zip, descomprimimos y ubicamos en una carpeta temporal. Ejecutamos dentro de dicha carpeta: python setup.py install
Añadimos en variables del sistemas las siguientes rutas PATH:
- C:\gnuplo\bin
Sistema gráfico 2D.
Descargamos e instalamos:
- Pyx Es un .tar.gx, descomprimimos y ubicamos en una carpeta temporal. Ejecutamos dentro de dicha carpeta: python setup.py install
- MikTex Es un .exe. Lo ejecutamos e instalamos en una carpeta cyto nombre no tenga espacios: C:\MiKTeX2.8
Añadimos en variables del sistemas las siguientes rutas PATH:
- C:\Archivos de programa\MiKTeX2.8\miktex\bin
Sistema gráfico. Conversations.
- Graphviz Es un .exe. Lo ejecutamos e instalamos. Opcional puesto que, de momento, no lo usaremos.
Añadimos en variables del sistemas las siguientes rutas PATH:
- C:\Archivos de programa\Graphviz2.24\bin Por defecto se debe crear en la instalación.
Sistema gráfico 3D.
- VPython Es un .exe. Lo ejecutamos e instalamos.
Creo que no se me olvida nada, así que…
Ejecutando Scapy. Primeros pasos.
NOTA: En esta primera parte estudiaremos scapy de forma básica. Ejemplos faciles de comprender para, en una segunda parte y quizá una tercera, usar scapy con toda su funcionalidad y potencia.
Nos situamos en C:\Python25\Lib\site-packages\scapy.py y ejecutamos de la forma:
C:\Python25\Lib\site-packages>python scapy.py
scapy.py:3671: Warning: ‘with’ will become a reserved keyword in Python 2.6
scapy.py:3673: Warning: ‘with’ will become a reserved keyword in Python 2.6
INFO: Can’t find Crypto python lib. Won’t be able to decrypt WEP
Welcome to Scapy (1.2.0.2-win)
>>>
Vemos un par de advertencias e información sobre paquetes no instados que, ahora, no necesitamos.
Seguimos. En scapy tenemos una serie de comandos básicos:
- ls() Lista de protocolos usados
- lsc() Lista de comandos o funciones.
- conf configuración scapy.
- help() Ayuda sobre funciones. Por ejemplo: help(p0f)
- …
También funciones IP(), ICMP(), TCP(), UDP() … que corresponden a los protocolos. Las podemos usar con ls():
>>> ls(IP)
version : BitField = (4)
ihl : BitField = (None)
tos : XByteField = (0)
len : ShortField = (None)
id : ShortField = (1)
flags : FlagsField = (0)
frag : BitField = (0)
ttl : ByteField = (64)
proto : ByteEnumField = (0)
chksum : XShortField = (None)
src : Emph = (None)
dst : Emph = (‘127.0.0.1’)
options : IPoptionsField = (»)
Obtenemos, como veis, los campos de las cabeceras que corresponden a cada protocolo.
>>> ls(TCP)
sport : ShortEnumField = (20)
dport : ShortEnumField = (80)
seq : IntField = (0)
ack : IntField = (0)
dataofs : BitField = (None)
reserved : BitField = (0)
flags : FlagsField = (2)
window : ShortField = (8192)
chksum : XShortField = (None)
urgptr : ShortField = (0)
options : TCPOptionsField = ({})
Vamos a jugar un poco con IP(). Usaremos la función str() propia de Python que transforma un dato en una cadena:
Podemos crear un paquete de foma básica usando los campos de la cabecera IP ya aprendidos:

Con a.show() mostramos el contenido de la cabecera del datagrama IP.
Seguimos añadiendo datos y encapsulamos TCP en nuestro paquete:
Vemos que consturimos un paquete, capa por capa y que los datos de campos que no introducimos, se rellenan por defecto.
Seguimos manipulando, complicando y en este caso seguimos añadiendo datos de campos que nos interesan. Añadimos los Flags TCP SYN+FIN….:
Seguimos, y a ver si alguien se da cuenta de un detalle:
Convertimos en hexadecimal:

Con scapy, podemos enviar los paquetes contruidos por nosotros con la función send(). Enviamos el paquete que ya hemos construidos y almacenado en la variable b. Primero un paquete, luego diez más:
>>> send(b)
.
Sent 1 packets.
>>> send([b]*10)
……….
Sent 10 packets.
>>>
Construimos un paquete ICMP y enviamos con sr1:
Si haceis un a.show, se observa el campo ICMP type, que se trata de un echo request, que, además, como veis en la captura obtiene respuesta (Received 4 packets).
Podríamos, entonces, usando la misma técnica, realizar un SYN Scan de la forma:
Complicamos un poco el asunto, usamos otros campos y funciones para profundizamos el el estudio de scapy.
Ahora realizaremos otro SYN SCAN, pero:
- Puertos de origen aleatorios,
- Una lista de puertos de destino,
- Visualizaremos para comprobar, los paquetes enviados:
Bien, dejamos aquí, de momento, la creación, manipulado y envío de paquetes. Volveremos en la segunda parte. Vamos a estudiar ahora otra funcionalidad de scapy.
Scapy como sniffer.
La función sniffer de scapy es…. sniff(). ¿ Sencillo verdad ?. Podemos añadir una serie de argumentos. Como siempre, con un ejemplo práctico:
Vamos a capturar 20 paquetes y…..:
Hemos asignado la función sniff() a una variable. Vemos el resultado de la captura por protocolos y visualizamos el paquete número 5.
Podemos, como en otros capturadores estudiados, asignar filtros tipo libpcap, visualizaremos los paquetes capturados:
Podemos extraer de una captura, independientemente del filtro, las cabeceras que nos interesen. Por ejemlo, capturamos 50 paquetes y visualizamos la cabecera TCP del paquete 20:
>>> b=sniff(count=50)
Seguimos complicándonos con scapy.
La función pdfdump()
Como tengo ya los ojos medio chiguatos, necesito ver un paquete de forma más limpia y gráfica:
Usamos la captura sniff() anterior y:
>>> ver=b[10]
>>> ver.pdfdump()
.. se nos abrirá el lector PDF con el siguiente contenido:
Muy interesante. Esta función pdfdump() nos permite un estudio más detallado y cómodo de un determinado paquete.
Formateando los datos
Con sniff() podemos formatear la salida de los datos según nuestras necesitades: de muchas formas. Entre ellas con sprintf() y lambda.
- sprinft() Para dar formato a una cadena vlcándola a una variable. No es propia de Python.
- lambda El operador lambda de Python, sirve para crear funciones anónimas en línea. Al ser funciones anónimas, es decir, sin nombre, estas no podrán ser referenciadas más tarde.
Las funciones lambda se construyen mediante el operador lambda, los parámetros de la función separados por comas , dos puntos (:) y el código de la función.
Vamos a introducir también iface que sirve para indicar el dispositivo de red a usar en nuestra captura.
Un ejemplo muy sencillo para comenzar a entender estos conceptos. Usaremos con lambda la función summary() que ya lo hemos visto en la captura anterior con nsummary(), la diferencia entre ambos es que con nsummary() se nos devuelve la captura con la numeración de paquetes y summary() sin ella:
Probad lo siguiente:
>>> sniff(count=10, prn=lambda x: x.show())
Interesante ¿ verdad ?.
Un ejemplo más complicado. Añadimos \ para escribir en varias líneas. Observad como formateamos para sacar solo la información que nos interesa. Es decir:
- %IP.src% IP origen
- %IP.dst% IP destino
- %IP.proto% Protocolo IP.
Añadimos ahora un filtro y queremos obtener también los flags de TCP con %TCP.flags%:
De momento solo llevamos el 1% de lo que se puede hacer con scapy.
Observad en esta otra captura los datos que obtenemos:
>>> a=sniff(filter=»src host http://www.google.es and port 80″, prn=lambda x: x.sprintf
(«%SYSTEM.time% – \
… id=%IP.id%»))
11:30:21.865892 – id=605
11:30:22.050796 – id=606
11:30:22.115925 – id=609
11:30:22.116034 – id=610
11:30:22.116879 – id=611
11:30:22.475155 – id=616
La función plot()
Realizamos una captura de 300 paquetes y…:
>>> a=sniff(count=300)
>>> a.plot(lambda x:len(x))
Se nos abrirá una ventana con el siguiente contenido. Ya estudiaremos más adelante como interpretar los datos:
Traceroute. traceroute() y la función trace3D()
Como siempre, la mejor manera, un ejemplo:
a continuación…:
>>>a.trace3D()
y se nos abrirá una ventana con el siguiente contenido:
Si «picamos» en la bola verde, veremos las IPs, si pulsamos Control, veremos los puertos abiertos.
La función traceroute() la veremos más adelante de forma más avanzada.
Leyendo archivos .pcap de otros: Wireshark, Tshark, Windump / TcpDump.
Usando la función rdpcap() podemos leer archivos .pcap:
—————————————————
Para no complicar mucho la cosa, es suficiente para esta primera parte. Veremos el formateo de los datos de forma más avanzada, sniff, contrucción de paquetes, fingerprinting, scripts, etc. en los siguientes capítulos.
Scaperl: Scapy in Perl.
Habrá que probarlo.
Hola Alfon !!!
Muy bueno tu tutorial, espero ansioso las otras partes.
Yo estoy interesado en recoger los paquetes de la capa de aplicaion ordenados … y veo que esto con sniff y controlando que el paqute tiene RAW, esta solucionado.
Ahora bien, como controlo ese RAW, vamos como lo filtro, para sacar la capa de aplicaion de las sesiones ordenadas???
Ahhi otra duda, a veces usas _, por ejemplo en IP(_), que es o que vale _???
Gracias por tu ayuda y me reitero muy gran post.
Sencillamente impresionante -;)
Gracias a todos por vuestros comentarios. Yiban: _ en python se refiere al último resultado. Respecto a RAW trataré de incluirlo en las siguientes partes del artículo. Podrías poner aquí un ejemplo de como «sulucionas» el tema de los RAW packets y a partir de ahí….
Dabo, Gracias… aunque como dice shin shan.. no es pa tanto.
Saludos,
muy buen articulo muchisimas gracias por el aporte
Gracias neotrons.
Tengo un problema, no entiendo la parte que dice que nos situamos en scapy.py para ejecutarlo. Desde donde y como hago eso, ya lo intente buscar pero no encontre nada de ayuda. Gracias
Su huebada no se descarga
Pingback: Seguridad Python (manipulación de paquetes) | darkuskyo.net
Disculpa, tu artículo es algo antigüo, sin embargo es muy muy bueno, pero tengo un problema, no sé cómo descargar scapy para windows, podrías ayudarme con eso?.. gracias por tu atención