0.12 Android und Sicherheit Inhaltsverzeichnis

Android ist toll, weil es angeblich frei ist. Angeblich, weil Richard M. Stallman Android weder als frei noch als Open Source ansieht. Und wenn jemand "Software-Freiheit" beurteilen kann, dann er. Bei näherem Hinsehen definiert sich diese Freiheit als das Freisein von Qualitätskontrolle, das Freisein von Updates und als Freiheit im Sinne von Alleingelassenwerden. Ob und wie frei Android von Sicherheit ist, untersuche ich hier mit eventuellen Fortsetzungen.

Stichwort-Liste

0.12.1 Angriffe wegen fehlender Updates?

Ich habe diesen Artikel begonnen aufgrund einer Email, in der ich gefragt wurde, warum Android häufiger angegriffen wird und mehr unter Malware zu leiden hat als iOS. Ob es an den ausbleibenden Updates für die Geräte liegt oder ob Android echte Sicherheitsprobleme hat.

Es sind in der Regel "Trojaner", die im Android-Markt auftauchen. Gerne sind das um Schadcode erweiterte Kopien bekannter Apps. Typischerweise wählen die dann kostenpflichtige Telefonnummern oder verschicken kostenpflichtige SMS ohne daß der User das sieht. Diese Art von Schädlingen hat auf iOS weniger Chancen aus mindestens drei Gründen:

Ein aktuell gehaltenes Android hat keine akuten echten Sicherheitsprobleme. Aber die Android-Plattform macht es Malware-Autoren viel leichter. Auf iOS muß man meist eine Sicherheitslücke suchen und nutzen, bei Android ist bislang bekannte Malware auf Sicherheitslücken gar nicht angewiesen gewesen. Es ist einfacher, die Sicherheit von Android "by design" zu umgehen, als einen Exploit für ungefixte Bugs zu schreiben. Das Suchen nach Android-Bugs fanden die Veranstalter von Pwn2Own 2012 auch zu langweilig, weil zu viele alte Bugs aus den zwei Jahren zuvor noch auf den Geräten offen waren.

Ein tragischer Aspekt ist, daß heute immer noch Neu-Geräte auf den Markt gebracht werden, die Android 2.x verwenden. Meistens sind das günstige Smartphones, die mit Android 4.x Probleme hätten, flüssig zu laufen. Darum besteht die Gefahr, daß Android 2.x noch lange im Einsatz sein wird. Geräte mit Android 2.x bekommen erst recht keine Updates mehr und sind daher leichter angreifbar, weil sie uralte bekannte Bugs aufweisen. Im März 2013 liefen zum Beispiel 55% aller Android-Geräte mit Android 1.x, 2.x oder 3.x., wobei 2.x mit 53,5% den größten Anteil hatte. Der auf Andoid 2.x angewiesene Billig-Markt ist ein Fluch für diese Plattform: Der Fluch der Freiheit und der Preis, den sie für den Marktanteil bezahlen müssen.

Android Verteilung März 2013

Tabelle und Diagramm stammen von Googles Entwickler-Seite.

0.12.2 Sandbox pervertiert

Üblicherweise wird für eine Sandbox ein Mandatory-Access-Control-Framework (MAC) verwendet, so wie es zum Beispiel Mac OS X, iOS und diverse GNU/Linux-Versionen anbieten. Die Zugriffsbeschränkungen können dabei unabhängig vom User durchgesetzt werden.

Android verwendet für sein App-Sandboxing kein MAC-Framework, sondern Discretionary Access Control (DAC): Typischerweise läuft unter Android jede App unter einem anderen User. Die App-Sandbox von Android besteht aus den POSIX-Usergrenzen. Unter Unix laufen jedoch normalerweise alle Apps eines Users auch unter seinem Account. Bei Android laufen Deine Apps jedoch nicht unter einem (Deinem) User, sondern unter soviel Usern wie Du Apps am laufen hast. Der Android-User ist eine gespaltene Persönlichkeit und man kann nicht einmal sagen, aus wievielen sie besteht.

Auf jeden Fall ist der Einsatz von POSIX-Usergrenzen als Sandbox für Apps zweierlei: Eine ziemlich schlaue Abkürzung, weil man damit die "Sandbox" geschenkt bekommt vom System, und andererseits ein Mißbrauch von User-Accounts zu nicht vorgesehenen Zwecken. Unix-User sind gut voneinander getrennt und diese Trennung überträgt Android einfach auf die Apps, indem sie völlig pervertiert jeder App einen eigenen User geben. Google mußte dadurch überhaupt keine Sandbox für seine Apps erstellen, sondern bekommt diese durch den billigen Trick geschenkt.

Wenn zwei Apps mit demselben Key signiert sind, können sie auch unter demselben User laufen. Das ist der Fall, wenn die Apps vom selben Entwickler oder Malware-Autor kommen.

Zum Vergleich: Alle iOS-Apps des Benutzers laufen unter demselben unprivilegiertem User "mobile", der also per DAC vom System-User "root" getrennt ist, haben jedoch eine standardisierte MAC-Sandbox, die die Daten der Apps voneinander trennt.

Was eine Android App ansonsten noch darf, hängt von ihren Benutzergruppen ab, zu denen sie gehört. Android verwendet Benutzergruppen unixtypisch für das Erteilen von zusätzlichen Berechtigungen. Der User und seine Zugehörigkeiten zu den Groups werden während der Installation der App definiert.

Zum Vergleich: Bei iOS-Apps können keine zusätzlichen Berechtigungen freigeschaltet werden. Die Sandbox ist fest definiert und es werden keine optionalen Benutzergruppen zugeordnet.

Vermutlich ist es diesem Umstand (jede App läuft unter einem anderen User) geschuldet, daß die SD-Card unter Android immer für alle lesbar und schreibbar ist. Standardmäßig wird dafür das FAT-Dateisystem verwendet, was keinerlei Zugriffsrechte kennt. Aber selbst SD-Cards unter ext4 sind typischerweise bei Android voll lesbar und schreibbar für jeden. Dieser Vollzugriff für beliebigen Code auf die SD-Card ist ein Problem, weil dadurch dort abgelegte Programme und Daten manipuliert werden können oder Malware sich dort problemlos einnisten kann. Das entspricht der nicht vorhandenen Sicherheit der ersten Windows-Versionen.

0.12.3 Rooten ist übel

Manche nicht standardmäßig mögliche Funktion kann unter Android nur dadurch vom User umgesetzt werden, indem er seiner App Root-Rechte gibt. Damit sind dann sämtliche "Permissions", die ja über User- und Group-IDs geregelt sind, wertlos: Die App darf alles mit und auf dem Gerät tun. Userland-Apps unter Root laufen zu lassen ist in der Unixwelt eine der Todsünden in punkto Sicherheit.

Zum Vergleich: Der Jailbreak auf iOS ermöglicht die Installation von nicht durch Apple geprüften Apps. Die Apps laufen jedoch nicht unter Root. Der Jailbreak verringert das Sicherheits-Niveau von iOS auf den Level von Android.

0.12.4 Android-Permissions, eine Show-Veranstaltung

Die Trennung der Android-Apps untereinander durch unterschiedliche User-IDs und die Freischaltung von zusätzlichen Rechten per Group-IDs ist erstmal eine gute Sache. Aber neben der kompletten Entwertung dieses Systems durch Root gibt es noch weitere Wege, die die Android-Permissions wertlos machen.

Standardmäßig muß der Benutzer alle Permissions während der Installation akzeptieren oder die App kann nicht installiert werden. Manche Systeme erlauben auch die Zuordnung von Einzel-Permissions, aber das ändert das folgende Problem nicht:

Das Zugeständnis von Berechtigungen passiert statisch und punktuell pro App bei der Installation. Die Nutzung der Rechte erfolgt jedoch dynamisch und verteilt und unterliegt nicht vollständig der Kontrolle, die der Benutzer zu haben glaubt, denn es gibt einige offizielle "by design" Möglichkeiten, alle scheinbar nicht erlaubten Dinge zu tun. Android Apps können verschiedene Arten von 2-Wege-Kommunikation verwenden, um in Teamwork die Permissions ad absurdum zu führen.

Alles oder nichts

Bei Android hat man die Wahl, entweder alle von der App geforderten Rechte zu gewähren, oder die App gar nicht zu installieren. Dieses "alles oder nichts" ist für den User sehr unbefriedigend, weil man einerseits die App nutzen möchte, andererseits ihr aber nur einen Teil der Zugriffsrechte einräumen möchte, was nicht möglich ist.

Berechtigungen für Android-Apps werden während der Installation zugeteilt. Für jede App wird typischerweise ein eigener User angelegt und dieser User wird optional Mitglied in verschiedenen User-Gruppen. Jede Gruppe stellt dabei eine andere Berechtigung dar.

Es ist von Android nicht vorgesehen, diese Zuordnung später zu ändern. Die "Security"-App "SRT AppGuard" verspricht zwar, dies zu tun, tatsächlich löscht sie jedoch die App und installiert sie mit geänderten Rechte-Wünschen und einer anderen Hersteller-Signatur neu. Damit löscht sie zwangsläufig die Userdaten und verhindert Updates der damit "gesicherten" Apps. So steht es ganz unten in den FAQs des Herstellers. Alle User-Daten der App zu löschen und alle Updates dieser App zu verhindern, ist nichts, was der Benutzer sich wünschen würde. Die App ist daher aus dem Google Play Store entfernt worden und wurde auch nicht wieder zugelassen.

Daß es auch anders geht, zeigt iOS, bei dem die Rechte für Zugriffe auf die verschiedenen User-Daten nicht statisch, sondern dynamisch erteilt werden. Die Berechtigungen für eine iOS-App, auf verschiedene Daten zugreifen zu dürfen, können jederzeit vom User einzeln geändert werden. Alle iOS-Apps bekommen ihre Zugriffsrechte auf Kontakte, Kalender, Photos und so weiter zur Laufzeit mitgeteilt, da sie beim System anfragen müssen, ob sie das Zugriffsrecht auf die jeweils gewünschte Art von User-Daten haben oder nicht. Die iOS-Apps sind auf diese dynamischen Rechte ausgelegt und sind auch bei Rechte-Verweigerung lauffähig, benutzen dann nur halt die entsprechenden User-Daten nicht.

App Services, Activities und ihre Freunde

Jede Android App kann, ohne daß der Benutzer das direkt sieht oder verhindern könnte, sogenannte "Services" anbieten. Jede Android App kann ebenso ungestört diese Dienste benutzen, um mit der anderen App zu kommunizieren. Services sind offizielle Android APIs für alle Apps.

Die Malware muß nur eine passende App wählen, die den gewünschten Service anbietet.

Da Google legitime Gründe für Inter-App-Kommunikation sah, haben sie Android um verschiedene einfache Arten von Interprocess Communication (IPC) für Apps erweitert, die auf GNU/Linux-Systemen nicht zu finden waren: Binder, Services (oben grad genannt), Intents (kommen gleich) und ContentProviders (für beispielsweise die Contacts). Diese IPC-Arten stehen natürlich auch Malware zur Verfügung, die damit die Permissions umgehen kann.

Wenn Deine Malware keinen Internet-Zugriff hat, könnte sie den passenden Service einer anderen App aufrufen oder sie benutzt einfach den immer vorhandenen eingebauten Browser über einen Intent, um Nachrichten rauszuschicken. Das geht auch unsichtbar im Hintergrund oder wenn das Gerät gesperrt wird. Und dazu benötigt die App keine spezielle Permission. Zum Empfangen muß sich die Malware lediglich für ein URI-Schema, beispielsweise "mybackdoor://" registriert haben, was der Benutzer ebenfalls nicht mitbekommt. Der kontaktierte böse Webserver macht beim Empfang einen Redirect auf die Malware-URI und kann damit Nachrichten an die Malware zurückschicken.

Man kann sich auch etwas mehr Mühe geben und ohne jede Permission eine Remote-Shell nutzen.

Zum Vergleich: Auf iOS gibt es solch reichhaltigen IPCs zwischen Apps nicht. Es gibt ein paar offizielle APIs, um das Adreßbuch zu benutzen und dergleichen, aber eine Kommunikation zwischen Dritt-Apps ist ansonsten wohl aufgrund der iOS-Sandboxen nur über URL-Schemen möglich. Etwas den Android-Inter-App-Services Vergleichbares findet man auf iOS nicht. Außerdem würde das auf iOS noch aus einem anderen Grund nicht funktionieren: iOS-Apps, die in den Hintergrund geschickt werden, dürfen zur Verlängerung der Akku-Laufzeit nur noch bestimmte Aktionen wie Musikabspielen, Voice over IP, Newsstand-Verarbeitung, Navigation oder Kommunikation mit externen Zubehörgeräten dauerhaft ausführen und ansonsten lediglich in begrenzter Zeit andere Aktionen wie Downloads sauber fertigstellen. Android-Apps können auch im Hintergrund mit Services uneingeschränkt weiter alles tun und dadurch überhaupt anderen Apps dauerhafte Kommunikation anbieten.

Permission Spreading

Neben der Nutzung von vorinstallierten Apps wie dem Browser kann man seine Permissions auch geschickt auf zwei eigene Apps aufteilen: Die eine beantragt Zugriff auf private Daten und die andere auf das Internet. Dann kooperieren die beiden, um die privaten Daten ins Netz zu stellen. Dem Benutzer kann so etwas als Addon für ein Spiel oder dergleichen untergeschoben werden.

0.12.5 Malware-Erkennung

Da bei Android in vielen Stores und beim "Side-Loading" auf eine Vorab-Untersuchung der Apps verzichtet wird und der "Bouncer" von Google Play sehr einfach auszutricksen ist, bleibt die Malware-Erkennung am Benutzer hängen. Der Android-Benutzer schaut sich die App an und installiert nur Apps, denen er vertraut oder die keine "gefährlichen Permissions" erfordern. Wie wir oben gesehen haben, kann jedoch eine App ohne Permissions trotzdem all das tun, wozu eigentlich Permissions erforderlich wären.

Der Android-Benutzer bekommt nun also seine Permission-Screens gezeigt, aber das hindert keine App daran, doch Dinge zu tun, die der Benutzer nicht abgenickt hat. Er wähnt sich jedoch fälschlicherweise in Sicherheit.

Im Gegensatz zu iOS-Apps können Android-APKs dynamisch Code nachladen, also zur Laufzeit ihr Verhalten beliebig ändern oder ergänzen. Diese Möglichkeit finden Android-Entwickler zwar gut, aber sie macht eine zuverlässige Beurteilung einer Android-Anwendung unmöglich. So kann ein Android-APK jederzeit bösartigen Code nachladen und auch wieder verschwinden lassen.

0.12.6 Beispiel-Exploit 1: Internet

Ich habe eine kleine App HelloDroid.apk inspiriert von einem Vortrag der "DEF CON 18" geschrieben, die zwar keine Permissions hat, aber trotzdem ins Internet kann. Getestet ist sie im Android-Emulator und auf einem "Nexus S" mit der Android-Version 4.0.3. Sie sollte mit jedem anderen Android ebenfalls funktionieren. Dieser Android-Exploit war recht einfach, was man auch daran sieht, daß es erst meine zweite App für Android ist; die erste war "Hello World!".

Die App funktioniert wie folgt: In ihrem Manifest deklariert sie, für das Android-Schema "mybackdoor" zuständig zu sein. Das bedeutet, daß der Android-Browser URLs mit diesem Typ an meine App durchreicht. Wenn so eine URL reinkommt, dann werden die Daten einfach als Textview in meiner App angezeigt.

Zuerst macht die App jedoch eine Anfrage an http://www.macmark.de/pushit.php. Das funktioniert über eine Activity, die einen Intent benutzt, der halt diese URL öffnen möchte. Netterweise schickt dann der Webbrowser die von mir gewünschte Anfrage ins Internet. Meine aufgerufene Webseite macht daraufhin eine Umleitung auf mybackdoor://data?param=rule_the_world_again, was dazu führt, daß diese Antwort meines Servers an meine App durchgereicht wird.

Wer den Emulator installiert hat kann, mit dem Android-Browser die apk-Datei runterladen und anschließend installieren, indem er sie in der Downloads-App anklickt. Echte Android-User brauchen natürlich nur ihr Telephone.

Meine App könnte also ein Trojaner sein, der sich von meinem Webserver, der als Command-And-Control-Server dienen könnte, neue Anweisungen holt und die dann ausführt. Ferngesteuert ohne Internet-Permission.

Download

Download

Download

Movie anschauen.

Zum Vergleich: Auf iOS kann man seine App auch für ein URL-Schema anmelden und es würde ebenso funktionieren. Aber: Hier behauptet niemand, daß das nur mir irgendwelchen Permissions möglich wäre. Wenn ich so eine App in Apples Store bringen will, muß ich diese Funktion dokumentieren, sonst breche ich die Regeln und fliege raus. Der Review-Prozeß untersucht die benutzten APIs und macht manuelle Tests. Lade ich Verhalten nach, indem ich mir Kommandos aus dem Netz hole, bin ich raus aus dem Store. Der Android-Market läßt jedoch solches Verhalten zu und verläßt sich darauf, daß meine App die Permissions nicht umgehen kann.

Von Apple würde so eine Trojaner-Funktion in einer App per se nicht geduldet, von Google hingegen schon; Android hat deshalb die entsprechend notwendigen Permissions, die darauf hinweisen sollten, daß meine App fröhlich mit dem Internet kommunizieren möchte, beziehungsweise müßten sie, falls nicht vorhanden, eben dies verhindern.

0.12.7 Beispiel-Exploit 2: Remote Shell

Ich habe noch eine weitere kleine App CmdDroid.apk geschrieben, die ebenfalls keine Permissions benötigt. CmdDroid geht ins Internet und holt sich von meinem Server ein paar Shell-Befehle ab, die er dann ausführt und mit ihren Ergebnissen anzeigt. Die benutzten Shell-Befehle können natürlich jederzeit geändert werden von mir.

Hier werden keine Sicherheitslücken oder Bugs ausgenutzt. Was hier passiert, ist alles von Google so entworfen worden, um die Permissions links liegen zu lassen.

Wollte man mit iOS remote Befehle nachladen und ausführen, ginge das nicht by design, sondern nur mit Bugs. So wie 2011 von Charlie mit der Codesign-Ausnahme in iOS 4.3 und 5 gezeigt wurde. Mit solchen Bugs fällt iOS dann auf das niedrigere Sicherheitsniveau von Android herunter, sagt Charlie – und ich auch.

0.12.8 Beispiel-Exploit 3: Kontakte

Hier ist eine App, die ohne eigene Permissions Kontaktdaten liest: ContactSucker.apk. Sie schafft das mit Hilfe eines Inter-App-Services, den diese App TroyDroid.apk bereitstellt. Services einer App werden dem User im Gegensatz zu Permissions nicht angezeigt. Das Beispiel zeigt, daß eine App, obwohl sie keine Permissions hat, trotzdem alles machen kann, indem sie einen Service einer anderen aufruft, die die gewünschten Permissions hat. Man kann daher der Permission-Liste einer installierten App nicht trauen, denn die App kann die Dienste anderer mächtigerer Apps nutzen, um heimlich Schindluder zu treiben. Zusätzlich könnte ich Deine Kontakte auch noch an meinen Server schicken; auf die gleiche Weise, wie die obigen Exploits funktionieren. Mit Services lassen sich alle Permissions erschleichen. Man muß deshalb damit rechnen, daß eine App ohne Permissions all das tun kann, was die Summe der installierten Apps tun darf.

Ist das ein Hack oder ein Bug in Android? Nein, denn dies ist ein dokumentiertes, zentrales, wichtiges, offizielles Feature von Android.

Geht das auch mit iOS? Nein, denn iOS-Apps können anderen Apps keine Services anbieten.

0.12.9 Beispiel-Exploit 4: Telefon

Und hier habe ich eine vierte Exploit-App geschrieben, die ohne eigene Permissions eine Nummer Deiner Wahl anruft: CallDroid.apk . Um ihre eigenen Permissions zu umgehen, benutzt sie einen Inter-App-Service, den die App CallBoy.apk bereitstellt.

Ein paar Screenshots zur Veranschaulichung: Keine Permissions wie man bei der Installation sieht, dann Eingabe einer Nummer, Einwahl und Telefonat.

Download

0.12.10 JavaScript, die Büchse der Pandora

Oben in 0.12.6 Beispiel-Exploit 1: Internet hatte ich schon eine Variante ausgeführt, wie Webseiten mit einer nativen APK kommunizieren können, indem man ein URL-Schema verwendet. Die Variante ist insofern harmlos, weil Texte interpretiert werden und kein direkter Zugriff auf die Anwendung möglich ist. Aber das heißt noch nichts, denn Google macht auch das möglich:

Die zweite Variante, wie eine Webseite mit einer APK zusammenarbeiten kann, ist echt gefährlich. Wie gefährlich, das ahnt Google selbst nicht. Wie Google richtig dokumentiert kann man mit

public void addJavascriptInterface (Object object, String name)

ein Java-Objekt aus der Anwendung dem JavaScript einer Webseite zur Verfügung stellen. Eine Anwendung kann einen WebView enthalten, der eine beliebige Webseite laden kann. Das JavaScript dieser Webseite hat dann Zugriff auf das bereitgestellte Java-Objekt. Sagt die offizielle Doku. Auf Android vor Version 4.2 kann JavaScript auf alle öffentlichen Methoden (auch geerbte) des Java-Objektes zugreifen, ab Version 4.2 nur auf öffentliche, die als JavascriptInterface markiert sind. In dem Zusammenhang warnt Google davor, daß ein Angreifer auf diesem Weg beliebigen Java-Code mit den Rechten der Anwendung ausführen könnte. Aber dabei bleibt es nicht.

Per Java-Reflection hat man darüber nicht nur Zugriff auf die Java-Laufzeitumgebung (Java-Runtime) und kann so beliebigen Java-Code ausführen, sondern es kommt noch besser. Wenn man in JavaScript auf das zur Verfügung gestellte Java-Objekt, ich nenne es hier ExposedJavaObject, so zugreift:

ExposedJavaObject.getClass().forName('java.lang.Runtime')
.getMethod('getRuntime',null).invoke(null,null).exec(cmd);

dann kann "cmd" ein beliebiges Shell-Kommando sein. Man kann also per JavaScript beliebige Betriebssystem-Befehle absetzen. Und damit ist die Büchse der Pandora offen. Der Programmierer kann hier nichts machen. Sobald er ein Java-Objekt auf diese Weise an JavaScript rübergereicht hat, kann JavaScript in der App und auf dem Android-System tun, was es will.

Schon im Dezember 2012 wurde dieses Problem öffentlich gemacht und gleich ein Beispiel mitgeliefert, das per JavaScript ein komplettes ARM-Binary auf das Android-System schreibt und dann Linux-Befehle aufruft, um dieses Binary zu starten. Inwzischen gibt es noch weitergehende Nutzungen, um diesen Design-Fehler noch bequemer ausnutzen zu können.

Was ist mit iOS? Da gibt es gar keinen vergleichbaren Weg. Nur den ersten harmlosen über das URL-Schema. Man kann JavaScript in iOS-Apps keine nativen Objekte zur Verfügung stellen wie auf Android. Auf OS X gibt es zwar etwas ähnliches, allerdings ist dort kein Weg bekannt, den Zugriff wie auf Android beliebig auszuweiten. Auf OS X muß eine App Keys (für Key-Value-Coding) und Selectoren explizit freigeben und ansonsten ist jeder andere Zugriff per Default geblockt.

Was kann Google tun? Nicht viel, denn die JavaScript-Bridge ist by design so gewollt und Java-Reflection kann man nicht abschalten. In Anbetracht der Tatsache, daß viele APKs (sprich Android-Apps) WebViews auf diese Weise benutzen, gibt es jede Menge Gelegenheiten, ein Android-System remote zu übernehmen. Apropos: Eric Schmidt, Google-Chef, sagte übrigens grad, daß Android sicherer als iOS wäre. Das Publikum soll in schallendes Gelächter augebrochen sein. Zu recht.

Wird eventuell fortgesetzt.

Valid XHTML 1.0!

Besucherzähler


Markus MöllerLatest Update: 10. October 2013 at 08:57h (german time)
Link: www.macmark.de/android.php
Written by: Markus Möller

Free counter and web stats
Backlinks-Statistik deaktiviert; kann rechts im Menü eingeschaltet werden.