Dieses Praktikum ist eine Einführung in eines der wichtigsten Werkzeuge im Netzwerkbereich zur Analyse von Protokollen, Paketen und Vorgängen im Netz: Wireshark. Wireshark
wird uns im Laufe der Vorlesung begleiten, daher ist es wichtig sich gleich am Anfang mit diesem Werkzeug vertraut zu machen.
Mit Wireshark
kann man Paketen live zuschauen, wie diese bei einer Netzwerkschnittstelle ankommen und versendet werden. Dies ist nützlich bei der Analyse des Netzwerks aber auch beim Entwickeln und Debuggen von Netzwerkanwendung und vieles mehr. Wireshark
ist hier sowas wie ein Industriestandard und wird auch im professionellen Umfeld häufig eingesetzt. Des Weiteren werden wir in diesem Praktikum HTTP besser kennenlernen, eines der wohl wichtigsten Protokolle der Anwendungsschicht. Gerade weil HTTP so zentral ist, ist es wichtig sich damit gut auszukennen und damit ist HTTP auch ein guter Anwendungsfall für die Einführung in Wireshark
.
Wireshark
selbst ist eine Anwendung, die auf allen gängigen Betriebssystemen lauffähig ist. Für dieses Praktikum kann/sollte Wireshark
auf dem eigenen Rechner installiert werden, denn es kann im Laufe der Vorlesung auch als praktische Lernhilfe verwendet werden, denn man kann damit jederzeit Paketverläufe nachvollziehen, Steuerinformationen in den Paketköpfen anschauen und so ein besseres Gespür für das Erlernte entwickeln und dieses verfestigen.
[Download Wireshark](https://www.wireshark.org/#download)
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:
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.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 sogenannte Display-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.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:
Display-Filter
-Zeile. Hier können Display-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.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.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:
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.
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.
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
.
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!
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.
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!
Kommen wir zur ersten Aufgabe. Heute dreht sich alles um HTTP 1.x. Laden Sie folgende Paketaufzeichnung heruntern und öffnen Sie diese in Wireshark. Mit Ihren neu erworbenen Fähigkeiten, beantworten Sie bitte folgende Fragen bezüglich der HTTP/1.x-Pakete in der Paketaufzeichnung. Diese Aufgabe dient dazu, dass Sie zum einen mit Wireshark warm werden, aber auch, um zu üben grundlegende Eigenschaften und Abläufe von HTTP mit Wireshark nachvollziehen zu können.
Zum Schluss vielleicht doch noch ein paar HTTP2 Fingerübungen. In HTTP2 ist ja alles ein wenig anders. Am interessantesten für uns sind aber die Header-Informationen, die im HEADERS-Frame zu finden sind. Insgesamt sind in HTTP2 die Filter nach Frames sortiert. Probieren Sie mal folgendes:
HTTP lässt sich heutzutage nicht mehr so einfach aufzeichnen. Warum und wie man es dann doch wieder schafft lernen Sie jetzt. Auch schauen wir uns ein Browser-Feature an, dass Web-Developer häufig einsetzen.
Beginnen Sie Pakete von Ihrer Hauptnetzwerkschnittstelle aufzuzeichnen. Besuchen Sie mit dem Chrome Browser die Webseite der Hochschule (www.hs-augsburg.de). Wenn Sie fertig sind, stoppen Sie die Aufzeichnung mit Wireshark und versuchen Sie Anfragen an den Spiegel zu finden. Wundern Sie sich nicht, wenn sie nicht fündig werden! (Hinweis: wenn sie etwas finden, dann sollte das maximal eine Weiterleitung sein)
Der Grund warum Sie nichts gefunden haben ist, dass viele Webseiten Ihre Daten mittlerweile verschlüsseln. Heißt das, Wireshark kann nicht mehr genutzt werden? Nicht ganz. Man muss Wireshark nur mitteilen, wo die Sitzungsschlüssel liegen. Die großen Browser (Firefox und Chrome) z.B. können diese loggen und Wireshark kann diese dann lesen. Auch Python Developer z.B. können dieses Feature nutzen, um den Netzwerkverkehr ihrer Anwendungen zu debuggen. Dazu muss man die Umgebungsvariable SSLKEYLOGFILE setzen und Firefox neu starten. Dabei geht man wie folgt vor:
export SSLKEYLOGFILE=/home/student/keylog.log
firefox &
www.hs-augsburg.de
, Sie sollten wie gewohnt HTTP und/oder HTTP2 in Wireshark sehen.Vielleicht haben Sie schon mal gesehen, dass Brower Private Windows
oder Incognito Windows
anbieten. Aber was passiert eigentlich, wenn solche Fenster benutzt werden? Das können Sie ja jetzt einfach herausfinden.
Der Browser übernimmt viel Arbeit, allerdings kann man die Arbeit des Browsers selbst übernehmen, denn HTTP, wie viele andere Protokolle auch, ist ein US ASCII codiertes Protokoll. Gehen Sie in die Shell und verbinden Sie sich mit dem Hochschul-Webserver via telnet
:
telnet www.hs-augsburg.de 80
gnutls-cli
gnutls-cli
:gnutls-cli www.hs-augsburg.de
In der Vorlesung haben wir ein paar, aber bei weitem nicht alle HTTP Paketkopffelder besprochen. Recherchieren Sie die Aufgabe der folgenden Felder:
Stellen Sie sicher, dass Sie die Funktion der Felder verstanden haben.
Mit dem Browser, den Sie für Ihr tägliches Browsen benutzen, vergleichen Sie mal, ob es Unterschiede gibt, wenn Sie gewisse Webseiten mit diesem Browser einmal ganz normal und einmal in Private Window besuchen. Hier ein paar Vorschläge:
Probieren Sie mal das Private Window von Chrome aus. Schickt Chrome auch den DNT Header? Vermuten Sie mal, warum Chrome sich so verhält.
Ich würde mich über Ihre Kritik und Verbesserungsvorschläge freuen. Auch Lob, klar. Eine kurze Umfrage finden Sie hier.