Vorbereitung
Der Startbildschirm
Wireshark
ist ein relativ vielseitiges Werkzeug von dem wir in diesem Praktikum nur die absoluten Grundlagen behandeln. Aber selbst nur mit diesen Grundlagen ausgestattet, kann man komplexe Fragestellungen mithilfe von Wireshark
beantworten. Nachdem Wireshark
gestartet wurde, sollte folgender Startbildschirm erscheinen (je nach Plattform gibt es evtl. leichte Unterschiede):
Die in der Abbildung nummerierten Boxen zeigen:
- Im zentralen Feld der Oberfläche sieht man eine Aufzählung der auf dem Rechner befindlichen Schnittstellen. Dabei zeigt rechts neben dem Namen ein kleiner, fortlaufender Graph Aktivität auf der Netzwerkschnittstelle an. In der Abbildung sieht man z.B., dass die WiFi-Schnittstelle
en0
ganz oben Aktivität aufzeigt, d.h. es werden Pakete empfangen/gesendet. Die Schnittstelle gleich darunter zeigt z.B. keinerlei Aktivität. Ein Doppelklick auf eine dieser Schnittstellen würde die Paketaufzeichnung auf eben dieser starten. - Der Haiflossen-Button startet ebenfalls die Aufzeichnung auf der in 1. ausgewählten Schnittstelle.
- Diese Schaltfläche führt zu weiteren Einstellungen. Von hier aus kann man ebenfalls eine Schnittstelle auswählen und die Aufzeichnung starten. Man kann aber auch andere Dinge tun, wie z.B. einen Dateinamen angeben in dem die Aufzeichnung gespeichert werden soll oder das Verhalten von Wireshark während der Aufzeichnung einstellen.
- Wie schon erwähnt kann man die Aufzeichnungen von Wireshark auch abspeichern. Über diese Schaltfläche kann man eine solche Datei öffnen, anstelle live von einer Netzwerkschnittstelle zu lesen.
- Hier werden verschiedene Quellen angezeigt, die Hilfe bereitstellen. Beim anklicken öffnen sich diese im Browser.
- Der Vollständigkeit halber sei gesagt, dass Wireshark alles aufzeichnet, was an Paketen ankommt und versendet wird. Das kann sehr viel sein und oft sind ein Großteil der Pakete uninteressant. Man kann Wireshark aber auch mit einem
Capture-Filter
dazu bringen nur die Pakete aufzuzeichnen, an denen man wirklich interessiert ist. Diese nutzen wir hier nicht, weil wir dafür später sogenannteDisplay-Filter
verwenden. Damit werden auch nur die Pakete angezeigt, die wir sehen wollen, aber dennoch werden alle Pakete aufgezeichnet. Sollte man feststellen, dass man vielleicht doch noch etwas anderes sehen möchte ist dies dann immer noch möglich. Die Syntax von Capture-Filtern und die von Display-Filtern sind grundsätzlich unterschiedlich und inkompatibel.
Paketaufzeichnung
Starten Sie die Paketaufzeichnung auf ihrer Hauptnetzwerkschnittstelle (wahrscheinlich die, die die meiste Aktivität zeigt). Die Oberfläche sollte sich ändern und Sie sollten in etwa dies hier sehen:
Die in der Abbildung nummerierten Boxen zeigen:
- Kontrollelemente um die Aufzeichnung zu starten, zu stoppen und neu zu starten.
- Die
Display-Filter
-Zeile. Hier könnenDisplay-Filter
eingegeben werden, die aus der Flut der Pakete nur noch die anzeigt, die auf den Filterausdruck passen (mehr dazu später). Dies ist die wohl wichtigste Einstellmöglichkeit von Wireshark und das primäre Augenmerk dieses Praktikums. Um sinnvolle Filterausdrücke schreiben zu können, muss man sich aber mit den jeweiligen Protokollen und wie ein Paket aufgebaut ist ein wenig auskennen. Ein Glück, dass es in dieser Vorlesung primär um Protokolle des Internets geht. - In dieser Liste werden die eingehenden und ausgehenden Pakete dargestellt. Jede Zeile entspricht dabei einem Paket. In der Standardeinstellung werden die Pakete chronologisch sortiert, aber die Ansicht lässt sich auch nach den anderen Spalten sortieren, indem man die jeweilige Spaltenüberschrift anklickt. Spalten können auch entfernt, oder hinzugefügt werden und neue Spalten können definiert werden. Wir arbeiten aber mit den Standardeinstellungen. Hier sollte es Spalten geben für:
- eine von Wireshark generierte, einfache, streng monoton steigende Rahmennummer,
- die Empfangs- bzw. Sendezeit (ab Beginn der Aufzeichnung),
- Quell- und Ziel-IP-Adresse,
- das höchste im Paket identifizierte Protokoll,
- die Länge des Pakets und
- eine Infospalte, die die gängigsten Informationen zusammenfasst.
- Klickt man in der Paketliste (3) auf eines der Pakete, dann wird dieses hier im Detail dargestellt. Die im Paket befindlichen Steuerinformationen der Protokolle werden hier - sortiert nach Protokoll - visuell aufbereitet und strukturiert dargestellt. Wer genau hinschaut erkennt den behandelten Protokollstapel, allerdings in umgekehrter Reihenfolge. Bei vielen Protokollen ist hier auch die Antwort bzw. Anfrage verlinkt, d.h. man kann dem Link durch klicken folgen und bekommt diese angezeigt.
- Wer die Paketdaten lieber so sieht, wie sie tatsächlich versendet wurden, der findet das Paket als Hexdump hier. Klickt man in der Paketdetailansicht (4) auf ein Feld, dann wird es hier auch hervorgehoben. Hier im Beispiel wurde das TTL-Feld des IPv4-Protokoll-Headers angeklickt und der Hexwert (0x40) wird hier hervorgehoben. Rechts neben der Hex-Ansicht wird das Paket auch in ASCII dekodiert. Bei vielen Paketdaten stehen hier nicht druckbare Symbole (durch Punkte dargestellt). So kann man aber leicht erkennen, ob ASCII-Text im Paket vorkommt, was bei vielen Protokollen der Anwendungsschicht z.B. der Fall ist.
- Die Statuszeile wird oft übersehen, aber in Ihr befinden sich viele wertvolle Informationen. So wird z.B. links angezeigt wie große das aktuell ausgewählte Protokollfeld ist (hier das ein Byte große TTL-Feld) und mit welchem Display-Filterausdruck man dieses Feld referenzieren kann (hier:
ip.ttl
). Auch rechts stehen interessante Informationen. Hier wird angezeigt wieviele Pakete aufgezeichnet wurden und wieviele davon angezeigt werden. Das ist in diesem Fall identisch, da noch kein Display-Filter gesetzt wurde.
Display-Filterausdrücke
Wie schon erwähnt reduzieren Display-Filter die angezeigten Pakete in der Paketliste auf die Pakete, die auf den Filterausdruck passen. Der wahrscheinlich einfachste Audruck ist ein Protokollname. Protokollnamen werden dabei klein geschrieben, also z.B. dns
und nicht DNS
oder ip
und nicht IP
! Es werden dann nur noch Pakete angezeigt, die zu diesem Protokoll passen.
Im der Abbildung oben sieht man was passiert, wenn ein Filter angewendet wird. Hier wurde der eben erwähnte dns
Protokollfilter genutzt. Dabei fallen folgende Dinge auf:
- In der Paketliste werden nur noch DNS Pakete angezeigt
- Die Statusleiste zeigt an, wieviele Pakete aktuell angezeigt werden. Von über 155.000 Paketen sind gerade einmal 14 übrig geblieben (diese werden aber wieder angezeigt, wenn der Filterausdruck gelöscht wird). Man kann sich leicht vorstellen, dass die Analyse von 14 DNS Paketen, die zwischen 155.000 Pakete versteckt sind eine Herausvorderung darstellen würden. Dank des Filterausdrucks ist diese Aufgabe viel einfacher geworden.
- Der DNS-Protokoll-Header im Paket wurde angeklickt. Jetzt sieht man das der DNS-Teil des Pakets 34 Byte gross ist (Statuszeile)
- Man sieht auch, dass ASCII-Anteile im DNS-Header vorkommen. Das sieht einem DNS-Namen sehr ähnlich!
Nach Protokollen filtern zu können ist schon sehr hilfreich, aber wäre es natürlich wünschenswert, wenn man nach mehr als nur dem Protokoll filtern könnte, z.B. nach bestimmten Protokolleigenschaften und Header-Werten. Mit Wireshark ist dies möglich. Eigenschaften bzw. Header-Felder eines Protokolls werden mit einem Punkt vom Protokoll getrennt im Filterausdruck angegeben. Dies hatten wir oben schon mit ip.ttl
gesehen. Nur ip.ttl
als Ausdruck zu nutzen wäre aber wenig sinnvoll, denn damit werden alle IP-Pakete, die ein TTL-Feld enthalten angezeigt und das sind alle IP-Pakete. Was man möchte, ist auf den Wert von gewissen Feldern filtern. Hier kommen logische Ausdrücke und Vergleichsoperatoren zum Einsatz. Vergleichsoperatoren haben eine Variante, welche der Englischen Sprache entstammen und eine Variante, die an C-Syntax erinnert. Man kann nach belieben zwischen diesen Varianten wählen.
Vergleichsoperatoren
Englisch | C-Syntax | Beschreibung | Beispiel |
---|---|---|---|
eq | == | Gleich | ip.src==10.0.0.5 |
ne | != | Ungleich | ip.src!=10.0.0.5 |
gt | > | Größer als | frame.len > 10 |
lt | < | Kleiner als | frame.len < 128 |
ge | >= | Größer oder gleich | frame.len ge 0x100 |
le | <= | Kleiner oder gleich | frame.len <= 0x20 |
contains | Protokoll oder Protokollfeld beinhaltet eine Wert | sip.To contains “a1762” | |
matches | ~ | Protokoll oder Text matched eine Perl-kompatible Regex | http.host matches “acme.(org|com|net)” |
bitwise_and | & | Bitweise Und-Verknüpfung | tcp.flags & 0x02 |
Die meisten der oben angegeben Vergleichsoperatoren bedürfen wahrscheinlich keiner großen Erklärung. Als Vergleichswerte gibt es (signed) Integer (auch als Octal- oder Hexadezimalzahl (0123
, 0xA3F
)), True und False sind als 1
und 0
kodiert (hilfreich um zu überprüfen, ob Protokoll-Flags gesetzt sind, z.B. tcp.flags.syn == 1
), Ethernet-Adressen (z.B. FF:FF:FF:FF:FF:FF
, die Ethernet-Broadcast-Adresse), IP-Adressen (z.B. 192.168.0.1
(v4) oder ::1
(v6)) und Strings (z.B. “User-Agent”). Zu den IP-Adressen sollte nicht unerwähnt bleiben, dass auch IP-Präfixe (Adressbereiche) in CIDR-Notation angegeben werden können (z.B. 192.168.0.0/16
). Vieles davon wird aber in diesem Praktikum noch nicht benötigt.
Auch wenn Vergleichsoperatoren schon viel genauere Ausdrücke erlauben als es ein einfacher Protokollfilert zulässt, ist es auch nur mit hilfe dieser Ausdrücke unmögliche komplexe Filterausdrücke zu schreiben. So kann man z.B. nicht alle TCP Pakete anzeigen lassen, die von einer bestimmten IP Adresse aus gesendet wurden. Dazu braucht man zusätzlich logische Operatoren um Vergleichsoperationen zu verknüfen. Die folgende Tabelle zeigt die in Wiresharks Filtersprache enthaltenen logischen Operatoren. Auch hier kann man wieder zwischen der Englischen under C-artigen Variante frei wählen und kombinieren.
Englisch | C-Syntax | Beschreibung | Beispiel |
---|---|---|---|
and | && | logische Und-Verknüpfung | ip.src==10.0.0.5 and tcp.flags.fin |
or | || | logische Oder-Verknüpfung | ip.scr==10.0.0.5 or ip.src==192.1.1.1 |
xor | ^^ | logisches Entweder-Oder | tr.dst[0:3] == 0.6.29 xor tr.src[0:3] == 0.6.29 |
not | ! | logische Negation | not llc |
[…] | Untersequenz | Details in der offiziellen Dokumentation | |
in | Auf Vorhandensein in einem Set prüfen | http.request.method in {“HEAD” “GET”} |
Bewaffnet mit Vergleichsoperatoren und logischen Operatoren kann man sehr komplexe Filterausdrücke schreiben um wirklich nur noch die Pakete angezeigt zu bekommen, die man sehen möchte.
Es gibt zusätzlich noch einen kleinen Satz an Funktionen, die man auf Protokollfelder anwenden kann, so z.B. Text in Zahlen umwandeln, oder Groß- in Kleinschreibung umwandeln und umgekehrt. Für Details wird hier aber auf die offizielle Dokumentation verwiesen.
Ganz zum Schluss noch ein paar Worte zu den letzten beiden Zeilen in der Tabelle der logischen Operatoren: den Untersequenzen und der Prüfung auf Vorhandensein in einem Set. Diese werden wir kaum nutzen, sind aber der Vollständigkeit halber hier aufgeführt. Es gibt auch hier eine Reihe an Syntax-Varianten. Für die komplette Liste und Beschreibung wird an dieser Stelle aber auf die offizielle Dokumentation verwiesen.
Filterausdrücke generieren
Mit dem Wissen aus dem vorherigen Abschnitt sollte man jetzt in der Lage sein händisch in der Display-Filterzeile Filterausdrücke zu formulieren. Dazu muss man sich natürlich mit den zu untersuchenden Protokollen auskennen. Ohne dieses Wissen lassen sich keine sinnvollen Audrücke erstellen. Zusätzlich muss man auch die Namen der Protokollfelder in Wireshark kennen, die nicht immer 1:1 dem Namen entsprechen, den der Protokollstandard verwendet. Auswendig muss das aber keiner lernen, denn Wireshark hat diverse Möglichkeiten beim Bauen eines Filterausdrucks zu helfen.
Fangen wir mit der Display-Filterzeile selbst an. Wer hier anfängt zu tippen bekommt Hilfe durch ein Kontextmenü. Gibt man z.B. nur ein h
ein, öffnet sich eine Liste aller Protokolle, die mit h
beginnen. Tippt man fleissig weiter und beendet mit z.B. http
, dann kann man durch einen Punkt die Protokolleigenschaften vom http
-Filter im Kontextmenü einsehen. Auch alte Filterausdrücke, die man schon einmal verwendet hat werden im Kontextmenü angezeigt (siehe Abbildung unten, das Kontextmenü ist rot eingerahmt).
Man sieht im Kontextmenü auch, dass ein Protokollfeld evtl. weitere, untergeordnete Informationen enthält. So kann bei http
zum Beispiel auf Antworten gefiltert werden mit http.response
. Dort kann dann wiederum der response code als Ausdruck gefunden werden mit http.response.code
.
Eine andere Art einen Filterausdruck zu erstellen findet man, wenn man in der Filterzeile rechtsklickt und Display Filter Expression
wählt (oder über Analyze
im Hauptmenü). Hier öffnet sich ein selbsterklärender Dialog den man nutzen kann um einen Ausdruck zu generieren.
Der Dialog ist etwas umständlicher zu benutzten als die Filterzeile selbst, aber man kann hier wunderbar durch die Protokolle navigieren. Wer sich mit Filtern nicht so gut ausgekennt ist hier vielleicht besser aufgehoben.
Letztlich kann man auch aus den Paketdaten heraus Filter generieren. Wenn man in der Paketliste oder in der Paketdetailansicht auf ein Protokollfeld rechtsklickt, und in dem erscheinenden Menü Apply as Filter
oder Prepare as Filter
auswählt, dann kann man so aus den Paketdaten heraus schnell Filter generieren. Das hat den praktischen Vorteil, dass sich so keine Typos einschleichen, allerdings muss man auch schon ein Paket gefunden haben, dass einen interessiert. Der Filter, der generiert wird ist leicht ausgegraut im Menü zu sehen.
Pakete markieren
Manchmal ist es interessant, wie lange Anfrage und Antwort auseinanderliegen. Die in Wireshark angezeigten Zeiten sind Zeitstempel, die die Zeit seit dem Start der Aufzeichung angeben. Wenn man die Pakete zwischen denen man die Zeit ermitteln möchte gefunden hat, dann kann man beide Werte voneinander abziehen, um die Zeit, die zwischen diesen beiden Pakete vergangen ist zu berechnen. Das ist allerdings recht umständlich und Wireshark bietet eine einfachere Methode an. Wenn Sie in der Paketliste via Rechtsklick das Kontextmenü öffen, werden Ihnen ein paar hilfreiche Funktionen angeboten. Eine davon ist setzen und löschen der Zeitreferenz (siehe Abbildung unten). Man kann bei beliebigen Paketen zeitlich wieder bei 0 anfangen. D.h. wenn man bei einer Anfrage die Zeitreferenz wieder auf 0 setzt, dann kann man die Zeit, die vergangen ist einfach bei der Antwort ablesen. Auch kann man Pakete markieren. Diese sind dann farblich hervorgehoben und sie verschwinden auch nicht, wenn ein Filter gesetzt wird, auf den das markierte Paket nicht passt. Indem man Pakete ignoriert, kann man diese auch “ausblenden”. Die Pakete sind zwar noch dargestellt, aber die Paketdetails werden ausgeblendet. Auch werden diese Pakete bei Filtern nicht mehr angezeigt, auch, wenn der Filter greifen würde. Mehrere Pakete kann man übrigens auf einmal ignorieren oder markieren. Das gilt aber nur für alle aktuell angzeigten und geschieht über das Edit
-Menü im Hauptmenü. Filter auf markierten Paketen erfolgt mit frame.marked == 1
.
Erweiterte Statistiken
Wireshark kann Vieles, aber gewisse Dinge sind durch Filterausdrücke nicht zu erreichen, denn die Filtern reduzieren die Anzahl an angezeigten Pakten, aber man kann z.B. keine besonderen Statistiken durch Filter auf den noch verbleibenden Paketen ausführen. Man kann sich z.B. alle HTTP-Antworten anzeigen lassen, aber nicht die Anzahl an verschiedenen darin befindlichen Status-Codes zählen lassen, denn die Antwort wäre eine Zahl und nicht eine Liste an Paketen. Für einige Protokolle gibt es solche erweiterte Statistiken, die mit Display-Filtern nicht generiert werden können. Diese befinden sich im Hauptmenü unter Statistics
. Für HTTP
und HTTP2
z.B. werden erweiterte Statistiken angeboten. Schauen Sie mal rein!
Gotchas
Es gibt ein paar Fehler, die man insbesondere als Wireshark-Newbie macht.
Es gibt Filterausdrücke wie ip.addr
oder tcp.port
die für mehr als ein Feld in einem Protokoll stehen. ip.addr
z.B. steht für die Sender-IP-Adresse und die Empfänger-IP-Adresse! D.h. ein Ausdruck wie dieser hier:
ip.addr != 192.168.0.1
wird Pakete anzeigen, die 192.168.0.1 als Adresses beinhalten, denn die zweite Adresse in einem Paket wird eine andere sein. Wer z.B. nur die Sender-IP-Adresse ansprechen will sollte diesen Filter benutzen:
ip.src != 192.168.0.1
Wer wirklich ausschliessen möchte, dass die IP-Adresse weder als Sender noch als Empfänger vorkommt könnte z.B. diesen Ausdruck verwenden:
! ( ip.addr == 192.168.0.1 )
Eine weitere mögliche Quelle der Verzweiflung ist, dass Paketinhalte manchmal vermeintlich nicht richtig dargestellt werden. So kann es z.B. passieren, das eine HTTP-Antwort komprimiert wird und man diese komprimierte Antwort ja nicht lesen kann, man bei HTTP aber lesbaren ASCII-Text erwartet. Wireshark bietet aber typischerweise alle Darstellungsweisen an, wenn Sie denn darstellbar sind. Das sieht man als Reiter in der Hex-Ansicht der Pakete wie in folgender Abbildung im unteren roten Kasten hervorgehoben.
Was man hier auch gut sieht ist, dass die HTTP-Antwort so groß war, dass sie über viele TCP-Segmente verteilt gesendet werden musste (in der Detailpaketansicht sieht man, dass es insgesamt 35 Segemente waren). Das letzte dieser Segmente wird als HTTP-Paket dargestellt. Die darin befindlichen Daten sieht man, wenn man den ersten Reiter wählt. Wenn man alle 35 Segmente zusammengefügt, und damit die komplette HTTP-Nachricht sehen möchte, dann muss man den zweiten Reiter wählen. Dies wird in der Abbildung gezeigt und man sieht deutlich, dass kein ASCII-Text zu sehen ist. Der Grund ist, dass die Daten in der Antworte komprimiert wurden (der HTTP-Header übrigens nicht!). Wenn man die unkomprimierten Daten sehen möchte, dann muss man den letzten Reiter wählen.
Jetzt sollten Sie in der Lage sein…
- Die Aufzeichnung von Paketen starte und stoppen
- Filterausdrück für Sie bekannte Protokolle bilden
- Pakete markieren, um z.B. Zeiten zu messen und sich erweiterte Statistiken anzuschauen.
Spielen Sie ein bisschen mit Wireshark herum, um die Bedienung und das erstellen von Display-Filtern zu üben. Bezgl. HTTP sei noch gesagt, je nachdem an welcher HTTP-Version man interessiert ist, gibt es zwei verschiedene Protokollfilter. Für die Versionen 1.x gibt es den Protokollausdruck http
, für Version 2 wird http2
verwendet. Wie man beide Protokollversionen herausfiltert sollte für Sie kein Problem mehr darstellen. Beim testen zu Hause seien Sie gewarnt, es könnte sein, dass Sie relativ wenig sehen werden, aber das ist normal und wird im Praktikum korrigiert! www.example.com
aber z.B. sollte funktionieren.
Viel Erfolg!