Categorías
Hacking Networking Programacion

Manipulación de Paquetes utilizando SCAPY – Funciones en Scapy y tratamiento de paquetes – Parte III

Seguramente es una de las partes más entretenidas y útiles en Scapy, se trata la lectura de ficheros de captura y en el envío de paquetes creados desde Scapy, para esto, existen algunas funciones que consiguen dichos objetivos, en primer lugar la función rdpcap permite leer ficheros de captura existentes y volcar los paquetes en una variable, para que posteriormente esta pueda ser tratada con las mismas funciones disponibles para el tratamiento de paquetes. Su uso es muy simple:

>>> readed=rdpcap(«/home/jdaanial/Escritorio/pcap_captured.cap»)>>> readed<pcap_captured.cap: TCP:261 UDP:28 ICMP:0 Other:0>

Estos paquetes se encuentran ahora almacenados en el array readed y pueden ser accedidos directamente utilizando su correspondiente posición

>>>readed[30]<Ether dst=52:54:00:12:35:02 src=08:00:27:40:6a:ff type=0x800 |<IP version=4L ihl=5L tos=0x0 len=62 id=25784 flags=DF frag=0L ttl=64 proto=udp chksum=0x5fb1 src=10.0.2.15 dst=10.50.96.5 options=[] |<UDP sport=55982 dport=domain len=42 chksum=0x7681 |<DNS id=43114 qr=0L opcode=QUERY aa=0L tc=0L rd=1L ra=0L z=0L rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR qname=’proxy.organization.es.’ qtype=A qclass=IN |> an=None ns=None ar=None |>>>>

Estos paquetes pueden ser manipulados del mismo modo que se ha indicando anteriormente, lo que evidentemente permite que puedan ser modificados y posteriormente reinyectados en la red con bastante facilidad (de hecho, es algo que hacen con bastante frecuencia herramientas tales como aircrack-ng para redes wireless, aunque no se encuentre escrita en lenguaje python).

Por otro lado, con Scapy existen una serie de funciones que permiten el envío de paquetes de varias formas, en concreto se cuenta con las funciones send y sendp las cuales, en esencia hacen lo mismo, pero la diferencia esta en que la función send trabaja sobre la capa 3 es decir al nivel de red en el modelo TCP/IP, donde se manejan protocolos tales como ARP, IP, ICMP, etc. Por esta razón con el uso de la función send no es necesario preocuparse por detalles a nivel de la capa de enlace de datos (capa 2), sin embargo, el uso de la función sendp trabaja sobre la capa 2 es decir a nivel de direccionamiento físico (MAC, LLC, etc.) por este motivo, cuando se utiliza esta función es necesario ser cuidadoso en seleccionar la interfaz de red adecuada y el correcto protocolo de enlace. En realidad, como puede asumirse de lo anterior, las funciones sendp y send solamente se diferencian en la capa del modelo TCP/IP sobre el que trabajan. Probablemente la siguiente imagen ya sea conocida por el lector y conozca en profundidad las capas que conforman el modelo OSI y su relación con el modelo TCP/IP, pero será útil para recordar y/o afianzar conocimientos

 

Por ejemplo, para enviar un simple paquete ICMP “Echo Reply” basta con ejecutar lo siguiente:

>>> icmpEcho=IP(dst=»192.168.1.1″, src=»192.168.1.33″)/ICMP()>>> send(icmpEcho) .Sent 1 packets.

Como se puede apreciar, es simple establecer un conjunto de paquetes (en este caso solamente 2 paquetes) e inyectarlos en la red utilizando la función “send” de esta forma, todo el proceso de direccionamiento y enrutamiento es automáticamente tratado por Scapy, este mismo conjunto de paquetes utilizando la función sendp tiene una forma distinta.

>>> icmpEcho=IP(dst=»192.168.1.1″, src=»192.168.1.33″)/ICMP()>>> send(icmpEcho) .Sent 1 packets.

Ahora bien, para visualizar correctamente los paquetes que se están enviando por medio de estas funciones se puede utilizar un sniffer como Wireshark o Tcpdump, en esta ocasión se ejecutará desde consola tcpdump a la espera de capturar paquetes SSH.

Enviando paquetes:

>>>sendp(rdpcap(«sniffed.cap»))sendp(rdpcap(«sniffed.cap»))…………………………………………………………………..Sent 77 packets.

Captura Tcpdump

>tcpdump -v tcp port 22 tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes23:02:22.931774 IP (tos 0x10, ttl 64, id 58245, offset 0, flags [DF], proto TCP (6), length 116)localhost.ssh > localhost.47328: Flags [P.], cksum 0xfe68 (incorrect -> 0xdd2e), seq 3071934001:3071934065, ack 4049562588, win 386, options [nop,nop,TS val 313759 ecr 306251], length 6423:02:22.932793 IP (tos 0x10, ttl 64, id 58245, offset 0, flags [DF], proto TCP (6), length 116)

localhost.ssh > localhost.47328: Flags [P.], cksum 0xfe68 (incorrect -> 0xdd2e), seq 0:64, ack 1, win 386, options [nop,nop,TS val 313759 ecr 306251], length 64

Las funciones send y sendp permiten el envío de paquetes, sin embargo no permiten capturar las respuestas que los destinatarios emiten cuando reciben dichos paquetes, en este orden de ideas, se puede utilizar la función sr que permite enviar y recibir respuestas, sin embargo esta función puede retornar un conjunto bastante amplio de resultados, en donde se incluyen los paquetes con las respuestas que ha emitido el destinatario y los paquetes que se han enviado y de los cuales no se ha obtenido ninguna respuesta. Una variante de esta función es sr1 la cual en esencia hace exactamente lo mismo que la función sr (es decir, enviar paquetes y recibir respuestas) pero con la diferencia de que solamente retorna un paquete (o conjunto de paquetes) con las respuestas emitidas por el destinatario(s)

>>> google=sr(IP(dst=»www.google.com»)/TCP(dport=443)) Begin emission:.Finished to send 1 packets…….*Received 8 packets, got 1 answers, remaining 0 packets

>>> google

(<Results: TCP:1 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

>>> google=sr(IP(dst=»www.google.com»)/TCP(dport=80))

Begin emission:

Finished to send 1 packets.

.*

Received 2 packets, got 1 answers, remaining 0 packets

>>> google

(<Results: TCP:1 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

El uso de la función sr ha podido enviar un par de paquetes IP al puerto 80 y 443 respectivamente, cuyos resultado son dos estructuras con los paquetes que han tenido respuestas y aquellos que no han dado ningún resultado. Como se ha indicado anteriormente, la función sr1 funciona básicamente igual, con la diferencia que solamente retorna aquellos paquetes que con respuestas por parte del destinatario

>>>google=sr1(IP(dst=»www.google.com«)/TCP(dport=80,sport=22))Begin emission:……Finished to send 1 packets……*Received 12 packets, got 1 answers, remaining 0 packets

>>> google

<IP version=4L ihl=5L tos=0x0 len=44 id=1793 flags= frag=0L ttl=53 proto=tcp chksum=0xeb8f src=173.194.35.176 dst=192.168.1.33 options=[] |<TCP sport=www dport=ssh seq=808745948 ack=1 dataofs=6L reserved=0L flags=SA window=14300 chksum=0x20a5 urgptr=0 options=[(‘MSS’, 1430)] |<Padding load=’\x00\x00′ |>>>

>>> google.show()

###[ IP ]###

version= 4L

ihl= 5L

tos= 0x0

len= 44

id= 1793

flags=

frag= 0L

ttl= 53

proto= tcp

chksum= 0xeb8f

src= 173.194.35.176

dst= 192.168.1.33

\options\

###[ TCP ]###

sport= www

dport= ssh

seq= 808745948

ack= 1

dataofs= 6L

reserved= 0L

flags= SA

window= 14300

chksum= 0x20a5

urgptr= 0

options= [(‘MSS’, 1430)]

###[ Padding ]###

load= ‘\x00\x00’

Como puede apreciarse, la respuesta tienen un paquete IP con los datos de las direcciones de origen y destino, (entre otras cosas) y un paquete TCP con los puertos de origen y destino, nótese como el orden ha cambiado, es decir, en el paquete de la petición se ha indicado que el puerto de destino era el 80 (HTTP) y el puerto de origen era el 22 (SSH), en la respuesta el puerto de destino es el 22 (es decir, el puerto de origen del emisor) y el puerto de origen es el 80 (es decir, el puerto al que iba dirigido inicialmente el paquete). Otro detalle interesante se encuentra en las flags del paquete, que en este caso tiene el valor de SA lo que significa que se trata de un paquete SYN/ACK.

NOTA: Del mismo modo que la función send las funciones sr y sr1 solamente trabajan con protocolos de la capa 3 (IP, ICMP, ARP, etc.) y así como la función sendp permite trabajar con la capa 2 (ver la imagen sobre las pilas OSI y TCP) también existen las funciones srp y sr1p que permiten trabajar al nivel de la capa de enlace de datos, donde evidentemente se tendrá un poco más de control sobre los paquetes y las opciones de envío de los mismos (establecer direcciones MAC y otros detalles a nivel de datos).

Las funciones en Scapy para el envío y recepción de paquetes son la base del funcionamiento de esta librería y probablemente sin ellas, carecería de sentido (o de utilidad). En la próxima publicación se hablará un poco más sobre estas funciones y otras características de interés contenidas en Scapy.

Por Daniel Echeverri

Formador e investigador en temas relacionados con la seguridad informática y hacking. Es el autor del blog thehackerway.com el cual ha sido el ganador del European Cybersecurity Blogger Awards 2021 en la categoría de “Best Technical Content“.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *