2016-08-16 1 views
2

Ich implementiere einen TCP-Handshake mit Python-RAW-Sockets. Der Linux-Kernel ist jedoch ziemlich nervig, weil er versucht, bestimmte Aspekte dieses Protokolls zu behandeln.TCP-Handshake mit Python-RAW-Sockets

Zum Beispiel, wenn ich ein SYN-Paket sende, antwortete der Server mit einem SYN, ACK-Paket; auf die der Kernel automatisch mit einem RST-Paket antwortet und die Verbindung zurücksetzt. Ich überwand meine dies alle diese Reset-Pakete fallen die folgenden iptable Regel:

-A OUTPUT -p tcp -m tcp --sport 999 --tcp-flags RST RST -j DROP 

Jetzt möchte ich das SYN-ACK-Paket empfangen durch den Server gesendet und ausdrucken. Aber ich erhalte nichts, wenn ich folgendes tun:

a = self.s.recvfrom(4096) 

Ich vermute, dass der Kernel die SYN sinkt, ACK, bevor ich empf kann es meine Steckdose verwenden. Kennt jemand eine angemessene Problemumgehung?

+0

Würden Sie Scapy verwenden? https://github.com/secdev/scapy/ –

+0

Ist scapy in der Lage, das SYN, ACK wiederzubeleben und zu parsen? Mit der Annahme, dass dieses Paket durch den Kernel – SivaDotRender

+0

fallen gelassen wurde, weiß ich nicht, schlug ich vor, es als eine mögliche höhere Bibliothek, die Sie verwenden können (oder zumindest von lernen), vs. versuchen, alles selbst von Grund auf neu zu machen. –

Antwort

1

Sie libpcap verwenden können, in Python es dieses Modul scheint: http://pylibpcap.sourceforge.net/ oder diese: https://pypi.python.org/pypi/pypcap

Mit pcap können Sie sich registrieren Meldungen vom Kernel zu empfangen. Indem Sie den richtigen Filter aus Ihrer Anwendung bereitstellen, können Sie TCP-Segmente vom Kernel empfangen. Ich habe libpcap in C verwendet und nehme an, dass Sie die angegebenen Module auf die gleiche Weise verwenden können. Für mich ist dies die beste Lösung, da Sie mit der Anwendung auf ziemlich normale Weise umgehen können.

Um zu vermeiden, dass der Kernel mit einer RST antwortet, ist Ihre Lösung mit iptables die beste für mich.

1

Während ich hoffe, dass jemand mit einer bequemeren Lösung kommt, wäre eine Möglichkeit, iptables zu verwenden, um eingehende TCP-Syn-Pakete an eine nfqueue übergeben. Nfqueue hat Python bindings, so sollte es kein Problem sein.

Die Idee ist, alle eingehenden TCP-Syncs zu fangen, bevor sie die TCP-Implementierung des Kernels erreichen. Übergeben Sie diese Pakete dann an die Warteschlange, die Ihre Benutzerland-App überwachen kann. Für jedes Paket, das Ihre App aus der Warteschlange erhält, muss es entscheiden (return a verdict), ob das Paket selbst behandelt werden soll (d. H. Das Paket so weit wie das OS fallen lässt) oder es an die reguläre TCP-Implementierung weitergegeben wird.

Ich weiß für eine Tatsache, dass dieser Ansatz funktioniert, aber es ist umständlich.

+0

Das klingt nach der vernünftigsten Lösung für mich atm. – SivaDotRender

1

Da Sie dies alles mit rohen Paketen tun, warum erstellen Sie nicht nur Ihre eigene MAC-Adresse und IP-Adresse? Sie müssen den Adapter in den Promiscuous-Modus versetzen, um Pakete zu empfangen, aber wenn Sie dies tun, sollte der Kernel keine Antworten an Ihre eingehenden Pakete senden, da sie scheinbar an "ein anderes System" adressiert sind. Dies macht es einfach, die Pakete, die Ihnen wichtig sind, von anderen zu filtern.

Sie müssen auch angemessen auf ARPs reagieren, damit das andere System Ihre MAC-Adresse findet. Und wenn Sie DHCP benötigen, um eine IP-Adresse zu erhalten, müssten Sie auch diese Interaktionen handhaben.