WLAN-Sicherheit mit Python-Skripten erforschen

Joachim Wendler , 123RF

Lauschangriff

WiFi ist heute allgegenwärtig. Es steckt nicht nur im heimischen WLAN-Router oder in so gut wie jedem Smartphone, auch in Werbetafeln und Überwachungskameras, in der Abfahrtszeitenanzeige an Haltestellen und sogar in Medizintechnik. Wenige Zeilen Python reichen, um der Sicherheit dieser Anwendungen auf den Zahn zu fühlen.
Drahtlose Netzwerke sind überall: Zu Hause, im Café und in der Firma. Im Gegensatz zu Kabelnetzen verliert der Admin bei WLANs allerdings schnell die ... (mehr)

WLAN-Netze (802.11) funken abhängig vom Standard auf den Frequenzen 2,4, 3,6 oder 5 GHz. Am weitesten verbreitet sind 2,4-GHz-Netze. Dieses Frequenzband ist dabei je nach Region weiter in Channel unterteilt. Das WLAN-Netz lässt sich entweder im Ad-hoc- oder im Infrastruktur-Modus betreiben. Ad-hoc bedeutet, dass zwei oder mehr Stationen direkt miteinander kommunizieren wollen. Beim Infrastruktur-Modus dient dagegen ein sogenannter Accesspoint als Vermittler. Damit ergibt sich hier eine sternförmige Topologie, in der der Accesspoint ähnlich wie ein Switch im Ethernet-Netzwerk agiert. Dieser Infrastruktur-Modus ist für WLAN-Netze der Normalfall.

Ein paar Grundlagen

Ein Client hat verschiedene Möglichkeiten, um sich über verfügbare Netze zu informieren. Eine Informationsquelle sind die Beacon-Frames, die der Accesspoint alle paar Millisekunden sendet. Jeder dieser Frames enthält Informationen wie die SSID (also den Netzwerknamen), die unterstützten Übertragungsraten und optional noch weitere Daten wie den verwendeten Channel und eingesetzte Sicherheitsmechanismen.

Der Client kann aber auch selbst aktiv werden und sogenannte Probe-Requests verschicken. Dabei fragt er entweder explizit nach Netzen, mit denen er schon mal verbunden war, oder er verwendet ein Nullbyte als SSID (Broadcast-SSID). Der Accesspoint antwortet darauf mit einem Probe-Response-Paket.

Das Protokoll 802.11 unterscheidet drei verschiedene Arten von Paketen oder Frames, nämlich die Typen Management, Data und Control. Abbildung 1 zeigt den schematischen Aufbau eines solchen Frames. Der Typ Management beinhaltet Pakete wie Beacons, Probe-Requests und Responses sowie (De-)Authentication und (De-)Assocciation. Der Typ Data enthält die eigentlichen Daten. Control-Pakete dienen dazu, die Reservierung des Mediums zu steuern sowie den Erhalt der Daten-Pakete zu bestätigen.

Abbildung 1: Der Header eines IEEE-802.11-Frames.

Der Frame-Control-Header eines Pakets definiert mithilfe von Typ und Subtyp, um was für ein Paket es sich handelt. Management-Frames haben den Typ 0, Control-Frames den Typ 1 und Data-Frames den Typ 2. Die Bedeutung der jeweiligen Management-Frame-Subtypen zeigt die Tabelle 1. Sie können als Filter in Wireshark sehr nützlich sein: Zum Beispiel unterdrückt man mit »wlan.fc.subtype!=8« alle Beacon-Frames.

Tabelle 1

Management-Frame-Subtypen

Nr.

Name

0

Association Request

1

Association Response

2

Reassociation Request

3

Reassociation Response

4

Probe Request

5

Probe Response

8

Beacon

9

Announcement Traffic Indication Message

10

Disassociation

11

Authentication

12

Deauthentication

13

Action

Der Duration-Header wird vorwiegend dazu verwendet, anzuzeigen, wie viele Mikrosekunden das Medium nach diesem Paket noch belegt ist. Die Control-Frames Request-to-Send (RTS) und Clear-to-Send (CTS) dienen dazu, das Medium zu reservieren. Eine Station, die viele Daten senden will, kann vorher ein RTS-Paket mit gesetztem Duration-Header senden. Andere Stationen werden bei Erhalt eines solchen Pakets mit einem CTS-Paket antworten und damit anzeigen, dass sie während der Dauer von soundso vielen Mikrosekunden selbst keinerlei Pakete senden werden, um Kollisionen zu vermeiden.

Die Destination-Address beinhaltet die MAC-Adresse der Station, die das Paket letztendlich erhalten soll. In der Source-Address steht die Adresse, die das Paket gesendet hat, und die Receiving-Station-Address entspricht der Adresse des Accesspoints oder der Bridge, die das Paket weiterleiten soll.

Anschließend folgt der Sequence-Control-Header, der aus einer Fragment- und einer Sequence-Nummer besteht. Jedes Datenpaket in einem 802.11-Netzwerk erhält eine eindeutige Sequence-Nummer. Diese Nummer wird nicht wie bei TCP per Byte erhöht, sondern nur per Datenpaket um eins hochgezählt. Pakete, die zu groß sind und deswegen in kleinere Fragmente zerlegt werden, erhalten eine eindeutige Fragment-Nummer beginnend bei null. Anders als bei TCP dient die Sequence-Nummer nicht zum Bestätigen der Pakete, sondern nur zum Filtern von Duplikaten.

802.11 sendet Pakete im Ping-Pong-Verfahren. Jedes gesendete Paket braucht erst eine Bestätigung, bevor das nächste Paket gesendet werden kann. Das gilt auch für einzelne Fragmente. Nicht bestätigte Pakete werden nach einer kurzen Wartezeit wieder gesendet (mit um eins erhöhtem Retry-Bit, das ebenfalls Bestandteil des Frame-Control-Headers ist).

Ein kleiner Sniffer

Einen ersten Eindruck, welche Informationen Pakete enthalten, die keine Beacon-Frames oder Probe-Response-Pakete sind, vermittelt der WLAN-Sniffer aus Listing 2. Er benötigt die Bibliothek Scapy, die sich mit

Listing 2

WLAN-Sniffer

 

pip install scapy

installieren lässt. Der Sniffer lauscht der Reihe nach auf allen 14 Kanälen, die bei der 2.4-GHz-Frequenz verfügbar sind, und sammelt maximal drei Sekunden lang Pakete. Damit die WLAN-Karte auch Pakete beachtet, die nicht an sie adressiert sind, muss sie zuvor mit

ifwconfig wlan0 mode  monitor

in einen Zustand geschaltet werden, der mit dem Promiscuous Mode bei kabelgebundenen Ethernet-Interfaces vergleichbar ist. Dabei mag es übrigens vorkommen, dass die Karte keinen Wechsel in den Monitor-Modus zulässt, solange sie benutzt wird. Die Quittung lautet dann:

SET failed on device wlan0 ; Device or resource busy.

Unter Linux schafft dann eine Prozedur Abhilfe, wie sie Listing 1 zeigt.

Listing 1

Mode-Wechsel

 

Falls vor Erreichen des Timeouts schon zehn Pakete aufgezeichnet wurden, springt das Programm einen Channel weiter. Für jedes eingelesene Paket ruft der Sniffer die Funktion »dump_packet()« auf. Handelt es sich bei dem eingelesenen Paket nicht um einen Beacon-Frame, ein Probe-Request- oder Probe-Response-Paket, werden die Source- und Destination-Adressen sowie die enthaltenen Layer des Pakets ausgegeben. Eventuell enthaltene weitere Daten zeigt der Sniffer in Hex und ASCII an (Abbildung 2).

Abbildung 2: Beispielhafte Ausgabe des kleinen Sniffer-Programms.
comments powered by Disqus

Artikel der Woche

Eigene Registry für Docker-Images

Wer selber Docker-Images herstellt, braucht auch eine eigene Registry. Diese gibt es ebenfalls als Docker-Image, aber nur mit eingeschränkter Funktionalität. Mit einem Auth-Server wird daraus ein brauchbares Repository für Images. (mehr)
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Google+

Ausgabe /2019