Pregunta

¿Cuál es la mejor manera de detectar paquetes de red con Python?

He escuchado en varios lugares que el mejor módulo para esto es un módulo llamado Scapy, desafortunadamente, hace que python.exe se bloquee en mi sistema. Supongo que es solo un problema con la forma en que lo instalé, excepto que muchas otras personas me han dicho que no funciona particularmente bien en Windows. (Si alguien está interesado, estoy ejecutando Windows Vista, lo que podría afectar las cosas).

¿Alguien sabe de una mejor solución?

UPD:

Después de leer la respuesta que me decía que instalara PyPcap, me equivoqué un poco y descubrí que Scapy, que había intentado usar, también me decía que instalara PyPcap, excepto que es una versión modificada para su uso . Fue este PyPcap modificado el que estaba causando el problema, aparentemente, ya que el ejemplo en la respuesta también causó un bloqueo.

Instalé la versión original de PyPcap (del sitio de Google), y Scapy comenzó a funcionar bien (no probé muchas cosas, pero al menos no se bloqueó tan pronto como comencé a oler). Envié un nuevo ticket de defecto a los desarrolladores de Scapy: http://trac.secdev.org/scapy/ ticket / 166 , espero que puedan hacer algo con él.

De todos modos, solo pensé en hacérselo saber.

¿Fue útil?

Solución

Uso de pypcap :

import dpkt, pcap
pc = pcap.pcap()     # construct pcap object
pc.setfilter('icmp') # filter out unwanted packets
for timestamp, packet in pc:
    print dpkt.ethernet.Ethernet(packet)

muestra de salida:

Ethernet(src='\x00\x03G\xb2M\xe4', dst='\x00\x03G\x06h\x18', data=IP(src='\n\x00\x01\x1c',
dst='\n\x00\x01\x10', sum=39799, len=60, p=1, ttl=128, id=35102, data=ICMP(sum=24667,
type=8, data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))

Ethernet(src='\x00\x03G\x06h\x18', dst='\x00\x03G\xb2M\xe4', data=IP(src='\n\x00\x01\x10',
dst='\n\x00\x01\x1c', sum=43697, len=60, p=1, ttl=255, id=64227, data=ICMP(sum=26715,
data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))

Otros consejos

El camino difícil

Puede rastrear todos los paquetes IP utilizando un socket sin procesar.
El socket sin formato es un socket que envía y recibe datos en binario.
El binario en python se representa en una cadena que tiene este aspecto \ x00 \ xff ... cada \ x .. es un byte.
Para leer un paquete IP, debe analizar el paquete recibido en binario de acuerdo con el protocolo IP.

Esta es una imagen del formato del protocolo IP con el tamaño en bits de cada encabezado.

 Formato de protocolo IP

Este tutorial puede ayudarlo a comprender el proceso de comprender un paquete sin procesar y dividirlo en encabezados: http://www.binarytides.com/python-packet-sniffer-code-linux/

La manera fácil

Otro método para rastrear paquetes IP muy fácilmente es usar el módulo scapy.

from scapy.all import *
sniff(filter="ip", prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}"))

Este código imprimirá para usted la IP de origen y la IP de destino para cada paquete de IP. Puede hacer mucho más con scapy leyendo su documentación aquí: http: // www .secdev.org / projects / scapy / doc / use.html

Depende del objetivo que esté tratando de lograr, pero si necesita construir un proyecto, el que tiene como características es rastrear paquetes IP, entonces recomiendo usar scapy para scripts más estables.

Utilice python-libpcap .

import pcap

p = pcap.pcapObject()
dev = pcap.lookupdev()
p.open_live(dev, 1600, 0, 100)
#p.setnonblock(1)
try:
    for pktlen, data, timestamp in p:
        print "[%s] Got data: %s" % (time.strftime('%H:%M', 
                                                   time.localtime(timestamp)),
                                     data)
except KeyboardInterrupt:
    print '%s' % sys.exc_type
    print 'shutting down'
    print ('%d packets received, %d packets dropped'
           ' %d packets dropped by interface') % p.stats()

puede usar sockets sin procesar, con la dirección IP de su interfaz (en modo administrador),

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_IP)
s.bind(("YOUR_INTERFACE_IP",0))
s.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
s.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
while True:
   data = s.recvfrom(10000)
   print data

Otra opción es pypcap .

Para analizar los resultados, Construir es muy hábil.

Si da miedo, intente el siguiente método. (Funciona en Windows 10)

# -*- coding: utf-8 -*-

# pip install scapy

"""
[{'name': 'Intel(R) 82574L Gigabit Network Connection',
  'win_index': '4',
  'description': 'Ethernet0',
  'guid': '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}',
  'mac': '00:0C:29:5C:EE:6D',
  'netid': 'Ethernet0'}]
"""

from pprint import pprint
from scapy.arch.windows import get_windows_if_list
from scapy.all import *


# disable verbose mode
conf.verb = 0


def parse_packet(packet):
    """sniff callback function.
    """
    if packet and packet.haslayer('UDP'):
        udp = packet.getlayer('UDP')
        udp.show()


def udp_sniffer():
    """start a sniffer.
    """
    interfaces = get_windows_if_list()
    pprint(interfaces)

    print('\n[*] start udp sniffer')
    sniff(
        filter="udp port 53",
        iface=r'Intel(R) 82574L Gigabit Network Connection', prn=parse_packet
    )


if __name__ == '__main__':
    udp_sniffer()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top