Redguards «Mobile Testing Lab» in Aktion – Hack mit uns eine App

Jul 28, 2022 von Stefan Bernhardsgrütter

Wir nutzen mobile Applikationen für E-Banking, Social Media, Medienkonsum aller Art oder um wichtige Dokumente zu bearbeiten, um sie dann auf dem Gerät zu speichern. Daher sind die Sicherheitsanforderungen an solche Apps stetig gewachsen – weshalb viele Kunden die Sicherheit ihrer mobilen Applikationen von Redguard prüfen lassen. Im Vergleich zu Penetration Tests von Webanwendungen, Netzwerken oder Software genereller Art, gibt es bei Mobile Apps jedoch einige Unterschiede, die beim Testing berücksichtigt werden müssen. Dazu haben wir ein «Mobile Testing Lab» entwickelt. Wie nutzen wir dieses im Alltag? Erhalten Sie hier einen Einblick.



Das «Mobile Testing Lab» wurde in einem früheren Blog-Beitrag bereits vorgestellt. Es besteht unter anderem aus den folgenden Komponenten:

  • Decompiler
  • Person-In-The-Middle Proxy
  • Virtuelle Telefon Emulatoren
  • Handelsübliches iPhone und Android-Gerät
  • Präpariertes iPhone und Android-Gerät (rooted/jailbroken)

Diese Werkzeuge können die Tester nutzen, um den Code der Anwendung, die Kommunikation zu involvierten Servern oder die lokal gespeicherten Daten zu analysieren. Damit ist es sogar möglich, in den Programmfluss einzugreifen und diesen zur Laufzeit zu verändern. Damit finden wir auch versteckte und nicht offensichtliche Sicherheitslücken.

Fiktiver Fall: Ist diese Mobile App sicher?

Damit Sie einen Einblick in die Nutzung unseres «Mobile Testing Labs» erhalten, schauen wir nun eine fiktive Anwendung an und suchen nach möglichen Sicherheitsrisiken.

Die fiktive Applikation Secure Editor wird dazu genutzt besonders sensitive Dateien anzuschauen und zu bearbeiten. Der Hersteller verspricht, dass die Daten nie unverschlüsselt auf dem Gerät gespeichert werden. Die Daten können direkt in der Cloud bearbeitet oder mit dem Gerät synchronisiert und offline bearbeitet werden.

Als zusätzliche Sicherheitsmassnahme müssen Benutzende beim Start jeweils ein Passwort eingeben, um Zugriff auf die Daten zu erhalten. Das folgende Bild zeigt diese Situation:



Die Demo-App Secure Editor kann Cloud-Daten lokal verschlüsselt abspeichern


Wir möchten nun prüfen, ob die Anwendung auch wirklich die versprochene Sicherheit bieten kann. Immerhin möchten Sie damit wichtige Firmendokumente bearbeiten und speichern. Daher fragen Sie Redguard an, die Anwendung im Rahmen eines Penetration Tests auf Sicherheitsrisiken zu analysieren.

Wie sieht ein Bedrohungsmodell aus?

Einer der ersten Schritte bei einem Penetration Test ist die Frage nach praktischen und relevanten Angriffen. Was könnte ein Angreifer alles anrichten? Was bringt einem Angreifer den grössten Nutzen? Was für Schäden können dadurch für Sie entstehen? Diese Fragen helfen, die Analyse zu fokussieren und sind wichtig bei der Priorisierung der einzelnen Tests.

Basierend auf diesen Fragen wird ein Bedrohungsmodell erstellt. In diesem Beispiel konzentrieren wir uns nun auf die lokal gespeicherten Daten. Eine mögliche Bedrohung kann sein, dass die lokal gespeicherten Daten ungenügend vor unberechtigten Zugriffen geschützt sind. Daher wollen wir nun Wege finden, dies zu verifizieren. Wir simulieren also einen Angriff mit dem Ziel, Zugriff auf die lokalen Daten zu erlangen.

So testen wir die App

Nun haben wir also einen Plan: Wir wollen Zugriff auf die lokalen Daten in unverschlüsselter Form. Dazu müssen wir als nächsten Schritt nun verstehen, wie die App technisch funktioniert. Und dazu benötigen wir nun einige Werkzeuge aus dem «Mobile Testing Lab».

Wie werden die Daten lokal gespeichert?

In diesem Beispiel nutzten wir eine iOS-Anwendung, der Angriff funktioniert in ähnlicher Weise aber auch für Android-basierte Systeme. Zunächst installieren wir den Secure Editor auf dem präparierten iPhone. Diese Geräte bezeichnet man auch als gerooted. Sie geben den Testern vollen Zugriff auf das lokale Dateisystem des Betriebssystems. Auf einem unpräparierten Gerät wäre dies nicht ohne weiteres möglich, da das Betriebssystem vor solchen Zugriffen schützt.

Nun kann die App ganz normal gestartet werden. Immerhin müssen wir auch selbst zuerst verstehen, welche Funktionen die App anbietet und wie diese genutzt werden. Wir melden uns also an und setzen ein Login-Passwort. Einfachheitshalber wird das Passwort Passw0rd gewählt. Danach können erste Dokumente aus der Cloud geladen und auf das lokale Gerät synchronisiert werden.

Nun kann geprüft werden, welche Dateien im lokalen Verzeichnis der App sind. Das folgende Bild zeigt einen Auszug der vorhandenen Daten. Dabei fiel eine Datei besonders auf.



Lokale Dateien nachdem Secure Editor verwendet wurde


Die interessante Datei ist die mit dem Namen OFFLINE. Interessant deshalb, weil wir wissen, dass die App Dateien offline speichern kann. Darin befinden sich jedoch keinerlei lesbaren Informationen und auch keine Hinweise auf den Dateityp. Es scheint so, als ob es eine vollständig verschlüsselte Datei wäre. Aber als erfahrene Security Tester haben wir natürlich bereits eine Vermutung, um was es sich dabei handeln könnte.

Auf der Suche nach Hinweisen ändern wir nun die Strategie: Wir schauen uns im Code der Anwendung um. Dazu nehmen wir einen sogenannten Disassembler. Damit kann man die für Menschen schwer lesbare Maschinensprache anschaulicher darstellen und mit relevanten Zusatzinformationen anreichern. Da der Hersteller den Code zudem nicht verschleiert, können wir schnell weitere interessante Hinweise wie beispielsweise Klassenbezeichnungen und Funktionsnamen auslesen.

Die Tester vermuten bereits, dass es sich um eine verschlüsselte SQLite-Datenbank handelt, da diese bei mobilen Applikationen oft zum Einsatz kommt. Nachdem die Anwendung dekompiliert wurde, suchen die Tester daher nach Stellen im Code, welche mit SQL und Verschlüsselung zusammenhängen. Und siehe da, es gibt eine eigene Klasse namens SQLCipherPlugin, welche potenziell interessante Funktionen bereitstellt:



Die Klasse SQLCipherPlugin könnte von der App dazu verwendet werden, die verschlüsselte Datei zu öffnen


Besonders die Funktion open könnte relevant sein. Wir vermuten, dass diese dazu verwendet wird, die verschlüsselte Datei zu öffnen. Unsere These, dass es sich bei der OFFLINE-Datei um eine verschlüsselte SQLite-Datenbank handelt, hat sich somit erhärtet.

Doch was ist das Passwort? Warum nicht einfach mal das Login-Passwort probieren? Wir öffnen die OFFLINE-Datei mit dem Tool DB Browser for SQLite. Tatsächlich wird auch ein Passwort-Feld angezeigt:



Entschlüsselung der SQLite-Datenbank mit dem Login-Passwort


Wir geben das Passwort Passw0rd ein, doch leider passiert nichts – die Datenbank bleibt verschlossen. Der Hersteller muss also ein anderes, uns aktuell noch unbekanntes, Passwort verwenden. 1:0 für die Entwickler.

Was sind unsere bisherigen Erkenntnisse?

  • Wir vermuten, dass die Datei OFFLINE die synchronisierten Daten beinhalten.
  • Wir vermuten stark, dass die Datei eine verschlüsselte SQLite-Datenbank ist.
  • Wir wissen, dass es in der App eine Klasse namens SQLCipherPlugin gibt, die eine open-Funktion hat.
  • Wir wissen, dass das Login-Passwort nicht als Schlüssel verwendet, wird.

Wie können wir die Daten entschlüsseln?

Da wir den Secure Editor auf dem präparierten Gerät installiert haben, können wir uns mit dem vorhandenen Wissen die open-Funktion genauer anschauen, während die App ausgeführt wird. Dies nennt man Function Hooking oder auch Laufzeitanalyse. Wie mit einem Haken hängen wir uns an diese Funktion und warten, bis sie aufgerufen wird. Unsere Hoffnung ist, dass das tatsächliche Passwort der Funktion als Parameter übergeben wird.

Dazu kommt das Frida-Framework zum Einsatz. Damit ist es relativ einfach, die Parameter eines beliebigen Funktionsaufrufs zu überwachen und auszulesen. Also überwachen wir die Funktion -[SQLCipherPlugin open:] und starten die «gehookte» App erneut. Wir sehen wieder den Login-Bildschirm mit der Passworteingabe. Nun geben wir das Passwort ein und siehe da: Unsere überwachte Funktion wird tatsächlich aufgerufen. Besser noch: Die Funktion besitzt genau zwei Parameter. Einer davon ist der Dateiname, der andere das gesuchte Passwort. Das folgende Video zeigt diesen Angriff mit der Android-Version der Applikation. Der Angriff funktioniert ähnlich auf iOS.



Die Laufzeitanalyse kann dazu genutzt werden, das tatsächliche Datenbankpasswort zur Laufzeit auszulesen


Unsere Vermutung hat sich somit bestätigt: Die Funktion wird dazu genutzt, die SQLite-Datenbank in der Datei OFFLINE mit einem Passwort zu öffnen. Die Tester versuchen nun, die vom Gerät extrahierte Datenbank mit dem Passwort d41e98d1eafa6d6011d3a70f1a5b92f0 zu öffnen. Dieses Mal erfolgreich:



Sesam öffne dich: Mit dem richtigen Passwort konnten wir die Datenbank öffnen


Doch was ist das nun für ein Passwort? Aufgrund der Länge der Zeichenkette vermuten technisch versierte Leser bereits, dass es sich um einen MD5-Hash handelt. Als Hash-Algorithmen bezeichnet man eine Klasse von sogenannten mathematischen Einwegfunktionen. Sie werden teilweise dazu verwendet, um Passwörter zu schützen. Wir gehen daher davon aus, dass die Entwickler einfach einen MD5-Hash des Login-Passworts gemacht haben. Dies ist einfach zu überprüfen: Wir kennen ja nun das Login-Passwort und können daher selbst den MD5-Hash berechnen:



Wir überprüfen die Vermutung, dass als Datenbankpasswort lediglich der MD5-Hash des Login-Passworts verwendet wird


Tatsächlich stimmt es mit dem Passwort überein, welches zum Entschlüsseln der Datenbank verwendet wird.

Fassen wir zusammen:

  • Secure Editor speichert die synchronisierten Daten in einer lokalen SQLite-Datenbank.
  • Diese Datenbank ist verschlüsselt.
  • Als Schlüssel wird der MD5-Hash des Login-Passworts verwendet.

Welches Risiko birgt die App für den Kunden?

Durch die Analyse haben wir ein fundiertes Verständnis darüber, wie die App Daten lokal speichert. Die nächste Frage ist nun, ob dies ein Risiko darstellt.

Wir sehen ein Risiko aus folgenden Gründen:

Das Fehlen von Schutzmassnahmen wie Code-Verschleierung oder Schutz vor Function Hooking zur Laufzeit macht es einem potentiellen Angreifer leicht. So konnten wir die App ohne Problem decodieren, die interessante Funktion finden und diese dann genau überwachen.

Benutzende tendieren dazu, bei solchen Anwendungen eher schwache Passwörter zu wählen, da auf einer kleinen Bildschirmtastatur nur ungern lange und komplexe Passwörter eingetippt werden. Mit dem Wissen, wie die Datenbank verschlüsselt wird, kann dieser Angriff nun auch automatisiert werden. Angreifer könnten zum Beispiel alle 8-stelligen Passwörter bestehend aus Zahlen und Buchstaben durchprobieren. Oder der Angreifer nutzt ein Wörterbuch mit oft genutzten Passwörtern. Unser Passwort Passw0rd ist dabei praktisch immer vertreten.

Da zudem ein einfacher MD5-Hash verwendet wird, existieren mittels sogenannter Rainbowtables sogar noch effizientere Angriffe, welche ebenfalls genutzt werden können.

Diese Angriffe können zudem alle offline durchgeführt werden, solange der Angreifer Zugriff auf die verschlüsselte Datenbank erlangt. Dies führt dazu, dass sehr starke Rechner dafür verwendet werden können, um die Wartezeiten für den Angreifer zu verkürzen.

So bekommt ein Angreifer Zugriff auf die Datenbank-Datei:

a) Die Angreifer kommen in den Besitz eines bereits gerooteten Geräts. In diesem Fall kann er oder sie die Datenbank direkt vom Gerät herunterladen.
b) Die Angreifer kommen in den Besitz eines unverschlüsselten, aber nicht gerooteten Geräts. Dieses kann von den Angreifern nun gerootet werden, damit so Zugriff auf die Datenbank erlangt wird.
c) Die verschlüsselte Datenbank wird bei einem Gerätebackup vom Gerät wegkopiert. Oft ist das Backup dann nicht mehr gleich gut geschützt, wie auf dem Gerät selbst. Zum Beispiel im Dokumentenordner eines Computers, der dann noch auf einen Cloud-Speicher synchronisiert wird. Die Angreifer könnten so über ein ungenügend geschütztes Backup an die verschlüsselte Datenbank kommen.

Wir gehen somit davon aus, dass die Wahrscheinlichkeit, dass die Datenbank erfolgreich entschlüsselt werden kann, eher gross ist, sofern diese in die Hände eines Angreifers gelangt.

Welche Gegenmassnahmen würden wir empfehlen?

Ein wichtiger Punkt bei unseren Berichten ist nicht nur die Risikobeschreibung, sondern auch konkrete Empfehlungen, wie man sich dagegen schützen kann. In diesem Fall sehen wir folgende Möglichkeiten, um die Sicherheit zu steigern:

Sie können sogenannte Passwort-Stretching-Algorithmen nutzen, um vom Login-Passwort das Datenbankpasswort abzuleiten. Diese Algorithmen haben das Ziel, die Berechnung des Datenbankpassworts zu erschweren. Dies führt dazu, dass Brute-Force-Angriffe nicht mehr so effizient durchführbar sind. Aber Achtung: Wenn ein Passwort in einem Wörterbuch vorkommt, kann es immer noch vergleichsweise schnell erraten werden.

Besser wäre es daher, wenn man ein sicheres Zufallspasswort generiert und dann die Hardware des Mobiltelefons nutzt, um dieses abzuspeichern. Dazu kann zum Beispiel biometrische Authentisierung wie ein Fingerabdruck oder ein Gesichts-Scan verwendet werden. Android wie auch iOS bieten sogenannte Keystores an, welche dazu genutzt werden können, Passwörter sicher zu speichern. Diese sind speziell geschützt und können so konfiguriert werden, dass sie zum Beispiel nur dann lesbar sind, wenn der Bildschirm entsperrt ist.

Diese Gegenmassnahme hat den Vorteil, dass eine entwendete, verschlüsselte Datenbank praktisch nicht mehr entschlüsselt werden kann. Angreifer könnten dies zwar immer noch mittels Function Hooking zur Laufzeit auslesen, dazu müsste aber neben der Datenbank auch gleich noch das Smartphone entwendet werden. Dadurch wird der Angriff um ein Vielfaches aufwändiger.

Das Verschleiern des Codes und Schutzmechanismen zur Verhinderung von Laufzeitanalyse können den Aufwand und somit die Kosten für einen solchen Angriff noch zusätzlich erhöhen.

Wir empfehlen unseren Kunden aber nicht, sich ausschliesslich auf diese Massnahmen zu verlassen, da ein Angreifer mit genügend Zeit, Erfahrung oder einer Portion Glück diese umgehen kann. Daher empfehlen wir diesbezüglich immer eine sorgfältige Kosten-Nutzen-Abwägung.

Fazit

Dieses Beispiel hat gezeigt, wie wir die verschiedenen Werkzeuge des «Mobile Testing Lab» nutzen können, um sehr tief unter die Haube einer Anwendung zu schauen – angefangen von Funktionsbezeichnungen im statischen Quellcode bis hin zur Laufzeitanalyse mittels Function Hooking. So konnte ein nicht offensichtliches Risiko identifiziert werden, das im schlimmsten Fall zum Verlust von sensitiven Daten führen kann.


Entwickeln Sie eine mobile App und möchten Sie diese geschützt wissen? Erkennen und beheben Sie Risiken besser früh als (zu) spät. Melden Sie sich unverbindlich bei uns – Wir unterstützen Sie gerne bei einem Penetration Test mit unserer Expertise und unserer Erfahrung.


< zurück