mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/mobile-pentesting/android-app-pentesting/android-an
This commit is contained in:
parent
6acc737122
commit
b3ebc73c5a
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
Diese Seite bietet einen praktischen Workflow, um die dynamische Analyse gegen Android-Apps wiederherzustellen, die Instrumentation erkennen/root‑blockieren oder TLS pinning erzwingen. Der Fokus liegt auf schneller Triage, häufigen Erkennungen und kopierbaren Hooks/Taktiken, um diese nach Möglichkeit ohne Repacking zu umgehen.
|
Diese Seite bietet einen praktischen Workflow, um die dynamische Analyse gegen Android‑Apps wiederherzustellen, die Instrumentierung erkennen/root‑blocken oder TLS pinning erzwingen. Der Fokus liegt auf schneller Triage, typischen Erkennungen und kopierbaren Hooks/Taktiken, um sie möglichst ohne Repacking zu umgehen.
|
||||||
|
|
||||||
## Detection Surface (what apps check)
|
## Detection Surface (what apps check)
|
||||||
|
|
||||||
- Root-Checks: su binary, Magisk paths, getprop values, common root packages
|
- Root checks: su binary, Magisk paths, getprop values, common root packages
|
||||||
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
|
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
|
||||||
- Native anti‑debug: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
|
- Native anti‑debug: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
|
||||||
- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present
|
- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present
|
||||||
@ -25,7 +25,7 @@ References:
|
|||||||
|
|
||||||
## Step 2 — 30‑second Frida Codeshare tests
|
## Step 2 — 30‑second Frida Codeshare tests
|
||||||
|
|
||||||
Try common drop‑in scripts before deep diving:
|
Versuche gängige Drop‑in‑Skripte, bevor du tiefer einsteigst:
|
||||||
|
|
||||||
- anti-root-bypass.js
|
- anti-root-bypass.js
|
||||||
- anti-frida-detection.js
|
- anti-frida-detection.js
|
||||||
@ -35,7 +35,7 @@ Example:
|
|||||||
```bash
|
```bash
|
||||||
frida -U -f com.example.app -l anti-frida-detection.js
|
frida -U -f com.example.app -l anti-frida-detection.js
|
||||||
```
|
```
|
||||||
Diese ersetzen typischerweise Java root/debug-Prüfungen, Prozess-/Service-Scans und native ptrace()-Aufrufe durch Stubs. Nützlich bei leicht geschützten Apps; gehärtete Ziele benötigen möglicherweise maßgeschneiderte Hooks.
|
Diese implementieren typischerweise Stubs für Java root/debug checks, process/service scans und native ptrace(). Nützlich bei leicht geschützten Apps; gehärtete Targets benötigen möglicherweise maßgeschneiderte Hooks.
|
||||||
|
|
||||||
- Codeshare: https://codeshare.frida.re/
|
- Codeshare: https://codeshare.frida.re/
|
||||||
|
|
||||||
@ -54,22 +54,22 @@ use http_communications/multiple_unpinner
|
|||||||
use root_detection/universal_root_detection_bypass
|
use root_detection/universal_root_detection_bypass
|
||||||
run com.target.app
|
run com.target.app
|
||||||
```
|
```
|
||||||
Tipp: Medusa ist großartig für schnelle Erfolge, bevor du eigene hooks schreibst. Du kannst auch modules gezielt auswählen und mit deinen eigenen scripts kombinieren.
|
Tipp: Medusa ist großartig für schnelle Erfolge, bevor du custom hooks schreibst. Du kannst auch modules gezielt auswählen und mit deinen eigenen scripts kombinieren.
|
||||||
|
|
||||||
## Schritt 3 — Detektoren zur Initialisierungszeit umgehen durch spätes Anhängen
|
## Schritt 3 — Bypass init-time detectors by attaching late
|
||||||
|
|
||||||
Viele Erkennungen laufen nur während des Prozess‑Spawns/onCreate(). Spawn‑time injection (-f) oder gadgets werden erwischt; spätes Anhängen, nachdem die UI geladen ist, kann unbemerkt vorbeischlüpfen.
|
Viele detections laufen nur während process spawn/onCreate(). Spawn‑time injection (-f) oder gadgets werden dabei erwischt; wenn du erst nach dem Laden der UI attachst, kannst du dagegen durchrutschen.
|
||||||
```bash
|
```bash
|
||||||
# Launch the app normally (launcher/adb), wait for UI, then attach
|
# Launch the app normally (launcher/adb), wait for UI, then attach
|
||||||
frida -U -n com.example.app
|
frida -U -n com.example.app
|
||||||
# Or with Objection to attach to running process
|
# Or with Objection to attach to running process
|
||||||
aobjection --gadget com.example.app explore # if using gadget
|
aobjection --gadget com.example.app explore # if using gadget
|
||||||
```
|
```
|
||||||
Wenn das funktioniert, halte die Sitzung stabil und fahre mit map- und stub-Checks fort.
|
Wenn das funktioniert, halte die Session stabil und fahre mit map und stub checks fort.
|
||||||
|
|
||||||
## Schritt 4 — Erkennungslogik mit Jadx und string hunting kartieren
|
## Schritt 4 — Detection-Logik mit Jadx und String-Hunting abbilden
|
||||||
|
|
||||||
Statische Triage-Schlüsselwörter in Jadx:
|
Statische Triage-Keywords in Jadx:
|
||||||
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
||||||
|
|
||||||
Typische Java-Muster:
|
Typische Java-Muster:
|
||||||
@ -78,16 +78,16 @@ public boolean isFridaDetected() {
|
|||||||
return getRunningServices().contains("frida");
|
return getRunningServices().contains("frida");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Häufige APIs zur Überprüfung/Hook:
|
Gängige APIs zum review/hook:
|
||||||
- android.os.Debug.isDebuggerConnected
|
- android.os.Debug.isDebuggerConnected
|
||||||
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
||||||
- java.lang.System.loadLibrary / System.load (Native-Bridge)
|
- java.lang.System.loadLibrary / System.load (native bridge)
|
||||||
- java.lang.Runtime.exec / ProcessBuilder (Prüf-/Erkennungsbefehle)
|
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
|
||||||
- android.os.SystemProperties.get (Root-/Emulator-Heuristiken)
|
- android.os.SystemProperties.get (root/emulator heuristics)
|
||||||
|
|
||||||
## Schritt 5 — Runtime stubbing mit Frida (Java)
|
## Schritt 5 — Runtime stubbing mit Frida (Java)
|
||||||
|
|
||||||
Überschreibe benutzerdefinierte Guards, damit sie sichere Werte zurückgeben, ohne repacking:
|
Override custom guards, um sichere Werte zurückzugeben, ohne repacking:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
const Checks = Java.use('com.example.security.Checks');
|
const Checks = Java.use('com.example.security.Checks');
|
||||||
@ -102,7 +102,7 @@ const AM = Java.use('android.app.ActivityManager');
|
|||||||
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Frühzeitige Abstürze triagieren? Dump die Klassen kurz bevor die App abstürzt, um wahrscheinliche Detection-Namespaces zu erkennen:
|
Frühe Abstürze triagieren? Dump classes kurz bevor es abstürzt, um wahrscheinliche Detection-Namespaces zu erkennen:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
Java.enumerateLoadedClasses({
|
Java.enumerateLoadedClasses({
|
||||||
@ -119,7 +119,7 @@ RootChecker.isDeviceRooted.implementation = function () { return false; };
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
Protokolliere und deaktiviere verdächtige Methoden, um den Ausführungsfluss zu bestätigen:
|
Protokolliere und neutralisiere verdächtige Methoden, um den Ausführungsfluss zu bestätigen:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
const Det = Java.use('com.example.security.DetectionManager');
|
const Det = Java.use('com.example.security.DetectionManager');
|
||||||
@ -131,7 +131,7 @@ return false;
|
|||||||
```
|
```
|
||||||
## Bypass emulator/VM detection (Java stubs)
|
## Bypass emulator/VM detection (Java stubs)
|
||||||
|
|
||||||
Gängige Heuristiken: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE, die generic/goldfish/ranchu/sdk enthalten; QEMU-Artefakte wie /dev/qemu_pipe, /dev/socket/qemud; Standard-MAC 02:00:00:00:00:00; 10.0.2.x NAT; fehlende telephony/sensors.
|
Gängige Heuristiken: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE mit generic/goldfish/ranchu/sdk; QEMU-Artefakte wie /dev/qemu_pipe, /dev/socket/qemud; Standard-MAC 02:00:00:00:00:00; 10.0.2.x NAT; fehlende telephony/Sensoren.
|
||||||
|
|
||||||
Schnelles Spoofing der Build-Felder:
|
Schnelles Spoofing der Build-Felder:
|
||||||
```js
|
```js
|
||||||
@ -143,7 +143,7 @@ Build.BRAND.value = 'google';
|
|||||||
Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys';
|
Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys';
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Ergänze Stub-Implementierungen für Datei-Existenzprüfungen und Identifikatoren (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList), damit realistische Werte zurückgegeben werden.
|
Ergänze Stub-Implementierungen für Dateiexistenzprüfungen und Identifikatoren (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList), damit realistische Werte zurückgegeben werden.
|
||||||
|
|
||||||
## SSL pinning bypass quick hook (Java)
|
## SSL pinning bypass quick hook (Java)
|
||||||
|
|
||||||
@ -166,23 +166,23 @@ return SSLContextInit.call(this, km, TrustManagers, sr);
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
Hinweise
|
Hinweise
|
||||||
- Für OkHttp erweitern: hook okhttp3.CertificatePinner und HostnameVerifier bei Bedarf, oder verwende ein universelles unpinning script von CodeShare.
|
- Für OkHttp erweitern: hook okhttp3.CertificatePinner und HostnameVerifier nach Bedarf, oder verwende ein universelles unpinning script von CodeShare.
|
||||||
- Beispiel ausführen: `frida -U -f com.target.app -l ssl-bypass.js --no-pause`
|
- Run example: `frida -U -f com.target.app -l ssl-bypass.js --no-pause`
|
||||||
|
|
||||||
## Schritt 6 — Der JNI/native-Spur folgen, wenn Java hooks fehlschlagen
|
## Schritt 6 — Follow the JNI/native trail when Java hooks fail
|
||||||
|
|
||||||
Verfolge JNI-Einstiegspunkte, um native Loader und Detection-Init zu lokalisieren:
|
Verfolge JNI-Einstiegspunkte, um native Loader und die Detektionsinitialisierung zu lokalisieren:
|
||||||
```bash
|
```bash
|
||||||
frida-trace -n com.example.app -i "JNI_OnLoad"
|
frida-trace -n com.example.app -i "JNI_OnLoad"
|
||||||
```
|
```
|
||||||
Schnelle native Triage der gebündelten .so-Dateien:
|
Schnelle native Triage von gebündelten .so files:
|
||||||
```bash
|
```bash
|
||||||
# List exported symbols & JNI
|
# List exported symbols & JNI
|
||||||
nm -D libfoo.so | head
|
nm -D libfoo.so | head
|
||||||
objdump -T libfoo.so | grep Java_
|
objdump -T libfoo.so | grep Java_
|
||||||
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
||||||
```
|
```
|
||||||
Interaktives/native reversing:
|
Interaktive/native reversing:
|
||||||
- Ghidra: https://ghidra-sre.org/
|
- Ghidra: https://ghidra-sre.org/
|
||||||
- r2frida: https://github.com/nowsecure/r2frida
|
- r2frida: https://github.com/nowsecure/r2frida
|
||||||
|
|
||||||
@ -202,28 +202,28 @@ reversing-native-libraries.md
|
|||||||
|
|
||||||
## Schritt 7 — Objection patching (embed gadget / strip basics)
|
## Schritt 7 — Objection patching (embed gadget / strip basics)
|
||||||
|
|
||||||
Wenn du repacking gegenüber runtime hooks bevorzugst, versuche:
|
Wenn Sie repacking runtime hooks vorziehen, versuchen Sie:
|
||||||
```bash
|
```bash
|
||||||
objection patchapk --source app.apk
|
objection patchapk --source app.apk
|
||||||
```
|
```
|
||||||
Hinweise:
|
Hinweise:
|
||||||
- Erfordert apktool; stelle sicher, dass du eine aktuelle Version gemäß der offiziellen Anleitung verwendest, um Build-Probleme zu vermeiden: https://apktool.org/docs/install
|
- Benötigt apktool; stelle eine aktuelle Version gemäß der offiziellen Anleitung sicher, um Build-Probleme zu vermeiden: https://apktool.org/docs/install
|
||||||
- Gadget injection ermöglicht instrumentation ohne Root, kann aber dennoch von stärkeren init‑time checks erkannt werden.
|
- Gadget injection ermöglicht instrumentation ohne root, kann jedoch immer noch von stärkeren init‑time checks erkannt werden.
|
||||||
|
|
||||||
Optional kannst du LSPosed-Module und Shamiko hinzufügen, um stärkeres root hiding in Zygisk-Umgebungen zu erreichen, und die DenyList pflegen, um Child-Prozesse abzudecken.
|
Optional: Füge LSPosed-Module und Shamiko hinzu, um Root-Hiding in Zygisk-Umgebungen zu verstärken, und kuratiere die DenyList so, dass auch child processes abgedeckt sind.
|
||||||
|
|
||||||
Referenzen:
|
Referenzen:
|
||||||
- Objection: https://github.com/sensepost/objection
|
- Objection: https://github.com/sensepost/objection
|
||||||
|
|
||||||
## Schritt 8 — Fallback: TLS pinning patchen für Netzwerksichtbarkeit
|
## Schritt 8 — Fallback: Patch TLS pinning für Netzwerk-Sichtbarkeit
|
||||||
|
|
||||||
Wenn instrumentation blockiert ist, kannst du den Traffic trotzdem untersuchen, indem du das Pinning statisch entfernst:
|
Wenn instrumentation blockiert ist, kannst du den Traffic trotzdem untersuchen, indem du pinning statisch entfernst:
|
||||||
```bash
|
```bash
|
||||||
apk-mitm app.apk
|
apk-mitm app.apk
|
||||||
# Then install the patched APK and proxy via Burp/mitmproxy
|
# Then install the patched APK and proxy via Burp/mitmproxy
|
||||||
```
|
```
|
||||||
- Tool: https://github.com/shroudedcode/apk-mitm
|
- Tool: https://github.com/shroudedcode/apk-mitm
|
||||||
- Für Tricks zur Netzwerk‑Konfiguration/CA‑Trust (und Benutzer‑CA‑Trust ab Android 7), siehe:
|
- Für Netwerkkonfiguration CA‑trust‑Tricks (und Android 7+ user CA trust), siehe:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
make-apk-accept-ca-certificate.md
|
make-apk-accept-ca-certificate.md
|
||||||
@ -233,7 +233,7 @@ make-apk-accept-ca-certificate.md
|
|||||||
install-burp-certificate.md
|
install-burp-certificate.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Praktische Befehlsübersicht
|
## Nützliche Befehls‑Cheat‑Sheet
|
||||||
```bash
|
```bash
|
||||||
# List processes and attach
|
# List processes and attach
|
||||||
frida-ps -Uai
|
frida-ps -Uai
|
||||||
@ -251,12 +251,30 @@ objection --gadget com.example.app explore
|
|||||||
# Static TLS pinning removal
|
# Static TLS pinning removal
|
||||||
apk-mitm app.apk
|
apk-mitm app.apk
|
||||||
```
|
```
|
||||||
## Tipps & Hinweise
|
## Universal proxy forcing + TLS unpinning (HTTP Toolkit Frida hooks)
|
||||||
|
|
||||||
- Bevorzuge late attaching gegenüber spawning, wenn Apps beim Launch abstürzen
|
Moderne Apps ignorieren häufig System-Proxies und erzwingen mehrere Pinning-Ebenen (Java + native), wodurch das Erfassen von Traffic mühsam wird, selbst wenn user/system CAs installiert sind. Ein praktischer Ansatz ist, universelles TLS unpinning mit Proxy-Forcing über fertige Frida-Hooks zu kombinieren und alles über mitmproxy/Burp zu routen.
|
||||||
- Einige Detections laufen in kritischen Flows (z. B. payment, auth) erneut — halte hooks während der Navigation aktiv
|
|
||||||
- Kombiniere static und dynamic: string hunt in Jadx, um Klassen vorzuselektieren; hook dann Methoden, um sie zur runtime zu verifizieren
|
Workflow
|
||||||
- Hardened apps können packers und native TLS pinning verwenden — erwarte, nativen Code zu reverse-engineeren
|
- Starte mitmproxy auf deinem Host (oder Burp). Stelle sicher, dass das Gerät die Host IP/port erreichen kann.
|
||||||
|
- Lade HTTP Toolkit’s konsolidierte Frida-Hooks, um sowohl TLS unpinning durchzuführen als auch die Proxy-Nutzung in gängigen Stacks zu erzwingen (OkHttp/OkHttp3, HttpsURLConnection, Conscrypt, WebView, etc.). Das umgeht CertificatePinner/TrustManager-Prüfungen und überschreibt Proxy-Selectoren, sodass der Traffic immer über deinen Proxy geleitet wird, selbst wenn die App Proxies explizit deaktiviert.
|
||||||
|
- Starte die Ziel-App mit Frida und dem Hook-Skript und zeichne die Requests in mitmproxy auf.
|
||||||
|
|
||||||
|
Beispiel
|
||||||
|
```bash
|
||||||
|
# Device connected via ADB or over network (-U)
|
||||||
|
# See the repo for the exact script names & options
|
||||||
|
frida -U -f com.vendor.app \
|
||||||
|
-l ./android-unpinning-with-proxy.js \
|
||||||
|
--no-pause
|
||||||
|
|
||||||
|
# mitmproxy listening locally
|
||||||
|
mitmproxy -p 8080
|
||||||
|
```
|
||||||
|
Hinweise
|
||||||
|
- Mit einem systemweiten Proxy über `adb shell settings put global http_proxy <host>:<port>` kombinieren, wenn möglich. Die Frida hooks erzwingen die Proxy-Nutzung selbst dann, wenn Apps die globalen Einstellungen umgehen.
|
||||||
|
- Diese Technik ist ideal, wenn Sie MITM mobile-to-IoT onboarding flows benötigen, bei denen pinning/proxy avoidance häufig vorkommt.
|
||||||
|
- Hooks: https://github.com/httptoolkit/frida-interception-and-unpinning
|
||||||
|
|
||||||
## Referenzen
|
## Referenzen
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user