diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 432bf44fc..e7e49e187 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -326,6 +326,7 @@ - [Android APK Checklist](mobile-pentesting/android-checklist.md) - [Android Applications Pentesting](mobile-pentesting/android-app-pentesting/README.md) - [Accessibility Services Abuse](mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md) + - [Android Anti Instrumentation And Ssl Pinning Bypass](mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md) - [Android Applications Basics](mobile-pentesting/android-app-pentesting/android-applications-basics.md) - [Android Task Hijacking](mobile-pentesting/android-app-pentesting/android-task-hijacking.md) - [ADB Commands](mobile-pentesting/android-app-pentesting/adb-commands.md) diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md index 3188664e1..6701de588 100644 --- a/src/mobile-pentesting/android-app-pentesting/README.md +++ b/src/mobile-pentesting/android-app-pentesting/README.md @@ -460,6 +460,12 @@ If you want to pentest Android applications you need to know how to use Frida. - You can find some Awesome Frida scripts here: [**https://codeshare.frida.re/**](https://codeshare.frida.re) - Try to bypass anti-debugging / anti-frida mechanisms loading Frida as in indicated in [https://erfur.github.io/blog/dev/code-injection-without-ptrace](https://erfur.github.io/blog/dev/code-injection-without-ptrace) (tool [linjector](https://github.com/erfur/linjector-rs)) +#### Anti-instrumentation & SSL pinning bypass workflow + +{{#ref}} +android-anti-instrumentation-and-ssl-pinning-bypass.md +{{#endref}} + ### **Dump Memory - Fridump** Check if the application is storing sensitive information inside the memory that it shouldn't be storing like passwords or mnemonics. diff --git a/src/mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md b/src/mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md new file mode 100644 index 000000000..37e708b20 --- /dev/null +++ b/src/mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md @@ -0,0 +1,227 @@ +# Android Anti-Instrumentation & SSL Pinning Bypass (Frida/Objection) + +{{#include ../../banners/hacktricks-training.md}} + +This page provides a practical workflow to regain dynamic analysis against Android apps that detect/root‑block instrumentation or enforce TLS pinning. It focuses on fast triage, common detections, and copy‑pasteable hooks/tactics to bypass them without repacking when possible. + +## Detection Surface (what apps check) + +- 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 +- 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 +- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins + +## Step 1 — Quick win: hide root with Magisk DenyList + +- Enable Zygisk in Magisk +- Enable DenyList, add the target package +- Reboot and retest + +Many apps only look for obvious indicators (su/Magisk paths/getprop). DenyList often neutralizes naive checks. + +References: +- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk + +## Step 2 — 30‑second Frida Codeshare tests + +Try common drop‑in scripts before deep diving: + +- anti-root-bypass.js +- anti-frida-detection.js +- hide_frida_gum.js + +Example: + +```bash +frida -U -f com.example.app -l anti-frida-detection.js +``` + +These typically stub Java root/debug checks, process/service scans, and native ptrace(). Useful on lightly protected apps; hardened targets may need tailored hooks. + +- Codeshare: https://codeshare.frida.re/ + +## Step 3 — Bypass init-time detectors by attaching late + +Many detections only run during process spawn/onCreate(). Spawn‑time injection (-f) or gadgets get caught; attaching after UI loads can slip past. + +```bash +# Launch the app normally (launcher/adb), wait for UI, then attach +frida -U -n com.example.app +# Or with Objection to attach to running process +aobjection --gadget com.example.app explore # if using gadget +``` + +If this works, keep the session stable and proceed to map and stub checks. + +## Step 4 — Map detection logic via Jadx and string hunting + +Static triage keywords in Jadx: +- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger" + +Typical Java patterns: + +```java +public boolean isFridaDetected() { + return getRunningServices().contains("frida"); +} +``` + +Common APIs to review/hook: +- android.os.Debug.isDebuggerConnected +- android.app.ActivityManager.getRunningAppProcesses / getRunningServices +- java.lang.System.loadLibrary / System.load (native bridge) +- java.lang.Runtime.exec / ProcessBuilder (probing commands) +- android.os.SystemProperties.get (root/emulator heuristics) + +## Step 5 — Runtime stubbing with Frida (Java) + +Override custom guards to return safe values without repacking: + +```js +Java.perform(() => { + const Checks = Java.use('com.example.security.Checks'); + Checks.isFridaDetected.implementation = function () { return false; }; + + // Neutralize debugger checks + const Debug = Java.use('android.os.Debug'); + Debug.isDebuggerConnected.implementation = function () { return false; }; + + // Example: kill ActivityManager scans + const AM = Java.use('android.app.ActivityManager'); + AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); }; +}); +``` + +Triaging early crashes? Dump classes just before it dies to spot likely detection namespaces: + +```js +Java.perform(() => { + Java.enumerateLoadedClasses({ + onMatch: n => console.log(n), + onComplete: () => console.log('Done') + }); +}); +``` + +Log and neuter suspicious methods to confirm execution flow: + +```js +Java.perform(() => { + const Det = Java.use('com.example.security.DetectionManager'); + Det.checkFrida.implementation = function () { + console.log('checkFrida() called'); + return false; + }; +}); +``` + +## Step 6 — Follow the JNI/native trail when Java hooks fail + +Trace JNI entry points to locate native loaders and detection init: + +```bash +frida-trace -n com.example.app -i "JNI_OnLoad" +``` + +Quick native triage of bundled .so files: + +```bash +# List exported symbols & JNI +nm -D libfoo.so | head +objdump -T libfoo.so | grep Java_ +strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root' +``` + +Interactive/native reversing: +- Ghidra: https://ghidra-sre.org/ +- r2frida: https://github.com/nowsecure/r2frida + +Example: neuter ptrace to defeat simple anti‑debug in libc: + +```js +const ptrace = Module.findExportByName(null, 'ptrace'); +if (ptrace) { + Interceptor.replace(ptrace, new NativeCallback(function () { + return -1; // pretend failure + }, 'int', ['int', 'int', 'pointer', 'pointer'])); +} +``` + +See also: {{#ref}} +reversing-native-libraries.md +{{#endref}} + +## Step 7 — Objection patching (embed gadget / strip basics) + +When you prefer repacking to runtime hooks, try: + +```bash +objection patchapk --source app.apk +``` + +Notes: +- Requires apktool; ensure a current version from the official guide to avoid build issues: https://apktool.org/docs/install +- Gadget injection enables instrumentation without root but can still be caught by stronger init‑time checks. + +References: +- Objection: https://github.com/sensepost/objection + +## Step 8 — Fallback: Patch TLS pinning for network visibility + +If instrumentation is blocked, you can still inspect traffic by removing pinning statically: + +```bash +apk-mitm app.apk +# Then install the patched APK and proxy via Burp/mitmproxy +``` + +- Tool: https://github.com/shroudedcode/apk-mitm +- For network config CA‑trust tricks (and Android 7+ user CA trust), see: + {{#ref}} + make-apk-accept-ca-certificate.md + {{#endref}} + {{#ref}} + install-burp-certificate.md + {{#endref}} + +## Handy command cheat‑sheet + +```bash +# List processes and attach +frida-ps -Uai +frida -U -n com.example.app + +# Spawn with a script (may trigger detectors) +frida -U -f com.example.app -l anti-frida-detection.js + +# Trace native init +frida-trace -n com.example.app -i "JNI_OnLoad" + +# Objection runtime +objection --gadget com.example.app explore + +# Static TLS pinning removal +apk-mitm app.apk +``` + +## Tips & caveats + +- Prefer attaching late over spawning when apps crash at launch +- Some detections re‑run in critical flows (e.g., payment, auth) — keep hooks active during navigation +- Mix static and dynamic: string hunt in Jadx to shortlist classes; then hook methods to verify at runtime +- Hardened apps may use packers and native TLS pinning — expect to reverse native code + +## References + +- [Reversing Android Apps: Bypassing Detection Like a Pro](https://www.kayssel.com/newsletter/issue-12/) +- [Frida Codeshare](https://codeshare.frida.re/) +- [Objection](https://github.com/sensepost/objection) +- [apk-mitm](https://github.com/shroudedcode/apk-mitm) +- [Jadx](https://github.com/skylot/jadx) +- [Ghidra](https://ghidra-sre.org/) +- [r2frida](https://github.com/nowsecure/r2frida) +- [Apktool install guide](https://apktool.org/docs/install) +- [Magisk](https://github.com/topjohnwu/Magisk) + +{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file