· 

Android Mustersperre knacken (mit Python und Root-Rechten)

Disclaimer: Die hier beschriebene Angriffstechnik darf nur auf dem eigenen Rechner durchgeführt werden. Auf Rechnern Dritter darf die hier beschriebene Angriffstechnik nur dann durchgeführt werden, wenn der Besitzer dieses Rechners seine Zustimmung dafür gegeben hat. Ich übernehme keine Haftung für jedweden durch Missachtung dieser Vorgaben entstandenen Schaden! Dieser Beitrag ist lediglich zu Bildungszwecken gedacht! Don't Learn to Hack - Hack to Learn!

1. Einführung

Viele denken, dass die Android-Mustersperre ein effektiver Schutz vor Angreifern ist. Dem ist leider nicht so. Es gibt sehr viele Angriffsvektoren, wie z. B. Shoulder Surfing oder Smudge Attacks. Wenn du ein gerootetes Smartphone hast, dann ist es aber noch viel einfacher diese Sperre zu umgehen - egal wie kompliziert das von dir gewählte Muster ist. Wir werden sehen, wie man das Muster anhand eines Key-Files auf deinem Smartphone entschlüsseln kann.

Zunächst müssen wir aber klären, was die Mustersperre überhaupt ist. Hierbei handelt es sich um ein wissensbasiertes Authentifizierungsverfahren, bei dem man eine visuelle Information - nämlich das Muster - erinnern muss. Das Muster wird in eine 3x3-Matrix aus Punkten eingetragen, die miteinander verbunden werden müssen. Ein Muster muss dabei verschiedene Anforderungen erfüllen.

  • Es müssen mindestens vier und maximal neun Punkte miteinander verbunden werden.
  • Es dürfen keine Punkte "übersprungen" werden. 
  • Das Muster muss gezeichnet werden können ohne den Finger vom Display zu nehmen.
  • Kein Punkt darf zweimal ausgewählt werden.

Durch einfache Enumeration findet man heraus, dass maximal 389.112 verschiedene Mustersperren möglich sind. Das ist ein ziemlich kleiner Schlüsselraum! Die Wahrscheinlichkeit mit einer Brute-Force-Attacke hier Erfolg zu haben, ist sehr groß. Doch dazu später mehr. Wir nummerieren die Punkte, die für die Mustersperre miteinander verbunden werden sollen, nun ganz einfach durch:

Das wird später noch einmal wichtig.

Wichtig: Ich gehe in diesem Artikel davon aus, dass dein Smartphone, auf dem du diesen Angriff durchführen willst, gerootet ist, d. h. du hast im Vorfeld bereits dafür gesorgt, dass du Zugriff auf quasi alles in deinem Smartphone hast. Die Variante ohne Rooting ist weitaus schwieriger, doch dazu in einem anderen Artikel mehr. Ich persönlich sehe im Rooten von Smartphones viele Nachteile. Um mal ein paar zu nennen:

  • Die Garantie des Herstellers erlischt, sobald du dein Smartphone gerootet hast.
  • Wenn beim Rooten etwas schiefgeht, dann kannst du das Gerät im schlimmsten Fall ggf. nur noch als Briefbeschwerer oder Türstopper verwenden. 
  • Einige Apps benötigen zwar Root-Rechte, doch viele andere Apps funktionieren dadurch ggf. nicht mehr, weil die Hersteller im Root-Modus zu viele Sicherheitslücken sehen und sich somit verpflichtet fühlen, den Anwender zu schützen.
  • Beim Rooten verschaffst du Schadsoftware weitere Zugriffsberechtigungen, die sehr fatal für die Sicherheit deiner Daten sind, wie wir in diesem Artikel noch sehen werden.

Aus diesen Gründen roote ich mein Smartphone nicht und werde den Angriff innerhalb eines Android-Emulators zeigen. Das hat den Vorteil, dass weder die Garantie an einem echten Gerät verloren geht und Schadsoftware, sollte sie die virtuelle Maschine befallen, keinen wirklichen Schaden anrichten kann, da sie mehr oder weniger "eingesperrt" ist. Wir werden uns also eine kleine Testumgebung einrichten, innerhalb derer wir den Angriff theoretisch durchspielen können. Du kannst das ganze natürlich auch auf deinem Smartphone durchführen, sofern es gerootet ist. Ich möchte dich hiermit aber nicht zum Rooten animieren.


2. Einrichten der Test-Umgebung

Zuerst brauchen wir einen geeigneten Android-Emulator, den man im Optimalfall leicht rooten kann. Hierfür eignet sich der Nox Player, den du dir hier herunterladen kannst. Der primäre Einsatzzweck dieses Emulators ist das Spielen von Handy-Games auf dem Rechner. Lade die Datei herunter und installiere sie. Nach erfolgreicher Installation steht dir ein vollwertiges Android-Smartphone zur Verfügung, mit dem du gefahrlos Herumexperimentieren kannst. 

Nun verschaffen wir uns Root-Rechte auf diesem Gerät. Klicke zuerst ganz oben rechts auf das Zahnrad-Symbol.

Danach öffnet sich ein Fenster mit den Systemeinstellungen. Dort musst du die Checkbox Root aktivieren und anschließend diese Änderung durch einen Klick auf "Änderungen sichern" bestätigen. Danach wirst du aufgefordert einen Reboot durchzuführen, damit die Änderungen wirksam werden. Folge dieser Anweisung und führe den Neustart durch.

Nun ist die Test-Maschine fast vollständig aufgesetzt. Was jetzt noch fehlt ist die Aktivierung des USB-Debuggings. Gehe hierzu im Smartphone auf die Einstellungen. Suche dort nach "über das Tablet". Klicke dort drauf und scrolle ganz runter bis zum Feld "Build-Nummer" und klicke sieben mal auf dieses Feld. Damit aktivierst du den sogenannten Entwickler-Modus. Wenn du bereits Entwickler bist, dann wirst du darüber entsprechend benachrichtigt. Wenn du zuvor noch kein Entwickler warst, wirst du beim Zurückgehen ein neues Feld sehen, das "Entwickleroptionen { }" heißt. 

Klicke dort drauf und scrolle runter bis zu dem Punkt "USB-Debugging". Aktiviere diese Option. Damit kannst du jetzt in den sogenannten Debugging-Modus und somit die Android Debug Bridge (adb) verwenden. Das ist notwendig, um auf die System-Dateien zuzugreifen, wo wir auch das gesture.key-File finden. Aber alles der Reihe nach. 

An dieser Stelle haben wir unsere Testumgebung fast vollständig aufgesetzt. Was jetzt noch fehlt, ist eine Mustersperre, die wir umgehen können. Klicke hierzu wieder auf die Einstellungen und wähle dort das Feld "Sicherheit" aus. Da wir eine Mustersperre zum Schutz verwenden wollen, wählst du Muster aus. Dort gibst du dann das gewünschte Muster ein. Wir wählen exemplarisch dieses Muster hier aus:

Das Muster muss danach zur Bestätigung erneut eingegeben werden. So, jetzt sind wir an dieser Stelle fertig. Wir können nun noch einmal kurz testen, ob wir beim Neustart tatsächlich dazu aufgefordert werden, unsere Mustersperre einzugeben. 

Nachdem das nun alles ganz hervorragend funktioniert hat, vergessen wir mal ganz schnell wieder, was wir als Muster eingegeben haben. Es gibt jetzt zwei verschiedene Angriffsmöglichkeiten über die Android Debug Bridge.

  1. Wir löschen das gesture.key-File vollständig vom System.
  2. Wir entschlüsseln das im gesture.key-File gespeicherte Muster und wissen somit die Mustersperre ohne sie entfernen zu müssen. 

Hacker bevorzugen oft die zweite Variante, weil man dadurch denjenigen, dem das Smartphone gehört, nicht alarmiert. Auch du möchtest vielleicht gerne wissen, wie deine Mustersperre aussah ohne gleich eine neue zeichnen zu müssen. Wir werden daher den zweiten Angriff durchführen. Hierfür ist aber noch ein bisschen mehr theoretischer Background und ein kleines Python-Tool notwendig. Am Ende des Artikel zeige ich dir noch, wie du das File einfach löschen kannst.


3. Reverse-Engineering

In jedem System muss bei wissensbasierten Authentifizierungsverfahren (und hierzu zählt auch die Mustersperre) irgendwo physisch hinterlegt sein, welche Information genau erinnert werden soll. Wie du aus meinem Video Wie Hacker Passwörter knacken weißt, werden diese Informationen nicht im Klartext hinterlegt, sondern vorher verschlüsselt. Mit der Android Debug Bridge können wir uns das sogenannte gesture.key-File vom Smartphone herunterladen. Dort ist die Mustersperre enthalten (allerdings verschlüsselt).

Um herauszufinden, wie Android das eingegebene Muster intern speichert, suchen wir nach einer Implementierung, die den dafür verwendeten Algorithmus offenbart. Unter android.googlesource.com findet man hier eine Funktion 'patternToHash', die für das Hashen des eingegebenen Patterns zuständig ist (Zeile 722-747).

Wie man Zeile 741 entnehmen kann, wird als Hash-Algorithmus SHA-1 genutzt. Der Code selbst ist sehr leicht nachvollziehbar. Als Parameter wird eine Liste mit Objekten vom Typ LockPatternView.Cell übergeben und in Zeile 734 die Anzahl an Verbindungspunkten geprüft, die gemäß den Standardvorgaben zwischen (einschließlich) 4 und (einschließlich) 9 liegen muss. In Zeile 735 wird ein Byte-Array-Container initialisiert, dessen Größe der Anzahl an Verbindungspunkte im Pattern (in Bytes) entspricht. Anschließend wird über die Liste iteriert und für jedes Element basierend auf der Position in der Pattern-Matrix ein Wert berechnet, der als Byte in dem Container gespeichert wird. In den Zeilen 741 bis 743 wird die Berechnung des SHA-1 Hashes für den zuvor zusammengesetzten Container ermittelt und zurückgegeben und Fehler durch eine NoSuchAlgorithmException abgefangen. 

Dem Funktions-Kommentar kann man bereits entnehmen, dass diese Vorgehensweise keinen sonderlich großen Schutz bietet - gut für uns.

Unbekannt ist bislang noch die Implementierung der Klasse LockPatternView.Cell, die jedoch auch eingesehen werden kann. Hierzu schreibe ich aber einen separaten Artikel! Nur so viel: Als Basis dient ein einfacher Zahlencode, der sich durch die Reihenfolge der Punkte ergibt, die für das Muster verwendet werden, also z. B. 12589. Wir gehen im Folgenden davon aus, dass wir diese Klasse nachimplementiert und alle möglichen Kombinationen für die Mustersperre samt SHA-1-Hash erfolgreich ermittelt haben.


4. Extraktion des gesture.key-Files

Als nächstes muss das gesture.key-File irgendwie von dem Gerät extrahiert werden. Hierfür benötigen wir die bereits angesprochene Android Debug Bridge. Navigiere hierfür in das bin-Verzeichnis deiner Nox Player Installation und öffne von dort aus ein Konsolenfenster. Tippe anschließend den Befehl

adb devices

ein. Wenn dort kein Gerät erscheint, musst du den Nox Player erst noch anmelden. Hierzu tippst du den Befehl 

adb connect

ein. Tippe dahinter eine IP-Adresse (z. B. die deines Localhosts) mit einer Port-Nummer (z. B. 62001) ein. 

Jetzt bist du startklar für das Herunterladen des gesture.key-Files. Hierfür benötigst du den Befehl pull. Dieser erwartet den Pfad zu einer Datei, die vom Gerät heruntergeladen werden soll. Der Pfad zum gesture.key-File lautet 

/data/system/gesture.key

Dieses Argument gibst du dem Befehl pull mit und drückst auf ENTER. Jetzt wird die gesture.key-Datei von dem Smartphone in das Verzeichnis geladen, in dem die adb.exe liegt und kann nun für das Knacken des dahinterstehenden Musters verwendet werden.


5. Knacken des Musters

Wenn du die Datei einfach so öffnest, wirst du mit dem Inhalt nicht viel anfangen können. Du brauchst einen Hex-Editor, um dir den SHA1-Hash des Musters anzeigen lassen zu können. Lade dir dazu einen x-beliebigen Hex-Editor herunter und ziehe das gesture.key-File dort hinein. Diesen Hash könntest du jetzt nehmen und diesen in meiner Datei mit den möglichen Mustersperren suchen. Am Ende müsste dann der Zahlencode 12589 herauskommen, denn das ist die Reihenfolge der Punkte, die wir zuvor als Mustersperre festgelegt haben.

Da du aber ein angehender Informatiker bist, schreibst du dir dafür selbstverständlich ein kleines Python-Skript. 

Hierfür benötigen wir zunächst die Bibliothek binascii, mit der wir später das gesture.key-File verarbeiten. Wir schreiben uns zwei Funktionen, nämlich read_gesture und search_hashread_gesture erhält einen Pfad zum gesture.key-File. Diese Datei wird geöffnet, gelesen, das Ergebnis in ein byte-Array geschrieben und anschließend in einen Hexadezimal-String umgewandelt.

def read_gesture(path):
    with open(path, "rb") as gesture:
        return binascii.hexlify(bytearray(gesture.read()))

search_hash bekommt als Parameter einen Pfad zur Datei mit den Mustersperren und den Hashwert, nach dem gesucht werden soll. Da wir ähnliche Funktionen schon in anderen meiner Tutorials programmiert haben, verzichten wir an dieser Stelle auf eine genaue Beschreibung der Vorgehensweise.

def search_hash(path, hash):
    with open(path, 'rb') as table:
        for line in table:
            if line.find(hash.upper()) != -1:
                print('Die Mustersperre lautet: ' + line.decode("utf-8")[0:line.decode("utf-8").index(';')])

Nun liest du zuerst mit read_gesture das gesture.key-File und übergibst dieses Ergebnis samt Angabe des Pfads zur Mustersperren-Datei an die Funktion search_hash.

sha1_hash = read_gesture("gesture.key")
search_hash("mustersperren.txt", sha1_hash)

Führe das Programm nun über die Konsole aus. Als Ergebnis erhältst du (wer hätte es gedacht) den Code 12589, den wir zuvor vergeben haben. Wir wechseln also wieder in den Nox Player, geben nach dem Hochfahren das Pattern ein und sind drin :)


6. Löschen des gesture.key-Files

Wie versprochen zeige ich dir noch die zuerst genannte Angriffstechnik, nämlich das Löschen des gesture.key-Files. Hierfür benötigst du den Befehl rm (remove). Du startest wieder die Android-Debug-Bridge und rufst die Shell auf. Darüber tippst du den Befehl rm und den Pfad zum gesture.key-File ein. Wenn du diesen Befehl ausführst, wird das gesture.key-File gelöscht. 

Was bringt das jetzt? Nun, wenn du jetzt einen Neustart durchführst, dann wirst du trotz der zuvor eingegeben Mustersperre nicht nach einem Passwort gefragt. Wenn also kein gesture.key-File vorhanden ist, fragt dich Android nicht nach der Eingabe einer Mustersperre - interessant. Wäre es vielleicht sogar möglich, dass wir das zu unserem Vorteil ausnutzen können?

Was würde denn passieren, wenn man ein gesture-File vorbereitet, das einen Code erhält, der unmöglich eingegeben werden kann und den man dann auf das Smartphone lädt? Hierzu öffnen wir unser zuvor heruntergeladenes gesture.key-File in einem Hex-Editor. Dort tragen wir dann z. B. willkürlich ganz oft den Buchstaben A ein. Der dahinterstehende SHA1-Hash gehört jetzt zu keiner eingebbaren Mustersperre. 

Diese modifizierte Datei ziehen wir uns nun in den Ordner, wo sich die Android Debug Bridge befindet und laden sie mit dem Befehl push auf das Smartphone. Die Syntax sieht wie folgt aus: Zuerst kommt der Befehl push, danach die Datei, die auf das Smartphone geladen werden soll (unser gesture.key-File) und dann der Ort, an den die Datei geladen werden soll (das ist in diesem Fall wieder /data/system/).

adb push gesture.key /data/system/

Fertig. Wenn du jetzt einen Neustart durchführst, wirst du nach einer Mustersperre gefragt, die du niemals richtig wirst eingeben können. Doch du weißt ja, wie du dich aus dieser unabsichtlichen Sperre mit dem Befehl rm wieder befreien kannst ;)


7. Schutzmaßnahmen

Die einzigen wirklichen Schutzmaßnahmen gegen diesen Angriff sehen vor, dass du 

  1. dein Smartphone nicht rootest und
  2. das USB-Debugging nicht einschaltest. 

Jetzt siehst du auch, warum ich dir nicht empfehlen würde, dein täglich verwendetes Smartphone zu rooten und mitzuführen. Da ich Hackern so wenige Angriffspunkte wie möglich bieten möchte, roote ich mein Smartphone nicht und schalte auch das USB-Debugging nicht ein bzw. deaktiviere es, sobald ich es nicht mehr brauche.


8. SHA-1-Datei für die Mustersperren

Hier kannst du die Datei mit den Mustersperren samt SHA1-Hashwerten herunterladen.

Download
mustersperre.txt
Text Dokument 18.9 MB