21
RAW-Sockets Dokumentation zur Semesterarbeit in der Vorlesung: „Rechnernetz Anwendungen“ Ausarbeitung von: Tobias Wawryniuk Vortrag vom 08.11.2006

RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

Embed Size (px)

Citation preview

Page 1: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

RAW-Sockets

Dokumentation zur Semesterarbeit in der Vorlesung: „Rechnernetz Anwendungen“

Ausarbeitung von: Tobias Wawryniuk Vortrag vom 08.11.2006

Page 2: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 2 -

Inhalt:

Vorwort ...................................................................................................................................... 3 RAW-Sockets............................................................................................................................. 4

Was ist ein Socket überhaupt? ............................................................................................... 4 Unterschiede in Betriebssystemen ..................................................................................... 4

Die verschiedenen Sockettypen ............................................................................................. 5 Was ist nun ein RAW-Socket?............................................................................................... 5

RAW-Socket unter Windows............................................................................................. 6 RAW-Socket in einer UNIX-Umgebung ........................................................................... 6

Wozu dient ein RAW-Socket? ............................................................................................... 7 Einordnung in das OSI Schichtenmodell ................................................................................... 8 Programmierung (Beispiele) .................................................................................................... 10

Allgemeines und Grundlagen............................................................................................... 10 Anlegen eines RAW-Sockets ........................................................................................... 11 Socketoptionen setzen...................................................................................................... 11 RAW-Socket (ver-)binden ............................................................................................... 12 Network Byte Order ......................................................................................................... 12

Grundgerüst: IP-Header ....................................................................................................... 12 Prüfsummen ......................................................................................................................... 13 Beispiel 1 – Der Ping ........................................................................................................... 13

Internet Control Message Protokoll ................................................................................. 14 Der ICMP- Header ........................................................................................................... 14 ECHO-Request und ECHO-Reply................................................................................... 15 Programmablauf ............................................................................................................... 15

Beispiel 2 – Der SYN-Flooder ............................................................................................. 16 Der 3-Wege-Handshake ................................................................................................... 17 Prinzip eines Flooders ...................................................................................................... 17 Programmablauf ............................................................................................................... 17

Beispiel 3 – Der TCP-Sniffer ............................................................................................... 18 Prinzip eines Sniffers ....................................................................................................... 18 Programmablauf ............................................................................................................... 19

Zusammenfassung.................................................................................................................... 20 Literaturverzeichnis:................................................................................................................. 21

LINUX ManPages (Fedora Core 5 Distribution – http://www.fedora.de)....................... 21 RFC – Request For Comment .......................................................................................... 21 Internetseiten .................................................................................................................... 21

Anlage (separate Datei):

Quellcode der Beispielprogramme: - „Ping“ - TCP-Flooder - TCP-Sniffer

Page 3: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 3 -

Vorwort

Das der Begriff ‚Socket’ im Bereich der Informatik und Kommunikationstechnik unmittelbar mit Rechnernetzwerken zu tun ist mittlerweile sicherlich unumstritten. So stößt man zum Beispiel auf diesen Begriff, wenn man über die Einstiegsliteratur diverser Programmier-sprachen hinausgeht und sich der Frage zuwendet, wie man Dienste eines entfernten Rechners nutzen kann. Nicht zu letzt taucht dieser Begriff bei Sicherheitsaspekten in Netzwerken auf, die zum Beispiel im Zusammenhang mit Angriffen auf ein Rechnersystem stehen.

Umso weiter man in die Materie hineintaucht, umso öfter findet man sich dann auch häufiger mit dem ‚RAW’ vor dem ‚Socket’ konfrontiert. Jedoch findet man weitaus weniger detaillierte Aussagen darüber, was nun genau darunter zu verstehen ist, wofür man nun den ‚RAW-Socket’ genau benötigt - und wie man ihn einsetzt.

Diese Dokumentation und der Vortag sollen ein Stück weit Einblick in geben - was sich hinter dem Begriff ‚RAW-Socket’ verbirgt und an Beispielen zeigen, wozu er eingesetzt werden kann.

Page 4: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 4 -

RAW-Sockets

Was ist ein Socket überhaupt? Um dem RAW-Socket auf die Spur zukommen sollte nicht gleich die Frage ‚Was ist ein RAW-Socket?’ aufgeworfen werden, sondern zuerst sollte definiert werden, was ein Socket ist.

Seinen Ursprung hat der Socket im BSD4.2 einem UNIX-Derivat der Berkeley Software Distribution und hat sich von dort aus zu einem Quasi-Standard entwickelt.

Der Begriff selbst stammt aus dem Englischen und bedeutet so viel wie „Fassung“ oder „(Anschluss-) Buchse“. Hier wird eigentlich klar, das es sich beim Socket um eine Schnittstelle handelt, die zum einen aus prozesstechnischer Sicht, aber auch aus programmtechnischer Sicht betrachtet werden kann.

Aus Programmtechnischer Sicht spricht man dann häufig von der ‚Socket API’ oder, um den historischen Hintergrund zu betonen vom ‚BSD Socket’. Als API soll ein Socket standardisiert sein, um auch auf andere Systeme portiert werden zu können. Er sollte einfach zu nutzen sein und Flexibilität in der Handhabung aufweisen. Im Konzept von BSD wird dies erreicht in dem der Socket als Datei aufgefasst wird. Er wird somit im Betriebssystem über einen ‚file discriptor’ identifiziert und wird auf ähnliche Art und Weise wie reguläre Dateien genutzt. Neben den grundlegenden Funktionen für Lesen und Scheiben – also zum Empfangen und Senden von Daten, stellt der Socket die Funktionalitäten der im Rechner verfügbaren Transportschichten bereit. Nach der Initialisierungsphase, in der Adressen, Protokolle und Optionen festgelegt werden könnte die Kommunikation sogar über die klassischen IO-Funktionen read(…) und write(…) abgewickelt werden.

Zusammenfassend kann man also festhalten, das der Socket eine Sammlung an Funktionen, Strukturen und Konstanten bereitstellt.

Wenn der Socket im Kontext eines Kommunikationsprozesses gesehen wird, dann stellt er den eindeutigen Anschluss eines Systems dar, über den ein Prozess mit seiner Partnerinstanz in Interaktion treten kann. In der TCP/IP-Welt ist zum Beispiel ein Socket durch die IP-Adresse, dem Protokollflag (TCP od. UDP) und einer Portnummer eindeutig identifiziert.

An Rande sei hier noch erwähnt, dass der Socket in der UNIX-Welt nicht nur zur Netzwerkkommunikation verwendet werden kann, sondern auch zur Interprozesskommunikation – man spricht dann vom so genannten UNIX-Socket.

Unterschiede in Betriebssystemen Neben dem Socketansatz gibt es zur Netzwerkkommunikation auch einen stream-orientierten Ansatz, dem TLI (Transport Layer Interface). Dieses Interface wurde von AT&T entwickelt und mit dem UNIX Betriebsystem SystemV Release 3.0 eingeführt.

Dies sei aber nur am Rande erwähnt, in diesem Abschnitt möchte ich näher auf die Unterschiede in den Socket-Implementierungen von Windows und UNIX/Linux eingehen.

Wie bereits erwähnt ist in der UNIX-Welt ein Socket ein spezieller Dateityp. An dieser Stelle sollte man sich von der klassischen Vorstellung einer Datei – einem statischen Speicherort von Daten – lösen und den Begriff etwas weiter fassen und einer Datei dynamischere Eigenschaften zuordnen. Unter UNIX sind auch Warteschlangen oder an das System angeschlossene Geräte als spezielle Dateitypen zu finden, also ist der Socket in diesem Punkt keine Ausnahme.

Page 5: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 5 -

Auf Windows-Systemen hingegen stellt der Socket einen eigenen Datentyp SOCKET dar (genauso wie eine Datei vom Datentyp FILE ist). Beide Typen können zwar als Integer gecastet werden, jedoch sollten Rückschlüsse auf die interne Struktur und die Verwaltung durch das Betriebsystem vermieden werden. Am besten man betrachtet diese Datentypen als Blackbox und nutzt sie lediglich als eindeutigen Identifikator.

Mit der Winsock API unterstützt Microsoft Windows das Socket-Konzept. In der Version Winsock 1.1 wurde die Implementierung an die Vorlage des BSD Sockets angelehnt.

In der Version 2.0 der Winsock API wurden diverse Erweiterungen hinzugefügt, so wurde die Unterstützung von Protokollen, wie IPX/SPX oder ATM hinzugefügt.

Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem mittels Winsock API anmeldet und via Optionsabsprache die verwendete API-Version aushandelt.

Die Details zur Winsock API können der Mircosoft-Dokumentation (MSDN Library) entnommen werden.

Die verschiedenen Sockettypen Wenn im Weiteren von Socket gesprochen wird, dann sind hier in erster Line die so genanten ‚Internet Sockets’ gemeint. Ein ‚Internet Socket’ bezeichnet einen Socket, der speziell die Schnittstelle zum Internet Protokoll (IP) bereitstellt. Hier ist also der Socket bereits an eine bestimmte Protokollfamilie gebunden. Allgemein gesehen ist der Diensterbringer also der TCP/IP-Protokoll-Stack des Betriebssystems.

Bei Internet Sockets wird zwischen dem Stream-Socket und dem Datagram-Socket unterschieden. Die Konstanten nach BSD wären SOCK_STREAM bzw. SOCK_DGRAM. Der Stream-Socket bietet eine verbindungsorientierte Kommunikation mit geregeltem Verbindungsaufbau bzw. –abbau. Ein weiteres Merkmal ist die Flusskontrolle, die sicherstellt, dass die Pakete in der Richtigen Reihenfolge beim Empfänger ankommen. Dieser Sockettyp stützt sich, wie man erahnen kann, auf das TCP-Protokoll.

Als Gegenstück existiert auf Grundlage des UDP-Protokolls der Datagram-Socket, er besticht durch seinen geringen Overhead. Die Header-Informationen sind deutlich geringer als beim TCP. Dadurch kann jedoch keine Verbindungskontrolle und Überwachung der Paketreihenfolge gewährleistet werden.

An dieser Stelle sei noch mal auf die Portnummer verwiesen. Beide Typen werden bei ihrer Erstellung mit einer Portnummer verstehen, dadurch können die Daten, die das Netzwerkinterface passieren eindeutig diesen Ports zugeordnet werden. Das IP-Protokoll selbst – als reines Protokoll der Vermittlungsschicht – kennt noch keine Ports, erst die Kombination mit einem Transportprotokoll bezieht die Portnummer zur Identifizierung des Sockets mit ein.

Was ist nun ein RAW-Socket? Nun endlich kann man sich dieser Frage zuwenden und dem eigentlichen Thema widmen. Der RAW-Socket existiert neben den bereits erwähnten Stream-Sockets und Datagram-Sockets quasi als dritter Sockettyp – SOCK_RAW. Für andere Protokollfamilien außerhalb IP-Welt gilt ähnliches. Ich werde mich jedoch im Weiteren nur auf den Bereich des Internet-Protokolls beschränken.

Die Besonderheit am RAW-Socket ist die Möglichkeit direkten Einfluss auf die Headerdaten eines jeden Paketes zu nehmen. Sowohl beim Senden, als auch beim Empfangen wird dem Payload (den eigentlichen Nutzdaten) der Header vorangestellt. Im konkreten Fall der Internet

Page 6: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 6 -

Sockets werden also im Buffer, der bei den Lese- bzw. Schreibzugriffen angegeben wird, sämtliche Daten, die ab Layer 3 (Vermittlungsschicht) im Paket enthalten sind abgelegt. Im Abschnitt ‚Insgesamt skizziert sich damit ein Einsatzgebiet für den RAW-Socket, das in den unteren Schichten des OSI-Modells einzuordnen ist.

Die Überwachung und Analyse des Netzwerkverkehrs ist so auf einer sehr systemnahen Ebene möglich. Sicherheitslücken können erkannt werden, indem man z.B. mittels RAW-Sockets Portscanner programmiert, oder SYN-Flooder verwendet um das Überlastverhalten von Systemen zu analysieren. Als weitere Anwendungsmöglichkeiten sollten aber auch Proxy- oder Gatewayimplementationen nicht unterschlagen werden.

Einordnung in das OSI Schichtenmodell’ wird dies noch deutlicher beschrieben.

Um diese Funktionalität zu erhalten muss beim Socket eine bestimmte Option gesetzt sein – die IP_HDRINCL – dies geschieht beim RAW-Socket unter anderem implizit beim Erstellen mit socket(…) oder kann nachträglich erfolgen.

Im Allgemeinen empfängt der RAW-Socket alle Daten, die an die entsprechende IP-Adresse, an die er gebunden wurde, gesendet werden. Je nach Implementierung können Abweichungen auftreten, so zum Beispiel können die Daten eine Kopie des eigentlichen Datagramms sein. – ICMP-Pakete werden so zum Beispiel vom Kernel beantwortet und der Programmierer braucht entsprechende Funktionen nicht zu implementieren.

Beim Versenden hat man dagegen ‚fast’ vollen Handlungsspielraum, dadurch bietet der RAW-Socket sich vor allem für die Entwicklung und Implementierung neuer Protokolle an.

Was den Handlungsspielraum einschränken könnte, wäre die Eigenschaft, dass einige Felder des IP-Headers, wie Prüfsumme und Gesamtlänge automatisch ausgefüllt werden, was aber eher hilfreich ist.

RAW-Socket unter Windows Bei der Entwicklung von RAW-Socket – Anwendungen unter Microsoft Windows gibt es einige Dinge zu beachten. Insbesondere mit der Einführung des Service Pack 2 für Windows XP wurden einige Restriktionen für die RAW-Sockets erhoben.

So ist der RAW-Socket primär für Empfang von IP-Paketes vorgesehen, TCP-Pakete können nicht gesendet werden und UDP-Pakete müssen an eine gültige, lokale IP-Adresse gebunden sein. (Quelle: Michael Howard’s Web Log)

Um die genauen Funktionalitäten, die die WinSock API liefert, auszunutzen, bedarf es ein intensives Studium der MSDN-Library. Socketoptionen, die nicht zueinander passen werden oft mit einem einfachen SOCKET_ERROR quittiert oder unvollständige Pakete, die man experimentell versenden möchte verschwinden im Ether – jedoch nicht auf dem Interface.

Nach zahlreichen, doch recht frustrierenden Versuchen habe ich mich dann der Entwicklung auf einem Linux-System zugewandt, was dann auch von Erfolg gekrönt war. Die Beispiele, die also in diesem Dokument erwähne, beziehen sich also auf UNIX-Implementierungen, deren Besonderheiten im folgenden Abschnitt beschrieben werden.

RAW-Socket in einer UNIX-Umgebung Wichtigster Punkt ist hier der Fakt, dass RAW-Sockets vom Betriebsystemkernel nur an Prozesse vergeben werden, die über superuser-Rechte verfügen. Im Klartext bedeutet das, dass das Programm vom Benutzer ‚root’, oder einem Account, der über diese Berechtigung verfügt, ausgeführt wird. Weitere Möglichkeiten, einem Prozess diese Rechte einzuräumen habe ich hier nicht betrachtet, da sie nicht unmittelbar zum Thema gehören. Dies zeigt jedoch schon mit welcher Sicherheitsproblematik das Thema RAW-Sockets verbunden ist.

Page 7: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 7 -

Ein weiterer wichtiger Punkt ergibt sich aus der Initialisierung des RAW-Sockets. Hier wird ein Protokoll angegeben, das dann ausschlaggebend dafür ist, welche Pakete der Socket empfängt. Die genaue Zuordnung ist im RFC 1700 – „assigned numbers“ festgelegt und sollte bei der Implementierung über die vordefinierten Konstanten, wie zum Beispiel IPPROTO_ICMP für ICMP-Pakete, realisiert werden.

Weiterhin sollte beachtet werden, dass der Socket in der Regel eine Kopie des Paketes erhält. Gerade bei dem genannten Beispiel der ICMP-Pakete erklärt es dadurch, dass empfangene Pakete, wie zum Beispiel die vom Typ „source quench“ durch den Kernel abgearbeitet werden und somit nicht vom Programm beantwortet werden müssen.

Wozu dient ein RAW-Socket? Insgesamt skizziert sich damit ein Einsatzgebiet für den RAW-Socket, das in den unteren Schichten des OSI-Modells einzuordnen ist.

Die Überwachung und Analyse des Netzwerkverkehrs ist so auf einer sehr systemnahen Ebene möglich. Sicherheitslücken können erkannt werden, indem man z.B. mittels RAW-Sockets Portscanner programmiert, oder SYN-Flooder verwendet um das Überlastverhalten von Systemen zu analysieren. Als weitere Anwendungsmöglichkeiten sollten aber auch Proxy- oder Gatewayimplementationen nicht unterschlagen werden.

Page 8: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 8 -

Einordnung in das OSI Schichtenmodell

In diesem Abschnitt möchte ich als Zusammenfassung und zum besseren Verständnis eine Einordnung in das OSI-Schichtenmodell geben. Damit soll ebenfalls noch mal eine Abgrenzung zu der ‚klassischen’ Socket-Programmierung erfolgen.

Ein grundlegender Aspekt des OSI-Schichtenmodells ist, wie der Name schon sagt, die Einteilung des Kommunikationsprozesses in Schichten. Jede Schicht erfüllt dabei ganz spezifische Aufgaben, wobei eine höhere Schicht auf die Dienste einer untergeordneten Schicht zurückgreifen kann. Dabei werden unter anderem die zu verarbeitenden Daten mit entsprechenden Steuerinformationen an die darunterliegende Schicht weitergereicht – man spricht von der so genanten Dienstweiterreichung. Untergeordnete Schichten werden als Diensterbringer bezeichnet und übergeordnete Schichten als Dienstnutzer. Die nun weiter zu reichenden Daten setzen sich aus den Daten der Dienstnutzer und den eigenen Headerdaten zurammen. Jede Schicht umschließt also das Datenpaket mit eigenen Steuerinformationen.

Der Sessionlayer (Layer 5) zum Beispiel ist für das korrekte Handling einer Verbindung zuständig. Dabei gehören Aufgaben, wie Verbingungsaufbau, Verbindungsabbau und die Flusssteuerung während des Datenaustausches. Auf diese Funktionalitäten setzt die ‚klassische’ Socketprogrammierung auf, und stellt somit der Anwendung eine abgeschlossene Schnittstelle zur Netzwerkkommunikation zur Verfügung.

Im Schichtenmodell des TCP/IP-Protokols (Internetprotokoll) entspricht also die Implementierung, die der Programmierer vornimmt dem Application-Layer (Schicht 4). Im OSI-Modell entspricht das dann den Schichten 5-7. Zu diesen OSI-Schichten gehören, die bereits erwähnt, die Sitzungsschicht (Sessionlayer), die Darstellungsschicht (Presentation-layer) und die Anwendungsschicht (Application-layer).

Abbildung 1: Übersicht Schichtenmodelle

Page 9: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 9 -

RAW-Sockets brechen nun insofern das stickte Schichtenmodell auf, indem man die Header der darunterliegenden Schichten manipulieren kann. Der Diensterbringer erhält quasi eine Vorgabe, wie der seinen Header zu gestalten hat.

Im Endeffekt obliegt es nun dem Programmierer, mit seiner Implementation die Aufgaben der Schichten 2 (Internetschicht) und 3 (Transportschicht) des Internetprotokolls sicherzustellen. Im OSI-Modell sind das die Schichten 3 (Netzwerkschicht) und 4 (Transportschicht).

Schichten unterhalb dieser Aufgeführten werden von den hier betrachteten RAW-Sockets, die als Grundlage das Internetprotokoll haben, nicht berührt. Um noch tiefer im OSI-Modell hinab zu steigen wäre es nötig eine andere Protokollfamilie für den Socket zu wählen, die bereits auf Paketebene (z.B. Ethernetframes) aufsetzt. Dies hat seine Ursache darin, dass in diesem Header ein Feld existiert, das den Inhalt spezifiziert. Ist der RAW-Socket für das Internetprotokoll spezifiziert, ist das logischerweise das IP-Protokoll.

Diese Einordnung sollte eigentlich ausreichen um das Wesen des RAW-Sockets zu verdeutlichen: Die Verantwortung, das die Aufgaben, der hier eingegrenzten Layer, ordnungsgemäß erfüllt werden, obliegt nun dem Programmierer und seiner Implementation.

Dies betrifft natürlich nur den von b.z.w. für seine Anwendung relevanten Teil der gesamten Kommunikation, die über die Schnittstelle abgewickelt werden soll. Von darunterliegenden Schichten und Kommunikationsprozessen, die er mit seinem Socket nicht tangiert, kann er annehmen, dass sie ordnungsgemäß ablaufen.

Page 10: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 10 -

Programmierung (Beispiele)

Im nun folgenden Abschnitt soll anhand von Beispielen die Programmierung mit RAW-Sockets veranschaulicht werden. und einen praxisorientierten Überblick über ausgewählte Anwendungsmöglichkeiten geben.

Die Beispiele sind voll Funktionsfähig, erheben jedoch keinen Anspruch auf Vollständigkeit. So wird an einigen Stellen bewusst auf Fallunterscheidungen oder Fehlerbehandlungen verzichtet, um den Code der Übersichtlichkeit wegen nicht zu stark aufzublähen.

In den einzelnen Beispielen wird dann jeweils auf die Besonderheiten der verwendeten Protokolle eingegangen und die daraus resultierenden Arbeitsschritte der Implementierung abgeleitet. In den unterschiedlichen Beispielen werden dabei verschiedene Funktionen der Socket-API verwendetet, die scheinbar die gleiche oder zumindest eine ähnliche Funktionalität bieten, es wird dann jedoch erklärt, wieso diese Funktion verwendet wurde und nicht der Anderen der Vorzug gegeben wurde. Dieser Sachverhalt schießt aber keineswegs aus, dass das Problem auch auf einen anderen Weg durchaus eleganter gelöst hätte werden können.

Die drei Beispiele, für die ich mich entschieden habe, beschreiben jeweils ein in sich geschlossenes Anwendungsgebiet.

Da wäre als erstes der ‚hausgemachte’ Ping. Der Ping ist zwar als grundlegendes Diagnosetool in jeder Implementierung des TCP/IP-Stacks vorhanden, veranschaulicht aber sehr gut die Anwendung des RAW-Sockets.

Mit dem zweiten Beispiel, einem SYN-Flooder werden unzählige Verbindungsaufbau-Anfragen gesendet, die beim Empfänger eine hohe Ressourcenbelastung erzeugen können. So kann sein Verhalten bei Überlast beurteilt werden.

Im dritten Beispiel geht es um einen TCP-Sniffer, der eingehende TCP-Pakete mitschneidet und eine kurze Info ausgibt. Dieses Tool könnte bei entsprechender Erweiterung zur Überwachung eines Interfaces genutzt werden.

An dieser Stelle sei in Hinblick auf den Verwendungszweck nochmals erwähnt, das nicht die RAW-Sockets das Hacker-Tools darstellen, sondern der böswillige Umgang mit den Funktionen, die durch diese bereitgestellt werden. Ich deswegen absichtlich zu diesen Beispielen den positiven Nutzen genannt – ohne Zweifel können Sie auch schadhaft missbraucht werden, was hier aber nicht Sinn und Zweck der Sache ist.

Allgemeines und Grundlagen Als Grundlagen betrachte ich hier das ‚klassische’ Socket-Konzept - die Funktionen, die zum Aufbau, zum Senden und zum Schließen der Verbindung nötig sind.

Jede Kommunikation über Sockets fängt damit an, dass erstmal ein Socket erstellt wird. In der nächsten Phase wird dieser an eine lokale Adresse gebunden und dann kann, je nach Anwendungsfall, der Socket angewiesen werden, eine Verbindung zu einem Entfernten Rechner aufzubauen, oder auf eingehende Verbindungen zu warten - soweit die Theorie. Es ist dabei sicherlich Verständlich, dass es durchaus Außnahmen gibt: Wenn der Socket das verbindungslose Protokoll UDP nutzen soll, dann wird eine connect-Funktion, die auf eine Bestätigung der Gegenseite wartet wenig Sinn machen.

Ganz ähnlich verhält es sich bei einem RAW-Socket, hier wird in erster Linie solch eine Anweisung eine Pseudoverbindung einrichten. Das System verhält sich so als würde eine

Page 11: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 11 -

Verbindung aufgebaut werden, tatsächlich muss dies jedoch noch durch die Eigene Implementierung realisiert werden. Der eigentliche Datenaustausch wird dann mit den Funktionen wie send(..) , sento(…) bzw. recv(…) und recvfrom(…) durchgeführt. Während hier, bei der klassischen Socket-Programmierung der Buffer nur das Datagramm, also die Nutzdaten, enthält, ist beim RAW-Socket zusätzlich immer der IP-Header vorangestellt. (bzw. wird beim Senden erwartet).

Das beenden ist relativ unspektakulär und geschieht in beiden Fällen mit dem close(..).

Anlegen eines RAW-Sockets Auf die socket(…) -Funktion möchte ich im Vorfeld der Beispiele doch noch etwas genauer eingehen, da sich hier dem System bekannt gegeben wird, das es sich nicht um einen klassischen Socket handelt.

Die Allgemeine Syntax lautet:

int socket(int domain, int type, int protocol);

Der erste Parameter gibt die Protokollfamilie des Sockets an, in allen Beispielen wird das die Konstante PF_INET sein, die auf die Familie des Internet-Protokolls hinweist. Ebenso wird der 2. Parameter bei den drei Beispielen der gleiche sein – hier wird SOCK_RAW angeben – eben die Anforderung eines RAW-Sockets. Der 3. Parameter spezifiziert ein Protokoll. Hier steht entweder die Konstante IPPROTO_RAW, oder eine Protokollnummer nach der RFC 1700 (Assigned Numbers). Zur übersichtlicheren Programmierung existieren aber auch hierzu entsprechende Konstanten, die in der Headerdatei <netinet/in.h> zu finden sind. (Je nach System können die Kontanten auch in einer anderen Datei definiert sein.)

Wird als Protokoll die Konstante IPPROTO_RAW angegeben, so kann der Socket jedes im Header angegebene Protokoll versenden. Der Empfang funktioniert jedoch nicht für alle Protokolle, in diesem Fall sollte ein Protokoll angegeben werden, dessen Pakete Empfangen werden sollen.

Weiterhin impliziert die Konstante IPPROTO_RAW die Socketoption IP_HDRINCL, die im Folgenden erläutert wird.

Socketoptionen setzen Mit dem Befehl setsockopts(…) können verschiedene Optionen des Sockets eingestellt werden. Die Optionen können den Socket direkt betreffen, oder spezielle Funktionalitäten beeinflussen, die durch das verwendete Protokoll gegeben sind. So lassen sich Optionen zur Nebenläufigkeit oder zu Timeouts festlegen.

Im Zusammenhang mit dem RAW-Socket ist hier jedoch nur die erwähnte Header-Include-Option (IP_HDRINCL) wichtig.

Die genaue Syntax lautet:

int setsockopts(int s, int level, int optname, void *optval, socklen_t *optlen);

Auf den ersten Blick sieht dieser Befehl relativ abschreckend aus, da er sehr allgemein gehalten wurde. Der erste Parameter ist der Socket, gefolgt von dem Level der Option, also ob die Option den Socket an sich betrifft, oder Protokollspezifisch ist. Dann der dritte Parameter, die Bezeichnung der Option und zum Schluss ein Pointer auf den Wert der Option. Da auch Zeichenketten möglich sind ist die Länge, des Wertes, auf den der Pointer zeigt ebenfalls nötig (5. Parameter).

Page 12: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 12 -

Für die hier relevante Option könnte die Anweisung wie folgt lauten: int true = 1; setsockopts(fd, SOL_SOCK, IP_HDRINCL, &true, sizeof(true));

Damit ist der RAW-Socket für die in diesen Beispielen benötigten Funktionalitäten konfiguriert.

RAW-Socket (ver-)binden Zu Beginn eines Kommunikationsprozesses muss der Socket, an IP-Adressen gebunden werden. Im Normalfall werden Quell- und Zieladresse benötigt. der RAW-Socket benötigt jedoch nur eine gültige Quelladresse, bei der Zieladresse spricht man von einer so genannten Pseudoadresse, da das eigentliche Ziel erst durch den Inhalt der Header spezifiziert wird. Ebenso verhält es sich mit den Portnummern, die in den Adressstukturen angegeben werden.

Um den Socket an die Adressen zu binden werden auch hier die gewohnten Funktionen connect(…) und bind(…) der Socket API verwendet.

Übernimmt das Programm eine aktive Rolle, dann empfiehlt es sich vorzugsweise connect(…) zu verwenden. Wartet das Programm am Anfang auf eine Eingehende Verbindung, so ist bind(…) sicherlich die bessere Alternative.

Da die realen Verbindungen selbst implementiert werden lässt die API hier den Programmierer etwas Handlungsspielraum – etwaige Einschränkungen sollten dann der Dokumentation der API entnommen werden.

Network Byte Order Die Network Byte Order ist eine Definition, bei festgelegt wird in welcher Reihenfolge die Bytes zu interpretieren sind. Dies ist insofern wichtig, da sie nicht unbedingt der Host Byte Order entsprechen muss. Daher sollten alle numerischen Werte vorher korrekt konvertiert werden.

Allgemein wird die Byteorder zwischen Little-Endian und Big-Endian unterschieden, dabei steht bei der Big-Endian der niederwertigste Block am Ende (rechts). Übertagen auf den Netzwerkbereich – hier ist ein Block ein Oktett – bedeutet das, die höherwertigen Oktetts stehen vor den Niederwertigen. Analoges gilt für die einzelnen Bits eines Oketts.

Die entsprechenden Funktionen ‚htons(…) / htonl(…) ’ zum konvertieren von Host- in Network Byte Order bzw. ‚ntohs(…) / ntoh(…) ’ für die entgegengesetzte Richtung sollten zur besseren Portierbarkeit immer verwendet werden. (Das Suffix ‚s’ oder ‚l’ gibt hierbei den Datentyp, also short bzw. long an.)

Grundgerüst: IP-Header Bevor ich mich nun den Beispielen widme, möchte ich noch kurz auf den IP-Header eingehen. Er wird in allen Beispielen verwendet, was auch nicht weiter erstaunlich sein sollte, da es ja um die Internet-RAW-Sockets geht. Die detaillierte Bedeutung und Verwendung der einzelnen Felder kann dem RFC 791 „Internet Protocol“ entnommen werden. In der Praxis erweist es sich als sehr hilfreich eine Struktur des IP-Headers anzulegen, ihn mittels Casting und Zeigerarithmetik auf den Anfang des Paketpuffers „zu legen“. So können die Felder auf einfache Art und Weise manipuliert werden und man braucht nicht „von Hand“ den jeweiligen Offset zu ermitteln. Als ganz praktisch ist es auch, dass bestimmte Felder, wie IP Cecksum und Total Length von der Socket API gefüllt werden und es nicht nötig ist diese Werte selber zu ermitteln. Weiterhin können die Felder Source Address und Packet Id auf 0x00 gesetzt werden, dann wird hier ebenfalls die Socket-API bemüht.

Page 13: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 13 -

Abbildung 2 : IP-Header (Quelle: RFC 791) Wie auch bei den anderen Protokollen, werden in diesen Beispielen die Header relativ statisch gesetzt. Hauptsächlich die Felder der Adressen und des Protokolls wurden über Variablen gesetzt. Die folgende Abbildung zeigt die Funktion, mit der in den Beispielen der IP-Header gesetzt wird. Sollte ein weiteres Feld modifiziert werden, dann lässt es sich mit der Casting / Zeigerarithmetik –Technik immer noch relativ effektiv realisieren.

Prüfsummen Die Prüfsumme des IP-Headers wird durch den IP-Stack ermittelt, jedoch nicht die Prüfsummen der anderen höherliegenden Protokolle. Wie sich genau die Prüfsummen zusammensetzen regeln die einzelnen RFC. Oft wird das Einer-Komplement einer Quersumme verwendet.Beim TCP werden z.B. auch einige Felder des IP-Headers verwendet, die dann einen Pseudoheader bilden, der nur bei der Prüfsummenberechnung benötigt wird.

Beispiel 1 – Der Ping Kommen wir nun zum ersten Beispiel. Wie bereits erwähnt ist der Ping ein grundlegendes Netzwerktool, bei dem getestet wird, ob ein entferntes Host-System über das Netzwerk erreichbar ist. Voraussetzung ist natürlich, dass der andere Host auf diese Anfrage reagiert und eine entsprechende Antwort zurücksendet.

Page 14: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 14 -

Wird ein Ping positiv beantwortet, so kann davon ausgegangen werden, dass die unteren Schichten im Netzwerk-Protokoll-Stack ordnungsgemäß funktionieren und eine Kommunikation zwischen diesen Systemen mittels IP möglich ist.

Für diesen Test nutzt der Ping das ICMP Protokoll und sendet so genannte ECHO-Anforderungen, wartet anschießend auf das Antwortecho, das ECHO-Reply.

Dieser Vorgang wird von dem Ping-Programm so oft wiederholt bis eine vorgegebene Anzahl von erreicht wurde oder der Benutzer das Programm beendet.

Internet Control Message Protokoll Das Internet Control Message Protokoll, oder kurz ICMP ist wie das TCP und UDP ein Unterprotokoll des IP-Protokolls, wird also auf der Ebene des Transportlayers angesiedelt. Mittels ICMP tauschen die Hosts Steuerinformationen aus, die sich direkt auf das IP-Protokoll beziehen und Aufschluss über den Zustand des Netzes geben. Neben den Echo-Paketen existieren noch viele weitere Pakettypen, die z.B. Auskunft darüber geben, ob ein Host über einen bestimmten Weg nicht erreichbar ist, oder das die empfangenen Datenpakete in einer zu hohen Geschwindigkeit eintreffen. Näheres dazu beschreibt das RFC …..

Die meisten ICMP-Pakete werden direkt vom Implementierten IP-Stack bearbeitet, so dass eine Anwendung sich in der Regel nicht darum kümmern muss. Genau aus diesem Grund wurde der Ping auch als Beispiel gewählt, da mit RAW-Sockets dennoch ICMP-Pakete gesendet und empfangen werden können.

Der ICMP- Header Der ICMP-Header ist sehr schlank aufgebaut, nur kurze Anfragen und Antworten ausgetauscht werden und keine Verbindungsorientierte Kommunikation erfolgt.

Abbildung 3 : ICMP-Header (Quelle: Tipps zur RAW-Socket Programmierung ) Der allgemeine ICMP-Headers teilt sich in drei Felder. Im Feld Type wird der Typ des Paketes angegeben, also die Art der Nachricht. Code, sofern vom Typ benutzt, spezifiziert die Nachricht genauer. Die Prüfsumme (Checksum) erstreckt sich über das gesamte ICMP-Paket (einschließlich dem von Type und Code abhängigem Teil). Für die Berechnung der Prüfsumme wird das Feld Cecksum selbst mit 0x00 aufgefüllt.

Page 15: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 15 -

ECHO-Request und ECHO-Reply

Abbildung 4 : "ECHO" ICMP-Header (Quelle: RFC 792) Beim Ping werden die Typen 0x00 (ECHO-Reply) und 0x08 (ECHO-Request) verwendet, das Feld Code wird hierbei nicht benutzt und sollte zur Sicherheit auf 0x00 gesetzt werden.

Der Bereich von Type und Code abhängiger Teil wird durch die Felder Identifer und Seqence Number ersetzt, gefolgt von optionalen Daten.

Identifier sollte eine Zufallszahl sein, die das Paket eindeutig zu einem Prozess zuordnet. Somit können zwischen zwei Systemen gleichzeitig mehrere Ping-Kommandos ausgeführt werden. Verschiedene Anfragen und Antworten, die zu einem Prozess gehören werden durch die Sequence Number unterschieden bzw. zugeordnet. Im einfachsten Fall kann die Sequenznummer mit jedem abgesendeten Request inkrementiert werden.

Durch optionale Daten kann das Paket künstlich aufgebläht werden. Pings mit unterschiedlich großen Datenfeldern können somit Aufschluss über das Antwortverhalten (Verzögerung, etc.) des Netzes geben. Die Länge dieses Feldes definiert sich durch die Gesamtlänge des IP-Paketes.

Programmablauf Nun nachdem die Grundlagen geklärt sind soll hier noch kurz der Gesamtablauf des Beispiels erklärt werden.

In der vorbereitenden Phase wurden die Quell und Zieladressen erzeugt und die nötigen Puffer zum Empfangen und Senden der Pakete angelegt. Ebenfalls wurde ein Datenbereich angelegt, der dann in den entsprechenden Sendepuffer kopiert wird. In den Adressstrukturen müssen keine Ports angegeben werden, da ja das ICMP-Protokoll keine Ports kennt.

Abschießend wird der Socket angelegt und die Optionen gesetzt. Das Protokoll für den Socket ist IPPROTO_ICMP, dadurch wird sichergestellt, das nur empfangene ICMP-Pakete an diesen Socket weitergeleitet werden. Danach kann der Socket mit connect() an die Pseudozieladresse gebunden werden, der Socket ist dann lediglich auf das Senden vorbereitet.

Page 16: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 16 -

Abbildung 5 : Codefragment – Ping Jetzt kann im Sendepuffer der IP-Header erstellt werden und die Sequence Nummer und der Identifier initialisiert werden. Ist dies abgeschlossen geht es in eine Sequenzschleife, die je Zyklus eine Anfrage sendet und dann auf Antwort wartet. Weiterhin wird in der Schleife die Sequenznummer erhöht und die ICMP-Prüfsumme gelöscht und erneut berechnet.

In diesem Beispiel muss der IP-Header von Paket zu Paket nicht verändert werden, da sich lediglich die IP-Prüfsumme ändert, die aber vom IP-Stack direkt gesetzt wird.

Das Empfangen an sich geschieht hier ebenfalls in einer Schleife. Da er nur auf ICMP-Paket reagiert ist es nur nötig das empfangene ICMP-Paket auf Identifier und Sequenznummer zu testen. In einem Programm für den realen Einsatz sollte hier unbedingt ein Timeout implementiert werden.

Das Beispielprogramm beendet die Sequenzschleife nach vier Durchläufen, was aber zu Demonstrationszwecken vollkommen ausreichen sollte.

Damit möchte ich auch das erste Beispiel beenden und mich dem nächsten, dem TCP-Flooder zuwenden.

Beispiel 2 – Der SYN-Flooder Wie sie sicherlich gemerkt haben sind hier die beiden Begriffe TCP-Flooder und SYN-Flooder gleichbedeutend. Dies hat seine Ursache im Technischen Hintergrund.

SYN bezeichnet dabei ein Flag im TCP-Header, das zur Synchronisierung benutzt wird bzw. einen Wunsch zum Verbindungsaufbau signalisiert (wenn zuvor keine Verbindung etabliert war). Ob nun das Protokoll, oder das Flag stärker betont wird ist für den Sachverhalt weniger wichtig, da beide Dinge darauf hinweisen womit geflutet wird.

Um das Prinzip des Flooders besser verstehen können sollte man wissen wie im IP oder besser gesagt im TCP Verbindungen aufgebaut werden. Dazu wird das im folgenden Abschnitt erklärte Verfahren eingesetzt.

Page 17: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 17 -

Der 3-Wege-Handshake Mit dem 3-Way-Handshake wird beim Verbindungsaufbau sichergestellt, dass beide Kommunikationspartner einen definierten Ausgangspunkt für die Kommunikation erreichen. Nutzdaten die nach diesem Verbindungsaufbau gesendet werden, werden vom Empfänger auch als solche behandelt. Verlorengegangene Pakete können durch entsprechende Mechanismen im Protokoll erkannt werden. Zu diesen Mechanismen werden die Felder Sequence Number und Acknowledgement Number des TCP-Headers benutzt.

Wie der Name verrät erfolgt der Verbindungsaufbau in drei Schritten. Im ersten Schritt sendet dabei der Host, der die Verbindung aufbauen möchte ein TCP-Paket, das mit gesetztem SYN-Flag den Verbindungswunsch signalisiert. Der Zielhost bestätigt dann dieses Paket indem in seiner Antwort die beiden Flags SYN und ACK gesetzt sind. ACK steht für Acknowledgement, also die Empfangsbestätigung. In dieser Bestätigung muss natürlich auch angegeben werden was bestätigt wird. Hierzu dient das bereits erwähnte Feld Acknowledgement Number. Per Definition wird das Paket bestätigt indem seine Sequenznummer um die Größe der Nutzdaten erhöht wird und als Acknowledge Number zurückgesendet wird. Der Wert entspricht also dem relativen Offset des nächsten erwarteten Oktetts. Während des Verbindungsaufbaues werden nicht unbedingt Nutzdatenübertragen, in diesem Fall wird die nächstfolgende Sequenznummer als Bestätigung gesendet. Als dritten Schritt bestätigt dann der Ausgangshost den Empfang der Bestätigung indem der die gleiche Prozedur mit der Sequenznummer der Bestätigung durchführt.

Nach diesen Schritten ist die Verbindung aufgebaut und die Nutzdaten (höhere Protokolle wie z.B. HTTP) können ausgetauscht werden. Sollte aufgrund von Übertragungsfehlern ein Paket nicht ankommen, so entsteht in der Kette der Sequenz- und Acknowledgenummern eine Lücke, das vermisste Paket kann erneut angefordert werden.

In diesem zweiten Beispiel genügt jedoch der Erste Teil des 3-Way-Handshakes.

Prinzip eines Flooders Prinzip eines Flooders ist es nun unzählige Verbindungen aufzubauen, dabei wird nun nur das erste TCP-Paket mit dem SYN-Flag gesendet. Der Zielhost geht dann davon aus, dass ein anderer Host eine Verbindung aufbauen will und sendet seine Bestätigung. Anschließend wartet er auf das eintreffen der Rückbestätigung, die aber der Flooder nicht senden wird. Dieser ignoriert sogar schon die Bestätigung des SYN-Paketes und sendet fleißig immer neue SYN-Pakete, die den Zielhost derart beschäftigen, dass er sogar in einen instabilen und unsicheren Zustand gelangen könnte.

Programmablauf In diesem zweiten Beispiel ist der eigentliche Programmablauf deutlich einfacher als beim Ping. Der RAW-Socket wird mit dem Protokollparameter IPPROTO_TCP erstellt, dadurch wird der Empfang von TCP-Paketen ermöglicht, was aber in diesem Beispiel keine Anwendung findet. Es sollte jedoch darauf geachtet werden, das die IP-Implementation die Pakete an den Socket weiterleitet bzw. verwirft und nicht mit einem Reset (RST) antwortet. In diesem Fall würde der zu flutende Rechner auf seine Bestätigung ein solches Reset erhalten können und seine Ressourcen wieder freigeben. Die Wahrscheinlichkeit der Überlast wäre deutlich geringer. In der Testumgebung wurden die empfangenen Pakete ignoriert und so bedurfte es keiner gesonderten Behandlung.

Ferner brauchen auch hier in den Adress-Strukturen für Quell- und Zielsystem keine Portnummern angegeben werden, diese werden dann im beim Erstellen des TCP-Headers gesetzt.

Page 18: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 18 -

Im einfachsten Fall würde es ausreichen in einem Sendepuffer das Paket zu erstellen und in einer Endlosschleife zu versenden. Zur besseren Demonstration wurden im Beispiel jedoch zwei Schleifen verwendet, so dass nach 100.000 Paketen eine Statusmeldung aufgegeben wird. Weiterhin sind in der inneren Schleife Funktionen implementiert, die eine Modifikation des Paketes erlauben würden, hier aber lediglich das Paket neu erstellen.

Abbildung 6 : Codefragment - TCP-Flooder Die Funktionen zum Erstellen der Header arbeiten auch hier sehr statisch, da sie ja lediglich zu Demonstationszwecken da sind und das Programm keine Vorlage für einen böswilligen Flooder darstellen soll.

Zur Ergänzung sei hier gesagt, dass viele Systeme sich diesem kritischen Sachverhalt bereits angenommen haben und dafür sorgen, dass das System weiterhin stabil läuft. In der Testumgebung reagierte das System mit der Meldung: „eth0: Too much work in interrupt.“. Allen Anschein nach wurden die Verbindungswünsche, die nicht bearbeitet werden konnten verworfen.

Beispiel 3 – Der TCP-Sniffer Im Dritten und Letzten Beispiel möchte ich mich wieder etwas Seriöserem zuwenden. Der TCP-Sniffer scheint dem Begriff nach vielleicht doch nicht so seriös, aber ich betrachte ihn hier als Diagnosetool, mit dem das eigene Netzwerkinterface untersucht wird. Ein Systemadministrator kann sich mit Hilfe eines solchen Tools einen Überblick über den Netzwerkverkehr verschaffen.

Der Aufbau dieses Programms ist weitestgehend unabhängig von dem Protokoll, das mitgeschnitten werden soll, genauso gut hätte auch das UDP Protokoll verwendet werden können. Der besseren Demonstration halber wurde hier TCP gewählt.

Prinzip eines Sniffers Der Grund beziehungsweise die Eigenschaft, die es überhaupt ermöglicht Pakete mitzuschneiden liegt darin, dass der Raw-Socket eine Kopie der Eingehenden Pakete erhält.

Page 19: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 19 -

Somit arbeiten die Programme für die das Paket eigentlich bestimmt ist ohne Probleme weiter. Wenn der Socket für ein Bestimmtes Protokoll erstellt wurde, dann filtert bereits der IP-Stack des Kernels die relevanten Pakete und stellt auch nur von Diesen eine Kopie zu.

Letztlich ist das auch schon die Funktionsweise eines Sniffers – an einem Interface zu lauschen und bestimmte Pakete mitzuschneiden. In der Praxis werden die Pakete häufig genauer analysiert, so werden sie zum Beispiel auf bestimmte Muster hin überprüft – ein Missbrauch wäre so das gezielte Suchen nach Passwörtern.

Ein wichtiger Punkt, der sich in diesem Beispiel ergibt und unbedingt geklärt werden sollte ist die Tatsache, dass es sich hier immer noch um Raw-Socket des Internetprotokolls handelt, daher werden auch nur IP-Pakete mitgeschnitten. Viele Werkzeuge, wie zum Beispiel Ethereal arbeiten mit paketbasierenden Capture-Routinen, die bereits Ethernet-Frames mitschneiden und daher noch mehr Informationen liefern können.

Programmablauf Wie auch in den anderen Beispielen wird hier in der ersten Phase der RAW-Socket erzeugt. Dies geschieht üblicher Weise mit dem socket(…) -Befehl und den setzten der Optionen.

Abweichend von den anderen Beispielen wird hier jedoch nicht der connect(…) -Befehl zum Verbindungsaufbau benutzt, sondern ein bind(…) ausgeführt. Der Grund hierfür liegt darin, dass es keinen speziellen Zielhost gibt, von dem die Pakete empfangen werden sollen. Der Socket empfängt dann alle Pakete, die an die entsprechende lokale Adresse gesendet wurden, unabhängig von wo sie kommen. Da Ports erst Bestandteil der Transportprotokolle TCP und UDP sind, spielt es auch keine Rolle, von und an welchem Port diese Pakete sind.

In der zweiten Phase wird wieder eine Schleife durchlaufen, die jedes neu ankommende Paket analysiert. Im Beispiel werden die Daten für Absender-IP, Ziel- und Quellport herausgefiltert. Zusätzlich wird die Anzahl der empfangenen Bytes und der Payload ausgegeben.

Abbildung 7 : Codefragment - TCP-Sniffer Zur Vereinfachung wurde darauf verzichtet den Payload näher zu untersuchen. Sofern nur lesbare ASCII-Zeichen enthalten sind wird die Ausgabe auch keine Probleme damit haben. Daher eignet sich dieses Beispiel gut für HTTP- oder FTP-Requests.

Page 20: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 20 -

Zusammenfassung

Rundum sind die RAW-Sockets, wie die Beispiele doch zeigen sollten, ein sehr interessantes Thema. Mit ihrer Möglichkeit, die Pakete zum großen Teil selber zu Erstellen eröffnen sie dem Anwendungsentwickler eine gute Basis zur Entwicklung eigener IP-basierender Protokolle. Weiterhin sind ihm dadurch Möglichkeiten gegeben Überwachungstool zu entwickeln, die seinen eigenen Bedürfnissen entsprechen. Dies setzt natürlich voraus, dass dies durch die entsprechende API möglich ist.

Oft werden RAW-Sockets in die Ecke des illegalen geschoben und als unsicher betrachtet, jedoch ist das meiner Meinung nach eine zu voreilig getroffene Bewertung. Jedes Werkzeug kann man für gute als auch für schlechte Dinge gebrauchen und so ist es auch mit den RAW-Sockets. Es kommt immer auf die Absicht des Nutzers bzw. des Entwicklers drauf an.

Fakt ist jedenfalls, dass die Programmierung mit RAW-Sockets besonders gut durchdacht sein sollte, da es ohne Zweifel ein Sicherheitsrelevantes Thema ist – sowohl für die Stabilität des Systems, als auch wegen möglicher Angriffpunkte die sich ergeben könnten.

Page 21: RAW-Sockets - iks.hs-merseburg.deuheuert/pdf/Anwendung Rechnernetze/Vortraege... · Wichtigster Aspekt ist hier, dass sich die Anwendung vor Nutzung eines Sockets beim Betriebsystem

- 21 -

Literaturverzeichnis:

Netzwerkprogrammierung unter LINUX und UNIX; Stefan Fischer, Walter Müller; UNIX easy Embedded Internet in der Industrieautomation; Klaus-D. Walter; Hüthing Beej’s Guide to Network Programming Using Internet Sockets (PDF); Brain „Beej“ Hall Netzwerkprogrammierung mit BSD-Sockets (PDF); Felix Opatz - Zotteljedi Programmierung in der Unix-Umgebung; W. Richard Stevens; Addison-Wesley

LINUX ManPages (Fedora Core 5 Distribution – http:/ /www.fedora.de) Section 7 – socket Section 7 – packet Section 7 – raw Section 7 – ip Section 7 – tcp Section 7 – udp Section 7 – icmp Section 2 – bind Section 2 – connect

RFC – Request For Comment RFC 791 - Internet Protocol RFC 792 - Internet Control Message Protocol RFC 793 - Transmission Control Protocol RFC 768 - User Datagram Protocol RFC 1700 - Internet Assigned Numbers

Internetseiten http://www.wikipedia.de; 31.10.2006 http://www.codeproject.com/csharp/pktcap.asp; 31.10.2006 http://www.slaughterarts.de/code/syn_flooding.html, 31.10.2006 http://en.wikipedia.org/wiki/Internet_socket, 31.10.2006 http://en.wikipedia.org/wiki/Raw_socket, 31.10.2006 http://www.zotteljedi.de/doc/socket-tipps/index.html, 31.10.2006