SuperAPI AI Directory

mobile-pentest

Security & auditing

View repository

Updated 10-16 06:58

About this skill

What this skill does

Performs end-to-end penetration testing of Android and iOS mobile applications covering static analysis, dynamic instrumentation, network traffic interception, and data storage inspection. Maps findings to OWASP MASVS categories and produces a structured report.

When to use

  • Security assessment of a mobile app before production release
  • Bug bounty testing against Android APKs or iOS IPAs
  • Verifying that cert pinning, root/jailbreak detection, and secure storage controls are implemented correctly
  • Compliance validation against OWASP MASTG / MASVS

Prerequisites

Common tools

  • frida / frida-tools — dynamic instrumentation framework
  • objection — runtime mobile exploration toolkit (wraps Frida)
  • Burp Suite — HTTP/S proxy for traffic interception
  • MobSF (Mobile Security Framework) — automated static/dynamic analysis

Android-specific

  • jadx — APK decompiler (Java/Kotlin source recovery)
  • apktool — APK disassembly and smali analysis
  • adb (Android Debug Bridge) — device communication
  • drozer — Android attack surface assessment

iOS-specific

  • class-dump — Objective-C class headers from Mach-O binaries
  • otool — binary inspection (protections, linked libraries)
  • ipatool / Frida iOS Dump — IPA extraction from a jailbroken device
  • Jailbroken device or iOS simulator with Frida server

Install common tools

# Frida + objection
pip3 install frida-tools objection

# MobSF (Docker)
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf

# JADX (Android)
# Download latest release from https://github.com/skylot/jadx/releases
# Then: jadx --version

# apktool
# https://apktool.org/docs/install
apktool --version

# drozer (Android)
pip3 install drozer

Inputs

Field Description Example
TARGET_APP Path to APK (Android) or IPA (iOS) /tmp/target.apk
DEVICE_ID ADB device ID or Frida device name emulator-5554
PACKAGE_NAME Application package / bundle ID com.example.app
BURP_HOST Burp Suite proxy address 127.0.0.1:8080

Workflow

Step 1: Set up the test environment

TARGET_APP="${TARGET_APP:-/tmp/target.apk}"
PACKAGE_NAME="${PACKAGE_NAME:-com.example.app}"
DEVICE_ID="${DEVICE_ID:-emulator-5554}"
BURP_HOST="${BURP_HOST:-127.0.0.1:8080}"
OUTPUT_DIR="/tmp/mobile-pentest-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$OUTPUT_DIR"

# Android: verify device connectivity
adb -s "$DEVICE_ID" shell echo "[+] Device connected" 2>/dev/null \
    || echo "[!] Device not found — start emulator or connect physical device"

# Install Frida server on Android device (adjust arch as needed)
# frida-server binary should already be pushed to /data/local/tmp/frida-server
# adb shell "/data/local/tmp/frida-server &"

echo "[+] Output directory: $OUTPUT_DIR"

Step 2: Static analysis

Android

# Decompile APK with JADX
jadx -d "$OUTPUT_DIR/jadx-output" "$TARGET_APP"
echo "[+] JADX decompilation complete: $OUTPUT_DIR/jadx-output"

# Disassemble with apktool (smali + resources)
apktool d "$TARGET_APP" -o "$OUTPUT_DIR/apktool-output" --no-src
echo "[+] apktool disassembly complete"

# Manifest analysis — permissions, exported components, debuggable flag
MANIFEST="$OUTPUT_DIR/apktool-output/AndroidManifest.xml"
echo "[*] Checking AndroidManifest.xml..."

# Debuggable flag
grep -i 'android:debuggable="true"' "$MANIFEST" \
    && echo "[FINDING] App is debuggable — remove for production" \
    || echo "[OK] android:debuggable not set to true"

# Backup allowed
grep -i 'android:allowBackup="true"' "$MANIFEST" \
    && echo "[FINDING] android:allowBackup=true — sensitive data may be backed up" \
    || echo "[OK] android:allowBackup not set to true"

# Exported activities / receivers / providers
echo "[*] Exported components:"
grep -E 'exported="true"' "$MANIFEST" | grep -oE 'android:name="[^"]*"'

# Hardcoded secrets / API keys in decompiled source
echo "[*] Scanning for hardcoded secrets..."
grep -rE '(api[_-]?key|secret|password|token|private[_-]?key)\s*=\s*"[^"]{6,}"' \
    "$OUTPUT_DIR/jadx-output" --include="*.java" -l \
    | tee "$OUTPUT_DIR/hardcoded-secrets.txt"

# Certificate pinning implementations
grep -rn "CertificatePinner\|TrustManager\|X509TrustManager\|checkServerTrusted\|pinnedCertificates" \
    "$OUTPUT_DIR/jadx-output" --include="*.java" \
    | tee "$OUTPUT_DIR/cert-pinning-refs.txt"

# Root detection
grep -rn "isRooted\|RootBeer\|/su\|Superuser.apk\|com.topjohnwu.magisk" \
    "$OUTPUT_DIR/jadx-output" --include="*.java" \
    | tee "$OUTPUT_DIR/root-detection-refs.txt"

# WebView configuration
grep -rn "setJavaScriptEnabled\|addJavascriptInterface\|setAllowFileAccess" \
    "$OUTPUT_DIR/jadx-output" --include="*.java" \
    | tee "$OUTPUT_DIR/webview-refs.txt"

echo "[+] Static analysis artifacts saved to $OUTPUT_DIR"

iOS

# Extract IPA
unzip -q "$TARGET_APP" -d "$OUTPUT_DIR/ipa-contents"
APP_BINARY=$(find "$OUTPUT_DIR/ipa-contents" -name "*.app" -type d | head -1)
BINARY_NAME=$(basename "$APP_BINARY" .app)
BINARY_PATH="$APP_BINARY/$BINARY_NAME"

echo "[+] Binary: $BINARY_PATH"

# Binary protections
echo "[*] Binary protection flags:"
otool -hv "$BINARY_PATH" | grep -E "PIE|ASLR" || echo "  PIE: check MHEXECUTABLE flags manually"
otool -lv "$BINARY_PATH" | grep -A5 "LC_ENCRYPTION_INFO" | grep cryptid

# Class dump (Objective-C)
class-dump -H "$BINARY_PATH" -o "$OUTPUT_DIR/class-dump/" 2>/dev/null \
    && echo "[+] class-dump output: $OUTPUT_DIR/class-dump/" \
    || echo "[!] class-dump failed — binary may be Swift-only or encrypted"

# Info.plist analysis
INFOPLIST="$APP_BINARY/Info.plist"
echo "[*] Info.plist — ATS exceptions:"
plutil -p "$INFOPLIST" | grep -A3 "NSAppTransportSecurity" \
    || echo "  No ATS exceptions found"

echo "[*] URL schemes:"
plutil -p "$INFOPLIST" | grep -A2 "CFBundleURLSchemes"

# Hardcoded secrets in binary strings
strings "$BINARY_PATH" | grep -iE '(api[_-]?key|secret|password|token|private[_-]?key)' \
    | tee "$OUTPUT_DIR/ios-hardcoded-secrets.txt"

# Jailbreak detection references
strings "$BINARY_PATH" | grep -iE '(cydia|substrate|jailbreak|/bin/bash|/etc/apt)' \
    | tee "$OUTPUT_DIR/jailbreak-detection-refs.txt"

Step 3: Dynamic analysis with Frida

Android — SSL pinning bypass and root detection bypass

# List running apps on device
frida-ps -U -a

# Launch app with objection for runtime exploration
objection -g "$PACKAGE_NAME" explore

# Inside objection shell — common commands:
# android sslpinning disable          — bypass SSL pinning
# android root disable                — disable root detection
# android hooking list classes        — list all classes
# android hooking watch class <name>  — hook all methods of a class
# memory search --string "Bearer "    — search memory for auth tokens

Reference: See REFERENCE.md for the standalone Frida SSL pinning bypass script (OkHttp3 + Conscrypt) and iOS Keychain dump script.

Android — Intent interception and content provider testing

# drozer: list attack surface
# Start drozer agent on device first, then:
# drozer console connect
echo "[+] drozer command reference saved to $OUTPUT_DIR/drozer-commands.txt"

Reference: See REFERENCE.md for the full drozer command reference (attack surface, activities, content providers, broadcast receivers, SQL injection).

iOS — Frida dynamic analysis

# List processes on jailbroken device (Frida server must be running)
frida-ps -U

# Launch with objection (Frida server must be running on device)
objection -g "$PACKAGE_NAME" explore
# ios sslpinning disable | ios jailbreak disable | ios keychain dump
# ios nsuserdefaults get | ios hooking list classes
# ios hooking watch method "-[ClassName methodName]" --dump-args --dump-return

Reference: See REFERENCE.md for the iOS Keychain dump Frida script.

Step 4: Network traffic analysis

# Point device proxy to Burp Suite ($BURP_HOST) and install Burp CA cert
# Android: adb push burp-cert.der /sdcard/ → Settings > Security
# iOS: Safari download of Burp CA → Settings > General > Profile
# Then bypass SSL pinning via Frida (Step 3) to intercept HTTPS traffic

# Capture checklist: auth token format, expiry/refresh, no plaintext PII,
# no sensitive data in URL params, HSTS enforced, API endpoints documented

Step 5: Data storage inspection

Android

# Pull app data directory (requires root or debuggable app)
adb -s "$DEVICE_ID" shell "run-as $PACKAGE_NAME find /data/data/$PACKAGE_NAME -type f" \
    | tee "$OUTPUT_DIR/app-files.txt"

# SharedPreferences
adb -s "$DEVICE_ID" shell "run-as $PACKAGE_NAME cat /data/data/$PACKAGE_NAME/shared_prefs/*.xml 2>/dev/null" \
    | tee "$OUTPUT_DIR/shared-prefs.txt"
grep -iE '(password|token|secret|key)' "$OUTPUT_DIR/shared-prefs.txt" \
    && echo "[FINDING] Sensitive data found in SharedPreferences"

# SQLite databases
adb -s "$DEVICE_ID" shell "find /data/data/$PACKAGE_NAME -name '*.db'" \
    | while read db; do
        adb -s "$DEVICE_ID" shell "run-as $PACKAGE_NAME sqlite3 $db '.tables'" 2>/dev/null
    done | tee "$OUTPUT_DIR/sqlite-tables.txt"

# External storage
adb -s "$DEVICE_ID" shell "find /sdcard/Android/data/$PACKAGE_NAME -type f" \
    | tee "$OUTPUT_DIR/external-storage.txt"

# Backup analysis
adb -s "$DEVICE_ID" backup -noapk "$PACKAGE_NAME" -f "$OUTPUT_DIR/backup.ab"
echo "[+] Backup saved — decode with: java -jar abe.jar unpack $OUTPUT_DIR/backup.ab $OUTPUT_DIR/backup-extracted.tar"

iOS

# On jailbroken device via SSH or objection:
cat <<'EOF'
# Inside objection:
ios nsuserdefaults get
ios keychain dump
ios cookies get

# File system locations to inspect:
# /var/mobile/Containers/Data/Application/<UUID>/Documents/
# /var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/<bundle-id>.plist
# /var/mobile/Containers/Data/Application/<UUID>/Library/Caches/
# /var/mobile/Containers/Data/Application/<UUID>/tmp/

# Check for sensitive data in background screenshots:
# /var/mobile/Containers/Data/Application/<UUID>/Library/SplashBoard/Snapshots/
EOF

echo "[*] iOS data storage checklist:"
cat <<'EOF'
[ ] Keychain items classified with correct accessibility setting (kSecAttrAccessibleWhenUnlocked)
[ ] NSUserDefaults contains no sensitive data
[ ] Core Data / SQLite databases encrypted or contain no PII
[ ] Cache files do not persist sensitive responses
[ ] Background screenshots do not expose sensitive screens
[ ] Pasteboard not used for sensitive data
EOF

Step 6: Generate MASVS-mapped findings report

Reference: See REFERENCE.md for the Python report template generator that produces a structured findings-report.md with per-finding tables and MASVS mapping sections.

# Run the report generator (requires OUTPUT_DIR and PACKAGE_NAME env vars)
python3 generate-report.py

Reference: See REFERENCE.md for the full MASVS Coverage Checklist (7 categories: STORAGE, CRYPTO, AUTH, NETWORK, PLATFORM, CODE, RESILIENCE).

Done when

  • Static analysis complete: manifest reviewed, secrets scanned, pinning/root detection identified
  • Dynamic analysis complete: Frida/objection sessions recorded, pinning bypassed
  • Network traffic captured via Burp Suite with proxy certificate installed
  • Data storage inspected: SharedPreferences/NSUserDefaults, SQLite, Keychain reviewed
  • All findings documented with MASVS mapping, severity, PoC, and remediation
  • Report saved to $OUTPUT_DIR/findings-report.md

Failure modes

Problem Cause Solution
frida-server not running Server not started on device adb shell "/data/local/tmp/frida-server &"
objection can't attach Package name wrong or app not running Verify with frida-ps -U -a
SSL bypass not working Custom pinning implementation Inspect pinning code in JADX output and write targeted hook
adb: device not found USB debugging disabled Enable USB debugging in Developer Options
JADX out of memory Large APK jadx --deobf --threads-count 2 -Xmx4g target.apk
iOS Frida server disconnects USB connection drops Use frida-server over network (-H device-ip)

Notes

  • All testing must be performed only against applications you own or have explicit written authorization to test.
  • Root/jailbreak bypass techniques are for security validation only — document findings and recommend mitigations, do not weaponize.
  • Frida scripts and objection sessions should be conducted in an isolated test environment, not on production devices with real user data.
  • Reference: OWASP MASTG and OWASP MASVS