Skip to main content

Mobile VAPT Notes (iOS Statis Analysis)

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

Mobile VAPT Notes (iOS)
#


iOS Static Analysis
#

Static Analysis
#

Automated Analysis with MobSF
#

Modern MobSF Setup and Usage:
#
# MobSF Docker (Recommended - Latest version, isolated environment)
# Pull latest image:
docker pull opensecurity/mobile-security-framework-mobsf:latest

# Run with persistent storage and optimized settings:
docker run -d \
  --name mobsf \
  -p 8000:8000 \
  -v "$HOME/mobsf-data:/home/mobsf/.MobSF" \
  -e MOBSF_ANALYZER_IDENTIFIER="com.mobsf.analyzer" \
  --restart unless-stopped \
  opensecurity/mobile-security-framework-mobsf:latest

# Access MobSF: http://localhost:8000
# Default credentials: mobsf / mobsf

# CRITICAL: Change default password immediately
docker exec -it mobsf python manage.py changepassword mobsf

# Alternative: Direct installation (for customization)
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
cd Mobile-Security-Framework-MobSF
./setup.sh  # Installs all dependencies

# Configure MobSF (optional):
nano MobSF/settings.py
# Key settings:
# - MALWARE_ANALYSIS = True  # Enable VirusTotal integration
# - VT_API_KEY = "your_key"  # VirusTotal API key
# - DOMAIN_MALWARE_SCAN = True  # Scan domains
# - APKID_ENABLED = True  # Better packer/protector detection

# Run MobSF:
./run.sh  # Linux/macOS
# Or: python manage.py runserver 0.0.0.0:8000
Analyzing iOS Applications with MobSF:
#
# Method 1: Web Interface (Interactive)
# 1. Browse to http://localhost:8000
# 2. Drag and drop IPA file
# 3. Wait for analysis (2-10 minutes depending on app size)
# 4. Review comprehensive security report

# Method 2: REST API (Automation)
# Get API key: MobSF Web UI → API Docs → Generate Key

# Upload and analyze IPA:
curl -X POST http://localhost:8000/api/v1/upload \
  -H "Authorization: YOUR_API_KEY_HERE" \
  -F "file=@app.ipa"

# Response includes scan hash, use for retrieving results:
SCAN_HASH="abc123def456..."

# Get analysis report:
curl -X POST http://localhost:8000/api/v1/report_json \
  -H "Authorization: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d "{\"hash\": \"$SCAN_HASH\"}" \
  | jq . > mobsf_report.json

# Download PDF report:
curl -X POST http://localhost:8000/api/v1/download_pdf \
  -H "Authorization: YOUR_API_KEY_HERE" \
  -d "hash=$SCAN_HASH" \
  -o report.pdf

# Automation script:
cat > analyze_with_mobsf.sh << 'SCRIPT'
#!/bin/bash
IPA_FILE="$1"
API_KEY="YOUR_API_KEY"
MOBSF_URL="http://localhost:8000"

if [ ! -f "$IPA_FILE" ]; then
    echo "Usage: $0 <path_to_ipa>"
    exit 1
fi

echo "[*] Uploading $IPA_FILE to MobSF..."
RESPONSE=$(curl -s -X POST "$MOBSF_URL/api/v1/upload" \
  -H "Authorization: $API_KEY" \
  -F "file=@$IPA_FILE")

SCAN_HASH=$(echo "$RESPONSE" | jq -r '.hash')
echo "[+] Scan hash: $SCAN_HASH"

echo "[*] Waiting for analysis to complete..."
sleep 30  # Wait for analysis

echo "[*] Retrieving report..."
curl -s -X POST "$MOBSF_URL/api/v1/report_json" \
  -H "Authorization: $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"hash\": \"$SCAN_HASH\"}" \
  | jq . > "${IPA_FILE%.ipa}_mobsf_report.json"

echo "[+] Report saved: ${IPA_FILE%.ipa}_mobsf_report.json"
SCRIPT

chmod +x analyze_with_mobsf.sh
./analyze_with_mobsf.sh app.ipa
Key Areas to Review in MobSF iOS Report:
#
1. Binary Analysis (Security Features):
#
# MobSF automatically checks for critical binary protections:

# PIE (Position Independent Executable) - ASLR:
# ✓ Expected: Enabled (PIE flag present)
# ✗ Risk: Disabled - Predictable memory layout, easier exploitation

# Stack Canaries (Stack Smashing Protection):
# ✓ Expected: Enabled (__stack_chk_guard, __stack_chk_fail symbols)
# ✗ Risk: Disabled - Buffer overflow vulnerabilities easier to exploit

# ARC (Automatic Reference Counting):
# ✓ Expected: Enabled (_objc_release, _objc_retain symbols)
# ✗ Risk: Disabled - Memory management issues, potential UAF vulnerabilities

# Binary Encryption (FairPlay DRM):
# App Store apps: cryptid = 1 (encrypted)
# Jailbroken dumps: cryptid = 0 (decrypted)
# Analysis requires decrypted binary

# Restricted/Banned APIs:
# MobSF flags usage of dangerous functions:
# - strcpy, strcat, sprintf (buffer overflows)
# - gets, scanf (unsafe input)
# - system, popen (command injection risks)
# - rand, random (weak randomness)

# Manual verification in MobSF report:
jq '.binary_analysis' mobsf_report.json
2. App Transport Security (ATS) Analysis:
#
# Critical: ATS weakening allows insecure HTTP connections
# MobSF checks Info.plist for:

# CRITICAL FINDING: NSAllowsArbitraryLoads = YES
# Risk: Allows all HTTP connections, defeats HTTPS-only policy

# HIGH FINDING: NSAllowsArbitraryLoadsInWebContent = YES
# Risk: WebViews can load HTTP content

# HIGH FINDING: NSAllowsLocalNetworking = YES
# Risk: Allows unencrypted local network connections

# MEDIUM: NSExceptionDomains with insecure settings
# Risk: Specific domains exempted from HTTPS

# Review ATS configuration in MobSF report:
jq '.app_transport_security' mobsf_report.json

# Example bad configuration:
{
  "NSAppTransportSecurity": {
    "NSAllowsArbitraryLoads": true  // CRITICAL vulnerability
  }
}

# Example acceptable exception (should be justified):
{
  "NSAppTransportSecurity": {
    "NSExceptionDomains": {
      "legacy-api.example.com": {
        "NSExceptionAllowsInsecureHTTPLoads": true,
        "NSExceptionMinimumTLSVersion": "TLSv1.2"
      }
    }
  }
}
3. URL Schemes and Deep Links:#
# MobSF extracts custom URL schemes from Info.plist
# These are potential attack vectors for:
# - Deep link hijacking
# - Parameter injection
# - Unauthorized data access

# Review URL schemes:
jq '.urls' mobsf_report.json

# Example vulnerable URL scheme:
# myapp://webview?url=https://evil.com  (open arbitrary URLs)
# myapp://profile?id=../../../etc/passwd  (path traversal)
# myapp://pay?amount=1000000&account=attacker  (parameter tampering)

# Testing URL schemes (documented in report):
# Use adb or direct testing on device
4. Permissions and Entitlements:
#
# MobSF analyzes Info.plist for privacy-sensitive permissions:

# HIGH RISK permissions (require justification):
# - NSCameraUsageDescription (Camera access)
# - NSMicrophoneUsageDescription (Microphone access)
# - NSLocationAlwaysUsageDescription (Background location)
# - NSPhotoLibraryUsageDescription (Photo access)
# - NSContactsUsageDescription (Contacts access)
# - NSCalendarsUsageDescription (Calendar access)

# Review permissions:
jq '.permissions' mobsf_report.json

# MobSF also extracts entitlements from binary:
# - keychain-access-groups (keychain sharing)
# - application-identifier
# - com.apple.developer.associated-domains (universal links)
# - com.apple.security.application-groups (app group sharing)

# Check for excessive or unnecessary permissions
5. Hardcoded Secrets Detection:
#
# MobSF scans for hardcoded sensitive data:

# API Keys and Tokens:
# - AWS keys (AKIA...)
# - Firebase: google-services.json/plist
# - API endpoints with embedded keys
# - OAuth client secrets

# Credentials:
# - Hardcoded passwords
# - Database credentials
# - Private keys (PEM, p12, etc.)

# URLs and Endpoints:
# - API base URLs
# - Admin panels
# - Debug/staging endpoints

# Review in MobSF report:
jq '.secrets' mobsf_report.json
jq '.urls' mobsf_report.json

# Common patterns flagged:
# - "password" : "hardcoded123"
# - "api_key" : "sk_live_abc123..."
# - "secret" : "confidential_data"
# - Regex matches for API keys, tokens, etc.
6. File and Database Analysis:
#
# MobSF identifies sensitive files in IPA:

# Databases:
# - *.sqlite, *.db (SQLite databases)
# - Core Data stores (*.momd, *.mom)
# - Realm databases (*.realm)

# Configuration files:
# - *.plist (preferences, configuration)
# - *.json (settings, API config)
# - *.xml (configuration data)

# Certificates and keys:
# - *.pem, *.crt, *.cer (certificates)
# - *.key, *.p12 (private keys)
# - *.keystore (Java keystores)

# Cache and logs:
# - Cache.db (WebKit cache)
# - *.log (log files with potential secrets)

# Review files:
jq '.files' mobsf_report.json

# Extract specific file types for manual review:
unzip app.ipa
find Payload/ -name "*.plist" -o -name "*.sqlite" -o -name "*.db"
7. Code Analysis and Vulnerabilities:
#
# MobSF performs static code analysis (SAST):

# Cryptography issues:
# - Weak algorithms (DES, RC4, MD5, SHA1)
# - Hardcoded encryption keys
# - ECB mode usage
# - Weak random number generation

# Insecure data storage:
# - NSUserDefaults for sensitive data
# - Unencrypted databases
# - Files in shared directories

# Insecure communication:
# - HTTP usage
# - Weak TLS configuration
# - Certificate validation bypasses

# WebView vulnerabilities:
# - JavaScript enabled
# - File access enabled
# - JavaScript bridges

# Review vulnerabilities:
jq '.code_analysis' mobsf_report.json
jq '.severity_count' mobsf_report.json  # Count by severity
8. Third-Party Libraries and Components:
#
# MobSF identifies embedded frameworks and libraries:

# Security concerns:
# - Outdated libraries with known CVEs
# - Vulnerable SDKs
# - Unnecessary permissions from libraries

# Review libraries:
jq '.libraries' mobsf_report.json

# Common vulnerable libraries to check:
# - AFNetworking (check version)
# - Alamofire (check version)
# - Firebase SDK (check version)
# - Facebook SDK (known privacy issues)
# - OpenSSL (check version for Heartbleed, etc.)

# Cross-reference with CVE databases:
# https://www.cvedetails.com/
# https://nvd.nist.gov/

Manual Static Analysis
#

Extract and Explore IPA Contents:
#
# Rename and extract IPA:
cp app.ipa app.zip
unzip -q app.zip
cd Payload/

# Find the .app bundle:
APP_NAME=$(ls -1 | grep ".app$" | head -1)
cd "$APP_NAME"

# Overview of IPA structure:
tree -L 2  # If tree is installed
# Or:
find . -maxdepth 2 -type d

# Key directories and files:
# - Info.plist               (app configuration and metadata)
# - <AppName> (binary)       (main executable)
# - Frameworks/              (embedded frameworks)
# - PlugIns/                 (app extensions)
# - Assets.car               (compiled asset catalog)
# - Base.lproj/              (base localization resources)
# - *.mobileprovision        (provisioning profile)
# - embedded.mobileprovision (embedded provisioning)
# - SC_Info/                 (Swift metadata)
# - *.storyboard             (interface files)
# - *.plist                  (various configuration files)
Binary Protection Analysis:
#
# Identify main executable:
MAIN_EXEC=$(ls -1 | grep -v "\\." | head -1)
echo "Main executable: $MAIN_EXEC"

# Get file type and architecture:
file "$MAIN_EXEC"
# Expected: Mach-O universal binary with 2 architectures (arm64, armv7)
# Or: Mach-O 64-bit executable arm64

# 1. Check ASLR/PIE (Position Independent Executable):
otool -hv "$MAIN_EXEC" | grep PIE
# Expected output: PIE
# If missing: Binary is not position-independent (security risk)

# Alternative using jtool2 (modern alternative to otool):
# Install: brew install --cask jtool2
jtool2 --pages "$MAIN_EXEC" | grep PIE

# 2. Check Stack Canaries (Stack Protection):
otool -I -v "$MAIN_EXEC" | grep stack
# Expected: __stack_chk_guard and __stack_chk_fail symbols
# These indicate stack canary protection is enabled

# More detailed check:
nm "$MAIN_EXEC" | grep -E "stack_chk|stack_chk_fail"

# 3. Check ARC (Automatic Reference Counting):
otool -I -v "$MAIN_EXEC" | grep objc_release
# Expected: _objc_release, _objc_retain symbols present
# Indicates modern memory management

# More comprehensive ARC check:
nm "$MAIN_EXEC" | grep -E "objc_release|objc_retain|objc_autorelease"

# 4. Check Binary Encryption (FairPlay DRM):
otool -arch arm64 -l "$MAIN_EXEC" | grep -A5 LC_ENCRYPTION_INFO
# Key field: cryptid
# cryptid 1 = encrypted (App Store binary)
# cryptid 0 = decrypted (required for analysis)

# If encrypted, analysis is limited - must decrypt first
if otool -l "$MAIN_EXEC" | grep -q "cryptid 1"; then
    echo "[!] Binary is encrypted - use frida-ios-dump to decrypt"
fi

# 5. Check for Weak Cryptographic Functions:
otool -I -v "$MAIN_EXEC" | grep -E "_CC_MD5|_CC_SHA1|_DES_|_RC4_|_CCCrypt"
# MD5, SHA1, DES, RC4 are considered weak
# Should use SHA256+, AES, modern algorithms

# Detailed crypto analysis:
nm "$MAIN_EXEC" | grep -i -E "md5|sha1|des|rc4" | sort -u

# 6. Check for Insecure Memory Functions:
otool -I -v "$MAIN_EXEC" | grep -E "_gets|_strcpy|_strcat|_sprintf|_vsprintf"
# These functions are buffer overflow risks
# Modern code should use safer alternatives (strlcpy, snprintf, etc.)

# 7. Check for Debugging Symbols:
otool -I -v "$MAIN_EXEC" | grep -E "_NSLog|_printf"
# Excessive logging may leak sensitive information

# Check if binary is stripped:
nm "$MAIN_EXEC" | wc -l
# Low count (< 100) indicates stripped binary
# High count indicates symbols present (easier to reverse)

# 8. Check for Anti-Debugging:
nm "$MAIN_EXEC" | grep -i -E "ptrace|sysctl|isatty"
# Presence suggests anti-debugging measures

# 9. Check Code Signing:
codesign -dv "$MAIN_EXEC" 2>&1
# Shows: Authority, TeamIdentifier, Sealed Resources

# Verify signature:
codesign --verify --verbose "$MAIN_EXEC"
# If valid: no output
# If invalid: error message

# 10. Extract entitlements:
codesign -d --entitlements - "$MAIN_EXEC" 2>/dev/null | xmllint --format -
# Shows app capabilities and permissions

# Alternative using jtool2:
jtool2 --ent "$MAIN_EXEC"

# 11. Modern security features check (iOS 15+):
# Pointer Authentication Codes (PAC):
otool -hv "$MAIN_EXEC" | grep -i "pac"
# If present: Enhanced exploit mitigation

# Control Flow Integrity (CFI):
# Check for __auth sections:
otool -l "$MAIN_EXEC" | grep -i "__auth"
Comprehensive Binary Analysis Script:
#
#!/bin/bash
# ios_binary_analysis.sh - Comprehensive binary security check

BINARY="$1"

if [ ! -f "$BINARY" ]; then
    echo "Usage: $0 <binary_path>"
    exit 1
fi

echo "======================================"
echo "iOS Binary Security Analysis"
echo "Binary: $BINARY"
echo "======================================"
echo

# File info
echo "[*] File Information:"
file "$BINARY"
echo

# Architecture
echo "[*] Architectures:"
lipo -info "$BINARY" 2>/dev/null || echo "Single architecture"
echo

# PIE/ASLR
echo "[*] PIE (ASLR) Protection:"
if otool -hv "$BINARY" | grep -q PIE; then
    echo "✓ ENABLED"
else
    echo "✗ DISABLED - SECURITY RISK"
fi
echo

# Stack Canaries
echo "[*] Stack Canaries:"
if nm "$BINARY" 2>/dev/null | grep -q stack_chk; then
    echo "✓ ENABLED"
else
    echo "✗ DISABLED - SECURITY RISK"
fi
echo

# ARC
echo "[*] ARC (Automatic Reference Counting):"
if nm "$BINARY" 2>/dev/null | grep -q objc_release; then
    echo "✓ ENABLED"
else
    echo "✗ DISABLED - Memory safety risk"
fi
echo

# Encryption
echo "[*] Binary Encryption:"
CRYPTID=$(otool -l "$BINARY" 2>/dev/null | grep cryptid | head -1 | awk '{print $2}')
if [ "$CRYPTID" = "1" ]; then
    echo "✗ ENCRYPTED - Decrypt before analysis"
elif [ "$CRYPTID" = "0" ]; then
    echo "✓ DECRYPTED - Ready for analysis"
else
    echo "? UNKNOWN"
fi
echo

# Weak crypto
echo "[*] Weak Cryptography Functions:"
WEAK_CRYPTO=$(nm "$BINARY" 2>/dev/null | grep -i -E "md5|sha1|_des_|_rc4_" | wc -l)
if [ "$WEAK_CRYPTO" -gt 0 ]; then
    echo "✗ FOUND ($WEAK_CRYPTO references)"
    nm "$BINARY" 2>/dev/null | grep -i -E "md5|sha1|_des_|_rc4_" | head -5
else
    echo "✓ NONE DETECTED"
fi
echo

# Insecure functions
echo "[*] Insecure Memory Functions:"
INSECURE=$(nm "$BINARY" 2>/dev/null | grep -E "gets|strcpy|strcat|sprintf" | wc -l)
if [ "$INSECURE" -gt 0 ]; then
    echo "✗ FOUND ($INSECURE references)"
    nm "$BINARY" 2>/dev/null | grep -E "gets|strcpy|strcat|sprintf" | head -5
else
    echo "✓ NONE DETECTED"
fi
echo

# Symbols stripped
echo "[*] Symbol Information:"
SYMBOL_COUNT=$(nm "$BINARY" 2>/dev/null | wc -l)
if [ "$SYMBOL_COUNT" -lt 100 ]; then
    echo "✓ STRIPPED ($SYMBOL_COUNT symbols) - Harder to reverse"
else
    echo "✗ NOT STRIPPED ($SYMBOL_COUNT symbols) - Easier to reverse"
fi
echo

# Code signing
echo "[*] Code Signing:"
codesign --verify --verbose "$BINARY" 2>&1 | head -3
echo

# Entitlements
echo "[*] Entitlements:"
codesign -d --entitlements - "$BINARY" 2>/dev/null | xmllint --format - | head -20
echo

echo "======================================"
echo "Analysis complete!"
echo "======================================"
Usage:
#
chmod +x ios_binary_analysis.sh
./ios_binary_analysis.sh Payload/Instagram.app/Instagram

iOS Info.plist and Configuration Analysis
#

Info.plist Analysis
#

Extract and Convert Info.plist:
#

# Info.plist is often in binary format, must convert to XML for readability

# Method 1: Using plutil (built-in on macOS)
plutil -convert xml1 Info.plist -o Info.xml

# Verify conversion:
file Info.xml
# Should show: XML 1.0 document text

# Method 2: Using plistutil (Linux alternative)
# Install: sudo apt install libplist-utils
plistutil -i Info.plist -o Info.xml

# Method 3: Using Python (cross-platform)
python3 << 'PYTHON'
import plistlib
with open('Info.plist', 'rb') as f:
    plist = plistlib.load(f)
with open('Info.xml', 'w') as f:
    plistlib.dump(plist, f)
PYTHON

# Pretty print for analysis:
plutil -p Info.plist | less

# Extract specific values:
plutil -extract CFBundleIdentifier raw Info.plist
plutil -extract CFBundleVersion raw Info.plist
plutil -extract CFBundleShortVersionString raw Info.plist

Critical Security-Relevant Info.plist Keys:
#

1. App Transport Security (ATS) Configuration:
#
# Extract ATS configuration:
plutil -extract NSAppTransportSecurity json Info.plist 2>/dev/null || echo "ATS not configured"

# Search for dangerous ATS configurations:
grep -A 10 "NSAppTransportSecurity" Info.xml

# CRITICAL vulnerabilities to identify:

# CRITICAL: Global HTTP allowed
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>  <!-- CRITICAL: Disables ATS entirely -->
</dict>

# HIGH: WebView HTTP allowed
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>  <!-- HIGH: WebViews can load HTTP content -->
</dict>

# HIGH: Local networking unencrypted
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>  <!-- HIGH: Allows HTTP to local IP addresses -->
</dict>

# MEDIUM: Specific domain exceptions
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>legacy-api.example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>  <!-- MEDIUM: HTTP allowed for specific domain -->
            <key>NSIncludesSubdomains</key>
            <true/>  <!-- Applies to all subdomains -->
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>  <!-- Minimum TLS version -->
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>  <!-- Disables Perfect Forward Secrecy -->
        </dict>
    </dict>
</dict>

# Secure ATS configuration (recommended):
<key>NSAppTransportSecurity</key>
<dict>
    <!-- No NSAllowsArbitraryLoads -->
    <!-- Specific exceptions only, with justification -->
    <key>NSExceptionDomains</key>
    <dict>
        <key>api.example.com</key>
        <dict>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.3</string>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
        </dict>
    </dict>
</dict>

# Automated ATS security check:
cat > check_ats.sh << 'SCRIPT'
#!/bin/bash
PLIST="$1"

echo "[*] Checking ATS configuration..."

if plutil -extract NSAppTransportSecurity.NSAllowsArbitraryLoads raw "$PLIST" 2>/dev/null | grep -q "1\|true"; then
    echo "✗ CRITICAL: NSAllowsArbitraryLoads is enabled (HTTP allowed globally)"
elif plutil -extract NSAppTransportSecurity.NSAllowsArbitraryLoadsInWebContent raw "$PLIST" 2>/dev/null | grep -q "1\|true"; then
    echo "✗ HIGH: NSAllowsArbitraryLoadsInWebContent is enabled (WebViews can use HTTP)"
elif plutil -extract NSAppTransportSecurity.NSAllowsLocalNetworking raw "$PLIST" 2>/dev/null | grep -q "1\|true"; then
    echo "⚠ MEDIUM: NSAllowsLocalNetworking is enabled (local HTTP allowed)"
else
    echo "✓ ATS appears properly configured"
fi

# Check for domain exceptions
if plutil -extract NSAppTransportSecurity.NSExceptionDomains json "$PLIST" 2>/dev/null; then
    echo "⚠ Domain exceptions configured - review each for necessity"
fi
SCRIPT

chmod +x check_ats.sh
./check_ats.sh Info.plist
2. URL Schemes (Deep Links) Analysis:#
# Extract URL schemes:
plutil -extract CFBundleURLTypes json Info.plist 2>/dev/null

# Search in XML format:
grep -A 15 "CFBundleURLTypes" Info.xml

# URL Scheme structure:
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>  <!-- or Viewer -->
        <key>CFBundleURLName</key>
        <string>com.example.app.url</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myapp</string>
            <string>mycompany</string>
        </array>
    </dict>
</array>

# Extract all URL schemes:
plutil -extract CFBundleURLTypes json Info.plist 2>/dev/null | \
  jq -r '.[].CFBundleURLSchemes[]'

# Or using grep/sed:
grep -A 2 "CFBundleURLSchemes" Info.xml | \
  grep "<string>" | \
  sed 's/.*<string>\(.*\)<\/string>.*/\1/'

# Common URL scheme vulnerabilities:

# 1. Generic/Collision-prone schemes:
# - "http", "https" (conflicts with Safari)
# - "file" (path traversal risks)
# - Common words like "app", "open", "view"

# 2. Dangerous URL handlers:
# - myapp://webview?url=https://evil.com (arbitrary URL loading)
# - myapp://file?path=/etc/passwd (path traversal)
# - myapp://execute?cmd=whoami (command injection)
# - myapp://sql?query=DROP TABLE users (SQL injection)

# Security testing for URL schemes:
# Create test URLs and open on device:
# xcrun simctl openurl booted "myapp://test"

# From computer (device connected):
idevice-app-runner -u <UDID> --url "myapp://profile?id=1"

# Via Safari on device:
# Type URL in address bar: myapp://action?param=value

# URL Scheme security checklist script:
cat > check_url_schemes.sh << 'SCRIPT'
#!/bin/bash
PLIST="$1"

echo "[*] Extracting URL schemes..."
SCHEMES=$(plutil -extract CFBundleURLTypes json "$PLIST" 2>/dev/null | \
  jq -r '.[].CFBundleURLSchemes[]' 2>/dev/null)

if [ -z "$SCHEMES" ]; then
    echo "✓ No custom URL schemes found"
    exit 0
fi

echo "[!] Found URL schemes:"
echo "$SCHEMES" | while read scheme; do
    echo "  - $scheme://"
    
    # Check for dangerous patterns
    if echo "$scheme" | grep -qE "^(http|https|file|ftp)$"; then
        echo "    ✗ CRITICAL: Reserved scheme name (collision risk)"
    fi
    
    if [ ${#scheme} -lt 4 ]; then
        echo "    ⚠ WARNING: Very short scheme name (collision risk)"
    fi
    
    # Generate test URLs
    echo "    Test URLs:"
    echo "      $scheme://webview?url=https://evil.com"
    echo "      $scheme://file?path=../../../etc/passwd"
    echo "      $scheme://profile?id=1' OR '1'='1"
done
SCRIPT

chmod +x check_url_schemes.sh
./check_url_schemes.sh Info.plist
3. Universal Links (Associated Domains):#
# Extract associated domains (Universal Links):
plutil -extract com.apple.developer.associated-domains json Info.plist 2>/dev/null

# Or from entitlements:
codesign -d --entitlements - Payload/*.app/* 2>/dev/null | \
  grep -A 5 "associated-domains"

# Format:
<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:example.com</string>
    <string>applinks:www.example.com</string>
    <string>applinks:*.example.com</string>  <!-- Wildcard subdomain -->
</array>

# Universal Links require apple-app-site-association file on server
# Verify AASA file exists:
curl https://example.com/.well-known/apple-app-site-association
# Or: curl https://example.com/apple-app-site-association

# Validate AASA format:
curl -s https://example.com/.well-known/apple-app-site-association | jq .

# Expected structure:
{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "TEAM_ID.com.example.app",
        "paths": [
          "/articles/*",
          "/products/*",
          "NOT /admin/*"
        ]
      }
    ]
  }
}

# Security concerns:
# - Wildcard domain matching (*.example.com)
# - Overly broad path matching (/* allows all paths)
# - Misconfigured AASA file (allows unintended deep links)
# - HTTP AASA file (must be HTTPS)
4. Privacy-Sensitive Permissions (iOS 14+ Privacy Manifest):
#
# iOS 14+ requires usage descriptions for privacy-sensitive features
# Extract all NSUsageDescription keys:
plutil -p Info.plist | grep -i "UsageDescription"

# Critical permissions to check:

# Location (always high-risk):
plutil -extract NSLocationAlwaysAndWhenInUseUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSLocationWhenInUseUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSLocationAlwaysUsageDescription raw Info.plist 2>/dev/null

# Camera and Microphone:
plutil -extract NSCameraUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSMicrophoneUsageDescription raw Info.plist 2>/dev/null

# Photo Library:
plutil -extract NSPhotoLibraryUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSPhotoLibraryAddUsageDescription raw Info.plist 2>/dev/null

# Contacts and Calendar:
plutil -extract NSContactsUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSCalendarsUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSRemindersUsageDescription raw Info.plist 2>/dev/null

# Health and Motion:
plutil -extract NSHealthShareUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSHealthUpdateUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSMotionUsageDescription raw Info.plist 2>/dev/null

# Bluetooth:
plutil -extract NSBluetoothAlwaysUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSBluetoothPeripheralUsageDescription raw Info.plist 2>/dev/null

# Face ID:
plutil -extract NSFaceIDUsageDescription raw Info.plist 2>/dev/null

# Speech Recognition:
plutil -extract NSSpeechRecognitionUsageDescription raw Info.plist 2>/dev/null

# Tracking (iOS 14.5+, critical for privacy):
plutil -extract NSUserTrackingUsageDescription raw Info.plist 2>/dev/null

# HomeKit:
plutil -extract NSHomeKitUsageDescription raw Info.plist 2>/dev/null

# Media Library:
plutil -extract NSAppleMusicUsageDescription raw Info.plist 2>/dev/null

# Local Network (iOS 14+):
plutil -extract NSLocalNetworkUsageDescription raw Info.plist 2>/dev/null
plutil -extract NSBonjourServices json Info.plist 2>/dev/null

# Comprehensive permission audit:
cat > audit_permissions.sh << 'SCRIPT'
#!/bin/bash
PLIST="$1"

echo "======================================"
echo "iOS Privacy Permission Audit"
echo "======================================"
echo

PERMISSIONS=(
    "NSLocationAlwaysAndWhenInUseUsageDescription:Location (Always)"
    "NSLocationWhenInUseUsageDescription:Location (When In Use)"
    "NSCameraUsageDescription:Camera"
    "NSMicrophoneUsageDescription:Microphone"
    "NSPhotoLibraryUsageDescription:Photo Library"
    "NSContactsUsageDescription:Contacts"
    "NSCalendarsUsageDescription:Calendar"
    "NSRemindersUsageDescription:Reminders"
    "NSMotionUsageDescription:Motion & Fitness"
    "NSHealthShareUsageDescription:Health (Read)"
    "NSHealthUpdateUsageDescription:Health (Write)"
    "NSBluetoothAlwaysUsageDescription:Bluetooth"
    "NSFaceIDUsageDescription:Face ID"
    "NSSpeechRecognitionUsageDescription:Speech Recognition"
    "NSUserTrackingUsageDescription:App Tracking"
    "NSLocalNetworkUsageDescription:Local Network"
)

for perm in "${PERMISSIONS[@]}"; do
    KEY="${perm%%:*}"
    NAME="${perm##*:}"
    
    DESC=$(plutil -extract "$KEY" raw "$PLIST" 2>/dev/null)
    if [ $? -eq 0 ]; then
        echo "✓ $NAME:"
        echo "  Usage Description: $DESC"
        
        # Check if description is generic/insufficient
        if echo "$DESC" | grep -qE "^(App|Application|This app)"; then
            echo "  ⚠ WARNING: Generic description - Apple may reject"
        fi
        echo
    fi
done

# Check for tracking (iOS 14.5+ requirement)
if plutil -extract NSUserTrackingUsageDescription raw "$PLIST" 2>/dev/null >/dev/null; then
    echo "⚠ App requests tracking permission - ensure user consent"
else
    echo "✓ No tracking permission requested"
fi
SCRIPT

chmod +x audit_permissions.sh
./audit_permissions.sh Info.plist
5. Dangerous Application Settings:
#
# Check for dangerous configuration flags:

# 1. UIFileSharingEnabled (iTunes File Sharing):
plutil -extract UIFileSharingEnabled raw Info.plist 2>/dev/null
# If true: App's Documents folder is accessible via iTunes/Finder
# Risk: Sensitive data exposure

<key>UIFileSharingEnabled</key>
<true/>  <!-- HIGH RISK: Exposes Documents folder -->

# 2. LSSupportsOpeningDocumentsInPlace:
plutil -extract LSSupportsOpeningDocumentsInPlace raw Info.plist 2>/dev/null
# If true: Allows in-place document opening
# Risk: Path traversal, unauthorized file access

<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>  <!-- MEDIUM RISK: Document access -->

# 3. UISupportsDocumentBrowser:
plutil -extract UISupportsDocumentBrowser raw Info.plist 2>/dev/null
# If true: Enables document browser
# Risk: Broader file system access

# 4. UIRequiresPersistentWiFi:
plutil -extract UIRequiresPersistentWiFi raw Info.plist 2>/dev/null
# If true: Keeps WiFi active in background
# OPSEC: May indicate background data collection

# 5. UIBackgroundModes (background execution):
plutil -extract UIBackgroundModes json Info.plist 2>/dev/null
# Modes to investigate:
# - "location" (background location tracking)
# - "fetch" (background data fetching)
# - "remote-notification" (push notification handling)
# - "voip" (VoIP calling)
# - "audio" (background audio)
# - "bluetooth-central" (Bluetooth in background)
# - "bluetooth-peripheral" (Bluetooth peripheral)

<key>UIBackgroundModes</key>
<array>
    <string>location</string>  <!-- Background location -->
    <string>fetch</string>     <!-- Background refresh -->
    <string>remote-notification</string>
</array>

# 6. Debug/Development flags (should NOT be in production):
plutil -extract ITSAppUsesNonExemptEncryption raw Info.plist 2>/dev/null
# If false: App uses encryption exempt from export compliance
# Should be properly justified

# Dangerous settings check script:
cat > check_dangerous_settings.sh << 'SCRIPT'
#!/bin/bash
PLIST="$1"

echo "[*] Checking for dangerous application settings..."
echo

# File sharing
if plutil -extract UIFileSharingEnabled raw "$PLIST" 2>/dev/null | grep -q "1\|true"; then
    echo "✗ HIGH RISK: UIFileSharingEnabled - Documents folder exposed via iTunes"
else
    echo "✓ File sharing disabled"
fi

# Document handling
if plutil -extract LSSupportsOpeningDocumentsInPlace raw "$PLIST" 2>/dev/null | grep -q "1\|true"; then
    echo "⚠ MEDIUM RISK: LSSupportsOpeningDocumentsInPlace enabled"
fi

# Background modes
BG_MODES=$(plutil -extract UIBackgroundModes json "$PLIST" 2>/dev/null)
if [ $? -eq 0 ]; then
    echo "⚠ Background modes enabled:"
    echo "$BG_MODES" | jq -r '.[]' | while read mode; do
        echo "  - $mode"
        if [ "$mode" = "location" ]; then
            echo "    ✗ WARNING: Background location tracking"
        fi
    done
else
    echo "✓ No background modes enabled"
fi
echo

# Check for debuggable flag (shouldn't exist in Info.plist, but check)
if grep -q "debuggable" "$PLIST"; then
    echo "✗ CRITICAL: Debuggable flag found - remove for production"
fi
SCRIPT

chmod +x check_dangerous_settings.sh
./check_dangerous_settings.sh Info.plist
6. Application Metadata Extraction:
#
# Extract key application metadata for documentation:

# Bundle Identifier (unique app ID):
BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw Info.plist)
echo "Bundle ID: $BUNDLE_ID"

# Display Name:
DISPLAY_NAME=$(plutil -extract CFBundleDisplayName raw Info.plist 2>/dev/null || \
               plutil -extract CFBundleName raw Info.plist)
echo "Display Name: $DISPLAY_NAME"

# Version information:
VERSION=$(plutil -extract CFBundleShortVersionString raw Info.plist)
BUILD=$(plutil -extract CFBundleVersion raw Info.plist)
echo "Version: $VERSION (Build $BUILD)"

# Minimum iOS version:
MIN_IOS=$(plutil -extract MinimumOSVersion raw Info.plist 2>/dev/null || \
          plutil -extract LSMinimumSystemVersion raw Info.plist 2>/dev/null)
echo "Minimum iOS: $MIN_IOS"

# Supported device families:
DEVICES=$(plutil -extract UIDeviceFamily json Info.plist 2>/dev/null)
echo "Device Families: $DEVICES"
# 1 = iPhone/iPod, 2 = iPad

# Supported orientations:
ORIENTATIONS=$(plutil -extract UISupportedInterfaceOrientations json Info.plist 2>/dev/null)
echo "Orientations: $ORIENTATIONS"

# Launch screen/storyboard:
LAUNCH=$(plutil -extract UILaunchStoryboardName raw Info.plist 2>/dev/null || \
         plutil -extract UILaunchImages raw Info.plist 2>/dev/null)
echo "Launch: $LAUNCH"

# Status bar configuration:
STATUS_BAR=$(plutil -extract UIStatusBarHidden raw Info.plist 2>/dev/null)
echo "Status Bar Hidden: $STATUS_BAR"

# Complete metadata extraction script:
cat > extract_metadata.sh << 'SCRIPT'
#!/bin/bash
PLIST="$1"

cat << EOF
====================================
iOS Application Metadata
====================================

Application Information:
  Bundle ID: $(plutil -extract CFBundleIdentifier raw "$PLIST" 2>/dev/null)
  Display Name: $(plutil -extract CFBundleDisplayName raw "$PLIST" 2>/dev/null || plutil -extract CFBundleName raw "$PLIST" 2>/dev/null)
  Version: $(plutil -extract CFBundleShortVersionString raw "$PLIST" 2>/dev/null)
  Build: $(plutil -extract CFBundleVersion raw "$PLIST" 2>/dev/null)
  
Platform Requirements:
  Minimum iOS: $(plutil -extract MinimumOSVersion raw "$PLIST" 2>/dev/null || echo "Not specified")
  Device Families: $(plutil -extract UIDeviceFamily json "$PLIST" 2>/dev/null | jq -r 'join(", ")' || echo "Not specified")
  
Security:
  Requires iPhone OS: $(plutil -extract LSRequiresIPhoneOS raw "$PLIST" 2>/dev/null || echo "false")
  Supports Secure Coding: $(plutil -extract NSSupportsSecureCoding raw "$PLIST" 2>/dev/null || echo "false")

====================================
EOF
SCRIPT

chmod +x extract_metadata.sh
./extract_metadata.sh Info.plist

iOS Filesystem and Code Analysis
#

Filesystem Analysis
#

1. Comprehensive File Discovery:
#

# Navigate to extracted IPA contents:
cd Payload/*.app/

# 1. List all files with metadata:
find . -type f -exec ls -lh {} \; | sort -k5 -h
# Shows files sorted by size

# 2. Identify file types:
find . -type f -exec file {} \; | grep -v "ASCII text" | sort -u
# Shows non-text files (binaries, images, databases, etc.)

# 3. Search for sensitive file types:
find . -type f \( \
  -name "*.plist" -o \
  -name "*.sqlite" -o \
  -name "*.db" -o \
  -name "*.realm" -o \
  -name "*.pem" -o \
  -name "*.crt" -o \
  -name "*.cer" -o \
  -name "*.p12" -o \
  -name "*.key" -o \
  -name "*.keystore" -o \
  -name "*.jks" -o \
  -name "*.json" -o \
  -name "*.xml" -o \
  -name "*.conf" -o \
  -name "*.config" -o \
  -name "*.properties" \
\) -ls

# 4. Find configuration files:
find . -type f -name "*config*" -o -name "*settings*" -o -name "*preferences*"

# 5. Database files analysis:
find . -name "*.sqlite" -o -name "*.db" | while read db; do
    echo "[*] Database: $db"
    sqlite3 "$db" ".tables" 2>/dev/null || echo "  [!] Not a valid SQLite database"
    echo "  Size: $(ls -lh "$db" | awk '{print $5}')"
    echo
done

# 6. Identify encrypted/obfuscated files:
find . -type f -exec file {} \; | grep -i "encrypted\|data"

# 7. Look for backup files (potential data leaks):
find . -type f \( -name "*.bak" -o -name "*.backup" -o -name "*~" -o -name "*.old" \)

# 8. Check for development/debug artifacts:
find . -type f \( \
  -name "*.log" -o \
  -name "*.txt" -o \
  -name "*.md" -o \
  -name "README*" -o \
  -name "TODO*" -o \
  -name ".DS_Store" \
\)

2. Search for Hardcoded Secrets:
#

# 1. Search for common secret patterns in all text files:
grep -r -n -i -E "(password|passwd|pwd)[ ]*[:=][ ]*['\"][^'\"]{3,}" . 2>/dev/null | \
  grep -v ".png\|.jpg\|.jpeg\|.gif\|.ttf\|.otf"

# 2. API Keys and Tokens (comprehensive patterns):
cat > search_secrets.sh << 'SCRIPT'
#!/bin/bash
# Modern secret pattern detection

SEARCH_DIR="${1:-.}"
OUTPUT="secrets_found.txt"

echo "[*] Searching for hardcoded secrets in: $SEARCH_DIR"
echo "[*] Results will be saved to: $OUTPUT"
echo

> "$OUTPUT"  # Clear output file

# AWS Keys
echo "[*] Searching for AWS keys..."
grep -r -n -E "AKIA[0-9A-Z]{16}" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Generic API Keys (various formats)
echo "[*] Searching for generic API keys..."
grep -r -n -i -E "(api[_-]?key|apikey|api[_-]?secret)[ ]*[:=][ ]*['\"][a-zA-Z0-9_\-]{20,}['\"]" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Firebase
echo "[*] Searching for Firebase credentials..."
grep -r -n -i -E "firebase[_-]?(api|key|secret|url|database)" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"
find "$SEARCH_DIR" -name "GoogleService-Info.plist" -o -name "google-services.json" | tee -a "$OUTPUT"

# OAuth/JWT Secrets
echo "[*] Searching for OAuth/JWT secrets..."
grep -r -n -i -E "(client[_-]?secret|oauth[_-]?secret|jwt[_-]?secret)[ ]*[:=]" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Private Keys
echo "[*] Searching for private keys..."
grep -r -n "-----BEGIN.*PRIVATE KEY-----" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"
grep -r -n "-----BEGIN RSA PRIVATE KEY-----" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Database Credentials
echo "[*] Searching for database credentials..."
grep -r -n -i -E "(db[_-]?password|database[_-]?password|mysql[_-]?password|postgres[_-]?password)[ ]*[:=]" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Connection Strings
echo "[*] Searching for connection strings..."
grep -r -n -E "(mongodb://|postgresql://|mysql://|jdbc:)" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Slack Tokens
echo "[*] Searching for Slack tokens..."
grep -r -n -E "xox[baprs]-[0-9a-zA-Z]{10,}" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Stripe Keys
echo "[*] Searching for Stripe keys..."
grep -r -n -E "(sk|pk)_(test|live)_[0-9a-zA-Z]{24,}" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# GitHub Tokens
echo "[*] Searching for GitHub tokens..."
grep -r -n -E "gh[pousr]_[A-Za-z0-9_]{36,}" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Twilio
echo "[*] Searching for Twilio credentials..."
grep -r -n -E "AC[a-z0-9]{32}" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Passwords (various formats)
echo "[*] Searching for hardcoded passwords..."
grep -r -n -i -E "(password|passwd|pwd)[ ]*[:=][ ]*['\"][^'\"]{3,}['\"]" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Bearer Tokens
echo "[*] Searching for bearer tokens..."
grep -r -n -i "bearer [a-zA-Z0-9_\-\.]{20,}" "$SEARCH_DIR" 2>/dev/null | tee -a "$OUTPUT"

# Generic Base64 Secrets (potential encoded credentials)
echo "[*] Searching for Base64 encoded data (potential secrets)..."
grep -r -n -E "['\"][A-Za-z0-9+/]{40,}={0,2}['\"]" "$SEARCH_DIR" 2>/dev/null | \
  head -20 | tee -a "$OUTPUT"

# Hex-encoded keys (32+ chars)
echo "[*] Searching for hex-encoded keys..."
grep -r -n -E "['\"][0-9a-fA-F]{32,}['\"]" "$SEARCH_DIR" 2>/dev/null | \
  head -20 | tee -a "$OUTPUT"

echo
echo "[+] Search complete! Results in: $OUTPUT"
echo "[*] Total findings: $(wc -l < "$OUTPUT")"
SCRIPT

chmod +x search_secrets.sh
./search_secrets.sh .

3. URL and Endpoint Discovery:
#

# Find all HTTP/HTTPS URLs:
grep -r -h -o -E "https?://[a-zA-Z0-9./?=_&%-]+" . 2>/dev/null | \
  sort -u > discovered_urls.txt

# Find API endpoints:
grep -r -h -o -E "https?://[a-zA-Z0-9.-]+/api/[a-zA-Z0-9./?=_&%-]+" . 2>/dev/null | \
  sort -u > api_endpoints.txt

# Find internal/development URLs:
grep -r -i -E "(localhost|127\.0\.0\.1|192\.168\.|10\.|172\.16\.|dev\.|staging\.|test\.)" . 2>/dev/null | \
  grep -E "https?://" > internal_urls.txt

# Extract unique domains:
cat discovered_urls.txt | \
  sed -E 's|https?://([^/]+).*|\1|' | \
  sort -u > domains.txt

# Check for development/debug endpoints:
grep -i -E "(debug|test|staging|dev|admin|internal)" discovered_urls.txt

# URL discovery with categorization:
cat > analyze_urls.sh << 'SCRIPT'
#!/bin/bash
SEARCH_DIR="${1:-.}"

echo "[*] Discovering URLs and endpoints..."

# Extract all URLs
grep -r -h -o -E "https?://[a-zA-Z0-9./?=_&%-]+" "$SEARCH_DIR" 2>/dev/null | \
  sort -u > all_urls.txt

# Categorize URLs
echo "[*] Categorizing URLs..."

grep -i "api" all_urls.txt > api_urls.txt
grep -E "(localhost|127\.0\.0\.1|192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.)" all_urls.txt > internal_urls.txt
grep -i -E "(dev|staging|test|debug)" all_urls.txt > dev_urls.txt
grep -i -E "(admin|console|dashboard|panel)" all_urls.txt > admin_urls.txt
grep "http://" all_urls.txt > http_urls.txt  # Insecure HTTP

echo "[+] URL Discovery Results:"
echo "  Total URLs: $(wc -l < all_urls.txt)"
echo "  API endpoints: $(wc -l < api_urls.txt)"
echo "  Internal URLs: $(wc -l < internal_urls.txt)"
echo "  Dev/Test URLs: $(wc -l < dev_urls.txt)"
echo "  Admin URLs: $(wc -l < admin_urls.txt)"
echo "  Insecure HTTP: $(wc -l < http_urls.txt)"

# Extract unique domains
sed -E 's|https?://([^/:]+).*|\1|' all_urls.txt | sort -u > domains.txt
echo "  Unique domains: $(wc -l < domains.txt)"
echo
echo "[*] Files created: all_urls.txt, api_urls.txt, internal_urls.txt, domains.txt"
SCRIPT

chmod +x analyze_urls.sh
./analyze_urls.sh .

4. Email Address Discovery:
#

# Extract email addresses:
grep -r -h -o -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" . 2>/dev/null | \
  sort -u > emails.txt

# Categorize emails:
grep -E "@(gmail|yahoo|hotmail|outlook)\.com" emails.txt > personal_emails.txt
grep -v -E "@(gmail|yahoo|hotmail|outlook)\.com" emails.txt > company_emails.txt

echo "[*] Email Discovery:"
echo "  Total emails: $(wc -l < emails.txt)"
echo "  Personal: $(wc -l < personal_emails.txt)"
echo "  Company: $(wc -l < company_emails.txt)"

5. Cryptographic Material Search:#

# Search for crypto-related terms and potential keys:
grep -r -n -i -E "(encrypt|decrypt|cipher|crypto|aes|des|rsa|sha|md5|hmac)" . 2>/dev/null | \
  grep -v ".png\|.jpg\|Binary" | \
  head -50 > crypto_references.txt

# Search for initialization vectors (IVs):
grep -r -n -i "iv[ ]*[:=]" . 2>/dev/null

# Search for encryption keys:
grep -r -n -i -E "(encryption[_-]?key|cipher[_-]?key|secret[_-]?key)[ ]*[:=]" . 2>/dev/null

# Search for key derivation:
grep -r -n -i -E "pbkdf2|scrypt|argon2|bcrypt" . 2>/dev/null

# Find certificate files:
find . -type f \( -name "*.pem" -o -name "*.crt" -o -name "*.cer" -o -name "*.p12" -o -name "*.pfx" \) -exec ls -lh {} \;

6. Database Query Pattern Search (SQL Injection vectors):
#

# Search for SQL queries:
grep -r -n -i -E "(select|insert|update|delete|drop|create table)[ ]+.*(from|into|set|where)" . 2>/dev/null | \
  grep -v ".png\|Binary" | \
  head -30 > sql_queries.txt

# Search for string concatenation in queries (potential SQL injection):
grep -r -n -E "\\+.*['\"].*SELECT|SELECT.*\\+|stringWithFormat.*SELECT" . 2>/dev/null

# Search for dynamic query construction:
grep -r -n -i "executeQuery\|rawQuery\|execSQL" . 2>/dev/null

Plist Files Analysis
#

Analyze All Plist Files:
#

# Find all plist files:
find . -name "*.plist" -type f > plist_files.txt

# Analyze each plist:
cat > analyze_plists.sh << 'SCRIPT'
#!/bin/bash

echo "[*] Analyzing all plist files..."
echo

find . -name "*.plist" -type f | while read plist; do
    echo "=== $plist ==="
    
    # Check if binary or XML
    if file "$plist" | grep -q "binary"; then
        echo "[*] Binary plist - converting to XML"
        plutil -convert xml1 "$plist" -o "${plist}.xml" 2>/dev/null
        PLIST_TO_READ="${plist}.xml"
    else
        PLIST_TO_READ="$plist"
    fi
    
    # Display contents
    plutil -p "$PLIST_TO_READ" 2>/dev/null || cat "$PLIST_TO_READ"
    
    # Check for sensitive data
    if grep -i -q "password\|secret\|key\|token\|api" "$PLIST_TO_READ" 2>/dev/null; then
        echo "[!] ALERT: Potential sensitive data found!"
    fi
    
    echo
done
SCRIPT

chmod +x analyze_plists.sh
./analyze_plists.sh | tee plist_analysis.txt

Common Plist Files to Examine:
#

# 1. Main Info.plist (already covered)
cat Info.plist

# 2. Preferences plist (app settings):
find . -path "*/Library/Preferences/*.plist"

# 3. UserDefaults plist:
# At runtime: /var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/<bundle-id>.plist

# 4. Configuration plists:
find . -name "*config*.plist" -o -name "*settings*.plist"

# 5. Localization plists:
find . -name "Localizable.strings" -o -name "InfoPlist.strings"

# 6. Firebase configuration (common in modern apps):
find . -name "GoogleService-Info.plist"
if [ -f "GoogleService-Info.plist" ]; then
    echo "[!] Firebase configuration found - check for sensitive data:"
    plutil -p GoogleService-Info.plist | grep -i -E "api_key|project_id|database_url"
fi

React Native Bundle Analysis
#

Detect React Native Applications:
#

# Check for React Native indicators:
find . -name "main.jsbundle" -o -name "*.bundle" -o -name "index.*.bundle"

# Check for React Native frameworks:
find . -path "*/Frameworks/React.framework" -o -path "*/Frameworks/React-Core.framework"

# Verify if React Native:
if [ -f "main.jsbundle" ] || [ -d "Frameworks/React.framework" ]; then
    echo "[+] React Native app detected"
else
    echo "[-] Not a React Native app"
fi

Decompile React Native Bundle:
#

# Method 1: Using react-native-decompiler (Modern, Recommended)
# Install:
npm install -g @react-native-community/cli react-native-decompiler

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

# Alternative with specific options:
npx react-native-decompiler \
  --input main.jsbundle \
  --output ./decompiled_js \
  --verbose

# Method 2: Manual extraction for Hermes bytecode (newer RN versions)
# Hermes is React Native's optimized JavaScript engine

# Check if bundle is Hermes bytecode:
file main.jsbundle
# If shows "Hermes JavaScript bytecode", need different approach

# Decompile Hermes bytecode:
# Install hermes-dec:
npm install -g hermes-dec

# Decompile:
hermes-dec main.jsbundle -o decompiled_hermes.js

# Method 3: Using hbctool (Hermes Bytecode Toolkit)
git clone https://github.com/bongtrop/hbctool.git
cd hbctool
pip3 install -r requirements.txt

# Disassemble Hermes bytecode:
python3 hbctool.py disasm ../main.jsbundle ../disassembled.hasm

# Decompile (experimental):
python3 hbctool.py decompile ../main.jsbundle ../decompiled_output/

# Method 4: Using react-native-bundle-visualizer (analyze, not decompile)
npx react-native-bundle-visualizer main.jsbundle
# Opens browser with bundle composition analysis

Analyze Decompiled React Native Code:
#

cd decompiled_js/

# 1. Find sensitive data in decompiled JS:
grep -r -n -i -E "(api[_-]?key|secret|password|token)[ ]*[:=]" . | \
  head -30 > rn_secrets.txt

# 2. Find API endpoints:
grep -r -h -o -E "https?://[a-zA-Z0-9./?=_&%-]+" . | \
  sort -u > rn_api_endpoints.txt

# 3. Find AsyncStorage usage (React Native's local storage):
grep -r -n "AsyncStorage\.\(setItem\|getItem\|multiSet\)" . | \
  head -20 > rn_async_storage.txt

# 4. Find fetch/network calls:
grep -r -n -E "fetch\(|axios\.|XMLHttpRequest" . | \
  head -30 > rn_network_calls.txt

# 5. Find authentication/auth patterns:
grep -r -n -i -E "(login|authenticate|auth[^a-z]|token|bearer)" . | \
  head -30 > rn_auth_patterns.txt

# 6. Find navigation/routing (potential for deep link issues):
grep -r -n "NavigationContainer\|createStackNavigator\|navigate\(" . | \
  head -20

# 7. Search for crypto operations:
grep -r -n -i -E "crypto|encrypt|decrypt|cipher|hash" . | \
  head -20

# 8. Find environment configs:
grep -r -n -E "process\.env\|__DEV__|Config\." . | \
  head -20 > rn_config.txt

# Comprehensive React Native analysis script:
cat > analyze_react_native.sh << 'SCRIPT'
#!/bin/bash
RN_DIR="${1:-.}"

echo "[*] Analyzing React Native code in: $RN_DIR"
echo

# API endpoints
echo "[*] Extracting API endpoints..."
grep -r -h -o -E "https?://[a-zA-Z0-9./?=_&%-]+" "$RN_DIR" 2>/dev/null | \
  sort -u > rn_endpoints.txt
echo "  Found $(wc -l < rn_endpoints.txt) unique endpoints"

# Secrets
echo "[*] Searching for secrets..."
grep -r -n -i -E "(api[_-]?key|apikey|secret|password|token)[ ]*[:=]" "$RN_DIR" 2>/dev/null | \
  head -50 > rn_secrets.txt
echo "  Found $(wc -l < rn_secrets.txt) potential secrets"

# AsyncStorage usage
echo "[*] Finding AsyncStorage usage..."
grep -r -n "AsyncStorage\." "$RN_DIR" 2>/dev/null > rn_storage.txt
echo "  Found $(wc -l < rn_storage.txt) AsyncStorage references"

# Network calls
echo "[*] Finding network requests..."
grep -r -n -E "fetch\(|axios\.|XMLHttpRequest|HttpClient" "$RN_DIR" 2>/dev/null > rn_network.txt
echo "  Found $(wc -l < rn_network.txt) network call references"

# Authentication patterns
echo "[*] Finding authentication patterns..."
grep -r -n -i -E "login|authenticate|authorization|bearer|jwt" "$RN_DIR" 2>/dev/null | \
  head -30 > rn_auth.txt
echo "  Found $(wc -l < rn_auth.txt) auth-related references"

# Deep links / navigation
echo "[*] Finding navigation and deep links..."
grep -r -n -E "Linking\.(openURL|getInitialURL)|navigate\(|createStackNavigator" "$RN_DIR" 2>/dev/null > rn_navigation.txt
echo "  Found $(wc -l < rn_navigation.txt) navigation references"

echo
echo "[+] Analysis complete! Check generated files:"
echo "  - rn_endpoints.txt"
echo "  - rn_secrets.txt"
echo "  - rn_storage.txt"
echo "  - rn_network.txt"
echo "  - rn_auth.txt"
echo "  - rn_navigation.txt"
SCRIPT

chmod +x analyze_react_native.sh
./analyze_react_native.sh decompiled_js/

Swift/SwiftUI Specific Analysis
#

Analyze Swift Code (Modern iOS Development):
#

# Swift apps may have different structure than Objective-C

# 1. Check for Swift usage:
otool -L Payload/*.app/* | grep -i swift
# Or:
nm Payload/*.app/* | grep -i swift | head -20

# 2. Extract Swift class names (Swift uses name mangling):
nm Payload/*.app/* | grep "^_\$s" | head -50 > swift_symbols.txt

# 3. Demangle Swift symbols for readability:
# Install swift-demangle (part of Swift toolchain)
# macOS with Xcode: /usr/bin/swift-demangle
cat swift_symbols.txt | swift-demangle > demangled_swift_symbols.txt

# 4. Look for SwiftUI indicators:
nm Payload/*.app/* | grep -i "swiftui"

# 5. Extract Swift metadata:
otool -s __TEXT __swift5_fieldmd Payload/*.app/* | strings

# 6. Modern Swift string analysis:
# Swift 5.7+ uses new string representation
strings Payload/*.app/* | grep -E "^[a-zA-Z0-9/_.-]{10,}" | \
  sort -u > extracted_strings.txt

# Check for sensitive strings:
grep -i -E "password|secret|key|token|api" extracted_strings.txt

Swift-Specific Security Patterns:
#

# 1. Search for UserDefaults (Swift equivalent of NSUserDefaults):
nm Payload/*.app/* | grep -i "userdefaults"

# 2. Search for Keychain access:
nm Payload/*.app/* | grep -i "keychain"

# 3. Search for Combine framework (reactive programming):
nm Payload/*.app/* | grep -i "combine"

# 4. Search for async/await patterns (Swift 5.5+):
nm Payload/*.app/* | grep -i "async"

# 5. Check for Swift Concurrency:
nm Payload/*.app/* | grep -i "task\|actor"

Advanced Pattern Matching with Ripgrep
#

# Install ripgrep (faster than grep for large codebases):
# macOS: brew install ripgrep
# Linux: sudo apt install ripgrep
# Or download from: https://github.com/BurntSushi/ripgrep/releases

# Ripgrep advantages: faster, better Unicode support, respects .gitignore

# 1. Search for API keys with context:
rg -i "api[_-]?key" --context 2

# 2. Search for secrets with file type filtering:
rg -i "(password|secret|token)" -t plist -t json

# 3. Search for URLs:
rg -o "https?://[a-zA-Z0-9./?=_&%-]+" | sort -u

# 4. Search with regex patterns (more powerful):
rg "AKIA[0-9A-Z]{16}"  # AWS keys
rg "xox[baprs]-[0-9]{10,}"  # Slack tokens
rg "sk_live_[0-9a-zA-Z]{24,}"  # Stripe keys

# 5. Search excluding binary files:
rg -t txt -t json -t plist "password"

# 6. Case-insensitive search with line numbers:
rg -i -n "firebase"

# 7. Search for multiple patterns:
rg -e "api_key" -e "api_secret" -e "access_token"

# 8. Search with custom file types:
rg --type-add 'ios:*.{m,mm,swift,h}' -t ios "NSUserDefaults"

Automated Secret Scanning with Modern Tools
#

Using TruffleHog (Git Secret Scanner):
#

# Install TruffleHog:
pip3 install truffleHog

# Scan extracted IPA directory:
trufflehog --regex --entropy=True file://Payload/Instagram.app/ > trufflehog_results.json

# With custom regexes:
cat > custom_regexes.json << 'JSON'
{
  "Firebase API Key": "AIza[0-9A-Za-z\\-_]{35}",
  "AWS Access Key": "AKIA[0-9A-Z]{16}",
  "Slack Token": "xox[baprs]-[0-9]{10,}",
  "Generic API Key": "[a|A][p|P][i|I][_]?[k|K][e|E][y|Y].*['|\"][0-9a-zA-Z]{32,45}['|\"]"
}
JSON

trufflehog --regex --rules custom_regexes.json file://Payload/Instagram.app/

Using Gitleaks:
#

# Install Gitleaks:
# macOS: brew install gitleaks
# Linux: Download from https://github.com/zricethezav/gitleaks/releases

# Scan directory:
gitleaks detect --source Payload/Instagram.app/ --report-path gitleaks_report.json --verbose

# With custom rules:
cat > gitleaks.toml << 'TOML'
title = "iOS App Secret Detection"

[[rules]]
id = "firebase-api-key"
description = "Firebase API Key"
regex = '''AIza[0-9A-Za-z\-_]{35}'''

[[rules]]
id = "aws-access-key"
description = "AWS Access Key"
regex = '''AKIA[0-9A-Z]{16}'''

[[rules]]
id = "generic-api-key"
description = "Generic API Key"
regex = '''[a|A][p|P][i|I][_-]?[k|K][e|E][y|Y].*['"][0-9a-zA-Z]{20,}['"]'''

[[rules]]
id = "stripe-key"
description = "Stripe API Key"
regex = '''(sk|pk)_(test|live)_[0-9a-zA-Z]{24,}'''
TOML

gitleaks detect --config gitleaks.toml --source Payload/Instagram.app/ --report-path report.json

Using Semgrep (Semantic Code Analysis):
#

# Install Semgrep:
pip3 install semgrep

# Scan for iOS-specific patterns:
semgrep --config "p/mobsf" Payload/Instagram.app/

# Custom iOS security rules:
cat > ios_security_rules.yaml << 'YAML'
rules:
  - id: hardcoded-api-key
    pattern: |
      let $KEY = "$VALUE"
    pattern-where:
      - metavariable: $KEY
        regex: (api[_-]?key|apikey)
    message: "Hardcoded API key detected"
    severity: ERROR
    languages:
      - swift

  - id: nsuserdefaults-sensitive
    pattern: |
      UserDefaults.standard.set($VALUE, forKey: $KEY)
    pattern-where:
      - metavariable: $KEY
        regex: (password|token|secret)
    message: "Sensitive data stored in UserDefaults"
    severity: WARNING
    languages:
      - swift

  - id: insecure-http-url
    pattern: |
      URL(string: "http://$URL")
    message: "Insecure HTTP URL detected"
    severity: WARNING
    languages:
      - swift
YAML

semgrep --config ios_security_rules.yaml Payload/Instagram.app/

Framework and Library Analysis
#

Identify Third-Party Frameworks:
#

# List all frameworks:
find . -name "*.framework" -type d

# For each framework, get info:
find . -name "*.framework" -type d | while read fw; do
    echo "=== $(basename "$fw") ==="
    
    # Framework version (if available):
    INFO_PLIST="$fw/Info.plist"
    if [ -f "$INFO_PLIST" ]; then
        echo "  Version: $(plutil -extract CFBundleShortVersionString raw "$INFO_PLIST" 2>/dev/null || echo 'N/A')"
        echo "  Bundle ID: $(plutil -extract CFBundleIdentifier raw "$INFO_PLIST" 2>/dev/null || echo 'N/A')"
    fi
    
    # Framework binary (if exists):
    FW_BINARY="$fw/$(basename "$fw" .framework)"
    if [ -f "$FW_BINARY" ]; then
        echo "  Architecture: $(lipo -info "$FW_BINARY" 2>/dev/null | cut -d: -f3 || echo 'N/A')"
    fi
    
    echo
done > framework_inventory.txt

cat framework_inventory.txt

Check for Known Vulnerable Libraries:
#

# Common vulnerable iOS libraries to check:

# 1. AFNetworking (check version)
if find . -name "AFNetworking" -type d | grep -q .; then
    echo "[!] AFNetworking detected - check version for CVEs"
    # Versions < 4.0 have known vulnerabilities
fi

# 2. Alamofire (check version)
if find . -name "Alamofire" -type d | grep -q .; then
    echo "[!] Alamofire detected - check version"
fi

# 3. Firebase SDK (check version)
if find . -name "Firebase*" -type d | grep -q .; then
    echo "[!] Firebase SDK detected"
    find . -name "Firebase*" -type d | while read fw; do
        INFO="$fw/Info.plist"
        if [ -f "$INFO" ]; then
            VERSION=$(plutil -extract CFBundleShortVersionString raw "$INFO" 2>/dev/null)
            echo "  - $(basename "$fw"): $VERSION"
        fi
    done
fi

# 4. Facebook SDK (privacy concerns)
if find . -name "Facebook*" -type d | grep -q .; then
    echo "[!] Facebook SDK detected - potential privacy concerns"
fi

# 5. Realm (check version)
if find . -name "Realm*" -type d | grep -q .; then
    echo "[!] Realm database detected"
fi

# 6. OpenSSL (check for Heartbleed and other CVEs)
if find . -name "*OpenSSL*" -type d | grep -q .; then
    echo "[!] OpenSSL detected - check for vulnerabilities"
fi

# Create comprehensive framework report:
cat > analyze_frameworks.sh << 'SCRIPT'
#!/bin/bash

echo "iOS Framework Security Analysis"
echo "================================"
echo

# Find all frameworks
FRAMEWORKS=$(find . -name "*.framework" -type d)

if [ -z "$FRAMEWORKS" ]; then
    echo "No frameworks found"
    exit 0
fi

echo "$FRAMEWORKS" | while read fw; do
    FW_NAME=$(basename "$fw" .framework)
    echo "Framework: $FW_NAME"
    
    INFO="$fw/Info.plist"
    if [ -f "$INFO" ]; then
        VERSION=$(plutil -extract CFBundleShortVersionString raw "$INFO" 2>/dev/null || echo "Unknown")
        BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw "$INFO" 2>/dev/null || echo "Unknown")
        echo "  Version: $VERSION"
        echo "  Bundle ID: $BUNDLE_ID"
        
        # Check for known vulnerable frameworks
        case "$FW_NAME" in
            "AFNetworking")
                echo "  [!] Check CVEs for AFNetworking $VERSION"
                echo "      Known vulnerabilities in versions < 4.0"
                ;;
            "OpenSSL"|"libssl")
                echo "  [!] Check for Heartbleed and other OpenSSL CVEs"
                ;;
            "Facebook"*)
                echo "  [!] Privacy concerns - Facebook SDK tracks user data"
                ;;
            "Firebase"*)
                echo "  [!] Ensure Firebase credentials are not exposed"
                ;;
        esac
    fi
    
    # Check binary
    BINARY="$fw/$FW_NAME"
    if [ -f "$BINARY" ]; then
        ARCH=$(lipo -info "$BINARY" 2>/dev/null | cut -d: -f3)
        echo "  Architectures: $ARCH"
        
        # Check for symbols that might indicate vulnerabilities
        if nm "$BINARY" 2>/dev/null | grep -q -i "strcpy\|strcat\|sprintf"; then
            echo "  [!] WARNING: Unsafe string functions detected"
        fi
    fi
    
    echo
done
SCRIPT

chmod +x analyze_frameworks.sh
./analyze_frameworks.sh

Asset Analysis
#

Analyze Assets.car (Compiled Asset Catalog):
#

# Assets.car contains all images, colors, and other resources
# Extract using acextract (part of iOS-artwork-extractor)

# Method 1: Using acextract
# Install: brew install acextract
acextract -i Assets.car -o extracted_assets/

# Method 2: Using Asset Catalog Tinkerer (GUI, macOS only)
# Download from: https://github.com/insidegui/AssetCatalogTinkerer

# Method 3: Manual with cartool
git clone https://github.com/steventroughtonsmith/cartool.git
cd cartool
make
./cartool ../Assets.car ../extracted_assets/

# Analyze extracted assets:
cd extracted_assets/

# Look for interesting images:
ls -lh *.png | head -20

# Search for screenshots (may contain sensitive data):
find . -name "*screenshot*" -o -name "*demo*" -o -name "*test*"

# Search for logos/branding:
find . -name "*logo*" -o -name "*icon*" -o -name "*brand*"

# Check metadata in images:
exiftool *.png | grep -E "(Author|Creator|Copyright|Software)"

Analyze Storyboards and XIBs:
#

# Storyboards contain UI layout information
# Can reveal app flow, features, hidden screens

# Find all storyboards:
find . -name "*.storyboard" -o -name "*.xib"

# Storyboards are XML, can be analyzed directly:
cat > analyze_storyboards.sh << 'SCRIPT'
#!/bin/bash

echo "[*] Analyzing storyboards..."

find . -name "*.storyboard" | while read sb; do
    echo "=== $(basename "$sb") ==="
    
    # Extract view controller names:
    grep "customClass=" "$sb" | sed 's/.*customClass="\([^"]*\)".*/\1/' | sort -u
    
    # Look for interesting UI elements:
    if grep -q "textField" "$sb"; then
        echo "  [*] Contains text fields (potential input fields)"
    fi
    
    if grep -q "webView" "$sb"; then
        echo "  [*] Contains web view (potential web content)"
    fi
    
    if grep -q -i "password" "$sb"; then
        echo "  [!] Contains password field"
    fi
    
    echo
done
SCRIPT

chmod +x analyze_storyboards.sh
./analyze_storyboards.sh

Strings Analysis
#

Extract and Analyze All Strings:
#

# Extract strings from main binary:
strings Payload/*.app/YourApp > all_strings.txt

# Categorize strings:

# 1. URLs and endpoints:
grep -E "https?://" all_strings.txt | sort -u > string_urls.txt

# 2. File paths:
grep -E "^(/[a-zA-Z0-9_/-]+|~/|\.\./).*" all_strings.txt | sort -u > string_paths.txt

# 3. Potential secrets (uppercase alphanumeric 20+ chars):
grep -E "^[A-Z0-9]{20,}$" all_strings.txt > string_potential_keys.txt

# 4. Email-like strings:
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" all_strings.txt | sort -u > string_emails.txt

# 5. SQL-like strings:
grep -i -E "select|insert|update|delete|from|where" all_strings.txt | head -30 > string_sql.txt

# 6. Crypto-related:
grep -i -E "encrypt|decrypt|cipher|aes|rsa|sha|md5|key|iv|salt" all_strings.txt > string_crypto.txt

# 7. Class/method names (camelCase):
grep -E "^[a-z]+[A-Z][a-zA-Z0-9]*$" all_strings.txt | sort -u > string_methods.txt