Dass Android-Geräte vermehrt ins Visier von Angreifern geraten, ist eine Folge ihrer Popularität. Android-Designschwächen erleichtern Crackern bislang ihr Tun. Das SE-Linux-Projekt der NSA ist dabei, mit SE Android zumindest die Auswirkungen von Exploits drastisch zu mindern.
Android besitzt bereits ein Sicherheitsframework. Es beschränkt den Zugriff einzelner Apps auf bestimmte Bereiche des Telefons oder Tablets. Das Android Security Model gewährleistet auf zwei Ebenen Sicherheit: dem Application- und dem Kernel-Level. Auf der App-Ebene prüft Android den Zugriff auf Anwenderprogramm-Komponenten einerseits und den Zugriff von Apps auf Systemressourcen andererseits. Der Programmierer beschreibt in einem Manifest, worauf seine Applikation zugreifen soll; der Anwender erlaubt oder verbietet die Zugriffe dann auf seinem Gerät.
Auf dem Kernel-Level bemüht sich Android jede Applikation in einer eigenen Sandbox zu betreiben und jedes Umgehen der Application-Level-Security zu verhindern. Dabei arbeitet Android transparent und nutzt das Linux Discretionary Access Control System (DAC, benutzerbezogene Zugriffskontrolle).
Wie zahlreiche Exploits für Android zeigen, genügt dies jedoch nicht. Denn obwohl jede Applikation eine eigene Benutzer-ID verwendet, kann eine Applikation bei der Rechtevergabe schlampen und anderen Benutzern Leserechte an den eigenen sensitiven Dateien geben. Angriffe erfolgen dann durch Malware, die der Anwender aus dem Google Market installiert. Da liegt es nahe, Android mit einem funktionierenden Mandatory Access Control System auszurüsten – wie es mit SE Linux [1] für Linux bereitsteht.
Vorbereitung ist alles
Nach Vorarbeiten wie in [2] beschrieben, wurde am 6. Januar 2012 SE Android [3] vorgestellt. Die Software soll bei richtiger Konfiguration die Privilege Escalation einzelner Apps und Zugriffe auf die Daten anderer Apps (Data Leakage) verhindern. Zudem garantiert SE Android die Integrität der Apps und ihrer Daten. Auch lässt sich das Rooten des Geräts durch legitime Toolkits verhindern. Unterm Strich steigt die Sicherheit der Android-Telefone und -Tablets [4].
Einige Mutige haben die Software schon auf ihre Google-Nexus-Geräten aufgespielt. Erfolgsorientierte Telefonbesitzer sollten von SE Android aber besser die Finger lassen – die Software ist schlicht noch nicht fertig und stabil. Für erste Gehversuche im Emulator ist sie jedoch bereits zu gebrauchen – dieser Artikel erklärt die Schritte dorthin.
Ein langer Weg
Ein Anwender, der SE Android ausprobieren möchte, muss zurzeit einigen Aufwand treiben. Da SE Android noch nicht komplett in Android aufgegangen ist, muss er das Android-Betriebssystem patchen und selbst übersetzen. Er beginnt am besten damit, ein Buildsystem aufzubauen. Während andere Distributionen auch funktionieren, gelingt es Ubuntu 10.04 (64 Bit) am besten [5]. (Andere Ubuntu-Versionen erweisen sich als problematisch und benötigen Anpassungen in den Paketen und Skripten.)
Für die spätere Übersetzung ist eine Reihe von Paketen erforderlich. Der Anwender installiert diese einfach aus dem Ubuntu-Repository mit dem Befehl aus Listing 1. Das einzige Paket, welches der Anwender danach noch installieren muss, ist das originale Oracle-Sun Java JDK – Open JDK funktioniert hier nicht. Eine einfache Installationsmöglichkeit bietet das Skript »oab-java6.sh« [6]. Es lädt selbstständig die Dateien von Oracle und erzeugt automatisch Debian-Pakete in dem Verzeichnis »/var/local/oab/deb« , die sich anschließend mit »dpkg« einfach installieren lassen.
Die Befehle in Listing 2 dienen dazu, das Android-Code-Repository zu erzeugen und SE Android zu erweitern. Das Synchronisieren des Repository dauert in Abhängigkeit von der Internetverbindung bis zu einigen Stunden. Grundsätzlich sollte der Anwender vorher für ausreichend Platz gesorgt haben. Nach der Übersetzung benötigt der Code insgesamt bis zu 30 GByte Speicher.
Listing 1
Pakete installieren
01 sudo aptitude install git-core gnupg flex bison \ 02 gperf build-essential zip curl zlib1g-dev libc6-dev \ 03 lib32ncurses5-dev ia32-libs x11proto-core-dev \ 04 libx11-dev lib32readline5-dev lib32z-dev \ 05 libgl1-mesa-dev g++-multilib mingw32 tofrodos \ 06 python-markdown libxml2-utils xsltproc java-comm
Listing 2
SE-Android-Repository
01 mkdir ~/bin 02 export PATH=~/bin:$PATH 03 curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo 04 chmod a+x ~/bin/repo 05 mkdir android-repo 06 cd android-repo 07 repo init -u https://android.googlesource.com/platform/manifest 08 wget http://selinuxproject.org/~seandroid/local_manifest.xml 09 mv local_manifest.xml .repo 10 repo sync
Um das Übersetzen zu beschleunigen, kann der Nutzer den Ccache Compiler einsetzen – so er ihn konfiguriert. Dazu initialisiert er den Cache mit dem »ccache« -Kommando aus dem Repository:
export USE_CCACHE=1 prebuilt/linux-x86/ccache/ccache -M 50G
Die Vorbereitungsarbeiten sind geschafft. Mit den Kommandos
source build/envsetup.sh lunch full-eng make -j4 HAVE_SELINUX=true
startet nun endlich der Übersetzungsvorgang des Betriebssystems.
Emulator in Betrieb nehmen
Um (SE) Android in einem Emulator zu testen, bedarf es noch eines passend übersetzten Kernels:
cd kernel/goldfish make ARCH=arm goldfish_armv7_defconfig make ARCH=arm CROSS_COMPILE=../../prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
Der Emulator befindet sich schon auf dem PC, da er im Android-Repository enthalten ist. Er startet mit:
emulator -show-kernel -kernelkernel/goldfish/arch/arm/boot/zImage
Hat alles geklappt, erscheint die grafische Oberfläche des Qemu-basierten Emulators (Abbildung 1). Für die ersten Tests eignet sich die Android Debug Bridge (ADB, [7]). Mit dieser kann der Anwender auf angeschlossenen Android-Systemen direkt Befehle ausführen. ADB spricht auch den Emulator an, beispielsweise mit »adb devices« . Als Antwort kommt daraufhin:
List of devices attached emulator-5554 device
Mit »adb shell« erhält der Anwender eine Shell mit einem Rootprompt. Listing 3 zeigt die ersten Gehversuche auf ihr. Trotz Rootprompt stehen nicht sämtliche Privilegien zur Verfügung. Das ändert sich erst mit dem Befehl »su 0« , zu sehen in Listing 3 ab Zeile 11. Zusätzlich kann der Anwender die Befehle »ls -Z« und »ps -Z« nutzen, um die Typen der Dateien und die Domänen der Prozesse zu ermitteln.
Dabei fällt auf, dass die Applikationen nur in wenige Domänen aufgeteilt sind (siehe Listing 4). Alle Android-Apps verwenden die Domäne »trusted_app« . Lediglich der SE Android Manager (Abbildung 2) benutzt die Domäne »system_app« . SE Android garantiert offenbar die Sicherheit auf andere Weise.
Listing 3
Kommandos auf der Shell
01 # id 02 uid=0(root) gid=0(root) context=u:r:shell:s0 03 # getenforce 04 Permissive 05 # setenforce 1 06 # getenforce 07 Could not get enforcing status: Permission denied 08 # setenforce 0 09 setenforce: Could not set enforcing status: Permission denied 10 11 # su 0 getenforce 12 Enforcing 13 # su 0 setenforce 0 14 # getenforce 15 Permissive
Listing 4
Android-ps -Z
01 LABEL USER PID PPID NAME 02 u:r:init:s0 root 1 0 /init 03 u:r:kernel:s0 root 2 0 kthreadd 04 [...] 05 u:r:servicemanager:s0 system 32 1 /system/bin/servicemanager 06 u:r:vold:s0 root 33 1 /system/bin/vold 07 u:r:netd:s0 root 35 1 /system/bin/netd 08 u:r:debuggerd:s0 root 36 1 /system/bin/debuggerd 09 u:r:rild:s0 radio 37 1 /system/bin/rild 10 u:r:surfaceflinger:s0 system 38 1 /system/bin/surfaceflinger 11 u:r:zygote:s0 root 39 1 zygote 12 u:r:drmserver:s0 drm 40 1 /system/bin/drmserver 13 u:r:mediaserver:s0 media 41 1 /system/bin/mediaserver 14 u:r:dbusd:s0 bluetooth 42 1 /system/bin/dbus-daemon 15 u:r:installd:s0 root 43 1 /system/bin/installd 16 u:r:keystore:s0 keystore 44 1 /system/bin/keystore 17 u:r:qemud:s0 root 45 1 /system/bin/qemud 18 u:r:shell:s0 shell 48 1 /system/bin/sh 19 u:r:adbd:s0 root 51 1 /sbin/adbd 20 u:r:system:s0 system 81 39 system_server 21 u:r:system_app:s0 system 190 39 com.android.systemui 22 u:r:trusted_app:s0:c31 app_31 204 39 com.android.inputmethod.latin 23 u:r:radio:s0 radio 217 39 com.android.phone 24 u:r:system_app:s0 system 229 39 com.android.settings 25 u:r:trusted_app:s0:c3 app_3 269 39 android.process.acore 26 u:r:trusted_app:s0:c19 app_19 277 39 com.android.smspush 27 u:r:trusted_app:s0:c33 app_33 297 39 com.android.provision 28 u:r:trusted_app:s0:c5 app_5 318 39 com.android.calendar 29 u:r:trusted_app:s0:c32 app_32 329 39 com.android.launcher 30 u:r:trusted_app:s0:c13 app_13 356 39 com.android.deskclock 31 u:r:trusted_app:s0:c20 app_20 380 39 com.android.providers.calendar 32 u:r:trusted_app:s0:c3 app_3 400 39 com.android.contacts 33 u:r:system_app:s0 system 425 39 com.android.seandroid_manager 34 u:r:trusted_app:s0:c2 app_2 455 39 com.android.voicedialer 35 u:r:trusted_app:s0:c1 app_1 461 39 android.process.media 36 u:r:trusted_app:s0:c4 app_4 484 39 com.android.email 37 u:r:trusted_app:s0:c6 app_6 507 39 com.android.exchange 38 u:r:trusted_app:s0:c12 app_12 528 39 com.android.mms 39 u:r:trusted_app:s0:c17 app_17 564 39 com.android.gallery3d 40 [...]

Abbildung 2: Im SE Android Manager – er läuft in einer eigenen Domäne – darf der Anwender den Enforcing Mode aktivieren und die booleschen Variablen verwalten.
Das Sicherheitskonzept von SE Android
Angreifer benutzen gern privilegierte Dienste als Ziel für Rootexploits. Android selbst bietet hier nur wenig Sicherheit: Per Default darf eine App nur mit wenigen privilegierten Diensten kommunizieren. Will sie mit weiteren Daemons kommunizieren, zum Beispiel »RECEIVE_SMS« , »BLUETOOTH« oder »ACCESS_FINE_LOCATION« , muss die App dies bei ihrer Installation anfordern.
Die meisten Anwender bestätigen solche Anforderungen aber unkritisch. Ist die Kommunikation einmal erlaubt und weist der privilegierte Dienst eine Sicherheitslücke auf, wie zum Beispiel Androids Volume-Daemon »vold« , der Massenspeicher wie SD-Cards verwaltet, dann bricht Androids Schutz zusammen. Der Angreifer erhält Zugriff auf einen mit Rootrechten laufenden Prozess. Dies wird er nutzen, um beispielsweise eine Set-UID-Shell zu erzeugen und dauerhaft Rootrechte zu erhalten – wie beim Gingerbreak-Exploit [8].
SE Android verhindert dies, indem es für jeden privilegierten Dienst eine eigene Domäne verwendet. Aus Listing 4, Zeile 6, ist ersichtlich, dass der »vold« in der Domäne »vold« läuft. Sie erhält nur die Privilegien, die der Daemon für die vorgesehenen Aufgaben benötigt. Beim Gingerbreak-Exploit würde SE Android daraufhin anhand der Defaultpolicy viele Privilegien verweigern. So dürfte »vold« nicht die Rechte oder den Eigentümer einer Datei verändern, was zum Erzeugen einer Set-UID-Shell jedoch erforderlich wäre. Auch die Kommunikation des »vold« über einen Netlink-Socket verbietet die Policy.
Selbst in Fällen, in denen SE Androids Defaultpolicy einen Angriff nicht umfassend genug abzufedern vermag, verhindert das Framework den Angriff auf andere Weise: Auch eine angreifende App muss nämlich die Set-UID-Rootshell starten. SE Android kontrolliert diese App in der Domäne »trusted_app« . Da der zugehörige SE Linux Security Context beim Aufruf eines Set-UID-Binary aber erhalten bleibt, sieht ihn Android als einen Prozess mit Rootprivilegien an – und SE Android unterbindet dessen Ablauf. Der Exploit ist zwar formal erfolgreich, bleibt aber wirkungslos!
App-Security
Das Android Security Model versieht jede App bei der Installation mit einer einzigartigen User-ID, die für die gesamte Zeit der Installation der App gültig bleibt. Auf einem anderen Gerät erhält die gleiche App jedoch vielleicht eine andere User-ID. Der Programmierer kann jedoch per Manifest-XML-File verlangen, dass zwei Apps auch die gleiche ID erhalten sollen (»sharedUserId« ). Nun kommt es auf den Programmierer an, welche Rechte er den von der Applikation erzeugten Dateien zuweist.
In den letzten Monaten häufen sich Berichte, dass Apps ihre sensiblen Daten nicht richtig sichern, beispielsweise die Skype-App. Diese speicherte Adressen, Kontakte, Chatlogs lesbar (»MODE_WORD_READABLE« ) für alle anderen Applikationen [9]. Ähnliche Sicherheitslücken offenbarten die Apps von Lookout, Symantec, Well Fargo und der Bank of America.
SE Android wirkt dem entgegen, indem es jeder App eine eigene MLS-Category zuweist (in Listing 4 etwa »u:r:trusted_app:s0:c20« ). Dateien, die eine App erzeugt, labelt SE Android automatisch mit der entsprechenden MLS-Category. Das Verzeichnis »/data/data« enthält zum Beispiel für jede App ein eigenes, entsprechend gelabeltes Unterverzeichnis. Der Zugriff auf ein Verzeichnis gelingt nur, wenn die MLS-Categorys von Prozess und Datei übereinstimmen.
Da nicht der Autor der App die MLS-Category bestimmt und auch die App die Category nicht wechseln darf, verhindert SE Android damit den Zugriff auf die Daten anderer Applikationen – egal ob ein Programmierer böswillig gehandelt oder ob er bei der Vergabe der DAC-Rechte nur einen Fehler gemacht hat.
Schwieriges Unterfangen
Das Portieren von SE Linux auf Android war bisher ein Kraftakt. Die Ausgangslage: Der Android-Kernel enthielt mehrere spezifische Subsysteme, für die SE Linux keinerlei Unterstützung bot. Für den Android-Userspace galt das Gleiche. Auch das von Android verwendete Dateisystem YAFFS 2 speicherte keine Security-Kontexte. Die gängigen SE-Linux-Policies erwiesen sich zudem als vollkommen ungeeignet für SE Android. Und viele Apps kommunizierten zu allem Überfluss über Frameworks, die SE Linux nicht überwacht hat.
Diese Probleme haben die SE-Android-Entwickler im Wesentlichen gelöst, indem sie sowohl den Kernel als auch das Dateisystem um SE-Linux-Funktionen erweitert haben. Auch der Userspace wurde minimal modifiziert, sodass Befehle wie »ls -Z« und »ps -Z« funktionieren. Seit der Entwicklung auf Gingerbread (Android 2.3), gilt SE Android auch als kompatibel zum Android Open Source Project (AOSP ab Version 4.0.3, [10]).
Erstaunlicherweise ist SE Android dadurch kaum umfangreicher geraten als Android: Der Bootcode wächst von 3444 KByte auf 3584 KByte, die Recovery-Partition von 3776 auf 3928 KByte und das System selbst um gerade mal 0,03 Prozent.
Anwender, die sich mit SE Android beschäftigen und die Policy erweitern wollen, finden alle notwendigen Werkzeuge. Die SE-Linux-AVC-Denial-Protokolle aus dem Emulator beziehen sie mit:
adb shell su 0 cat /proc/kmsg > dmesg.txt
Der Befehl liest den Kernel-Protokollspeicher aus. Die Daten analysiert der Anwender dann mit dem üblichen »audit2allow« -Befehl. Hierbei muss er angeben, dass er die SE-Android-Policy als Grundlage verwenden will:
audit2allow -p out/target/product/generic/root/sepolicy.24 < dmesg.txt
Die selbst erzeugten Regeln hinterlegt er in »sepolicy.[te|fc|pc]« -Dateien, die er zum Beispiel in »build/target/board/generic« speichert. Beim nächsten Zusammenbau des Android-Systems fügt der Compiler diese zur Policy hinzu.
Fazit und Ausblick
SE Linux war ursprünglich ein Projekt der National Security Agency, mit dem es gelungen ist, ein allgemein verfügbares Betriebssystem mit Eigenschaften auszustatten, die Regierungsbehörden, Geheimdienste und Militär benötigen, um die Sicherheit ihrer Daten zu gewährleisten. Das Massenphänomen Android, dem Google mehr Usability als Sicherheit in die Wiege gelegt hat, kann vergleichbare Schützenhilfe gut gebrauchen.
Bleibt zu hoffen, dass SE Android bald einen Zustand erreicht, der den Produktiveinsatz erlaubt. Auch beschränkt sich SE Android zurzeit auf den Kernel, das abstrakte Android-Rechtemodell zu unterstützen oder zu überwachen gelingt der Software nicht. Sie bleibt vorerst blind für Zugriffe aus dem Android-Framework auf Komponenten wie WLAN oder Telefon. Trotz aller Mängel sagt die Prognose: Android wird wehrhaft.
Infos
- Ralf Spenneberg, “SE Linux”: Linux-Magazin 06/06, S. 36
- S. Bugiel, L. Davi, A. Dmitrienko, S. Heuser, A.-R. Sadeghi, B. Shastry. “Practical and Lightweight Domain Isolation on Android”, Proceedings of the 1st ACM CCS Workshop on Security and Privacy in Mobile Devices (SPSM), ACM Press, 2011
- SE Android: http://selinuxproject.org/page/SEAndroid
- “The Case for SE Android” (Video): http://video.linux.com/videos/the-case-for-security-enhanced-se-android
- Android-Umgebung: http://source.android.com/source/initializing.html
- »oab-java6.sh« : https://raw.github.com/flexiondotorg/oab-java6/master/oab-java6.sh
- Android Debug Bridge: http://developer.android.com/guide/developing/tools/adb.html
- CVE-2011-1823: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1823
- CVE-2011-1717: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1717
- Android Open Source Project: http://source.android.com







