2008-09-21 8 views
15

Ok, ich weiß, diese Situation ist etwas ungewöhnlich, aber ich muss eine TCP-Verbindung (der 3-Wege-Handshake) nur mit rohen Sockets (in C, in Linux) einrichten - dh ich muss Konstruiere die IP-Header und TCP-Header selbst. Ich schreibe einen Server (also muss ich zuerst auf das eingehende SYN-Paket antworten), und aus welchem ​​Grund auch immer, ich kann es scheinbar nicht richtig machen. Ja, ich weiß, dass ein SOCK_STREAM das für mich erledigen wird, aber aus Gründen, auf die ich nicht eingehen möchte, ist das keine Option.TCP-Handshake mit SOCK_RAW-Socket

Die Tutorials, die ich online bei der Verwendung von Raw-Sockets gefunden habe, beschreiben, wie man einen SYN flooder baut, aber das ist etwas einfacher als eine TCP-Verbindung aufzubauen, da man keine Antwort basierend auf dem Original erstellen muss Paket. Ich habe die SYN flooder Beispiele funktioniert, und ich kann das eingehende SYN-Paket gut aus dem Raw-Socket lesen, aber ich habe immer noch Probleme beim Erstellen einer gültigen SYN/ACK-Antwort auf ein eingehendes SYN vom Client.

Also, kennt jemand eine gute Anleitung zur Verwendung von Raw-Sockets, die über das Erstellen eines SYN-Flooders hinausgeht, oder hat jemand irgendeinen Code, der dies tun könnte (mit SOCK_RAW und nicht SOCK_STREAM)? Ich wäre sehr dankbar.


MarkR ist absolut richtig - das Problem ist, dass die Kernel-Reset-Pakete in Reaktion auf das erste Paket sendet, weil es der Hafen denkt geschlossen ist. Der Kernel schlägt mich auf die Antwort und die Verbindung stirbt. Ich benutzte tcpdump, um die Verbindung bereits zu überwachen - ich hätte aufmerksamer sein sollen und gemerkt haben, dass es ZWEI Antworten gab, von denen eine ein Reset war, der die Dinge durcheinander brachte, sowie die Antwort, die mein Programm erzeugte. D'OH!

Die Lösung, die am besten funktioniert, ist die Verwendung einer iptables-Regel, wie von MarkR vorgeschlagen, um die ausgehenden Pakete zu blockieren. Es gibt jedoch einen einfacheren Weg als die Verwendung der Markierungsoption, wie vorgeschlagen. Ich stimme nur überein, ob das Reset-TCP-Flag gesetzt ist. Im Verlauf einer normalen Verbindung wird dies wahrscheinlich nicht benötigt, und es ist für meine Anwendung nicht wirklich wichtig, wenn ich alle ausgehenden Reset-Pakete von dem verwendeten Port sperre. Dies blockiert effektiv die unerwünschte Antwort des Kernels, aber nicht meine eigenen Pakete. Wenn der Port mein Programm auf zuhört 9999 ist dann sieht das iptables-Regel wie folgt aus:

iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP 

Antwort

1

Ich habe kein Tutorial, aber ich vor kurzem verwendet Wireshark um eine gute Wirkung einige Raw Sockets Programmierung zu debuggen ich tat . Wenn Sie die Pakete, die Sie senden, erfassen, wird Wireshark einen guten Job machen, um Ihnen zu zeigen, ob sie fehlerhaft sind oder nicht. Es ist auch nützlich, um es mit einer normalen Verbindung zu vergleichen.

2

Ich kann Ihnen nicht auf irgendwelche Tutorials helfen.

Aber ich kann Ihnen ein paar Ratschläge geben zu den Tools, mit denen Sie beim Debuggen helfen können.

Zunächst einmal, wie bmdhacks vorgeschlagen hat, erhalten Sie eine Kopie von wireshark (oder tcpdump - aber wireshark ist einfacher zu bedienen). Halten Sie einen guten Händedruck fest. Stellen Sie sicher, dass Sie dies speichern.

Erfassen Sie einen Ihrer Handshakes, der fehlschlägt. Wireshark hat ziemlich gute Paketanalyse und Fehlerüberprüfung. Wenn es also einen einfachen Fehler gibt, wird es Ihnen wahrscheinlich sagen.

Als nächstes erhalten Sie eine Kopie von tcpreplay. Dies sollte auch ein Tool namens "tcprewrite" enthalten. tcprewrite ermöglicht es Ihnen, Ihre zuvor gespeicherten Capture-Dateien in zwei zu teilen - eine für jede Seite des Handshakes. Sie können dann tcpreplay verwenden, um eine Seite des Handshakes abzuspielen, so dass Sie einen konsistenten Paketsatz zum Spielen haben.

Dann verwenden Sie wireshark (erneut), um Ihre Antworten zu überprüfen.

9

Sie möchten einen Teil eines TCP-Stacks im Userspace implementieren ... das ist in Ordnung, einige andere Apps tun dies.

Ein Problem, auf das Sie stoßen werden, ist, dass der Kernel (allgemein negative, nicht hilfreiche) Antworten auf eingehende Pakete aussendet. Dies wird jede Kommunikation vermasseln, die Sie versuchen zu initiieren.

Eine Möglichkeit, dies zu vermeiden, ist die Verwendung einer IP-Adresse und Schnittstelle, die der Kernel keinen eigenen IP-Stack verwendet - was in Ordnung ist, aber Sie müssen sich mit Link-Layer-Stuff (speziell Arp) beschäftigen. Das würde einen Socket erfordern, der niedriger ist als IPPROTO_IP, SOCK_RAW - du brauchst einen Paket-Socket (glaube ich).

Es kann auch möglich sein, die Antworten des Kernels mit einer iptables-Regel zu blockieren - aber ich vermute eher, dass die Regeln auch auf Ihre eigenen Pakete angewendet werden, es sei denn, Sie können sie anders behandeln lassen (vielleicht mit einem netfilter) "mark" auf Ihre eigene Pakete?)

Lesen Sie die Manpages

Buchse (7) ip (7) Paket (7)

welche über verschiedene Optionen und ioctls erklären, die sich auf Typen von Steckdosen.

Natürlich brauchen Sie ein Werkzeug wie Wireshark, um zu sehen, was vor sich geht. Sie benötigen mehrere Maschinen, um dies zu testen. Ich empfehle, vmware (oder ähnliches) zu verwenden, um die benötigte Hardware zu reduzieren.

Entschuldigung, ich kann ein bestimmtes Tutorial nicht empfehlen.

Viel Glück.

0

Es gibt Strukturen für IP- und TCP-Header, die in "netinet/ip.h" & bzw. "netinet/tcp.h" deklariert sind. Vielleicht möchten Sie die anderen Header in diesem Verzeichnis nach zusätzlichen Makros durchsuchen, die nützlich sein könnten.

Sie senden ein Paket mit dem gesetzten SYN-Flag und einer zufälligen Sequenznummer (x). Du solltest ein SYN + ACK von der anderen Seite erhalten. Dieses Paket wird eine Bestätigungsnummer (y) haben, die die nächste Sequenznummer anzeigt, die die andere Seite zu empfangen erwartet, sowie eine andere Sequenznummer (z). Sie senden ein ACK-Paket zurück, das die Sequenznummer x + 1 und ack Nummer z + 1 hat, um die Verbindung abzuschließen.

Sie müssen auch sicherstellen, dass Sie die entsprechenden TCP/IP-Prüfsummen berechnen & füllen Sie den Rest der Kopfzeile für die Pakete, die Sie senden. Vergessen Sie auch nicht Dinge wie Host & Netzwerk-Byte-Reihenfolge.

TCP ist in RFC 793 definiert hier zur Verfügung: http://www.faqs.org/rfcs/rfc793.html

0

Je nachdem, was Sie versuchen, vorhandene Software zu tun, kann es sein, leichter zu bekommen, die TCP-Handshake für Sie zu behandeln.

Ein Open-Source-IP-Stack ist lwIP (http://savannah.nongnu.org/projects/lwip/), der einen vollständigen tcp/ip-Stack bietet. Es ist sehr gut möglich, dass es im Benutzermodus mit SOCK_RAW oder pcap läuft.

0

Wenn Sie Raw-Sockets verwenden, wenn Sie mit anderen Quell-Mac-Adresse an die tatsächliche senden, ignoriert Linux das Antwortpaket und nicht eine erste senden.

+0

Ich weiß, es ist 4 Jahre alt Frage, aber Ihr Vorschlag sieht ziemlich interessant, so entschied ich, Sie um Klärung bitten. Die Frage ist: Gibt es ein Problem mit dem Router beim Routing Antwortpaket zu bestimmten Computer mit falschen MAC-Adresse des Geräts? Wird das Paket jetzt von einer Firewall oder einem Antivirenprogramm gefiltert? –

+0

Eine gefälschte MAC-Adresse kann von Switches gefiltert werden, wenn sie für die Portsicherheit konfiguriert sind. Möglicherweise gibt es ACLs auf der MAC-Ebene, aber normalerweise hindert Sie nichts daran, MACs zu spoofen. Sie müssen nur sicherstellen, dass Ihre Netzwerkkarte Antworten auf diesen gefälschten Mac akzeptiert (indem Sie den Mac zur Tabelle der akzeptierten Pakete hinzufügen oder indem Sie ihn in den Promisc-Modus setzen). Dies ist eine schlechte Idee, dies zu tun, wenn Sie nicht autorisiert sind. – eckes