Mobile Penetration Testing Methodology — iOS and Android

Published May 3, 2026 · 18 min read · VAPT

Mobile pentests look superficially like web pentests — an HTTP API at the bottom, a UI at the top — but the interesting bugs live in places web testers do not normally touch: keychains and Keystores, deep links and intent filters, certificate pinning, biometric prompts, local SQLite stores, runtime code that can be hooked. This methodology walks an iOS + Android engagement end-to-end, mapped to the OWASP Mobile Application Security project and the MASVS control set (L1, L2, R).

Scope and rules of engagement

  • App package — signed release IPA (iOS) and APK or AAB (Android), with the exact version under test.
  • Test accounts in two tenants and two roles (mandatory for authorisation testing).
  • Backend API endpoints — production or pre-prod; aligned with the API pentest scope if joint engagement.
  • Jailbroken iPhone (or corellium) and rooted Android (or genymotion / android-studio emulator with magisk).
  • Out-of-scope: certificate pinning issues that depend on a jailbroken device alone (those need additional context to be material).

MASVS — verification levels

OWASP MASVS defines three levels: L1(standard security — any mobile app),L2(defence in depth — apps handling sensitive data or regulated PII), andR(resilience against reverse engineering — apps with IP, anti-cheat or anti-fraud requirements). Scope the engagement against the level the app is supposed to meet and report against that bar — do not flag missing R controls on an L1 app.

MASVS GroupCoverage
MASVS-STORAGESensitive data at rest — Keychain, Keystore, files
MASVS-CRYPTOCryptographic primitives, key management
MASVS-AUTHAuthentication, session, biometric
MASVS-NETWORKTLS, pinning, hostname validation
MASVS-PLATFORMIPC, deep links, intents, WebView
MASVS-CODECode quality, dependency hygiene, hardening
MASVS-RESILIENCEAnti-tamper, anti-debug, integrity (level R)
MASVS-PRIVACYUser-visible privacy controls and consent

Tooling matrix

ToolPlatformUse
MobSFiOS + AndroidStatic + dynamic analysis, automated triage
JADXAndroidDEX-to-Java decompiler — the standard Android source viewer
apktoolAndroidAPK unpack/repack, smali editing
class-dumpiOSObjective-C class hierarchy from Mach-O
FridaiOS + AndroidDynamic instrumentation, hooks, runtime patching
ObjectioniOS + AndroidFrida-powered runtime exploration without writing scripts
DrozerAndroidIPC and content provider security framework
Burp / mitmproxyiOS + AndroidHTTPS interception with installed root CA

Phase 1 — static analysis

Static is cheap and high-yield. Run MobSF first for the automated triage report; review JADX manually for everything MobSF does not parse.

Android static

  • Decompile with JADX — review for hardcoded secrets, API keys, URLs, weak crypto.
  • Inspect AndroidManifest.xml — exported activities, services, content providers, broadcast receivers; android:allowBackup; android:debuggable; deep-link intent filters.
  • Network security config — res/xml/network_security_config.xml; cleartext traffic permitted; trust anchors.
  • Native libraries — lib/*/*.so; review for JNI side-channel and pinned libraries used in obfuscation.

iOS static

  • Run class-dump against the Mach-O binary for Objective-C; for Swift use otool -l and the ipsw / ground-truth tooling.
  • Inspect Info.plist — URL schemes, App Transport Security exceptions, background modes.
  • Embedded resources — strings in the binary often leak API keys; strings -a App.app/App | grep -E '(api|key|token)'.
  • Provisioning profile + entitlements — codesign -d --entitlements :- App.app.
# Android: MobSF static scan
docker run -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
# upload APK in browser, review report

# Android: JADX from CLI
jadx -d out target.apk
grep -RInE "(api[_-]?key|secret|password|aws_access)" out/

# Android: manifest extraction
apktool d -s -o target-out target.apk
cat target-out/AndroidManifest.xml | grep -E "exported|debuggable|allowBackup"

# iOS: class-dump (after decryption with frida-ios-dump)
class-dump -H App.app/App -o headers/
strings -a App.app/App | grep -iE "(api[_-]?key|secret|token|http)"
codesign -d --entitlements :- App.app/App

Phase 2 — dynamic analysis and traffic interception

Dynamic analysis means running the app on a real (or emulated) jailbroken/rooted device with traffic intercepted through Burp or mitmproxy.

  • Install Burp's CA in the system store on Android (after API 24, user-installed CAs are not trusted by default — this requires either a system-trusted install on a rooted device or a network-security-config exemption).
  • On iOS, install the Burp profile and trust it under Settings → General → About → Certificate Trust Settings.
  • Confirm traffic flows through Burp on a non-pinned endpoint before assuming pinning is the cause of empty traffic.
  • For pinned apps, bypass with Frida hooks (Objection's built-in is a one-liner, see below).

Phase 3 — certificate pinning bypass

Pinning is implemented in many ways: OkHttp CertificatePinner, Network Security Config XML, custom X509TrustManager, native pinning with BoringSSL or OpenSSL. The Frida ecosystem has stable bypass scripts for the common patterns; for custom pinning, you write a hook against the verification function.

# Android: Objection one-liner
objection -g com.target.app explore
android sslpinning disable

# Android: Frida with the Universal Android SSL Pinning Bypass script
frida -U -l https://codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida/ \
  -f com.target.app

# iOS: Objection
objection -g TargetApp explore
ios sslpinning disable

# iOS: ssl-kill-switch3 (replacement for the deprecated kill-switch-2)
# https://github.com/nabla-c0d3/ssl-kill-switch2

Phase 4 — secure storage validation

Sensitive data should sit in the platform's secure storage, not in NSUserDefaults,SharedPreferences, plain SQLite or the filesystem.

  • iOS — Keychain with the appropriate accessibility class (kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, ...WhenUnlockedThisDeviceOnly for sensitive items). Anything in NSUserDefaults or ~/Documents is fair game in the report.
  • Android — AndroidKeyStore for keys, EncryptedSharedPreferences (Jetpack Security) for KV. SQLite without SQLCipher and unencrypted Realm databases are findings.
  • Backup posture — Android android:allowBackup="true" can leak data via adb backup; iCloud / iTunes backup of sensitive Keychain items happens unless the accessibility class includes ThisDeviceOnly.
  • Reference: Apple Platform Security guide; Android security best practices.
# Objection: dump iOS keychain
ios keychain dump

# Objection: enumerate Android shared preferences
android hooking list shared_preferences
android shared_preferences get com.target.app target_prefs

# Pull SQLite from Android sandbox (rooted)
adb shell run-as com.target.app cat databases/target.db > target.db
sqlite3 target.db ".tables"

Phase 5 — biometric and authentication bypass

Biometric prompts (Touch ID, Face ID, Android BiometricPrompt) gate access to sensitive flows. Common bugs:

  • Biometric result evaluated client-side only — success boolean replaced via Frida hook.
  • Token issued before biometric success and only displayed after — Frida-dump the in-memory token.
  • Fallback to passcode permitted when policy says no.
  • Jailbreak-detection bypass — same Frida pattern, hook the detection routine to return clean.
# Frida: hook Android BiometricPrompt result
Java.perform(function() {
  var Cb = Java.use("androidx.biometric.BiometricPrompt$AuthenticationCallback");
  Cb.onAuthenticationSucceeded.implementation = function(r) {
    console.log("[+] Forcing biometric success");
    return this.onAuthenticationSucceeded(r);
  };
});

# Objection iOS LocalAuthentication bypass
ios ui biometrics_bypass

Phase 6 — deep-link and IPC attacks

On Android, exported activities, intent filters, content providers and broadcast receivers form a rich IPC attack surface. On iOS, custom URL schemes and Universal Links are the equivalent.

  • Drozerrun app.package.attacksurface com.target.app enumerates the attack surface; run app.activity.start --component com.target.app com.target.app.AdminActivity starts an exported activity directly.
  • Content provider URI traversalcontent://com.target.app.provider/../../../data/data/com.target.app/databases/target.db patterns.
  • Custom URL scheme parameter injectiontargetapp://login?next=https://attacker.example redirect chains.
  • Universal Link / App Link mis-association — missing apple-app-site-association or assetlinks.json letting another app capture the link.
  • WebView javascript: URL handling — deep links that open a WebView with attacker-controlled URL.
# Android: launch exported activity directly
adb shell am start -n com.target.app/.AdminActivity

# Android: deep-link probe with extras
adb shell am start -W -a android.intent.action.VIEW \
  -d "targetapp://reset?token=anything&user=victim" com.target.app

# iOS: simulator URL scheme
xcrun simctl openurl booted "targetapp://login?next=https://attacker.example"

# Drozer attack-surface
drozer console connect
> run app.package.attacksurface com.target.app
> run app.provider.finduri com.target.app
> run scanner.provider.traversal -a com.target.app

Phase 7 — runtime instrumentation patterns

Frida is the workhorse. Common runtime patterns the operator should know cold:

  • Hook a Java method — Java.use("com.target.X").method.implementation = function() {...}.
  • Hook an Objective-C method — Interceptor.attach(ObjC.classes.X["- selector:"].implementation, ...).
  • Trace native calls — frida-trace -U -i "CC*" -f com.target.app for CommonCrypto.
  • Memory-scan for tokens — Memory.scanSync(...) across the heap.
  • Defeat root/jailbreak detection — hook the detection function, return clean.

Phase 8 — backend API testing in context

A mobile pentest is incomplete without exercising the backend API. The mobile client's traffic, captured through the proxy, is a high-fidelity source of endpoint discovery. Replay those endpoints with a different account's token (BOLA), with privileged fields added to JSON bodies (mass assignment), without the auth token (anonymous fallback), with manipulated headers (X-Forwarded-For, X-Mobile-Device-ID). Many backend bugs are only reachable through the mobile API surface because the web client never talks to those endpoints in the same shape. Cross-reference findings with the OWASP API Security Top 10.

Phase 9 — resilience controls (level R)

Apps that need to resist reverse engineering — payments, anti-cheat games, DRM, anti-fraud wallets — should also implement the MASVS-RESILIENCE controls. Verify:

  • Anti-debug — detection of ptrace, frida-server, debugger ports; reaction (close app, alert backend) on detection.
  • Root / jailbreak detection — multiple independent checks across native + Java/Swift code so a single Frida hook cannot bypass all of them.
  • Integrity — signing certificate hash check at startup; backend attestation via Play Integrity or Apple App Attest.
  • Code obfuscation — ProGuard / R8 for Android; Swift / Obj-C symbol stripping for iOS; control-flow obfuscation for high-value routines.
  • Anti-tampering — runtime checksum of the loaded binary; refusal to start if the package signer differs from the embedded fingerprint.

The deliverable for level R explicitly catalogues which Frida hooks are required to bypass the app, how long the bypass took, and which of the customer's controls fired during the exercise.

Reporting

Map every finding to a MASVS control. Distinguish L1 vs. L2 vs. R applicability so the customer sees the bar they should be measured against. Include reproduction steps that work on the version under test — iOS / Android churn the platform APIs each year, so reports should pin tool versions and OS levels.

References: OWASP MASTG (Mobile App Security Testing Guide), OWASP MAS project, MobSF, Frida.

For a scoped iOS/Android pentest aligned with this methodology, see the AxVeil VAPT service.

Plan your mobile pentest with AxVeil.

iOS and Android coverage. MASVS L1/L2/R alignment, pinning bypass, secure storage, biometric bypass, deep-link and IPC attacks, retest included.

Talk to a senior operator about mobile pentest scope →
Share