Mobile VAPT Notes (iOS)#
Environment Setup#
Jailbreaking iOS Device#
Online Check: Use https://canijailbreak.com/ or https://ios.cfw.guide/ to determine jailbreak availability.
Modern Jailbreak Tools (2024-2025):
- Palera1n: iOS 15.0-17.4 (A11 and older), checkm8-based, semi-tethered
- Dopamine: iOS 15.0-16.6.1 (A12-A15, rootless on iOS 15.0-15.4.1)
- XinaA15: iOS 15.0-15.1.1 (A12-A15)
- Fugu15: iOS 15.0-15.1.1 (research jailbreak, rootful)
- TrollStore: iOS 14.0-16.6.1 (CoreTrust bypass, permanent IPA signing)
- Serotonin: iOS 16.0-16.6.1 (arm64e devices)
Critical Note: iOS 17.0+ has significantly enhanced security. Many modern apps detect jailbreaks more effectively. Consider using TrollStore for persistence when available.
Jailbreak Steps:
- Backup device - Always create encrypted iTunes/Finder backup before proceeding
- Download appropriate jailbreak tool for iOS version/device
- For checkm8-based jailbreaks: Boot device into DFU mode, connect via USB
- For semi-untethered: Sideload IPA via AltStore/Sideloadly, sign with Apple ID
- Execute jailbreak application, wait for respring
- Install package manager (Sileo recommended over Cydia for modern iOS)
OPSEC Considerations:
- Disable automatic iOS updates: Settings → General → Software Update → Automatic Updates
- Use burner Apple ID for sideloading to avoid primary account issues
- Document jailbreak method and iOS version for reproducibility
Installing Essential Tools on Jailbroken iOS Device#
Adding Repositories (Sileo/Zebra preferred for iOS 15+):#
# Essential modern repositories:
https://havoc.app/ # Havoc Repo (modern, maintained)
https://build.frida.re # Official Frida builds
https://repo.chariz.com/ # Chariz (well-maintained tweaks)
https://ellekit.space/ # ElleKit (modern hooking framework)
https://apt.procurs.us/ # Procursus bootstrap (for modern jailbreaks)
https://repo.dynastic.co/ # Dynastic Repo
SSH Access Setup#
Install OpenSSH:#
Via Sileo/Zebra: Search “OpenSSH” and install latest version (v9.x+ recommended)
Security Configuration:#
# IMMEDIATE: Change default passwords (alpine) - THIS IS CRITICAL
ssh root@<iOS_DEVICE_IP> # Or via USB tunnel
# Change root password:
passwd root
# Use strong password (16+ characters, alphanumeric + symbols)
# Change mobile user password:
passwd mobile
# Harden SSH configuration (OPSEC):
nano /etc/ssh/sshd_config
# Add/modify these lines:
PermitRootLogin yes
PasswordAuthentication yes
PubkeyAuthentication yes
PermitEmptyPasswords no
AllowTcpForwarding yes
MaxAuthTries 3
LoginGraceTime 60
# Restart SSH:
launchctl unload /Library/LaunchDaemons/com.openssh.sshd.plist
launchctl load /Library/LaunchDaemons/com.openssh.sshd.plist
SSH via USB (Recommended for stability & OPSEC):#
# Install usbmuxd tools:
# macOS: brew install libimobiledevice
# Linux: sudo apt install usbmuxd libimobiledevice6 libimobiledevice-utils
# Windows: Use iproxy.exe from libimobiledevice-win
# Forward SSH port via USB (more stable than WiFi):
iproxy 2222 44 # Modern iOS uses port 44, not 22
# Connect via USB tunnel:
ssh root@localhost -p 2222
# For persistent connection (add to ~/.ssh/config):
cat >> ~/.ssh/config << 'EOF'
Host iphone-usb
HostName localhost
Port 2222
User root
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
EOF
# Connect with: ssh iphone-usb
# Forward additional ports for tools:
iproxy 8080 8080 & # Burp Suite proxy
iproxy 27042 27042 & # Frida server (default port)
iproxy 4444 4444 & # Custom tools/shells
# Kill all iproxy processes:
pkill -f iproxy
OPSEC Tip: Use USB tunneling in restrictive network environments where WiFi scanning might detect testing activities.
Frida Installation & Setup#
Method 1: Via Package Manager (Recommended)#
# Add Frida repository (if not already added):
# Sileo/Zebra: Add https://build.frida.re
# Install "Frida" package from repository
# Latest stable: 16.x series (as of 2024)
# Frida server auto-starts as LaunchDaemon
# Verify Frida is running:
ssh root@localhost -p 2222
ps aux | grep frida-server
# Should see: /usr/sbin/frida-server
# Check Frida version:
/usr/sbin/frida-server --version
Method 2: Manual Installation (For latest/beta versions)#
# Check device architecture:
ssh root@<iOS_DEVICE_IP> "uname -m"
# arm64 for iPhone 5s through iPhone 15 Pro Max
# Download latest Frida from GitHub:
# Visit: https://github.com/frida/frida/releases
# For arm64: frida-server-16.x.x-ios-arm64.xz
# On your computer:
wget https://github.com/frida/frida/releases/download/16.5.9/frida-server-16.5.9-ios-arm64.xz
unxz frida-server-16.5.9-ios-arm64.xz
# Transfer to device:
scp -P 2222 frida-server-16.5.9-ios-arm64 root@localhost:/usr/sbin/frida-server
# Set permissions and ownership:
ssh -p 2222 root@localhost << 'EOF'
chown root:wheel /usr/sbin/frida-server
chmod 755 /usr/sbin/frida-server
ldid -S /usr/sbin/frida-server # Sign binary (required on some jailbreaks)
EOF
# Create LaunchDaemon for persistence (survives reboot on semi-untethered JB):
ssh -p 2222 root@localhost << 'EOF'
cat > /Library/LaunchDaemons/re.frida.server.plist << 'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>re.frida.server</string>
<key>Program</key>
<string>/usr/sbin/frida-server</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/frida-server</string>
<string>-l</string>
<string>0.0.0.0:27042</string>
</array>
<key>UserName</key>
<string>root</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>5</integer>
</dict>
</plist>
PLIST
chmod 644 /Library/LaunchDaemons/re.frida.server.plist
launchctl load /Library/LaunchDaemons/re.frida.server.plist
EOF
# Verify Frida is running:
ssh -p 2222 root@localhost "ps aux | grep frida-server"
Install Frida Tools on Computer:#
# Install latest Frida tools (must match server version):
pip3 install frida-tools==16.5.9
# Or for latest:
pip3 install frida-tools --upgrade
# Verify installation and version:
frida --version
frida-ps --version
# Test connection via USB:
frida-ps -U
# Should list running processes
# Test connection via network:
frida-ps -H <iOS_DEVICE_IP>:27042
# List installed applications with bundle IDs:
frida-ps -Uai
# Enhanced process listing:
frida-ps -Uai | grep -v "Apple" # Filter out Apple apps
Frida Anti-Detection:#
# Many apps detect Frida. Rename server and change ports:
ssh -p 2222 root@localhost << 'EOF'
mv /usr/sbin/frida-server /usr/sbin/debugserver
# Update LaunchDaemon plist with new path and port
sed -i '' 's/frida-server/debugserver/g' /Library/LaunchDaemons/re.frida.server.plist
sed -i '' 's/27042/31337/g' /Library/LaunchDaemons/re.frida.server.plist
launchctl unload /Library/LaunchDaemons/re.frida.server.plist
launchctl load /Library/LaunchDaemons/re.frida.server.plist
EOF
# Connect to renamed Frida:
frida -H <iOS_DEVICE_IP>:31337 -f <bundle_id>
Additional Essential Tools#
Install via Package Manager:#
# Critical tools for iOS testing (install via Sileo/Zebra):
# - Filza File Manager (v4.x) - Full filesystem access with GUI
# - NewTerm 3 - Modern terminal emulator for iOS
# - AppSync Unified - Install unsigned IPAs
# - Liberty Lite (Beta) - Jailbreak detection bypass
# - Cr4shed - Detailed crash logs for debugging
# - CocoaTop - Process manager
# - PreferenceLoader - For tweak settings
# - ElleKit or libhooker - Modern hooking frameworks
# Alternative substrate: Substitute (for older jailbreaks) or ElleKit (modern)
MobSF Setup:#
# Modern approach: Use Docker (updated image, faster setup):
docker pull opensecurity/mobile-security-framework-mobsf:latest
# Run MobSF with persistent storage:
docker run -it --rm \
-p 8000:8000 \
-v "$(pwd)/mobsf-data:/home/mobsf/.MobSF" \
opensecurity/mobile-security-framework-mobsf:latest
# Access web interface: http://localhost:8000
# Default credentials: mobsf / mobsf (CHANGE IMMEDIATELY in production)
# Alternative: Direct installation (Python 3.11+ required):
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
cd Mobile-Security-Framework-MobSF
./setup.sh # Linux/macOS
# Follow prompts, install dependencies
# Run MobSF:
./run.sh # Linux/macOS
# Or: python manage.py runserver 0.0.0.0:8000
# For API access (automation):
# Generate API key in MobSF web interface → API Documentation
curl -X POST http://localhost:8000/api/v1/upload \
-H "Authorization: <YOUR_API_KEY>" \
-F "file=@app.ipa"
Objection Installation:#
# Install objection (Python 3.8+ required):
pip3 install objection --upgrade
# Verify installation:
objection version
# Should show v1.11.0 or later
# Basic usage with modern options:
objection -g <bundle_id> explore
# With startup scripts for automation:
objection -g <bundle_id> explore \
--startup-command "ios sslpinning disable" \
--startup-command "ios jailbreak disable"
# Quiet mode (less output, better for scripting):
objection -g <bundle_id> explore --quiet
# For API/automation:
objection -g <bundle_id> run "ios keychain dump --json" | jq .
Additional Useful Tools:#
# iOS device management (updated):
brew install libimobiledevice ideviceinstaller ios-deploy # macOS
sudo apt install libimobiledevice-tools ideviceinstaller # Linux
# Modern IPA installation:
ideviceinstaller -l # List installed apps with bundle IDs
ideviceinstaller -i app.ipa # Install IPA
ideviceinstaller -u <bundle_id> # Uninstall by bundle ID
# For debugging and syslog:
idevicesyslog # Stream device logs
idevicedebug run <bundle_id> # Launch app with debugger
# TrollStore (iOS 14.0-16.6.1) for permanent signing:
# Install via guide at: https://ios.cfw.guide/installing-trollstore/
# Drag and drop IPAs into TrollStore for permanent installation
# Alternative: Sideloadly (cross-platform GUI):
# Download from: https://sideloadly.io/
# Easier than Cydia Impactor, supports latest iOS
Modern Automation Script:#
#!/bin/bash
# ios_setup_automation.sh - One-command iOS pentest setup
set -e
DEVICE_IP="${1:-$(ideviceinfo | grep -m1 'WiFiAddress' | cut -d: -f2 | xargs)}"
FRIDA_VERSION="16.5.9"
echo "[*] Setting up iOS device at $DEVICE_IP for penetration testing..."
# Setup USB tunneling
echo "[*] Setting up USB port forwarding..."
pkill -f iproxy 2>/dev/null || true
iproxy 2222 44 &>/dev/null &
iproxy 8080 8080 &>/dev/null &
iproxy 27042 27042 &>/dev/null &
sleep 2
# Test SSH connectivity
echo "[*] Testing SSH connection..."
if ! ssh -p 2222 -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@localhost "echo connected" &>/dev/null; then
echo "[!] SSH connection failed. Ensure OpenSSH is installed and device is jailbroken."
exit 1
fi
echo "[+] SSH connection successful!"
# Check Frida
echo "[*] Checking Frida installation..."
if ssh -p 2222 root@localhost "ps aux | grep -v grep | grep frida-server" &>/dev/null; then
echo "[+] Frida server is running"
else
echo "[!] Frida server not detected. Install via Sileo or run manual installation."
fi
# Install Frida tools locally
echo "[*] Installing/updating Frida tools..."
pip3 install -q --upgrade frida-tools objection
echo "[+] Setup complete! Test with: frida-ps -U"
iOS Traffic Interception - Burp Suite Setup#
Traffic Interception (Burp Suite) Setup#
Step 1: Configure Burp Suite Proxy#
# In Burp Suite Professional/Community:
# 1. Proxy → Proxy Settings → Proxy Listeners → Add
# 2. Binding:
# - Bind to port: 8080
# - Bind to address: All interfaces (0.0.0.0)
# 3. Request handling:
# - ☑ Support invisible proxying (important for some iOS apps)
# 4. Click OK
# For advanced OPSEC (non-standard port):
# Use port 8443 or 3128 instead of 8080 to avoid detection
# Verify Burp is listening:
# Proxy → Proxy Settings → Proxy Listeners
# Should show: 0.0.0.0:8080 [Running]
# Get your computer's IP address:
# macOS: ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}'
# Linux: ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v 127.0.0.1
# Windows: ipconfig | findstr IPv4
Step 2: Configure iOS Device Proxy#
# Method 1: Manual WiFi Proxy (Standard)
# On iOS device:
# 1. Settings → Wi-Fi
# 2. Tap (i) icon next to connected network
# 3. Scroll to "HTTP Proxy" → Configure Proxy → Manual
# 4. Server: <YOUR_COMPUTER_IP>
# 5. Port: 8080
# 6. Authentication: OFF
# 7. Tap "Save"
# Method 2: Global Proxy via Command Line (Jailbroken, more persistent)
ssh -p 2222 root@localhost << 'EOF'
# Set HTTP/HTTPS proxy
activator send libactivator.system.set-http-proxy
# Or manually via defaults:
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPEnable integer 1" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPProxy <YOUR_COMPUTER_IP>" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPPort 8080" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPSEnable integer 1" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPSProxy <YOUR_COMPUTER_IP>" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPSPort 8080" \
/var/preferences/SystemConfiguration/preferences.plist
# Restart network services
killall -HUP configd
EOF
# Method 3: Using Surge/Shadowrocket (App-based, more flexible)
# Install Surge or Shadowrocket from App Store/Sileo
# Configure proxy rules for selective interception
# Useful for testing specific apps without global proxy
Step 3: Install Burp CA Certificate (Critical for iOS 15+)#
Modern Certificate Installation Process:#
# iOS 15+ has stricter certificate requirements
# Certificate must be properly installed AND trusted in two locations
# Method 1: Standard Safari Installation (Most Common)
# 1. Ensure device proxy is configured to point to Burp
# 2. On iOS device, open Safari
# 3. Navigate to: http://burp or http://burpsuite
# 4. Tap "CA Certificate" button
# 5. Dialog appears: "This website is trying to download a configuration profile"
# 6. Tap "Allow"
# 7. Settings app opens automatically → Profile Downloaded
# 8. Tap "Install" (may require passcode)
# 9. Warning appears about root certificate → Tap "Install" again
# 10. Tap "Done"
# CRITICAL SECOND STEP (often missed):
# 11. Settings → General → About → Certificate Trust Settings
# 12. Under "ENABLE FULL TRUST FOR ROOT CERTIFICATES"
# 13. Toggle ON: "PortSwigger CA"
# 14. Warning dialog → Tap "Continue"
# Verification:
# - Settings → General → VPN & Device Management → PortSwigger CA (should show "Verified")
# - Settings → General → About → Certificate Trust Settings (should show green toggle)
# If download doesn't work, browse to: http://<YOUR_COMPUTER_IP>:8080/
Method 2: Manual Certificate Installation (Backup Method)#
# Export certificate from Burp Suite:
# 1. In Burp: Proxy → Proxy Settings → Import / Export CA certificate
# 2. Select: "Certificate in DER format"
# 3. Save as: burp-ca.der
# Convert DER to PEM (required for some iOS versions):
openssl x509 -inform DER -in burp-ca.der -out burp-ca.pem -outform PEM
# Serve certificate via Python HTTP server:
python3 -m http.server 8000
# On iOS device Safari:
# Navigate to: http://<YOUR_COMPUTER_IP>:8000/burp-ca.der
# Follow installation steps as in Method 1
# Alternative: Email certificate to yourself and open on device
# Or: AirDrop certificate from Mac to iOS device
Method 3: Configuration Profile Creation (Advanced)#
# Create a configuration profile for enterprise deployment
# Useful for testing multiple devices or MDM scenarios
# Install Apple Configurator (macOS only) or use online generators
# Example using openssl + manual XML:
cat > burp-certificate-profile.mobileconfig << 'PROFILE'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadCertificateFileName</key>
<string>burp-ca.pem</string>
<key>PayloadContent</key>
<data>
<!-- Base64 encoded certificate goes here -->
$(base64 -i burp-ca.pem | tr -d '\n')
</data>
<key>PayloadDescription</key>
<string>Burp Suite CA Certificate</string>
<key>PayloadDisplayName</key>
<string>Burp CA</string>
<key>PayloadIdentifier</key>
<string>com.portswigger.burp.ca</string>
<key>PayloadType</key>
<string>com.apple.security.root</string>
<key>PayloadUUID</key>
<string>$(uuidgen)</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>Burp Suite CA</string>
<key>PayloadIdentifier</key>
<string>com.portswigger.burp.profile</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>$(uuidgen)</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
PROFILE
# Serve and install profile
python3 -m http.server 8000
# On iOS: Navigate to http://<YOUR_COMPUTER_IP>:8000/burp-certificate-profile.mobileconfig
Step 4: Verify Traffic Interception#
# Test 1: Basic HTTPS interception
# On iOS device Safari, visit: https://www.google.com
# Check Burp Suite → Proxy → HTTP history
# Should see decrypted HTTPS traffic
# Test 2: App Store app traffic
# Open any app (e.g., Twitter, Instagram)
# Burp should show API calls
# If not, app may be using certificate pinning
# Test 3: Certificate validation
# Visit: https://badssl.com/ (various SSL test pages)
# Should intercept without errors if certificate is trusted
# Common issues and fixes:
# Issue: "Cannot connect to server" or SSL errors in apps
# Fix: Ensure certificate is trusted in Certificate Trust Settings
# Issue: No traffic appears in Burp
# Fix: Verify proxy settings are active (Settings → Wi-Fi → Proxy)
# Issue: Some apps refuse to connect
# Fix: App is using certificate pinning (see SSL pinning bypass section)
Advanced Burp Configuration for iOS:#
# Burp Suite Project Options (for better iOS testing):
# 1. TLS Pass Through (for pinned apps you're not testing yet)
# Proxy → Proxy Settings → TLS Pass Through
# Add: *.apple.com, *.icloud.com, *.mzstatic.com
# This allows iOS system services to function normally
# 2. Response Modification (bypass some client-side checks)
# Proxy → Proxy Settings → Response Modification
# Useful for modifying responses to bypass jailbreak detection
# 3. Invisible Proxying (for non-proxy-aware traffic)
# Proxy → Proxy Settings → [Your Listener] → Request handling
# ☑ Support invisible proxying
# Required for some iOS apps that don't honor system proxy
# 4. HTTP/2 Support (iOS apps increasingly use HTTP/2)
# Proxy → Proxy Settings → [Your Listener] → TLS
# ☑ Enable HTTP/2
# 5. Match and Replace Rules (automated testing)
# Proxy → Proxy Settings → Match and Replace
# Example: Replace "jailbroken":"true" with "jailbroken":"false"
Troubleshooting Common Issues:#
# Issue 1: "This website is trying to open Settings" but profile doesn't appear
# Solution: Ensure device is not in Supervised mode (check Settings → General → About)
# Or: Try downloading certificate via mobile Safari, not Chrome/Firefox
# Issue 2: Certificate installs but apps still show SSL errors
# Solution: Check Certificate Trust Settings - toggle must be GREEN
# Settings → General → About → Certificate Trust Settings
# Issue 3: No traffic in Burp despite proxy configured
# Debug steps:
curl -x http://<YOUR_COMPUTER_IP>:8080 http://example.com # Should show in Burp
ssh -p 2222 root@localhost
# Check active proxy:
scutil --proxy
# Should show HTTP/HTTPS proxy configured
# Issue 4: Intermittent connection issues
# Solution: iOS may be using alternative network paths (cellular, VPN)
# Disable cellular data for testing: Settings → Cellular → Cellular Data (OFF)
# Disable VPN: Settings → VPN (disconnect all)
# Issue 5: App refuses to work with proxy
# Solution: App likely has SSL pinning or proxy detection
# Next section covers bypassing these protections
Automated Setup Script:#
#!/bin/bash
# ios_burp_setup.sh - Automate Burp + iOS setup
COMPUTER_IP=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | head -1)
BURP_PORT=8080
echo "[*] Computer IP detected: $COMPUTER_IP"
echo "[*] Burp Suite should be running on port $BURP_PORT"
# Check if Burp is listening
if ! nc -z localhost $BURP_PORT 2>/dev/null; then
echo "[!] Burp Suite not detected on port $BURP_PORT"
echo "[!] Start Burp Suite first, then re-run this script"
exit 1
fi
echo "[+] Burp Suite detected"
# Setup iproxy for stable connection
echo "[*] Setting up USB tunneling..."
pkill -f iproxy 2>/dev/null || true
iproxy 2222 44 &>/dev/null &
iproxy $BURP_PORT $BURP_PORT &>/dev/null &
sleep 2
# Configure iOS device proxy via SSH (jailbroken devices only)
echo "[*] Configuring iOS device proxy..."
read -p "Configure proxy via SSH? (requires jailbreak) [y/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
ssh -p 2222 -o StrictHostKeyChecking=no root@localhost << EOF
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPEnable 1" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || \
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPEnable integer 1" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPProxy $COMPUTER_IP" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || \
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPProxy string $COMPUTER_IP" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPPort $BURP_PORT" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || \
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPPort integer $BURP_PORT" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPSEnable 1" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || \
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPSEnable integer 1" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPSProxy $COMPUTER_IP" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || \
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPSProxy string $COMPUTER_IP" \
/var/preferences/SystemConfiguration/preferences.plist
/usr/libexec/PlistBuddy -c "Set :NetworkServices:WiFi:Proxies:HTTPSPort $BURP_PORT" \
/var/preferences/SystemConfiguration/preferences.plist 2>/dev/null || \
/usr/libexec/PlistBuddy -c "Add :NetworkServices:WiFi:Proxies:HTTPSPort integer $BURP_PORT" \
/var/preferences/SystemConfiguration/preferences.plist
killall -HUP configd
echo "[+] Proxy configured successfully"
EOF
else
echo "[!] Manual proxy configuration required:"
echo " Settings → Wi-Fi → (i) → HTTP Proxy → Manual"
echo " Server: $COMPUTER_IP"
echo " Port: $BURP_PORT"
fi
echo ""
echo "[*] Next steps:"
echo " 1. On iOS device, open Safari"
echo " 2. Navigate to: http://burp"
echo " 3. Download and install CA certificate"
echo " 4. Settings → General → About → Certificate Trust Settings"
echo " 5. Enable trust for PortSwigger CA"
echo ""
echo "[*] Test with: curl -x http://localhost:$BURP_PORT http://example.com"
iOS Application Extraction and Analysis#
Application Extraction and Analysis#
Obtaining IPA Files from Jailbroken Device#
Method 1: Using frida-ios-dump (Recommended - Most Reliable)#
# Modern frida-ios-dump setup (2024 version)
git clone https://github.com/AloneMonkey/frida-ios-dump.git
cd frida-ios-dump
# Install dependencies (Python 3.8+ required):
pip3 install -r requirements.txt --upgrade
# Key dependencies: frida, paramiko, biplist, six
# Configuration (edit dump.py if needed):
# Default settings:
# - Host: USB connection (automatic)
# - Port: 2222 (SSH over USB via iproxy)
# - User: root
# - Password: (will prompt or use -P flag)
# Ensure prerequisites:
# 1. Frida server running on iOS device
ssh -p 2222 root@localhost "ps aux | grep frida-server"
# 2. iproxy forwarding SSH
iproxy 2222 44 &
# 3. Verify device connection
frida-ps -U | head -5
# List all applications with bundle IDs:
frida-ps -Uai
# Dump IPA file (modern syntax):
python3 dump.py <APP_DISPLAY_NAME_OR_BUNDLE_ID>
# Examples:
python3 dump.py Instagram
python3 dump.py com.burbn.instagram
python3 dump.py "App Store" # Quotes for names with spaces
python3 dump.py WhatsApp -o /tmp/ # Specify output directory
# With password authentication:
python3 dump.py Instagram -P "your_root_password"
# For network connection (non-USB):
python3 dump.py Instagram -H <iOS_DEVICE_IP> -p 22
# Verbose output for debugging:
python3 dump.py Instagram -v
# The dumped IPA will be saved as: <AppName>_<Version>_<Date>.ipa
# Example: Instagram_290.0.0_2024-01-15.ipa
# Common issues and solutions:
# Issue: "unable to find process with name/identifier"
# Solution: Ensure app is installed and running, check bundle ID with frida-ps -Uai
# Issue: "connection refused" or SSH errors
# Solution: Verify iproxy is running and SSH is accessible
# Issue: "dump failed" or incomplete IPA
# Solution: Ensure sufficient storage on device, try re-running
Modern frida-ios-dump Features:#
# Advanced dumping with options:
python3 dump.py <bundle_id> \
--output-dir /path/to/output \
--verbose \
--resume # Resume interrupted dump
# Batch dumping multiple apps:
cat > apps_to_dump.txt << 'EOF'
com.facebook.Facebook
com.twitter.twitter
com.instagram.instagram
EOF
while read app; do
echo "[*] Dumping $app..."
python3 dump.py "$app" || echo "[!] Failed to dump $app"
sleep 5
done < apps_to_dump.txt
# Automated dumping script:
cat > auto_dump.sh << 'SCRIPT'
#!/bin/bash
# Dump all user-installed apps
frida-ps -Uai | grep -v "Apple" | awk '{print $NF}' | while read bundle_id; do
if [[ ! -z "$bundle_id" ]]; then
echo "[*] Dumping: $bundle_id"
python3 dump.py "$bundle_id" -P "alpine" 2>&1 | tee -a dump.log
sleep 3
fi
done
SCRIPT
chmod +x auto_dump.sh
./auto_dump.sh
**Method 2: Using bagbak (Modern Alternative, Faster)#
# bagbak: Modern IPA dumping tool with better performance
# https://github.com/ChiChou/bagbak
# Installation:
npm install -g bagbak
# Or: pip3 install bagbak
# Usage (simpler than frida-ios-dump):
bagbak <bundle_id>
bagbak com.instagram.instagram
# Batch dump:
bagbak com.facebook.Facebook com.twitter.twitter
# With options:
bagbak --output /tmp/ipas com.app.example
# Advantages over frida-ios-dump:
# - Faster dumping (parallelized)
# - Better handling of app extensions
# - Automatic framework/plugin extraction
Method 3: Using flexdecrypt (For Stubborn Apps)#
# flexdecrypt: Hardware-accelerated decryption
# Install via package manager (Sileo/Zebra):
# Search: "flexdecrypt" and install
# SSH into device:
ssh -p 2222 root@localhost
# Find application bundle:
find /var/containers/Bundle/Application -name "*.app" | grep -i <app_name>
# Example: Find Instagram
INSTAGRAM_PATH=$(find /var/containers/Bundle/Application -name "Instagram.app" | head -1)
echo "Found at: $INSTAGRAM_PATH"
# Get main executable name:
APP_EXEC=$(basename "$INSTAGRAM_PATH" .app)
echo "Executable: $APP_EXEC"
# Decrypt the main binary:
flexdecrypt "$INSTAGRAM_PATH/$APP_EXEC"
# This creates: <executable>_decrypted
# For complete IPA creation:
cd "$(dirname "$INSTAGRAM_PATH")"
ls -la # Should see Instagram.app and other files
# Create Payload directory structure:
mkdir -p /tmp/Payload
cp -r "$INSTAGRAM_PATH" /tmp/Payload/
# Replace encrypted binary with decrypted:
cp "${INSTAGRAM_PATH}/${APP_EXEC}_decrypted" "/tmp/Payload/Instagram.app/$APP_EXEC"
# Decrypt frameworks (if needed):
for framework in "$INSTAGRAM_PATH"/Frameworks/*.framework/*; do
if file "$framework" | grep -q "Mach-O"; then
echo "[*] Decrypting: $framework"
flexdecrypt "$framework" 2>/dev/null || true
if [ -f "${framework}_decrypted" ]; then
mv "${framework}_decrypted" "$framework"
fi
fi
done
# Create IPA:
cd /tmp
zip -r Instagram.ipa Payload/
# Transfer to computer:
scp /tmp/Instagram.ipa user@<computer_ip>:~/Desktop/
# Or via USB:
exit # Exit SSH
scp -P 2222 root@localhost:/tmp/Instagram.ipa ~/Desktop/
# Cleanup:
ssh -p 2222 root@localhost "rm -rf /tmp/Payload /tmp/Instagram.ipa"
Method 4: Manual Extraction via SSH#
# Comprehensive manual extraction for maximum control
# 1. SSH into device
ssh -p 2222 root@localhost
# 2. Locate application bundle
# Applications are stored in: /var/containers/Bundle/Application/
# List all installed apps:
ls -la /var/containers/Bundle/Application/
# Find specific app (e.g., Twitter):
find /var/containers/Bundle/Application -name "*Twitter*" -type d
# Better: Use app's bundle ID to find path
# Install appinst tool or use ps:
ps aux | grep -i twitter
# Note the process path, e.g., /var/containers/Bundle/Application/ABC123-DEF.../Twitter.app/Twitter
# Or use objection:
objection -g com.atebits.Tweetie2 explore
env # Shows bundle path
# 3. Set variables for easier handling:
BUNDLE_ID="com.atebits.Tweetie2"
APP_PATH=$(find /var/containers/Bundle/Application -name "Twitter.app" -type d | head -1)
APP_NAME="Twitter"
APP_EXEC="Twitter" # Usually same as app name
echo "Bundle Path: $APP_PATH"
# 4. Create IPA structure
cd /tmp
mkdir -p Payload
cp -r "$APP_PATH" Payload/
# 5. Decrypt the binary (if encrypted)
# Check if encrypted:
otool -l "Payload/$APP_NAME.app/$APP_EXEC" | grep cryptid
# If cryptid 1, app is encrypted, must decrypt:
# Use flexdecrypt or frida-ios-dump
flexdecrypt "Payload/$APP_NAME.app/$APP_EXEC"
mv "Payload/$APP_NAME.app/${APP_EXEC}_decrypted" "Payload/$APP_NAME.app/$APP_EXEC"
# 6. Decrypt frameworks and plugins
for fw in Payload/$APP_NAME.app/Frameworks/*.framework/*; do
if file "$fw" | grep -q "Mach-O"; then
cryptid=$(otool -l "$fw" 2>/dev/null | grep cryptid | awk '{print $2}')
if [ "$cryptid" = "1" ]; then
echo "[*] Decrypting: $fw"
flexdecrypt "$fw" && mv "${fw}_decrypted" "$fw"
fi
fi
done
# 7. Include app extensions (if any)
PLUGIN_PATH="${APP_PATH/Bundle/Data}/Library/Application Support/PlugIns"
if [ -d "$PLUGIN_PATH" ]; then
mkdir -p "Payload/$APP_NAME.app/PlugIns"
cp -r "$PLUGIN_PATH"/* "Payload/$APP_NAME.app/PlugIns/"
fi
# 8. Create IPA archive
zip -r "${APP_NAME}.ipa" Payload/
# 9. Transfer to computer
# Method A: SCP
scp "/tmp/${APP_NAME}.ipa" user@<computer_ip>:~/Desktop/
# Method B: HTTP server
python3 -m http.server 8000 &
# On computer: curl -O http://<iOS_DEVICE_IP>:8000/${APP_NAME}.ipa
pkill -f "http.server"
# Method C: Via USB (from computer)
exit # Exit SSH
scp -P 2222 root@localhost:/tmp/Twitter.ipa ~/Desktop/
# 10. Cleanup
ssh -p 2222 root@localhost "rm -rf /tmp/Payload /tmp/${APP_NAME}.ipa"
Method 5: Using TrollStore for Decrypted IPAs (iOS 14.0-16.6.1)#
# TrollStore advantage: Apps installed via TrollStore are already decrypted
# Because they use a different installation method (CoreTrust bypass)
# If you previously installed an app via TrollStore:
# 1. Open TrollStore on iOS device
# 2. Long press on app you want to extract
# 3. Tap "Export IPA"
# 4. Choose location (Files app)
# Or via command line (SSH):
ssh -p 2222 root@localhost
# TrollStore apps are in: /var/containers/Bundle/Application/
# But installed differently, already decrypted
# Find TrollStore-installed app:
TROLLSTORE_PATH="/var/containers/Bundle/Application"
APP_PATH=$(find $TROLLSTORE_PATH -name "YourApp.app" | head -1)
# Create IPA directly (no decryption needed):
cd /tmp
mkdir Payload
cp -r "$APP_PATH" Payload/
zip -r app.ipa Payload/
# The binary is already decrypted, verify:
otool -l Payload/YourApp.app/YourApp | grep cryptid
# Should show: cryptid 0 (decrypted)
Installing IPA Files on Jailbroken Device#
Method 1: Using ideviceinstaller (Cross-platform, Reliable)#
# Ensure libimobiledevice is installed:
# macOS: brew install libimobiledevice ideviceinstaller
# Linux: sudo apt install libimobiledevice-tools ideviceinstaller
# Windows: Download pre-built binaries from libimobiledevice-win32
# List connected devices:
idevice_id -l
# Should show: <40-character-UDID>
# List installed applications:
ideviceinstaller -l
# Shows bundle IDs of all installed apps
# Install IPA file:
ideviceinstaller -i app.ipa
# For specific device (multiple devices connected):
ideviceinstaller -u <UDID> -i app.ipa
# Uninstall application:
ideviceinstaller -U <bundle_id>
ideviceinstaller -U com.example.app
# Reinstall (update) existing app:
ideviceinstaller -i app.ipa
# Will automatically upgrade if bundle ID matches
# List apps with additional details:
ideviceinstaller -l -o list_user
# Shows only user-installed apps
# Common errors and solutions:
# Error: "Could not connect to lockdownd"
# Solution: Reconnect device, ensure it's unlocked and "Trust This Computer" accepted
# Error: "Installation failed: ApplicationVerificationFailed"
# Solution: IPA is not properly signed, use alternative method or re-sign
Method 2: Using TrollStore (Recommended for iOS 14.0-16.6.1)#
# TrollStore provides permanent IPA installation without 7-day limit
# No computer required, directly on device
# Prerequisites:
# 1. TrollStore must be installed (see https://ios.cfw.guide/installing-trollstore/)
# 2. Your iOS version must be vulnerable to CoreTrust bug (14.0-16.6.1)
# Installation methods:
# Method A: Direct installation on device
# 1. Transfer IPA to device via AirDrop, Files app, or Safari download
# 2. Open Files app, navigate to IPA
# 3. Tap IPA → Share → TrollStore
# 4. App installs permanently (no expiration)
# Method B: Via TrollStore Helper
# 1. Open TrollStore app
# 2. Tap "+" button
# 3. Browse and select IPA file
# 4. Tap "Install"
# Method C: Via URL scheme (automation)
# On device Safari:
# apple-magnifier://install?url=https://example.com/app.ipa
# Method D: Via SSH (for automation)
ssh -p 2222 root@localhost << 'EOF'
# Transfer IPA to device first
TROLLSTORE="/var/jb/Applications/TrollStore.app/trollstorehelper"
# Install IPA:
$TROLLSTORE install /var/mobile/Downloads/app.ipa
# Uninstall by bundle ID:
$TROLLSTORE uninstall com.example.app
EOF
# Verify installation:
ideviceinstaller -l | grep <bundle_id>
Method 3: Using Sideloadly (GUI, Cross-platform)#
# Sideloadly: Modern alternative to Cydia Impactor
# Download from: https://sideloadly.io/
# Features:
# - Works on latest iOS versions
# - Supports Windows, macOS, Linux
# - Can install IPA files with Apple ID
# - Can remove app restrictions (jailbreak detection)
# Usage:
# 1. Connect iOS device via USB
# 2. Launch Sideloadly
# 3. Drag and drop IPA file
# 4. Enter Apple ID credentials (or use certificate)
# 5. Click "Start"
# 6. App will be installed (7-day certificate for free accounts)
# Advanced options in Sideloadly:
# - Remove PlugIns (remove app extensions)
# - Remove UISupportedDevices (allow on any device)
# - Remove URLScheme (prevent scheme conflicts)
# - Force original bundle ID (maintain app data)
# Command-line usage (if available):
# Not officially supported, but can automate via AppleScript/AutoHotKey
Method 4: Using ios-deploy (Developer Tool)#
# ios-deploy: Apple's official deployment tool (requires developer account)
# Install: npm install -g ios-deploy
# Install IPA:
ios-deploy --bundle app.ipa
# Install and launch:
ios-deploy --bundle app.ipa --debug
# Install to specific device:
ios-deploy --id <UDID> --bundle app.ipa
# Uninstall:
ios-deploy --uninstall_only --bundle_id <bundle_id>
# List installed apps:
ios-deploy --list_bundle_id
# Advantages:
# - Official Apple tool
# - Better debugging support
# - Can attach debugger to running app
# Disadvantages:
# - Requires Xcode and valid provisioning profile
# - More complex setup than alternatives
Method 5: Using AppSync Unified (Jailbreak Tweak)#
# AppSync Unified: Allows installation of unsigned IPAs on jailbroken devices
# Install via Sileo/Zebra from: https://cydia.akemi.ai/
# After AppSync is installed:
# Method A: Via Filza File Manager
# 1. Install Filza from Sileo/Zebra
# 2. Transfer IPA to device (AirDrop, Safari download, etc.)
# 3. Open Filza, navigate to IPA location
# 4. Tap IPA → Installer
# 5. Wait for installation to complete
# Method B: Via SSH + installer command
ssh -p 2222 root@localhost
# Transfer IPA:
# (Already on device or use scp)
# Install using installer command:
installer -i /path/to/app.ipa
# Or use ipainstaller (if available):
ipainstaller -i /var/mobile/Downloads/app.ipa
# Check installation:
ls /var/containers/Bundle/Application/ | grep -i "app_name"
# Method C: Automated installation script
cat > install_ipa.sh << 'SCRIPT'
#!/bin/bash
IPA_PATH="$1"
if [ ! -f "$IPA_PATH" ]; then
echo "Usage: $0 <path_to_ipa>"
exit 1
fi
echo "[*] Transferring IPA to device..."
scp -P 2222 "$IPA_PATH" root@localhost:/tmp/app.ipa
echo "[*] Installing IPA..."
ssh -p 2222 root@localhost << 'EOF'
cd /tmp
unzip -q app.ipa
cp -r Payload/*.app /var/containers/Bundle/Application/
uicache -a # Refresh app icon cache
rm -rf Payload app.ipa
EOF
echo "[+] Installation complete!"
SCRIPT
chmod +x install_ipa.sh
./install_ipa.sh app.ipa
Method 6: Using AltStore (No Jailbreak Required)#
# AltStore: Install IPAs without jailbreak (7-day limit for free Apple ID)
# Download from: https://altstore.io/
# Setup (one-time):
# 1. Install AltServer on computer (Windows/Mac)
# 2. Install AltStore app via AltServer to iOS device
# 3. Trust developer profile in Settings
# Usage:
# 1. Open AltStore on iOS device
# 2. Tap "+" → Browse and select IPA
# 3. Enter Apple ID password
# 4. App installs with 7-day certificate
# Automated refresh (requires computer on same network):
# AltServer can automatically refresh apps every 7 days
# AltStore advantages:
# - No jailbreak required
# - Works on latest iOS
# - Can install multiple IPAs (up to 3 for free Apple ID, 10 for developer)
Installation Troubleshooting:#
# Issue 1: "ApplicationVerificationFailed" error
# Cause: IPA is not signed or signature is invalid
# Solution: Re-sign IPA or use AppSync Unified on jailbroken device
# Issue 2: "Could not install app - Package is invalid"
# Cause: Corrupted IPA or missing Info.plist
# Solution: Re-download IPA, verify with: unzip -t app.ipa
# Issue 3: App installs but crashes immediately
# Cause: Missing frameworks, wrong architecture, or missing entitlements
# Solution: Check IPA contents, ensure all frameworks are present
unzip app.ipa
ls Payload/*.app/Frameworks/
# Issue 4: "This app cannot be installed because its integrity could not be verified"
# Cause: iOS 16+ enhanced security
# Solution: Use TrollStore or resign with valid certificate
# Issue 5: Installation hangs at "Installing..."
# Solution: Force restart device, or:
ssh -p 2222 root@localhost
killall installd
uicache -a # Refresh SpringBoard cache
# Verify installation:
ideviceinstaller -l | grep <bundle_id>
# Or:
ssh -p 2222 root@localhost "ls /var/containers/Bundle/Application/ | wc -l"
Batch Installation Script:#
#!/bin/bash
# batch_install_ipas.sh - Install multiple IPAs efficiently
IPA_DIR="$1"
if [ ! -d "$IPA_DIR" ]; then
echo "Usage: $0 <directory_containing_ipas>"
exit 1
fi
echo "[*] Installing IPAs from: $IPA_DIR"
# Ensure iproxy is running
iproxy 2222 44 &>/dev/null &
sleep 2
# Method 1: Using ideviceinstaller (no jailbreak)
for ipa in "$IPA_DIR"/*.ipa; do
if [ -f "$ipa" ]; then
echo "[*] Installing: $(basename "$ipa")"
ideviceinstaller -i "$ipa" 2>&1 | grep -E "(Complete|Failed)"
sleep 3
fi
done
# Method 2: Using SSH + AppSync (jailbroken devices)
# Uncomment if device is jailbroken with AppSync:
# for ipa in "$IPA_DIR"/*.ipa; do
# if [ -f "$ipa" ]; then
# echo "[*] Installing: $(basename "$ipa")"
# scp -P 2222 "$ipa" root@localhost:/tmp/app.ipa
# ssh -p 2222 root@localhost "installer -i /tmp/app.ipa && rm /tmp/app.ipa"
# sleep 2
# fi
# done
echo "[+] Batch installation complete!"
echo "[*] Installed apps:"
ideviceinstaller -l | tail -10