Aus Linux-Magazin 06/2012

Mandatory Access Control für Android

© complize, photocase.com

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.

Abbildung 1: Nach einigen Vorarbeiten startet SE Android im Emulator.

Abbildung 1: Nach einigen Vorarbeiten startet SE Android im Emulator.

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.

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

  1. Ralf Spenneberg, “SE Linux”: Linux-Magazin 06/06, S. 36
  2. 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
  3. SE Android: http://selinuxproject.org/page/SEAndroid
  4. “The Case for SE Android” (Video): http://video.linux.com/videos/the-case-for-security-enhanced-se-android
  5. Android-Umgebung: http://source.android.com/source/initializing.html
  6. »oab-java6.sh« : https://raw.github.com/flexiondotorg/oab-java6/master/oab-java6.sh
  7. Android Debug Bridge: http://developer.android.com/guide/developing/tools/adb.html
  8. CVE-2011-1823: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1823
  9. CVE-2011-1717: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1717
  10. Android Open Source Project: http://source.android.com

Der Autor

Ralf Spenneberg arbeitet als freier Unix- und Linux-Trainer, Berater und Autor. Mit seinem Unternehmen Open Source Training Ralf Spenneberg führt er Schulungen und Beratungen durch. In wenigen Wochen erscheint sein neues Buch “KVM für die Server-Virtualisierung”, das er gemeinsam mit Michael Kofler verfasst hat.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben