Einer der cooleren Talks auf dem 33C3 war Predicting, Decrypting, and Abusing WPA2/802.11 Group Keys von Mathy Vanhoef. Hauptpunkt des Talks ist die mögliche Berechenbarkeit von in WPA2/802.11 genutzten Schlüsseln, speziell den so genannten GMK (Group Master Key). Vom GMK abgeleitete Schlüssel werden in 802.11-Netzen genutzt um Broadcast und
Multicast-Traffic zu verschlüsseln (meist ist das Traffic vom AP zu den STA). Der Client erhält diesen abgeleiteten Schlüssel GTK (Group Temporal Key) vom AP während des 4-Wege-Handshakes.

Ursache für die Berechenbarkeit der Schlüssel sind schlechte Zufallszahlengeneratoren. Der Standard lässt offen welche Zufallsquellen genutzt werden, was bedeutet, dass nicht alle Hersteller betroffen sind (hostapd unter Linux z.B. nicht, da hier /dev/random oder /dev/urandom genutzt wird). Das macht die Sache natürlich spannender. Angriffe, die ein wenig Zufall, ein wenig Crypto und ein wenig Netzwerk drin haben sind halt immer noch die schönsten. ;)

Wie gesagt betreffen diese schwachen Keys nur Broadcast und Multicast-Traffic. Wie kommt man also an den Unicast-Traffic eines Clients? Im Talk wurde das innerhalb von 2 Minuten erklärt, im Paper sind leider auch nicht mehr Details. Insgesamt sind die Beschreibungen aber ausreichend um diesen Teil des Angriffs in einem kleinen Testaufbau nachvollziehen zu können. Die Tools für die Berechnung des GMK wurden leider, afaik, noch nicht veröffentlicht.

Ausgangssituation:

  • 3 WLAN-Geräte: STA_A (Alice Client), STA_M (Mallory Client), AP (Access Point)
  • Mallory hat den GMK und den abgeleiteten GTK erfolgreich berechnet
  • Mallory kann Unicast-Frames injecten (wie steht im Paper)

Die Idee: Mittels ARP Poisoning setzt STA_M die MAC, im jeweiligen Cache von STA_A und AP, auf Broadcast-MAC. Da jetzt auf Layer 2 die Broadcast-MAC adressiert wird, verschlüsseln die betroffenen Systeme Unicast-Traffic mit dem GTK statt mit dem PTK. Extrem simple und tolle Idee! Das musste ich ausprobieren. Mein Testaufbau:

  • 2 STA im WLAN, STA_A und STA_M
  • Ein einfacher OpenWRT-Router mit AP

Da mein Ziel ist herauszufinden ob der AP tatsächlich den Traffic mit dem GTK verschlüsselt habe ich in meinem Wireshark auf STA_M die decryption (mittels PMK) aktiviert - d.h. ihr seht auf den Screenshots allen Traffic (nicht nur den mit dem GTK verschlüsselten) entschlüsselten den Traffic.

Wie erkennt man mittels welchem Schlüssel ein Frame verschlüsselt wurde? Wireshark, großartig wie immer, zeigt an Schlüssel direkt an!

Wireshark PMG 802.11

So sieht ein normaler, entschlüsselter Ping im Wireshark aus. D.h. über den Key index (1/2 heißt Broadcast, 0 Unicast) oder der Angabe des Keys können wir direkt welcher Schlüssel zur Verschlüsselung des Frames genutzt wurde - in diesem Fall mittels PMK/PTK, also normaler Unicast-Traffic zwischen AP und STA_A.

Um den Angriff auszuprobieren muss nun STA_M die MAC-Adressen, wie oben beschrieben, spoofen.

Erstes Problem:

Meine OpenWRT-Kiste hatte keine Tools installiert um einen statischen MAC-Eintrag zu setzen und der Speicherplatz reicht nicht mehr um welche nach zu installieren (-.-). Lösung: Richtig spoofen! ;)

Nächstes Problem:

Auf die schnelle hab ich kein ARP-Spoofing-Tool gefunden was es im ARP reply erlaubt als Sender MAC die Broadcast (FF:FF:FF:FF:FF:FF) zu nutzen - für den klassischen ARP Spoof ist das ja auch nicht sinnvoll. Also hab ich mir das dsniff-Package von Arch geschnappt und den Quellcode von arpspoof gepachted:

dimi@hermes ~/dsniff/src/dsniff-2.4 % diff arpspoof.c ~/dsniff-patched/src/dsniff-2.4/arpspoof.c 
300c300
<           arp_send(l, ARPOP_REPLY, my_ha, spoof.ip,
---
>           arp_send(l, ARPOP_REPLY, brd_ha, spoof.ip,

Und schon funktioniert es:

dimi@hermes ~/dsniff-patched/src/dsniff-2.4 % sudo  ./arpspoof -i wlp4s0u2 -t 192.168.2.1 192.168.2.148
16:b:37:d5:f0:ce 98:de:d0:fe:51:1c 0806 42: arp reply 192.168.2.148 is-at ff:ff:ff:ff:ff:ff

Lässt man nun den Spoof gegen STA_A und AP rennen sieht das Netz zusammengefasst wie folgt aus:

  • STA_A

    • ARP-Cache: FF:FF:FF:FF:FF:FF 192.168.1.1
    • IP STA_A: 192.168.2.148
    • Gateway: 192.168.2.1
  • GW/AP:

    • ARP-Cache: FF:FF:FF:FF:FF:FF 192.168.2.148
    • IP: 192.168.2.1

Setzt man jetzt einen Ping von vom GW zu STA_A ab, sieht Mallory folgenden Traffic:

Wireshark PMG 802.11

Und die Details:

Wireshark PMG 802.11

Sehr schön zu sehen: STA_M sieht in diesem Fall 2 ICMP replys, einer davon mit einem PTK verschlüsselt. Dieses ist die Antwort vom STA_A an den AP. Da hier die Receiver Address explizit der AP ist, wird dieses Frame mit dem PTK verschlüsselt - obwohl die letztendliche Destination die Broadcast-Adresse ist. Hätte STA_M nicht den PMK wäre dieses Frame an dieser Stelle verschlüsselt geblieben. Bei der zweiten ICMP reply handelt es sich um das gleiche Paket, welches durch den AP aber entschlüsselt, mit dem GTK (siehe GTK im rechten und linken Bild) verschlüsselt und dann an die Broadcast-Adresse im Netz relayed wurde - ursprünglich ein Unicast-Paket welches STA_M durch das ARP Poisoning mitlesen kann. Cool!

Offene Fragen und Todos

Einige Erfahrungen, die ich während meines Tests gemacht habe (gerne Input per Mail, falls jemand ne gute Idee hat ;) )

  • airtun-ng und dot11decrypt entschlüsseln scheinbar mittels GTK verschlüsselte Frames nicht? (oder zeigen sie zumindest nicht an)
  • Gibt es Implementierungen für Scapy, die eine komplette WPA2-Authentifizierung erlauben? Es gibt ein Dot11 Layer und Funktionen für WEP-Decrypt, aber nichts für eine normale Association?
  • Es gibt noch keine Implementierung, die den obigen Angriff automatisiert?
  • Es gibt noch kein öffentliches Tool um den GMK für die betroffenen Hersteller zu berechnen?
  • Unicast Injection über den GTK ausprobieren!

Links