Mobile App Security Testing: Android and iOS Pentesting
A practical guide to mobile application security testing — from setting up your lab to finding vulnerabilities in Android and iOS apps.
Mobile App Security Testing: Android and iOS Pentesting
Mobile apps handle sensitive data: banking credentials, health records, personal messages. Yet many apps ship with critical vulnerabilities. This guide covers how to find them.
Setting Up Your Lab
Android Testing Environment
# Option 1: Emulator
# Install Android Studio, create emulator WITHOUT Play Store
# (Play Store = Google integrity checks = harder to root)
# Option 2: Physical device (recommended)
# Buy a cheap Pixel, enable Developer Options
# OEM Unlock + flash rooted image
# Essential tools
pip install frida-tools objection
apt install jadx apktool adb
iOS Testing Environment
# Jailbroken device required for full testing
# iPhone 6s-X on iOS 14-15 with checkra1n
# Or use Corellium (cloud-based, expensive)
# Tools
brew install libimobiledevice ideviceinstaller
pip install frida-tools objection
Proxy Setup (Both Platforms)
# Install Burp Suite CA on device
# Android: Settings > Security > Install from storage
# iOS: Settings > Profile Downloaded > Install
# Bypass certificate pinning (covered below)
Android Security Testing
Step 1: Static Analysis
# Extract APK from device
adb shell pm list packages | grep target
adb shell pm path com.target.app
adb pull /data/app/com.target.app-1/base.apk
# Or download from APKPure/APKMirror
# Decompile with jadx
jadx -d output/ target.apk
# What to look for in decompiled code:
grep -r "password" output/
grep -r "api_key" output/
grep -r "secret" output/
grep -r "http://" output/ # Insecure connections
grep -r "MODE_WORLD_READABLE" output/ # Insecure file storage
Manifest Analysis
<!-- AndroidManifest.xml - Check for: -->
<!-- Exported components (accessible to other apps) -->
<activity android:name=".AdminActivity" android:exported="true"/>
<!-- Can be launched by malicious app! -->
<!-- Debuggable (should be false in production) -->
<application android:debuggable="true">
<!-- Allows attaching debugger, extracting data -->
<!-- Backup enabled (data can be extracted) -->
<application android:allowBackup="true">
<!-- Insecure permissions -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!-- Does a calculator app need contacts? -->
Step 2: Dynamic Analysis
# Install on device
adb install target.apk
# Monitor with Frida
frida -U -f com.target.app -l script.js
# Or use objection for easy analysis
objection -g com.target.app explore
# In objection:
android hooking list activities
android hooking list services
android intent launch_activity com.target.app.AdminActivity
# Check for insecure storage
android keystore list
android clipboard monitor
Certificate Pinning Bypass
Most apps pin certificates to prevent MITM. Bypass with Frida:
// frida-ssl-bypass.js
Java.perform(function() {
// TrustManager bypass
var TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var TrustManagerImpl = Java.registerClass({
name: 'FakeTrustManager',
implements: [TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},
checkServerTrusted: function(chain, authType) {},
getAcceptedIssuers: function() { return []; }
}
});
var TrustManagers = [TrustManagerImpl.$new()];
var sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, TrustManagers, null);
});
# Or use objection (easier)
objection -g com.target.app explore
android sslpinning disable
Common Android Vulnerabilities
## Storage
□ SharedPreferences with MODE_WORLD_READABLE
□ SQLite databases with sensitive data unencrypted
□ Credentials in plaintext files
□ Backup enabled with sensitive data
## Network
□ HTTP instead of HTTPS
□ Certificate pinning missing
□ SSL errors ignored in code
## Components
□ Exported activities without authentication
□ Broadcast receivers leaking data
□ Content providers with SQL injection
## Code
□ Hardcoded credentials/API keys
□ Debuggable in production
□ WebView with JavaScript enabled + file access
Example: Exported Activity Exploit
# Find exported activities
aapt dump xmltree target.apk AndroidManifest.xml | grep -A5 "activity"
# Launch directly (bypassing login)
adb shell am start -n com.target.app/.AdminActivity
# If it opens without authentication = vulnerability!
iOS Security Testing
Step 1: Extract and Decrypt IPA
# On jailbroken device, apps are encrypted
# Use frida-ios-dump to decrypt
pip install frida-ios-dump
# Connect to device
frida-ps -Ua # List running apps
# Dump decrypted IPA
python dump.py "Target App"
Step 2: Static Analysis
# Unzip IPA
unzip target.ipa -d extracted/
# Find the binary
file extracted/Payload/Target.app/Target
# Mach-O 64-bit arm64 executable
# Extract strings
strings extracted/Payload/Target.app/Target | grep -i password
strings extracted/Payload/Target.app/Target | grep -i api
# Check Info.plist
plutil -p extracted/Payload/Target.app/Info.plist
# Look for:
# - URL schemes (can be hijacked)
# - ATS exceptions (insecure HTTP allowed)
# - Custom URL handlers
Step 3: Dynamic Analysis
# Use objection
objection -g "Target App" explore
# Dump keychain
ios keychain dump
# Check pasteboard
ios pasteboard monitor
# Hook methods
ios hooking watch class ViewController
ios hooking watch method "-[LoginVC validatePassword:]" --dump-args
# Disable jailbreak detection
ios jailbreak disable
Common iOS Vulnerabilities
## Storage
□ Sensitive data in UserDefaults (not encrypted)
□ Keychain items with wrong protection class
□ Data not cleared on logout
□ Cache containing sensitive info
## Network
□ ATS (App Transport Security) disabled
□ Certificate pinning missing
□ Sensitive data in URL parameters
## Binary
□ PIE disabled (no ASLR)
□ Stack canaries missing
□ ARC disabled (memory corruption possible)
## Code
□ Hardcoded credentials
□ Debugging symbols in release
□ Custom URL schemes without validation
Example: Keychain Extraction
# In objection
ios keychain dump
# Output:
# Account: [email protected]
# Service: com.target.app
# Data: SuperSecretPassword123
# Protection: kSecAttrAccessibleWhenUnlocked
#
# Problem: Password stored in plaintext in keychain
# Should use: Secure Enclave or encrypted data only
OWASP Mobile Top 10
| # | Vulnerability | What to Test |
|---|---|---|
| M1 | Improper Platform Usage | Permissions, intents, keychain |
| M2 | Insecure Data Storage | Files, databases, logs, clipboard |
| M3 | Insecure Communication | HTTPS, pinning, data in transit |
| M4 | Insecure Authentication | Session handling, biometrics bypass |
| M5 | Insufficient Cryptography | Weak algorithms, hardcoded keys |
| M6 | Insecure Authorization | Role checks, privilege escalation |
| M7 | Client Code Quality | Buffer overflows, format strings |
| M8 | Code Tampering | Integrity checks, repackaging |
| M9 | Reverse Engineering | Obfuscation, anti-debugging |
| M10 | Extraneous Functionality | Debug code, test backends |
Testing Checklist
## Pre-Testing
□ Set up proxy with valid CA
□ Root/jailbreak device
□ Install Frida, objection
□ Bypass certificate pinning
## Static Analysis
□ Decompile/decrypt app
□ Search for hardcoded secrets
□ Analyze manifest/Info.plist
□ Check binary protections
## Storage Testing
□ Check local databases
□ Examine keychain/SharedPreferences
□ Review file permissions
□ Check logs and cache
## Network Testing
□ Capture all traffic
□ Test certificate pinning
□ Check for sensitive data in requests
□ Test API authentication
## Authentication
□ Test session handling
□ Attempt biometric bypass
□ Check for auth bypasses
□ Test account lockout
## Platform-Specific
□ Android: Test exported components
□ Android: Check backup settings
□ iOS: Test URL schemes
□ iOS: Check ATS settings
Reporting Template
## Finding: Sensitive Data in Application Logs
**Severity**: High
**Location**: LoggingUtil.java, line 47
**Description**:
The application logs user passwords in plaintext when
authentication fails, which can be accessed by any app
with READ_LOGS permission.
**Steps to Reproduce**:
1. Install app on rooted device
2. Attempt login with wrong password
3. Run: adb logcat | grep password
4. Observe plaintext password in logs
**Impact**:
Malicious apps on the same device can harvest credentials.
**Recommendation**:
Never log sensitive data. Use logging frameworks that
automatically redact sensitive fields.
**Code Fix**:
```java
// Before
Log.d("Auth", "Login failed for user: " + email + " password: " + password);
// After
Log.d("Auth", "Login failed for user: " + email);
## Conclusion
Mobile app security is vast, but the fundamentals are:
1. **Static analysis** — What does the code reveal?
2. **Dynamic analysis** — What does the app actually do?
3. **Data storage** — Is sensitive data protected?
4. **Network security** — Is communication secure?
Start with the easy wins (hardcoded secrets, insecure storage) before diving into complex reverse engineering.
---
*Related: [API Security: OAuth2 Vulnerabilities](/articles/api-security-oauth-vulnerabilities)*