Question

Quel est le meilleur moyen de détecter les paquets réseau en utilisant Python?

J'ai appris de plusieurs endroits que le meilleur module pour cela est un module appelé Scapy. Malheureusement, python.exe se bloque sur mon système. Je suppose que c'est simplement un problème avec la façon dont je l'ai installé, sauf que beaucoup d'autres personnes m'ont dit que cela ne fonctionnait pas particulièrement bien sous Windows. (Si quelqu'un est intéressé, j'utilise Windows Vista, ce qui pourrait avoir des conséquences.)

Quelqu'un connaît-il une meilleure solution?

UPD:

Après avoir lu la réponse me disant d’installer PyPcap, j’ai un peu mal compris et découvert que Scapy, que j’avais essayé d’utiliser, me disait également d’installer PyPcap, sauf qu’il s’agissait d’une version modifiée. . C'est apparemment PyPcap modifié qui était à l'origine du problème, car l'exemple de la réponse provoquait également un blocage.

J'ai installé la version originale de PyPcap (à partir du site de Google) et Scapy a commencé à bien fonctionner (je n'ai pas essayé beaucoup de choses, mais au moins, cela ne s'est pas bloqué dès que j'ai commencé à renifler). J'ai envoyé un nouveau ticket d'incident aux développeurs Scapy: http://trac.secdev.org/scapy/ ticket / 166 , espérons qu'ils puissent faire quelque chose avec.

Quoi qu'il en soit, je pensais que je vous le ferais savoir.

Était-ce utile?

La solution

Utilisation 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)

exemple de sortie:

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'))))

Autres conseils

À la dure

Vous pouvez détecter tous les paquets IP à l'aide d'un socket brut.
Le socket Raw est un socket qui envoie et reçoit les données en binaire.
Le binaire en python est représenté dans une chaîne qui ressemble à ceci \ x00 \ xff ... chaque \ x .. est un octet.
Pour lire un paquet IP, vous devez analyser le paquet reçu en binaire conformément au protocole IP.

Ceci est une image du format du protocole IP avec la taille en bits de chaque en-tête.

 format du protocole IP

Ce tutoriel peut vous aider à comprendre le processus de compréhension d’un paquet brut et de le fractionner en en-têtes: http://www.binarytides.com/python-packet-sniffer-code-linux/

La solution de facilité

Une autre méthode pour détecter très facilement les paquets IP consiste à utiliser le module scapy.

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

Ce code imprimera pour vous l'adresse IP source et l'adresse IP de destination pour chaque paquet IP. Vous pouvez faire beaucoup plus avec scapy en lisant sa documentation ici: http: // www .secdev.org / projects / scapy / doc / usage.html

Cela dépend de l’objectif que vous essayez d’atteindre, mais si vous avez besoin de construire un projet qui renifle les paquets IP, je vous recommande d’utiliser scapy pour des scripts plus stables.

Utilisez 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()

vous pouvez utiliser des sockets brutes, avec votre adresse ip d'interface (en mode administrateur),

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

Une autre option est pypcap .

Pour analyser les résultats, Construct est très complexe.

Si vous êtes curé, essayez la méthode suivante. (Cela fonctionne sous 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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top