Skip to content
Categoria: Pentest8 min read

Android Mobile App Pentest: Frida, MobSF, and a Genymotion Lab

Por Lucas Andrade ·

End-to-end setup for dynamic analysis of your own APKs using Frida, MobSF, and Genymotion, with hands-on hooks and a technical checklist.

Android Mobile App Pentest: Frida, MobSF, and a Genymotion Lab
In this article

An APK is a zip file in a trench coat, and that is exactly what makes Android mobile pentesting both fun and surgical. At Basilisk OffSec we build labs that only ever test binaries we own or have written authorization to audit, because reverse engineering third-party apps without consent is a federal crime in almost every jurisdiction. This guide walks the full workflow: scope and law, a reproducible lab, static analysis, traffic interception, backend attack, custom hooks, local storage, runtime defenses and a clean report - in the order a real engagement actually runs.

First: scope, contract, threat model#

Before any Frida hook lands, we define scope, contract, and a real threat model, in the same spirit as STRIDE Threat Modeling in Sprints: A Full Microservice Walkthrough. Pin down in writing: which package names are in scope, whether the backend may be tested, which data classes are off-limits, and who the emergency contact is on a real finding. Skip that step and you are not doing research, you are collecting court dates. Also fix that findings only travel through encrypted channels.

The 2026 baseline stack#

The stack is simple: Genymotion Personal for x86_64 emulation with optional Google Apps, MobSF in Docker for static and automated dynamic analysis, Frida 16.x with frida-tools on the host, objection for fast workflows, and jadx-gui to read decompiled smali. Genymotion beats AVD on IO speed and exposes ADB on port 5555 out of the box. Spin up a rooted Android 13 image, drop Magisk via the setup-frida module, and push frida-server-arm64 to /data/local/tmp with 755 permissions. In under fifteen minutes you have a reproducible lab, isolated from your production network, which matches the philosophy of Malware Analysis in an Isolated Lab: Safe Setup with FlareVM and REMnux.

Static analysis with MobSF#

MobSF is your first pivot. Launch it with docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest, drag the APK into the UI, and it extracts AndroidManifest, dangerous permissions, hardcoded secrets, Janus checks, WebView usage with setJavaScriptEnabled, and even domains exposed in network_security_config. Static scans routinely surface forgotten AWS tokens, Firebase keys with public rules, and staging endpoints no one was supposed to see. Use that attack surface map to drive dynamic hypotheses, and do not fall into treating the MobSF numeric score as ground truth. Like any SAST, it produces noise, just like we covered in AppSec Shift-Left: SAST, SCA and Secrets Scanning Without Slowing the Team.

Decompiling and reading smali#

Open the APK in jadx-gui and read the decompiled Java while keeping the smali layer handy for details the decompiler swallows. Hunt the classics: Log.d with tokens, hardcoded endpoints, WebView.addJavascriptInterface, exported activities and receivers in the manifest, and string constants for crypto keys. Exported components with android:exported="true" and no permission are a direct entry point for a malicious app on the same device. Flag every such component as a dynamic test candidate for the next step.

SSL pinning bypass with Frida#

With the surface mapped, fire up Frida. A classic example is SSL pinning bypass so you can inspect TLS traffic through Burp or mitmproxy. Load the script with frida -U -f com.company.app -l ssl-bypass.js --no-pause; the hook rewrites checkServerTrusted on TrustManagerImpl and neutralizes okhttp3 CertificatePinner. With pinning gone, you become a man-in-the-middle proxy inside the emulator, capture authenticated JSON payloads, and probe the backend API like a normal web pentest, with Burp configured as in Web Pentesting From Scratch: Building a Safe Lab with DVWA, Juice Shop and Burp Suite. Remember: pinning bypass is only legitimate against the app you are licensed to audit.

Attacking the backend API#

Once traffic is clean, start hammering the API. The classic vectors come right back: mass assignment, IDOR on /v2/users/{id}, JWT with the none algorithm, GraphQL with introspection wide open. Apply the methodology from REST and GraphQL API Pentest: Technical Checklist for Legal Bug Bounty and, for backend injection, validate candidates with parameterized payloads as shown in SQL Injection in Practice: Exploiting, Detecting and Mitigating in a Controlled Lab. Remember the mobile app is just a client: the real authorization flaw almost always sits server-side, where the app UI was wrongly treated as a security boundary.

WebView and addJavascriptInterface#

An underrated target is the internal WebView. If the app loads remote HTML without an allowlist, you can chain XSS into a privileged context via addJavascriptInterface, calling exposed Java methods from JavaScript - on old API levels even reaching remote code execution through reflection. Check whether setAllowFileAccess, setAllowUniversalAccessFromFileURLs and loadUrl combine with user-controlled data. We dissect the payload mechanics in Modern XSS: DOM, Stored and Reflected With Real Examples in a Test Lab. A WebView that resolves intent:// URLs without filtering is also a deep-link hijacking candidate.

Custom hooks: where the pentester shines#

Three Frida scripts worth their weight in gold: dump AES keys passed to Cipher.init by capturing the first argument of SecretKeySpec; instrument SharedPreferences.Editor.putString to flag tokens stored in clear text; and hook java.io.File to log everything written under /data/data/com.company.app during login. Pair that with adb shell run-as com.company.app to pull sqlite databases and crack them open with sqlitebrowser. In a recent audit we found refresh_token persisted without keystore, a flaw that turned into a full account takeover within one afternoon.

Local storage and the keystore#

Sensitive data belongs in the Android Keystore with hardware-backed keys, never in SharedPreferences in clear text or an unencrypted SQLite file. Systematically check databases/, shared_prefs/, the cache and external storage paths for tokens, PII and crypto material. A common finding is a home-grown crypto layer whose key sits right next to the data - effectively plaintext. Recommend EncryptedSharedPreferences or Jetpack Security, with keys bound to StrongBox or the TEE and non-extractable under root.

Reviewing runtime defenses#

Do not wrap up before reviewing runtime defenses. Check root detection via RootBeer, Frida detection by scanning local ports (27042), emulator detection via Build.FINGERPRINT, and integrity via the Play Integrity API. Document exactly how each control was bypassed and propose defense in depth instead of silver bullets - a single root check that an objection one-liner kills is not protection. On the server side, harden SSH on the API bastion per SSH Hardening 2026: Algorithms, Certificates and Bastion Hosts.

Reporting and cleanup#

The report is the product: per finding, CVSS, reproduction steps, the affected class or endpoint, and a concrete remediation. Scrub artifacts, screenshots and PDFs before shipping the report, as in Metadata Hygiene: Stripping EXIF, PDF and Office Before You Publish, so no internal paths or client names leak. At the end, delete the pulled app data and roll the snapshot back. A good report prioritizes by real risk, not by the number of lines in the tool output.

objection for fast iteration#

Where a custom Frida script is too much effort, objection speeds up the cycle. After objection -g com.company.app explore, the commands android sslpinning disable, android keystore list, android hooking list classes and memory search --string "token" hit the most common targets in minutes. android hooking watch class_method ... --dump-args --dump-return shows a method's arguments and return values live without writing a line of JavaScript. Objection is a wrapper around Frida, not a replacement: for anything non-trivial you still write your own hooks, but for recon and pinning bypass the one-liner is unbeatably fast. Remember every objection action runs in the app's process memory and disappears on restart.

Check the intent-filter entries in the manifest: a deep-link handler with android:autoVerify="false" or a custom-scheme redirect (myapp://callback) can be intercepted by a malicious app on the same device. The classic hit is an OAuth flow that returns the authorization code to an unverified custom scheme: a second app registers the same scheme and captures the code. The countermeasure is verified App Links (HTTPS with assetlinks.json) plus PKCE, so an intercepted code is worthless without the verifier. Test every exported deep-link endpoint with adb shell am start -a android.intent.action.VIEW -d "..." and watch which activity launches without authentication.

FAQ: Emulator or physical device?#

For most work a rooted Genymotion emulator is enough and is faster and more disposable. You need physical devices when the app uses hardware-bound attestation, SafetyNet/Play Integrity with a strict verdict, NFC, Bluetooth peripherals, or device-specific sensors the emulator does not cleanly reproduce. A pragmatic mix: emulator for fast iteration, a dedicated test phone for the cases the emulator blocks.

FAQ: How do I bypass Play Integrity without physical root?#

Honestly: not always, and that is by design. Play Integrity with MEETS_STRONG_INTEGRITY is hardware-attested and is meant to reject exactly the modified environments you run. On an authorized test you document that the control holds, rather than breaking it at any cost - a passing integrity check is a positive result. Where the app only checks the weak verdict or evaluates the result client-side, that is precisely the flaw you report.

Conclusion and practical takeaway#

Run Genymotion, MobSF, and Frida inside a dedicated VM with a clean snapshot per engagement, and never tied to your personal identity. Work the workflow in fixed order: scope, static, decompile, traffic, backend, custom hooks, storage, runtime defenses, report. Most serious findings do not live in exotic crypto but in banal server-side authorization and in tokens persisted in clear text - that is where you look first, and that is where the value for the client is.

Related posts

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly