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 mitthreading
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
undqueue
Module, meinst dumultiprocessing
Modul (und den damit verbundenenqueue
) 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 mitthreading
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 istsniff()
undsend()
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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den wichtigsten Grund für dies ist wahrscheinlich, weil der Ressource sperren. Scapy ist
sniff()
Funktion wahrscheinlich haben die Sperre auf low-level-Netzwerk-Ressourcen, um in der Lage zu schnuppern Pakete.Verzögerung der beiden threads (nach dem starten des sniffer-thread) werden Sie sicherstellen, dass Scapy bekommen die Zeit, die es braucht, um so zu tun.
Sehen, wie wir kamen zu diesem Schluss, siehe die Diskussion oben in den Kommentar-Abschnitt.
Gl Asiri Rathnayake 🙂