Scapy fehl zu schnuppern Pakete, wenn mehrere threads verwenden

Werde ich versuchen zu demonstrieren, dass mein problem mit einem vereinfachten Beispiel.

Folgenden ist ein sehr einfaches (single-threaded) - Paket-sniffer (ICMP):

from scapy.all import *

m_iface = "wlan0"
m_dst = "192.168.0.1"

def print_summary(pkt):
  print pkt.summary()

def plain_sniff():
  sniff(iface = m_iface, count = 10, filter = "icmp and src {0}".format(m_dst), prn = print_summary)

Dieser sniffer funktioniert Prima und ich bekomme die Ausgabe:

WARNING: No route found for IPv6 destination :: (no default route?)
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0 / Raw
...

Als Nächstes erstellen Sie einen separaten thread für die sniffing-Pakete und Verwendung einer Queue zu kommunizieren, die erfassten Pakete zwischen den sniffer-Threads und dem Haupt-thread:

from threading import Thread
from Queue import Queue, Empty
from scapy.all import *

m_iface = "wlan0"
m_finished = False
m_dst = "192.168.0.1"

def print_summary(pkt):
  print pkt.summary()

def threaded_sniff_target(q):
  global m_finished
  sniff(iface = m_iface, count = 10, filter = "icmp and src {0}".format(m_dst), prn = lambda x : q.put(x))
  m_finished = True

def threaded_sniff():
  q = Queue()
  sniffer = Thread(target = threaded_sniff_target, args = (q,))
  sniffer.daemon = True
  sniffer.start()
  while (not m_finished):
    try:
      pkt = q.get(timeout = 1)
      print_summary(pkt)
    except Empty:
      pass

Dieser sniffer funktioniert auch einwandfrei und ich bekomme die gleiche Ausgabe wie oben. Allerdings, wenn ich änderungen an der Haupt-thread nur ein bisschen, so dass es verwendet die send() Funktion zwischen liest aus der Warteschlange wie folgt:

def threaded_sniff_with_send():
  q = Queue()
  sniffer = Thread(target = threaded_sniff_target, args = (q,))
  sniffer.daemon = True
  sniffer.start()
  while (not m_finished):
    send(IP(dst = m_dst) / ICMP()) # Here
    try:
      pkt = q.get(timeout = 1)
      print_summary(pkt)
    except Empty:
      pass

Dann bekomme ich die folgende bizarre Ausgang (der filter scheint nicht zu funktionieren):

WARNING: No route found for IPv6 destination :: (no default route?)
Sent 1 packets.
Ether / ARP who has 192.168.0.1 says 192.168.0.9
Sent 1 packets.
Ether / ARP is at a0:21:b7:1a:7a:db says 192.168.0.1
Sent 1 packets.
Ether / IP / ICMP 192.168.0.9 > 192.168.0.1 echo-request 0
Sent 1 packets.
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0
...

Dem Skript für die drei Sniffer heruntergeladen werden kann hier.

Meine aktuelle Systemkonfiguration ist wie folgt:

Python: 2.7.3
Scapy: 2.2.0
OS: Fedora 18

Interessanterweise alle drei Sniffer funktioniert auf meinem älteren Rechner:

Python: 2.6.4
Scapy: 2.0.0.10 (beta)
OS: Fedora 13

Zuerst dachte ich, es könnte die Scapy /Python-Versionen. Aber selbst wenn ich die installiert, die genau die gleiche Version auf meinen neuen Rechner, das Verhalten blieb.

Ich bin mir nicht ganz sicher, ob dies ist eine Frage, die geeignet für SO (kann ein bug-report zu Scapy?). Bitte entschuldigen Sie mich in diesem Fall.

  • Sieht aus wie ein bekannter bug : trac.secdev.org/scapy/ticket/747
  • Das Problem, das ich bin vor ist in Bezug auf multi-threading. Der code funktioniert gut, ohne threading.
  • Dies geschieht nicht, um etwas zu tun mit der Tatsache, dass die Netzwerk-Schnittstelle endet in "Premiscious-Modus" und nur eine Quelle binden können, um die Schnittstelle? Wenn nicht, haben Sie versucht, mit Hilfe der python - threading Bibliothek statt Warteschlange? ich bin mir nicht ganz sicher, wie die queue-system funktioniert, aber mit threading erhalten Sie mehr Kontrolle über das, was es tut, wenn mindestens, und Sie können, basteln Sie sich ein wenig.
  • Habe versucht, deaktivieren Sie den promiscuous-Modus, wie Sie vorgeschlagen, bekam aber das gleiche Ergebnis. Ich bin bereits über threading und queue Module, meinst du multiprocessing Modul (und den damit verbundenen queue) statt? Ich habe versucht, dass auch kein Glück. Danke.
  • und ich denke, wenn man einen sleep(30) vor dem ausführen der zweite thread, wenn mit threading es funktioniert?
  • Ich habe eine time.sleep(1) direkt nach dem Start der sniffer-thread (so, verzögerte sich der Haupt-thread ein wenig), und es funktioniert!!! Meine Vermutung ist, dass es eine Ressource überschneidungen zwischen Scapy ist sniff() und send() Funktionen, die nicht thread-sicher, und wenn wir die Verzögerung der Haupt-thread, dieses problem geht Weg. Bitte artikulieren, dies alles in eine Antwort und ich werde vergeben Sie die Punkte. Prost!!!
  • Ich hatte das gleiche problem. Ich habe nicht erhalten alle Pakete, die ohne Verzögerung zwischen dem starten sniffer und senden das Paket. Das problem wurde gelöst, nach Zugabe von 0,1 s Verzögerung. Aber neues problem erschien nach dem Zufallsprinzip nach dem ausführen meines scripts mehrmals. Erhielt ich Pakete, die nicht, die den Filterkriterien entsprechen. Hinzufügen 2s Verzögerung das problem behoben!!! Sicherlich ist dies ein bug in Scapy. Aber danke für das teilen deiner Lösung.

Schreibe einen Kommentar