Android Applications Basics

Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Try Hard Security Group


Android-Sicherheitsmodell

Es gibt zwei Ebenen:

  • Das Betriebssystem, das installierte Anwendungen voneinander isoliert.

  • Die Anwendung selbst, die Entwicklern ermöglicht, bestimmte Funktionalitäten freizulegen und Anwendungsfähigkeiten zu konfigurieren.

UID-Trennung

Jede Anwendung erhält eine spezifische Benutzer-ID. Dies wird während der Installation der App durchgeführt, damit die App nur mit Dateien interagieren kann, die ihrer Benutzer-ID gehören oder gemeinsam genutzte Dateien. Daher können nur die App selbst, bestimmte Komponenten des Betriebssystems und der Root-Benutzer auf die Daten der Apps zugreifen.

UID-Sharing

Zwei Anwendungen können so konfiguriert werden, dass sie dieselbe UID verwenden. Dies kann nützlich sein, um Informationen zu teilen, aber wenn eine von ihnen kompromittiert ist, werden die Daten beider Anwendungen kompromittiert. Deshalb wird dieses Verhalten nicht empfohlen. Um dieselbe UID zu teilen, müssen Anwendungen denselben android:sharedUserId-Wert in ihren Manifesten definieren.

Sandboxing

Das Android Application Sandbox ermöglicht es, jede Anwendung als eigenen Prozess unter einer separaten Benutzer-ID auszuführen. Jeder Prozess hat seine eigene virtuelle Maschine, sodass der Code einer App isoliert von anderen Apps ausgeführt wird. Ab Android 5.0(L) wird SELinux durchgesetzt. Grundsätzlich hat SELinux alle Prozessinteraktionen verweigert und dann Richtlinien erstellt, um nur die erwarteten Interaktionen zwischen ihnen zuzulassen.

Berechtigungen

Wenn Sie eine App installieren und um Berechtigungen bitten, fordert die App die in den uses-permission-Elementen in der AndroidManifest.xml-Datei konfigurierten Berechtigungen an. Das uses-permission-Element gibt den Namen der angeforderten Berechtigung im name-Attribut an. Es hat auch das maxSdkVersion-Attribut, das das Anfordern von Berechtigungen auf Versionen höher als die angegebene stoppt. Beachten Sie, dass Android-Anwendungen nicht alle Berechtigungen von Anfang an anfordern müssen, sie können auch Berechtigungen dynamisch anfordern, aber alle Berechtigungen müssen im Manifest deklariert sein.

Wenn eine App Funktionalitäten freigibt, kann sie den Zugriff nur auf Apps beschränken, die über eine bestimmte Berechtigung verfügen. Ein Berechtigungselement hat drei Attribute:

  • Der Name der Berechtigung

  • Das permission-group-Attribut, das das Gruppieren verwandter Berechtigungen ermöglicht.

  • Das Schutzniveau, das angibt, wie die Berechtigungen gewährt werden. Es gibt vier Typen:

  • Normal: Wird verwendet, wenn der App keine bekannten Bedrohungen drohen. Der Benutzer muss sie nicht genehmigen.

  • Gefährlich: Gibt an, dass die Berechtigung der anfordernden Anwendung einen erhöhten Zugriff gewährt. Benutzer werden aufgefordert, sie zu genehmigen.

  • Signature: Nur Apps, die vom selben Zertifikat wie das exportierende Komponente signiert sind, können Berechtigungen erhalten. Dies ist die stärkste Schutzart.

  • SignatureOrSystem: Nur Apps, die vom selben Zertifikat wie das exportierende Komponente signiert sind oder Apps, die mit Systemzugriff ausgeführt werden, können Berechtigungen erhalten.

Vorinstallierte Anwendungen

Diese Apps befinden sich in der Regel in den Verzeichnissen /system/app oder /system/priv-app und einige von ihnen sind optimiert (Sie finden möglicherweise nicht einmal die Datei classes.dex). Diese Anwendungen sind es wert, überprüft zu werden, da sie manchmal mit zu vielen Berechtigungen (als Root) ausgeführt werden.

  • Diejenigen, die mit dem AOSP (Android OpenSource Project) ROM ausgeliefert werden

  • Hinzugefügt vom Gerätehersteller

  • Hinzugefügt vom Mobilfunkanbieter (wenn bei ihnen gekauft)

Rooting

Um Root-Zugriff auf ein physisches Android-Gerät zu erhalten, müssen Sie in der Regel 1 oder 2 Schwachstellen ausnutzen, die normalerweise spezifisch für das Gerät und die Version sind. Sobald der Exploit funktioniert hat, wird normalerweise das Linux su-Binär in einen vom Benutzer definierten Pfad wie /system/xbin kopiert.

Sobald das su-Binär konfiguriert ist, wird eine andere Android-App verwendet, um mit dem su-Binär zu interagieren und Anfragen für Root-Zugriff zu verarbeiten wie Superuser und SuperSU (erhältlich im Google Play Store).

Beachten Sie, dass der Rooting-Prozess sehr gefährlich ist und das Gerät schwerwiegend beschädigen kann.

ROMs

Es ist möglich, das Betriebssystem zu ersetzen, indem Sie eine benutzerdefinierte Firmware installieren. Dadurch ist es möglich, die Nützlichkeit eines alten Geräts zu erweitern, Softwarebeschränkungen zu umgehen oder Zugriff auf den neuesten Android-Code zu erhalten. OmniROM und LineageOS sind zwei der beliebtesten Firmware-Versionen.

Beachten Sie, dass nicht immer eine Root-Berechtigung erforderlich ist, um eine benutzerdefinierte Firmware zu installieren. Einige Hersteller erlauben das Entsperren ihrer Bootloader auf dokumentierte und sichere Weise.

Auswirkungen

Sobald ein Gerät gerootet ist, kann jede App Root-Zugriff anfordern. Wenn eine bösartige Anwendung dies erhält, kann sie auf fast alles zugreifen und das Telefon beschädigen.

Grundlagen von Android-Anwendungen

  • Das Format von Android-Anwendungen wird als APK-Dateiformat bezeichnet. Es handelt sich im Wesentlichen um eine ZIP-Datei (durch Umbenennen der Dateierweiterung in .zip können die Inhalte extrahiert und angezeigt werden).

  • APK-Inhalte (nicht erschöpfend)

  • AndroidManifest.xml

  • resources.arsc/strings.xml

  • resources.arsc: enthält vorab kompilierte Ressourcen wie binäre XML.

  • res/xml/files_paths.xml

  • META-INF/

  • Hier befindet sich das Zertifikat!

  • classes.dex

  • Enthält Dalvik-Bytecode, der den standardmäßig ausgeführten kompilierten Java- (oder Kotlin-)Code der Anwendung darstellt.

  • lib/

  • Enthält native Bibliotheken, aufgeteilt nach CPU-Architektur in Unterverzeichnissen.

  • armeabi: Code für ARM-basierte Prozessoren

  • armeabi-v7a: Code für ARMv7 und höhere Prozessoren

  • x86: Code für X86-Prozessoren

  • mips: Code nur für MIPS-Prozessoren

  • assets/

  • Speichert verschiedene Dateien, die von der App benötigt werden, möglicherweise einschließlich zusätzlicher nativer Bibliotheken oder DEX-Dateien, die manchmal von Malware-Autoren verwendet werden, um zusätzlichen Code zu verbergen.

  • res/

  • Enthält Ressourcen, die nicht in resources.arsc kompiliert sind.

Dalvik & Smali

In der Android-Entwicklung wird Java oder Kotlin zur Erstellung von Apps verwendet. Anstatt wie bei Desktop-Apps den JVM zu verwenden, kompiliert Android diesen Code in Dalvik Executable (DEX) Bytecode. Früher verarbeitete die Dalvik Virtual Machine diesen Bytecode, aber jetzt übernimmt in neueren Android-Versionen die Android-Laufzeitumgebung (ART).

Für Reverse Engineering wird Smali entscheidend. Es ist die menschenlesbare Version des DEX-Bytecodes und fungiert wie eine Assemblersprache, indem es den Quellcode in Bytecode-Anweisungen übersetzt. Smali und baksmali beziehen sich in diesem Kontext auf die Assemblierungs- und Disassemblierungstools.

Intents

Intents sind das Hauptmittel, mit dem Android-Apps zwischen ihren Komponenten oder mit anderen Apps kommunizieren. Diese Nachrichtenobjekte können auch Daten zwischen Apps oder Komponenten übertragen, ähnlich wie GET/POST-Anfragen bei HTTP-Kommunikationen verwendet werden.

Ein Intent ist also im Grunde genommen eine Nachricht, die zwischen Komponenten übermittelt wird. Intents können an bestimmte Komponenten oder Apps gerichtet sein oder ohne einen spezifischen Empfänger gesendet werden. Um es einfach auszudrücken, kann ein Intent verwendet werden:

  • Um eine Aktivität zu starten, die typischerweise eine Benutzeroberfläche für eine App öffnet

  • Als Broadcasts, um das System und Apps über Änderungen zu informieren

  • Um einen Hintergrunddienst zu starten, zu stoppen und mit ihm zu kommunizieren

  • Um Daten über ContentProvider abzurufen

  • Als Rückrufe, um Ereignisse zu behandeln

Wenn anfällig, können Intents verwendet werden, um verschiedene Arten von Angriffen durchzuführen.

Intent-Filter

Intent-Filter definieren wie eine Aktivität, ein Dienst oder ein Broadcast-Empfänger mit verschiedenen Arten von Intents interagieren kann. Im Wesentlichen beschreiben sie die Fähigkeiten dieser Komponenten, wie z. B. welche Aktionen sie ausführen können oder welche Arten von Broadcasts sie verarbeiten können. Der primäre Ort, um diese Filter zu deklarieren, ist die AndroidManifest.xml-Datei, obwohl es auch möglich ist, sie für Broadcast-Empfänger zu codieren.

Intent-Filter bestehen aus Kategorien, Aktionen und Datenfiltern, wobei die Möglichkeit besteht, zusätzliche Metadaten einzuschließen. Diese Konfiguration ermöglicht es Komponenten, spezifische Intents zu verarbeiten, die den deklarierten Kriterien entsprechen.

Ein entscheidender Aspekt von Android-Komponenten (Aktivitäten/Dienste/Content-Provider/Broadcast-Empfänger) ist ihre Sichtbarkeit oder öffentlicher Status. Eine Komponente gilt als öffentlich und kann mit anderen Apps interagieren, wenn sie mit einem Wert von true als exportiert markiert ist oder wenn für sie ein Intent-Filter im Manifest deklariert ist. Entwickler haben jedoch die Möglichkeit, diese Komponenten explizit privat zu halten, um sicherzustellen, dass sie nicht unbeabsichtigt mit anderen Apps interagieren. Dies wird erreicht, indem das Attribut exportiert in ihren Manifestdefinitionen auf false gesetzt wird.

Darüber hinaus haben Entwickler die Möglichkeit, den Zugriff auf diese Komponenten weiter abzusichern, indem sie spezifische Berechtigungen verlangen. Das Attribut permission kann festgelegt werden, um durchzusetzen, dass nur Apps mit der festgelegten Berechtigung auf die Komponente zugreifen können, was eine zusätzliche Sicherheitsebene und Kontrolle darüber bietet, wer mit ihr interagieren kann.

<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>

Implizite Intents

Intents werden programmgesteuert mithilfe eines Intent-Konstruktors erstellt:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

Die Aktion des zuvor deklarierten Intents ist ACTION_SEND und das Extra ist eine mailto-Uri (das Extra ist die zusätzliche Information, die der Intent erwartet).

Dieser Intent sollte im Manifest wie im folgenden Beispiel deklariert werden:

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Ein Intent-Filter muss die Aktion, Daten und Kategorie übereinstimmen, um eine Nachricht zu empfangen.

Der "Intent-Auflösungsprozess" bestimmt, welche App jede Nachricht erhalten soll. Dieser Prozess berücksichtigt das Prioritätsattribut, das in der Intent-Filter-Deklaration festgelegt werden kann, und die mit der höheren Priorität wird ausgewählt. Diese Priorität kann zwischen -1000 und 1000 festgelegt werden, und Anwendungen können den Wert SYSTEM_HIGH_PRIORITY verwenden. Bei einem Konflikt erscheint ein "Auswahlfenster", damit der Benutzer entscheiden kann.

Explizite Intents

Ein expliziter Intent gibt den Klassennamen an, den er anvisiert:

Intent downloadIntent = new (this, DownloadService.class):

In anderen Anwendungen können Sie auf das zuvor deklarierte Intent zugreifen, indem Sie Folgendes verwenden:

Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);

Ausstehende Intents

Diese ermöglichen es anderen Anwendungen, im Namen Ihrer Anwendung Aktionen auszuführen, unter Verwendung der Identität und Berechtigungen Ihrer App. Beim Erstellen eines ausstehenden Intents sollte ein Intent und die auszuführende Aktion angegeben werden. Wenn der deklarierte Intent nicht explizit ist (nicht angibt, welcher Intent ihn aufrufen kann), könnte eine bösartige Anwendung die deklarierte Aktion im Namen der Opfer-App ausführen. Darüber hinaus, wenn keine Aktion angegeben ist, kann die bösartige App beliebige Aktionen im Namen des Opfers ausführen.

Broadcast-Intents

Im Gegensatz zu den vorherigen Intents, die nur von einer App empfangen werden, können Broadcast-Intents von mehreren Apps empfangen werden. Ab API-Version 14 ist es möglich, die App anzugeben, die die Nachricht empfangen soll, indem Intent.setPackage verwendet wird.

Alternativ ist es auch möglich, eine Berechtigung beim Senden des Broadcasts anzugeben. Die empfangende App muss über diese Berechtigung verfügen.

Es gibt zwei Arten von Broadcasts: Normal (asynchron) und Geordnet (synchron). Die Reihenfolge basiert auf der konfigurierten Priorität innerhalb des Empfängerelements. Jede App kann den Broadcast verarbeiten, weiterleiten oder verwerfen.

Es ist möglich, einen Broadcast mithilfe der Funktion sendBroadcast(intent, receiverPermission) aus der Klasse Context zu senden. Sie könnten auch die Funktion sendBroadcast aus dem LocalBroadCastManager verwenden, um sicherzustellen, dass die Nachricht die App nie verlässt. Dadurch müssen Sie nicht einmal einen Empfänger exportieren.

Sticky Broadcasts

Diese Art von Broadcasts können lange nach dem Senden abgerufen werden. Diese wurden in der API-Ebene 21 veraltet und es wird empfohlen, sie nicht zu verwenden. Sie ermöglichen es jeder Anwendung, die Daten abzufangen, aber auch zu ändern.

Wenn Sie Funktionen finden, die das Wort "sticky" enthalten, wie sendStickyBroadcast oder sendStickyBroadcastAsUser, überprüfen Sie die Auswirkungen und versuchen Sie, sie zu entfernen.

In Android-Anwendungen werden Deep Links verwendet, um eine Aktion (Intent) direkt über eine URL zu initiieren. Dies wird durch Deklarieren eines spezifischen URL-Schemas innerhalb einer Aktivität erreicht. Wenn ein Android-Gerät versucht, auf eine URL mit diesem Schema zuzugreifen, wird die angegebene Aktivität innerhalb der Anwendung gestartet.

Das Schema muss in der AndroidManifest.xml-Datei deklariert werden:

[...]
<activity android:name=".MyActivity">
<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="examplescheme" />
</intent-filter>
[...]

Die Schema aus dem vorherigen Beispiel ist exampleapp:// (beachten Sie auch die Kategorie BROWSABLE)

Dann können Sie im Datenfeld den Host und Pfad angeben:

<data android:scheme="examplescheme"
android:host="example"
/>

Um darauf von einer Webseite aus zuzugreifen, ist es möglich, einen Link wie folgt festzulegen:

<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>

Um den Code zu finden, der in der App ausgeführt wird, gehen Sie zur Aktivität, die durch den Deeplink aufgerufen wird, und suchen Sie die Funktion onNewIntent.

Erfahren Sie, wie Sie Deeplinks aufrufen, ohne HTML-Seiten zu verwenden.

AIDL - Android Interface Definition Language

Die Android Interface Definition Language (AIDL) ist darauf ausgelegt, die Kommunikation zwischen Client und Service in Android-Anwendungen durch Interprozesskommunikation (IPC) zu erleichtern. Da der direkte Zugriff auf den Speicher eines anderen Prozesses auf Android nicht zulässig ist, vereinfacht AIDL den Prozess, indem Objekte in ein vom Betriebssystem verstandenes Format umgewandelt werden, wodurch die Kommunikation zwischen verschiedenen Prozessen erleichtert wird.

Schlüsselkonzepte

  • Gebundene Dienste: Diese Dienste nutzen AIDL für IPC, ermöglichen es Aktivitäten oder Komponenten, sich an einen Dienst zu binden, Anfragen zu stellen und Antworten zu erhalten. Die Methode onBind in der Klasse des Dienstes ist entscheidend für die Initiierung der Interaktion und markiert sie als einen wichtigen Bereich für die Sicherheitsüberprüfung auf der Suche nach Schwachstellen.

  • Messenger: Als gebundener Dienst erleichtert Messenger die IPC mit dem Schwerpunkt auf der Verarbeitung von Daten durch die Methode onBind. Es ist wichtig, diese Methode genau auf unsichere Datenverarbeitung oder die Ausführung sensibler Funktionen zu überprüfen.

  • Binder: Obwohl die direkte Verwendung der Binder-Klasse aufgrund der Abstraktion von AIDL weniger häufig ist, ist es nützlich zu verstehen, dass Binder als Treiber auf Kernel-Ebene fungiert und den Datentransfer zwischen den Speicherbereichen verschiedener Prozesse erleichtert. Zur weiteren Vertiefung steht ein Ressource unter https://www.youtube.com/watch?v=O-UHvFjxwZ8 zur Verfügung.

Komponenten

Diese umfassen: Aktivitäten, Dienste, Broadcast-Empfänger und Anbieter.

Startaktivität und andere Aktivitäten

In Android-Apps sind Aktivitäten wie Bildschirme, die verschiedene Teile der Benutzeroberfläche der App anzeigen. Eine App kann viele Aktivitäten haben, von denen jede einen einzigartigen Bildschirm für den Benutzer darstellt.

Die Startaktivität ist das Haupttor zu einer App, das gestartet wird, wenn Sie auf das Symbol der App tippen. Sie ist in der Manifestdatei der App mit spezifischen MAIN- und LAUNCHER-Intents definiert:

<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Nicht alle Apps benötigen eine Startaktivität, insbesondere solche ohne Benutzeroberfläche, wie Hintergrunddienste.

Aktivitäten können anderen Apps oder Prozessen zur Verfügung gestellt werden, indem sie im Manifest als "exportiert" markiert werden. Diese Einstellung ermöglicht es anderen Apps, diese Aktivität zu starten:

<service android:name=".ExampleExportedService" android:exported="true"/>

Jedoch ist der Zugriff auf eine Aktivität von einer anderen App nicht immer ein Sicherheitsrisiko. Die Sorge entsteht, wenn sensible Daten unsachgemäß geteilt werden, was zu Informationslecks führen könnte.

Der Lebenszyklus einer Aktivität beginnt mit der Methode onCreate, die die Benutzeroberfläche einrichtet und die Aktivität auf die Interaktion mit dem Benutzer vorbereitet.

Anwendungsteilklasse

In der Android-Entwicklung hat eine App die Möglichkeit, eine Teilklasse der Application-Klasse zu erstellen, obwohl dies nicht obligatorisch ist. Wenn eine solche Teilklasse definiert ist, wird sie als erste Klasse innerhalb der App instanziiert. Die Methode attachBaseContext, wenn sie in dieser Teilklasse implementiert ist, wird vor der onCreate-Methode ausgeführt. Diese Einrichtung ermöglicht eine frühe Initialisierung, bevor der Rest der Anwendung startet.

public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}

@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}

Dienste

Dienste sind Hintergrundoperationen, die in der Lage sind, Aufgaben ohne Benutzeroberfläche auszuführen. Diese Aufgaben können auch dann weiterlaufen, wenn Benutzer zu anderen Anwendungen wechseln, wodurch Dienste für lang laufende Operationen unerlässlich sind.

Dienste sind vielseitig einsetzbar; sie können auf verschiedene Arten initiiert werden, wobei Intents die primäre Methode zum Starten sind, als Einstiegspunkt einer Anwendung. Sobald ein Dienst mit der Methode startService gestartet wird, wird seine onStart-Methode aktiviert und läuft weiter, bis die stopService-Methode explizit aufgerufen wird. Alternativ, wenn die Rolle eines Dienstes von einer aktiven Client-Verbindung abhängt, wird die Methode bindService verwendet, um den Client mit dem Dienst zu verbinden, wobei die onBind-Methode für den Datenaustausch verwendet wird.

Eine interessante Anwendung von Diensten umfasst die Wiedergabe von Hintergrundmusik oder das Abrufen von Netzwerkdaten, ohne die Interaktion des Benutzers mit einer App zu beeinträchtigen. Darüber hinaus können Dienste für andere Prozesse auf demselben Gerät über Exportieren zugänglich gemacht werden. Dies ist nicht das Standardverhalten und erfordert eine explizite Konfiguration in der Android-Manifestdatei:

<service android:name=".ExampleExportedService" android:exported="true"/>

Broadcast Receiver

Broadcast-Empfänger fungieren als Zuhörer in einem Nachrichtensystem und ermöglichen es mehreren Anwendungen, auf dieselben Nachrichten des Systems zu reagieren. Eine App kann einen Empfänger registrieren auf zwei Hauptarten: über das Manifest der App oder dynamisch im Code der App über die registerReceiver API. Im Manifest werden Broadcasts mit Berechtigungen gefiltert, während dynamisch registrierte Empfänger auch Berechtigungen bei der Registrierung angeben können.

Intent-Filter sind in beiden Registrierungsmethoden entscheidend und bestimmen, welche Broadcasts den Empfänger auslösen. Sobald ein übereinstimmender Broadcast gesendet wird, wird die Methode onReceive des Empfängers aufgerufen, sodass die App entsprechend reagieren kann, z. B. das Verhalten anpassen, um auf eine Benachrichtigung über einen niedrigen Akkustand zu reagieren.

Broadcasts können entweder asynchron sein und alle Empfänger ohne Reihenfolge erreichen oder synchron, wobei Empfänger den Broadcast basierend auf festgelegten Prioritäten erhalten. Es ist jedoch wichtig zu beachten, dass jede App sich selbst priorisieren kann, um einen Broadcast abzufangen.

Um die Funktionalität eines Empfängers zu verstehen, suchen Sie nach der Methode onReceive innerhalb seiner Klasse. Der Code dieser Methode kann das empfangene Intent manipulieren, was die Notwendigkeit der Datenvalidierung durch Empfänger hervorhebt, insbesondere bei Geordneten Broadcasts, die das Intent ändern oder verwerfen können.

Content Provider

Content Provider sind für das Teilen strukturierter Daten zwischen Apps unerlässlich und betonen die Bedeutung der Implementierung von Berechtigungen, um die Datensicherheit zu gewährleisten. Sie ermöglichen es Apps, auf Daten aus verschiedenen Quellen zuzugreifen, einschließlich Datenbanken, Dateisystemen oder dem Web. Spezifische Berechtigungen wie readPermission und writePermission sind entscheidend für die Kontrolle des Zugriffs. Darüber hinaus kann temporärer Zugriff durch grantUriPermission-Einstellungen im Manifest der App gewährt werden, wobei Attribute wie path, pathPrefix und pathPattern für eine detaillierte Zugriffskontrolle genutzt werden.

Die Eingabevalidierung ist entscheidend, um Sicherheitslücken wie SQL-Injektionen zu verhindern. Content Provider unterstützen grundlegende Operationen: insert(), update(), delete() und query(), die die Datenmanipulation und den Austausch zwischen Anwendungen erleichtern.

FileProvider, ein spezialisierter Content Provider, konzentriert sich auf das sichere Teilen von Dateien. Er wird im Manifest der App mit spezifischen Attributen definiert, um den Zugriff auf Ordner zu kontrollieren, die durch android:exported und android:resource auf Ordnerkonfigurationen verweisen. Es wird empfohlen, Vorsicht walten zu lassen, wenn Verzeichnisse freigegeben werden, um eine versehentliche Offenlegung sensibler Daten zu vermeiden.

Beispielhafte Manifestdeklaration für FileProvider:

<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>

Und ein Beispiel zur Angabe von freigegebenen Ordnern in filepaths.xml:

<paths>
<files-path path="images/" name="myimages" />
</paths>

Für weitere Informationen siehe:

WebViews

WebViews sind wie Mini-Webbrowser innerhalb von Android-Apps, die Inhalte entweder aus dem Web oder aus lokalen Dateien abrufen. Sie sind ähnlichen Risiken wie reguläre Browser ausgesetzt, aber es gibt Möglichkeiten, diese Risiken durch spezifische Einstellungen zu reduzieren.

Android bietet zwei Haupttypen von WebViews:

  • WebViewClient eignet sich gut für grundlegendes HTML, unterstützt jedoch nicht die JavaScript-Alert-Funktion, was sich darauf auswirken kann, wie XSS-Angriffe getestet werden können.

  • WebChromeClient verhält sich mehr wie die vollständige Chrome-Browsererfahrung.

Ein wichtiger Punkt ist, dass WebView-Browser keine Cookies mit dem Hauptbrowser des Geräts teilen.

Für das Laden von Inhalten stehen Methoden wie loadUrl, loadData und loadDataWithBaseURL zur Verfügung. Es ist entscheidend sicherzustellen, dass diese URLs oder Dateien sicher zu verwenden sind. Sicherheitseinstellungen können über die Klasse WebSettings verwaltet werden. Beispielsweise kann das Deaktivieren von JavaScript mit setJavaScriptEnabled(false) XSS-Angriffe verhindern.

Die JavaScript-"Bridge" ermöglicht es Java-Objekten, mit JavaScript zu interagieren, wobei Methoden ab Android 4.2 mit @JavascriptInterface markiert werden müssen, um Sicherheit zu gewährleisten.

Das Zulassen des Zugriffs auf Inhalte (setAllowContentAccess(true)) ermöglicht es WebViews, auf Inhaltsanbieter zuzugreifen, was ein Risiko darstellen kann, es sei denn, die Inhalts-URLs sind als sicher verifiziert.

Um den Dateizugriff zu kontrollieren:

  • Das Deaktivieren des Dateizugriffs (setAllowFileAccess(false)) beschränkt den Zugriff auf das Dateisystem, mit Ausnahmen für bestimmte Ressourcen, um sicherzustellen, dass sie nur für nicht-sensitive Inhalte verwendet werden.

Andere App-Komponenten und Mobile Geräteverwaltung

Digitale Signierung von Anwendungen

  • Digitale Signierung ist ein Muss für Android-Apps, um sicherzustellen, dass sie authentisch autorisiert sind, bevor sie installiert werden. Dieser Prozess verwendet ein Zertifikat zur App-Identifizierung und muss vom Paketmanager des Geräts bei der Installation überprüft werden. Apps können selbst signiert oder von einer externen CA zertifiziert sein, um unbefugten Zugriff zu verhindern und sicherzustellen, dass die App während der Bereitstellung auf dem Gerät unverändert bleibt.

App-Verifizierung für erhöhte Sicherheit

  • Ab Android 4.2 ermöglicht eine Funktion namens Apps überprüfen Benutzern, Apps vor der Installation auf Sicherheit zu überprüfen. Dieser Verifizierungsprozess kann Benutzer vor potenziell schädlichen Apps warnen oder sogar die Installation besonders bösartiger Apps verhindern, um die Sicherheit der Benutzer zu erhöhen.

Mobile Geräteverwaltung (MDM)

  • MDM-Lösungen bieten Überwachung und Sicherheit für mobile Geräte über die Device Administration API. Sie erfordern die Installation einer Android-App, um mobile Geräte effektiv zu verwalten und zu sichern. Zu den Hauptfunktionen gehören die Durchsetzung von Kennwortrichtlinien, die Verpflichtung zur Speicherung von Verschlüsselung und die Ermöglichung des Remote-Datenlöschens, um umfassende Kontrolle und Sicherheit über mobile Geräte zu gewährleisten.

// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);

if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}

Try Hard Security Group

Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Last updated