iOS Pentesting Complete Guide by SurajSharma
iOS Mobile Application Penetration Testing Guide
1. Lab Overview & Architecture
Why This Setup Works
Mobile application penetration testing on iOS has historically been tied to macOS and Xcode. This is no longer the case. A fully capable iOS pentesting lab can be built entirely on Windows 11, using a jailbroken iPhone as the target-and-test device. This guide proves that point with step-by-step instructions that work in production VAPT engagements.
Why a jailbroken iPhone?
A jailbroken device removes Apple’s sandbox restrictions, giving security researchers the ability to:
- Access the full filesystem, including application containers and keychains
- Attach dynamic instrumentation frameworks (Frida) to any running process
- Bypass signature verification to sideload tools
- Hook into low-level APIs and observe runtime behavior
- Extract encrypted IPA files from memory (in-memory decryption)
Without a jailbreak, most of these operations are impossible. The device is essentially a black box.
Why Windows is sufficient:
The tools used in iOS security research — Frida, Objection, Burp Suite, SSH clients, Python — all run natively on Windows 11. There is no requirement for Xcode, Apple developer accounts, or macOS for application security testing (as distinct from application development).
Benefits of each tool:
| Tool | Primary Benefit |
|---|---|
| Frida | Dynamic instrumentation; hook any function at runtime without recompiling |
| Objection | Frida automation; common pentesting tasks with single commands |
| Burp Suite | HTTP/HTTPS proxy; intercept, modify, replay traffic |
| SSH | Remote shell access to the device filesystem |
| OpenSSH/SFTP | File transfer; pull application data, SQLite databases, preferences |
Lab Architecture
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────┐
│ Windows 11 Host │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Burp Suite │ │ Python Environment │ │
│ │ (Proxy) │ │ frida-tools │ │
│ │ :8080 │ │ objection │ │
│ └──────┬───────┘ └──────────┬───────────┘ │
│ │ │ │
│ ┌──────▼───────────────────────▼───────────┐ │
│ │ WiFi Network (192.168.1.0/24) │ │
│ └──────┬────────────────────────┬──────────┘ │
│ │ USB (Frida/SSH) │ WiFi (Burp) │
└─────────┼────────────────────────┼──────────────┘
│ │
┌─────────▼────────────────────────▼──────────────┐
│ Jailbroken iPhone │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ frida-server│ │ OpenSSH │ │
│ │ (port 27042)│ │ (port 22) │ │
│ └──────────────┘ └──────────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Sileo/Zebra │ │ Target Application │ │
│ │ (packages) │ │ (under test) │ │
│ └──────────────┘ └──────────────────────┘ │
└──────────────────────────────────────────────────┘
Data flows:
- Frida (USB/WiFi): Windows host connects to frida-server on device. Frida instruments running processes, hooks functions, and streams results back to your terminal.
- SSH (USB/WiFi): Shell access for filesystem navigation, file transfer, command execution.
- Burp Proxy (WiFi): iPhone sends all HTTP/HTTPS traffic through Burp listener on the Windows host. You intercept, analyze, and modify requests.
2. Hardware & Software Requirements
Hardware
| Item | Specification | Notes |
|---|---|---|
| Windows PC | Windows 11 (22H2+) | 16GB RAM recommended; 8GB minimum |
| iPhone | See table below | Must support current jailbreak |
| USB Cable | Lightning or USB-C (device native) | Data-capable cable — not charge-only |
| WiFi Router | Any 2.4GHz/5GHz router | PC and iPhone on same subnet |
| USB Hub | Optional | Useful if port conflicts arise |
iPhone Compatibility Matrix
| Device | Max iOS | Jailbreak | Tool Support | Recommendation |
|---|---|---|---|---|
| iPhone X | iOS 16.x | Dopamine (rootless) | Full | ★★★★ Good |
| iPhone XS/XS Max | iOS 16.x | Dopamine (rootless) | Full | ★★★★ Good |
| iPhone 11 / Pro | iOS 17.x | Dopamine 2.x (beta) | Full | ★★★★★ Excellent |
| iPhone 12 / Pro | iOS 17.x | Dopamine 2.x (beta) | Full | ★★★★★ Excellent |
| iPhone 13 | iOS 17.x | Dopamine 2.x (beta) | Full | ★★★★★ Excellent |
| iPhone SE (2nd) | iOS 16.x | Dopamine (rootless) | Full | ★★★★ Good |
| iPhone 6s/7/8 | iOS 15.x | Palera1n (rootful) | Full | ★★★ Legacy use |
Recommendation for new lab setups: iPhone 11 or 12 running iOS 16.x gives the broadest jailbreak support and longest-term toolchain compatibility. Avoid cutting-edge iOS versions (17.4+) until the jailbreak ecosystem stabilizes.
Software (Windows)
- Python 3.10+ (from python.org)
- Git for Windows
- OpenSSH Client (built into Windows 11)
- WinSCP or FileZilla (SFTP)
- Burp Suite Community or Professional
- Visual Studio Code (optional, for script editing)
- iTunes (or Apple Device Driver) for USB connectivity
3. Jailbreak Preparation & Selection
Step 1: Check Your iOS Version
On the iPhone: Settings → General → About → Software Version
Note the exact version (e.g., 16.6.1 or 17.1.2). This determines which jailbreak is available.
Step 2: Check Device Model
Settings → General → About → Model Name (and Model Number for precision)
Cross-reference at: https://www.theiphonewiki.com/wiki/Models
Step 3: Determine Jailbreak Compatibility
Use canijailbreak.com or check the jailbreak project’s GitHub page for supported versions.
Modern Jailbreak Ecosystem
Dopamine (Recommended for iOS 15–16, A12+)
Dopamine is a rootless jailbreak for arm64e devices (A12 chip and newer) running iOS 15.0–16.x.
- GitHub: https://github.com/opa334/Dopamine
- Installs to
/var/jb/instead of root filesystem - Compatible with ElleKit (tweak injection framework)
- Sileo and Zebra are the package managers of choice
Installation overview:
- Download Dopamine IPA from GitHub releases
- Sideload using TrollStore (if available on your iOS version) or AltStore
- Run Dopamine from home screen
- Tap “Jailbreak” — device will respring
- Verify: Sileo/Zebra appear on home screen
Palera1n (Recommended for iOS 15–17, A8–A11)
Palera1n is a checkm8-based jailbreak for older devices (iPhone X and earlier). It supports both rootful and rootless modes.
- GitHub: https://github.com/palera1n/palera1n
- Requires a Mac or Linux to run the palera1n binary… but the Windows port exists via WSL2
Palera1n on Windows via WSL2:
1
2
3
4
# In WSL2 (Ubuntu)
sudo apt update && sudo apt install -y usbmuxd
# Connect iPhone via USB
# Follow palera1n WSL2 guide from project documentation
Checkra1n (Historical Reference)
Checkra1n was the pioneering checkm8-based jailbreak (iOS 12–14, A5–A11). It is largely superseded by Palera1n for newer iOS versions but remains relevant for older device testing.
Rootful vs. Rootless — Which to Use for Pentesting
| Aspect | Rootful | Rootless |
|---|---|---|
| Filesystem | Writes to / | Writes to /var/jb/ |
| Frida | Full support | Full support (adjusted paths) |
| SSH | /usr/bin/ssh | /var/jb/usr/bin/ssh |
| Compatibility | Maximum | Growing ecosystem |
| Stability | Very stable | Increasingly stable |
| Modern devices | A11 and older only | A12+ required |
Recommendation: For iPhone 11+ (A13), use Dopamine rootless. For iPhone X (A11), palera1n rootful gives maximum tool compatibility. This guide covers both, noting path differences where relevant.
4. Package Manager Setup
Cydia (Legacy)
Cydia was the original jailbreak package manager, built on APT. It is no longer maintained and should not be used for new setups. Mentioned here only because you may encounter it on older lab devices.
Sileo (Recommended)
Sileo is the modern, actively maintained package manager for jailbroken iOS. It has a native iOS UI, fast package resolution, and supports all modern repositories.
Verify Sileo is installed:
- Look for the Sileo app on your home screen after jailbreaking
- Most modern jailbreaks (Dopamine, Palera1n 2.x) install Sileo by default
If Sileo is missing:
- Open your current package manager (Zebra may be present)
- Add the Sileo repository:
https://repo.sileoapps.com/ - Search for “Sileo” and install
Zebra (Alternative)
Zebra is a lightweight, fast alternative to Sileo. It uses less memory and loads faster on older devices.
- Install from:
https://getzbra.com/repo/ - Suitable for iPhone 7/8/X where memory is constrained
Initial Package Manager Configuration
After jailbreaking with Dopamine:
- Open Sileo
- Navigate to Sources tab
- Tap the + button (top right)
- Add required repositories (see Section 5)
- Tap Refresh to fetch package lists
5. Repository Configuration
Why Repositories Matter
iOS jailbreak repositories (repos) follow the Debian APT format. Each repo is a server hosting .deb package files with a package index. Sileo/Zebra resolves dependencies and downloads binaries from these repos, similar to apt on Linux.
Security Considerations
Warning: Only add repositories from trusted sources. Malicious repos can distribute trojaned packages. Stick to the repos listed in this guide for pentesting tools.
Repository Reference Table
| Repository | URL | Purpose | Key Packages |
|---|---|---|---|
| Chariz | https://repo.chariz.com/ | Premium tweaks, utilities | Various system tweaks |
| Havoc | https://havoc.app/ | Curated packages | Various tools |
| Procursus (Dopamine) | https://apt.procurs.us/ | Core Unix tools | OpenSSH, curl, wget, vim |
| BigBoss | https://apt.thebigboss.org/repofiles/cydia/ | Legacy packages | AppSync Unified |
| Frida | https://build.frida.re/ | Frida server | frida, frida-server |
| RootHide Bootstrap | https://roothidejb.github.io/repo/ | Rootless essentials | Bootstrap packages |
| Checkra1n (legacy) | https://apt.bingner.com/ | Elucubratus tools | Core binaries |
How to Add a Repository
In Sileo:
- Open Sileo → Sources tab
- Tap Edit → +
- Enter the repository URL exactly as shown
- Tap Add Source
- Wait for index refresh
In Zebra:
- Open Zebra → Sources tab
- Tap + icon
- Enter URL → Add
Verify repository was added: After adding, the repo should appear in the Sources list with its package count. If it shows 0 packages or an error, the URL may be wrong or the repo may be temporarily down.
Refreshing Repositories
In Sileo: Pull down on the Sources tab to trigger a refresh. Or tap Refresh button.
From SSH (after OpenSSH is installed):
1
2
3
4
5
# Rootful
apt-get update
# Rootless (Dopamine/Procursus)
/var/jb/usr/bin/apt-get update
6. Essential iOS Pentesting Packages
OpenSSH
Purpose: Remote shell access from Windows to iPhone. Foundational for all other remote operations.
Installation:
- Sileo → Search → “OpenSSH” → Install
- Repository: Procursus (
https://apt.procurs.us/)
Verification:
1
2
3
# From Windows PowerShell
ssh root@<IPHONE_IP>
# Default password: alpine
Post-install (critical): Change the default root password immediately:
1
2
passwd root
passwd mobile
Common issues:
- If SSH refuses connection, verify OpenSSH is running: On device, NewTerm →
ps aux | grep sshd - Rootless path:
/var/jb/usr/sbin/sshd
NewTerm 3
Purpose: Terminal emulator directly on the iPhone. Essential for on-device command execution without SSH.
Installation: Sileo → Search → “NewTerm 3” (from Chariz repo)
Verification: NewTerm icon appears on home screen. Tap to open terminal.
Use case: Running commands when SSH is unavailable; checking device state; quick filesystem inspection.
Filza File Manager
Purpose: GUI filesystem browser for iOS. Navigate application containers, export files, inspect databases visually.
Installation: Sileo → Search → “Filza File Manager” (from Tigisoftware repo: https://tigisoftware.com/cydia/)
Verification: Filza app appears on home screen. Browse to /private/var/mobile/Containers/ to verify root filesystem access.
Pentesting use cases:
- Navigate to application’s Documents/Library/Caches folders
- Export SQLite databases for offline analysis
- View preference .plist files
- Access application binary
Frida
Purpose: Dynamic instrumentation framework. The core engine for runtime analysis, function hooking, and SSL pinning bypass.
Installation:
- Add Frida repo:
https://build.frida.re/ - Sileo → Search → “Frida” → Install
Two packages are needed:
re.frida.server— the on-device frida-server daemon- Dependencies are pulled automatically
Verification (after frida-tools installed on Windows):
1
2
# On Windows
frida-ps -U
Should list running processes on the iPhone.
AppSync Unified
Purpose: Bypass IPA signature verification. Required to install unsigned or re-signed IPA files for testing.
Installation:
- Add repo:
https://cydia.akemi.ai/ - Sileo → Search → “AppSync Unified” → Install
Verification:
- Install a test unsigned IPA via Filza (tap .ipa file → Install with AppSync)
- Application should launch without signature errors
PreferenceLoader
Purpose: Allows tweaks to add entries to the Settings app. Required dependency for many tools.
Installation: Sileo → Search → “PreferenceLoader”
RocketBootstrap
Purpose: Inter-process communication between tweaks and system daemons. Dependency for several security-relevant tweaks.
Installation: Sileo → Search → “RocketBootstrap”
Cephei (and Cephei 2)
Purpose: Common library used by many tweaks. Often required as a dependency.
Installation: Sileo → Search → “Cephei” (from Chariz repo)
libhooker / ElleKit
Purpose: Tweak injection framework. On Dopamine (rootless), ElleKit replaces older libhooker/Substrate.
Installation: Installed automatically by Dopamine. Verify:
1
2
# In NewTerm or SSH
ls /var/jb/usr/lib/libellekit.dylib
TrollStore
Purpose: Permanently sign and install IPA files without a developer account. Available on iOS 14.0–16.6.1 (and some 17.x versions).
Installation: Depends on iOS version. Refer to: https://github.com/opa334/TrollStore
Pentesting relevance: Install Frida Gadget-patched IPAs permanently. Install testing tools distributed as IPAs.
OpenSSL / wget / curl
Purpose: Network utilities for on-device downloads and certificate operations.
Installation:
1
2
# After SSH access established
apt-get install wget curl openssl
7. Windows Workstation Setup
Python Environment
Install Python 3.11+ from python.org. During installation, check “Add Python to PATH”.
Verify:
1
2
python --version
pip --version
Create a dedicated virtual environment for pentesting tools:
1
2
python -m venv C:\pentest\ios-env
C:\pentest\ios-env\Scripts\Activate.ps1
Install Core Python Tools
1
2
3
4
5
# Inside virtual environment
pip install frida-tools
pip install objection
pip install click
pip install hexdump
Verify installations:
1
2
3
frida --version
objection --version
frida-ps --help
Install Git
Download Git for Windows from https://git-scm.com/download/win
1
git --version
OpenSSH Client (Windows 11 Built-in)
Windows 11 ships with OpenSSH client. Verify:
1
ssh -V
If missing:
- Settings → Optional Features → Add Feature → OpenSSH Client
Install WinSCP (SFTP)
WinSCP provides a GUI for SFTP file transfer from the iPhone.
- Download from https://winscp.net/
- Install with default settings
- Create a new session: Protocol = SFTP, Host = iPhone IP, Port = 22, User = root
Burp Suite
Community Edition (free):
- Download from https://portswigger.net/burp/communitydownload
- Requires Java (bundled with installer)
Professional Edition (paid, recommended for client work):
- Includes Scanner, advanced Intruder, and project files
- Download from https://portswigger.net/burp/pro
Install with defaults. Launch and verify proxy listener is active.
Environment Variables
Add these to your Windows PATH for convenience:
1
2
3
4
5
6
7
# Add to System Environment Variables → PATH
C:\pentest\ios-env\Scripts
# Verify all tools are accessible
frida --version
objection --version
ssh -V
adb / iproxy (USB Tunneling)
For USB-based Frida connections (more reliable than WiFi):
1
2
3
4
# Install libimobiledevice via chocolatey
Set-ExecutionPolicy Bypass -Scope Process
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
choco install libimobiledevice
Or install iTunes (which includes Apple device drivers for USB recognition).
8. SSH Connectivity
Finding the iPhone’s IP Address
On the iPhone: Settings → Wi-Fi → Tap your network → IP Address
Or from Windows after USB connection:
1
2
# List connected iOS devices
ideviceinfo -k WiFiAddress
Basic SSH Connection
1
2
ssh root@192.168.1.45
# Password: alpine (default — change immediately)
Changing Default Passwords
1
2
3
4
5
6
# Connected via SSH
passwd root
# Enter new password twice
passwd mobile
# Enter new password twice
Security Note: The default password
alpineis publicly known. Any device on your network can SSH into an un-hardened jailbroken iPhone. Change passwords immediately after first SSH login.
SSH Config File
Create C:\Users\YourUser\.ssh\config:
1
2
3
4
5
Host iphone
HostName 192.168.1.45
User root
Port 22
ServerAliveInterval 60
Now connect with just:
1
ssh iphone
File Transfer with SCP
1
2
3
4
5
6
7
8
# Copy file from iPhone to Windows
scp root@192.168.1.45:/var/mobile/Documents/db.sqlite C:\pentest\artifacts\
# Copy file from Windows to iPhone
scp C:\pentest\tools\script.js root@192.168.1.45:/tmp/
# Copy entire directory
scp -r root@192.168.1.45:/private/var/mobile/Containers/Data/Application/UUID/ C:\pentest\artifacts\
SFTP Session
1
2
3
4
5
sftp root@192.168.1.45
sftp> ls /private/var/mobile/
sftp> get /private/var/mobile/Documents/file.sqlite
sftp> put C:\tools\script.js /tmp/script.js
sftp> bye
WinSCP GUI Session
- Open WinSCP
- New Session → SFTP → Host: 192.168.1.45 → Username: root → Password: (your new password)
- Connect
- Navigate iPhone filesystem on the right panel; Windows on left
- Drag files between panels to transfer
Pulling Application Data via SSH
1
2
3
4
5
6
# Find application container UUID
find /private/var/containers/Bundle/Application/ -name "AppName.app" -maxdepth 2
# Once UUID is known:
ls /private/var/mobile/Containers/Data/Application/UUID-HERE/
# Documents/ Library/ SystemData/ tmp/
9. iOS Filesystem Navigation
Key Directories
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# System Applications (pre-installed)
/Applications/
# Third-party app binaries (IPA contents)
/private/var/containers/Bundle/Application/<UUID>/AppName.app/
# App data containers (Documents, Library, Caches)
/private/var/mobile/Containers/Data/Application/<UUID>/
# Shared app groups
/private/var/mobile/Containers/Shared/AppGroup/<UUID>/
# Keychain (encrypted; extracted via keychain dumper tools)
/private/var/Keychains/keychain-2.db
# User preferences (.plist files)
/private/var/mobile/Library/Preferences/
# Crash logs
/private/var/mobile/Library/Logs/CrashReporter/
Application Sandbox Structure
Every third-party app has an isolated data container:
1
2
3
4
5
6
7
8
9
/private/var/mobile/Containers/Data/Application/<UUID>/
├── Documents/ ← User-generated files; iCloud-synced if enabled
├── Library/
│ ├── Application Support/ ← App databases, config files
│ ├── Caches/ ← Cache files; can be deleted by OS
│ ├── Preferences/ ← NSUserDefaults .plist files
│ └── WebKit/ ← WebView storage
├── SystemData/
└── tmp/ ← Temporary files; cleared on relaunch
Finding Application UUID
1
2
3
4
5
6
7
8
9
# Method 1: Frida (from Windows)
frida-ps -Ua
# Lists app name + bundle ID + PID
# Method 2: On device via SSH
ls /private/var/mobile/Containers/Data/Application/ | head -20
# Method 3: grep by app name
find /private/var/containers/Bundle/Application/ -name "*.app" 2>/dev/null
Reading Preference Files
1
2
3
4
5
6
7
# On device
cat /private/var/mobile/Library/Preferences/com.example.appname.plist
# Binary plists need plutil:
plutil -p /private/var/mobile/Library/Preferences/com.example.appname.plist
# Or pull to Windows and use plistlib (Python) or PListEdit Pro
scp root@iphone:/private/var/mobile/Library/Preferences/com.example.appname.plist C:\pentest\
SQLite Database Access
1
2
3
4
5
6
7
8
9
# On device
sqlite3 /path/to/database.sqlite
.tables
SELECT * FROM users;
.quit
# Pull to Windows for SQLite Browser
scp root@iphone:/path/to/database.sqlite C:\pentest\artifacts\
# Open with DB Browser for SQLite (https://sqlitebrowser.org/)
10. Burp Suite Configuration
Setting Up the Proxy Listener
- Launch Burp Suite
- Navigate to Proxy → Options (or Proxy → Proxy Settings in newer versions)
- Under Proxy Listeners, click Add:
- Bind to port:
8080 - Bind to address:
All interfaces(or your specific WiFi IP)
- Bind to port:
- Click OK
- Confirm the listener shows status Running
1
2
3
4
5
6
7
8
[Burp Proxy Listener Configuration]
┌────────────────────────────────────────┐
│ Proxy → Proxy Settings → Listeners │
│ │
│ ✓ Running 0.0.0.0:8080 │
│ │
│ [Add] [Edit] [Remove] │
└────────────────────────────────────────┘
Screenshot Placeholder: Burp Suite Proxy → Proxy Settings → Listeners tab showing 0.0.0.0:8080 running
Configuring iPhone WiFi Proxy
- On iPhone: Settings → Wi-Fi → (i) next to your network
- Scroll to HTTP PROXY section
- Select Manual
- Server: Your Windows PC’s IP address (e.g.,
192.168.1.100) - Port:
8080 - Authentication: Off (unless you’ve configured Burp auth)
- Tap Save (top right)
Verify: Open Safari on iPhone, browse to http://burpsuite/ — Burp should show intercepted traffic.
Intercept Toggle
In Burp → Proxy → Intercept: Toggle Intercept is on to hold requests for inspection, or leave off to let traffic flow through while logging in HTTP history.
HTTP History
All traffic (when not intercepting) appears in Proxy → HTTP History. Filter by host to isolate target app traffic.
Scoping
Set scope to avoid noise from system traffic:
- Target → Scope → Add target domain/IP
- Proxy → Intercept → Enable “And URL is in target scope”
11. Burp Certificate Installation
This is required for HTTPS traffic interception. Without it, the iPhone will show certificate errors for all HTTPS requests proxied through Burp.
Step 1: Download the Burp CA Certificate
With Burp running and iPhone proxy configured:
- On iPhone Safari: Navigate to
http://burpsuiteorhttp://YOUR_PC_IP:8080 - Tap CA Certificate
- iOS will prompt: “This website is trying to download a configuration profile”
- Tap Allow
Step 2: Install the Profile
- Go to Settings → General → VPN & Device Management
- Under “Downloaded Profile” you will see PortSwigger CA
- Tap it → Tap Install (top right)
- Enter your iPhone passcode if prompted
- Tap Install on the warning screen
- Tap Done
Step 3: Trust the Certificate
Installing alone is insufficient — you must explicitly trust it for SSL:
- Settings → General → About → Certificate Trust Settings
- Under “Enable Full Trust For Root Certificates”
- Toggle on PortSwigger CA
- Tap Continue on the warning
Verification
Open Safari and browse to https://google.com through Burp proxy. Burp should show the intercepted HTTPS request with no certificate error on the iPhone.
Screenshot Placeholder: Burp HTTP History showing intercepted HTTPS traffic from iPhone
Common Certificate Errors
| Error | Cause | Fix |
|---|---|---|
| “Cannot Verify Server Identity” | Certificate not trusted | Complete Step 3 |
| “Safari Cannot Open the Page” | Proxy not set / Burp not running | Verify listener, verify WiFi proxy |
| Certificate shows but HTTPS fails | App uses SSL pinning | See Section 12 |
| Profile install fails | iOS 15+ requires Safari for profile download | Use Safari, not Chrome |
12. SSL Pinning Bypass Preparation
What Is SSL Pinning?
SSL pinning (certificate pinning) is a security mechanism where an application hard-codes the expected server certificate or public key. When pinning is active, the app validates not just that the certificate is signed by a trusted CA, but that it matches a specific pinned value.
This means even if you install Burp’s CA as a trusted root, pinning-enabled apps will reject Burp’s dynamically generated certificate and terminate the connection.
Types of Pinning Implementations
| Method | Implementation | Hook Target |
|---|---|---|
| Certificate pinning | Hard-coded .der cert in bundle | SecTrustEvaluate |
| Public key pinning | Pinned public key hash | SSL handshake validation |
| TrustKit | Third-party library | TrustKit evaluate methods |
| Alamofire | ServerTrustPolicy | Alamofire evaluation |
| OkHttp (React Native) | CertificatePinner | OkHttp3 methods |
| Native NSURLSession | Custom URLAuthenticationChallenge | URLSession delegate |
Bypass Approaches Overview
There are three primary approaches for authorized testing:
- Objection (automated): Single command leverages Frida scripts to hook common pinning implementations
- Custom Frida scripts: Target app-specific pinning logic discovered through static analysis
- Recompile/patch: Modify the IPA, remove pinning code, re-sign (complex; not always necessary)
Frida-based Bypass Setup
Ensure frida-server is running on device (see Section 13). Then from Windows:
1
2
3
4
5
# Using objection (covers most common implementations)
objection -g com.example.targetapp explore
# Inside objection shell:
ios sslpinning disable
Custom Frida SSL Bypass Script
For apps where objection’s built-in bypass doesn’t work, use a targeted script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ssl_bypass.js — hook SecTrustEvaluateWithError (iOS 12+)
// Use only during authorized security assessments
if (ObjC.available) {
var SecTrustEvaluateWithError = Module.findExportByName('Security', 'SecTrustEvaluateWithError');
if (SecTrustEvaluateWithError) {
Interceptor.attach(SecTrustEvaluateWithError, {
onLeave: function(retval) {
retval.replace(0x1); // Return true
}
});
console.log('[+] SecTrustEvaluateWithError hooked');
}
}
Run:
1
frida -U -f com.example.app -l ssl_bypass.js --no-pause
Validation Process
After bypass:
- Launch target app
- Perform an action that makes a network request
- Check Burp HTTP History — HTTPS requests should now appear
- If still failing, the app may use multiple pinning layers or certificate transparency checks
Known SSL Bypass Scripts
For convenience, maintain a library of community bypass scripts for common frameworks. The ssl-kill-switch2 tweak (installable via Sileo) provides a system-wide bypass toggle, useful for initial traffic discovery:
- Repo:
https://julioverne.github.io/ - Package:
com.julioverne.sslkillswitch2 - After install: Settings → SSL Kill Switch 2 → Toggle on
Note: ssl-kill-switch2 affects all apps system-wide. Disable after use to avoid interference.
13. Frida Installation & Deployment
Architecture Check
Before installing frida-server, confirm your device’s CPU architecture:
1
2
3
4
# Via SSH on device
uname -m
# arm64 → A12+ devices (most modern)
# armv7 → Very old devices (pre-A7)
Installing Frida Server on Device
Method 1: Via Sileo (Recommended)
- Add Frida repo:
https://build.frida.re/ - Sileo → Search → “Frida” → Install
- This installs the frida-server daemon and a launchd plist to start it automatically
Method 2: Manual Deployment
If Sileo method fails, manually deploy the matching binary:
1
2
3
4
5
6
7
8
9
10
11
12
13
# On Windows — find matching version
frida --version
# e.g., 16.2.1
# Download matching frida-server from GitHub Releases
# https://github.com/frida/frida/releases
# File: frida-server-16.2.1-ios-arm64.xz
# Extract and transfer
scp frida-server root@iphone:/usr/sbin/frida-server
# On device (SSH)
chmod 755 /usr/sbin/frida-server
Starting Frida Server
Automatic (via launchd — if installed via Sileo):
1
2
3
4
5
# Check if running
ps aux | grep frida-server
# Start manually if not running
/usr/sbin/frida-server &
Rootless path (Dopamine):
1
/var/jb/usr/sbin/frida-server &
Verification from Windows
1
2
3
4
5
6
7
8
# List all processes on device (USB connection)
frida-ps -U
# List only installed apps
frida-ps -Ua
# List apps with PIDs
frida-ps -Uai
Expected output:
1
2
3
4
5
PID Name
---- -------
123 SpringBoard
456 MobileSafari
789 com.example.targetapp
USB vs WiFi Frida
USB (recommended — more reliable):
1
frida-ps -U # -U = USB device
WiFi:
1
frida-ps -H 192.168.1.45 # -H = host IP
Version Mismatch Resolution
The frida Python package version must match the frida-server version on device exactly:
1
2
3
4
5
6
7
8
9
# Check Windows frida version
frida --version
# Check device frida-server version (SSH)
/usr/sbin/frida-server --version
# If mismatched, upgrade/downgrade Python package
pip install frida==16.2.1 # match device version
pip install frida-tools==12.3.1 # matching tools
Common Frida Errors
| Error | Cause | Fix |
|---|---|---|
Failed to enumerate processes | frida-server not running | SSH → start frida-server |
Unable to connect to remote frida-server | Version mismatch | Match versions |
Frida is not installed on this device | Package missing | Install via Sileo |
Access denied | Server not running as root | Run as root: sudo frida-server & |
Spawn failed: unable to find process | Bundle ID wrong | Verify with frida-ps -Ua |
14. Objection Setup & Usage
What Is Objection?
Objection is a runtime mobile exploration toolkit built on Frida. It provides a REPL (interactive shell) with dozens of pre-built commands for common pentesting tasks, eliminating the need to write custom Frida scripts for routine operations.
Installation
1
2
pip install objection
objection --version
Basic Usage
Attach to running application:
1
objection -g com.example.targetapp explore
Spawn and attach:
1
objection -g com.example.targetapp explore --startup-command "ios sslpinning disable"
Objection REPL Commands
Once inside the objection shell (com.example.targetapp on (iPhone: 16.1) [usb] # ):
SSL/TLS:
1
ios sslpinning disable
Keychain:
1
2
ios keychain dump
ios keychain dump --json
File System:
1
2
3
4
5
env # Print app environment paths
ls # List files in current directory
cd /path/to/dir # Change directory
file download /path # Download file to Windows
file upload local.txt /remote/path
Pasteboard:
1
ios pasteboard monitor
NSUserDefaults:
1
ios nsuserdefaults get
Class/Method Enumeration:
1
2
3
4
ios hooking list classes
ios hooking list methods --class ClassName
ios hooking watch class ClassName
ios hooking watch method "-[ClassName methodName:]"
Jailbreak Detection Bypass:
1
ios jailbreak disable
Screenshot:
1
ios ui screenshot /tmp/screen.png
Useful Objection Workflows
Full data extraction workflow:
1
2
3
4
5
6
7
env
ios nsuserdefaults get
ios keychain dump --json
ls
cd Documents
ls
file download database.sqlite
Runtime method tracing:
1
2
3
ios hooking watch class NSURLSession
# Generates output for every NSURLSession call
# Useful for discovering undocumented API endpoints
15. Application Enumeration
Finding Installed Applications
From Windows via Frida:
1
frida-ps -Ua
From device SSH:
1
2
3
4
5
# List all bundle IDs of user-installed apps
ls /private/var/containers/Bundle/Application/
# Find specific app
find /private/var/containers/Bundle/Application/ -name "*.app" | grep -i "bankingapp"
Using ideviceinstaller (Windows):
1
2
choco install ideviceinstaller
ideviceinstaller -l # List all installed apps with bundle IDs
Getting Application Metadata
1
2
3
4
5
6
7
8
# On device SSH
cat /private/var/containers/Bundle/Application/<UUID>/AppName.app/Info.plist
# Key fields:
# CFBundleIdentifier → Bundle ID
# CFBundleVersion → Build number
# CFBundleShortVersionString → User-facing version
# NSAppTransportSecurity → ATS config (network security)
Reading Info.plist for Security Configuration
1
plutil -p /private/var/containers/Bundle/Application/<UUID>/AppName.app/Info.plist | grep -A5 "NSAppTransportSecurity"
Look for:
NSAllowsArbitraryLoads: true→ ATS disabled (all HTTP allowed)NSExceptionDomains→ Specific ATS exceptions per domainNSAllowsLocalNetworking→ Allows localhost HTTP
Discovering App Endpoints from Binary
1
2
3
# On device SSH
strings /private/var/containers/Bundle/Application/<UUID>/AppName.app/AppBinary | grep "https://"
strings /private/var/containers/Bundle/Application/<UUID>/AppName.app/AppBinary | grep "api\."
Runtime Discovery with Frida
1
2
3
4
5
6
7
8
9
10
11
12
# List all Objective-C classes loaded at runtime
frida -U com.example.app --eval "console.log(JSON.stringify(ObjC.classes))"
# Find classes related to networking
frida -U com.example.app --eval "
var classes = ObjC.classes;
for (var c in classes) {
if (c.toLowerCase().includes('network') || c.toLowerCase().includes('session')) {
console.log(c);
}
}
"
16. Static Analysis Setup
IPA Extraction
Before static analysis, you need the decrypted application binary. App Store IPAs are encrypted. A jailbroken device decrypts them in memory when running.
Method: Dump from memory using frida-ios-dump or bagbak
1
2
3
4
5
# Install bagbak (Windows-compatible IPA dumper)
pip install bagbak
# Dump target app to IPA
bagbak -U com.example.targetapp -o C:\pentest\ipas\
Or via frida-ios-dump:
1
2
3
4
5
git clone https://github.com/AloneMonkey/frida-ios-dump
cd frida-ios-dump
pip install -r requirements.txt
# Edit dump.py: set IPHONE_IP, PORT, USER, PASSWORD
python dump.py com.example.targetapp
IPA Structure Analysis
An IPA is a ZIP archive. Extract it:
1
2
3
# Rename .ipa to .zip, extract with 7-Zip
# Or:
Expand-Archive -Path app.ipa -DestinationPath C:\pentest\extracted\
Contents:
1
2
3
4
5
6
7
Payload/
└── AppName.app/
├── AppName ← Main binary (Mach-O)
├── Info.plist ← App metadata
├── embedded.mobileprovision ← Provisioning profile
├── Frameworks/ ← Embedded frameworks
└── Assets.car ← Compiled assets
Static Analysis with JADX (React Native / Cordova apps)
For React Native apps, the JavaScript bundle is embedded:
1
Payload/AppName.app/main.jsbundle
Open with any text editor. Often contains API keys, endpoints, and business logic in plaintext.
Strings Analysis
1
2
3
4
5
6
7
8
9
# Windows — use strings utility from Sysinternals or Git Bash
strings Payload/AppName.app/AppName > strings_output.txt
# Search for:
# API keys / tokens
findstr /i "key\|token\|secret\|password\|api" strings_output.txt
# URLs
findstr "https://" strings_output.txt
# AWS
findstr /i "amazonaws\|AKIA" strings_output.txt
Ghidra (Free Reverse Engineering)
- Download Ghidra from https://ghidra-sre.org/
- Launch Ghidra → New Project → Import File → Select Mach-O binary
- Ghidra will detect ARM64 architecture automatically
- Run auto-analysis
- Use Symbol Tree to browse functions
Finding sensitive functions:
- Window → Symbol Tree → search for:
login,auth,decrypt,key,pin
Checking for Weak Cryptography
1
2
# On device SSH
otool -L /path/to/binary | grep -i crypt
Or in Ghidra, search for imports: CCCrypt, SecKeyEncrypt, kSecAttrKeyType
17. Runtime Analysis Setup
Function Tracing
Trace all calls to a specific ObjC method:
1
frida-trace -U -m "-[NSURLSession dataTaskWithURL:completionHandler:]" com.example.app
Trace all C functions matching a pattern:
1
frida-trace -U -i "Sec*" com.example.app
Trace Swift functions:
1
frida-trace -U -m "*AppName*auth*" com.example.app
Runtime Hooking Script Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// hook_network.js
// Hook NSURLSession to log all requests
// Use only during authorized testing
if (ObjC.available) {
var NSURLSession = ObjC.classes.NSURLSession;
var dataTask = NSURLSession['- dataTaskWithURL:completionHandler:'];
Interceptor.attach(dataTask.implementation, {
onEnter: function(args) {
var url = ObjC.Object(args[2]);
console.log('[Network] Request URL: ' + url.toString());
}
});
console.log('[+] NSURLSession hooked');
}
Run:
1
frida -U -f com.example.app -l hook_network.js --no-pause
API Observation
Watch NSUserDefaults writes (credential storage detection):
1
2
3
4
5
6
7
8
9
// watch_defaults.js
var NSUserDefaults = ObjC.classes.NSUserDefaults;
Interceptor.attach(NSUserDefaults['- setObject:forKey:'].implementation, {
onEnter: function(args) {
var key = ObjC.Object(args[3]).toString();
var value = ObjC.Object(args[2]).toString();
console.log('[NSUserDefaults] Key: ' + key + ' | Value: ' + value);
}
});
Observe cryptographic operations:
1
frida-trace -U -i "CCCrypt" -i "CCHmac" com.example.app
Jailbreak Detection Bypass with Frida
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// jailbreak_bypass.js
var paths_to_fake = [
'/Applications/Cydia.app',
'/Library/MobileSubstrate/MobileSubstrate.dylib',
'/bin/bash',
'/usr/sbin/sshd',
'/etc/apt',
'/private/var/lib/apt/'
];
var NSFileManager = ObjC.classes.NSFileManager;
Interceptor.attach(NSFileManager['- fileExistsAtPath:'].implementation, {
onEnter: function(args) {
this.path = ObjC.Object(args[2]).toString();
},
onLeave: function(retval) {
if (paths_to_fake.indexOf(this.path) !== -1) {
console.log('[JB Bypass] Faking absence of: ' + this.path);
retval.replace(0x0);
}
}
});
18. Application Data Extraction
Sandbox Document Review
1
2
3
# SSH — navigate to app data container
cd /private/var/mobile/Containers/Data/Application/<UUID>/
find . -type f | head -50
Common findings:
.sqlite/.db— Databases.plist— Configuration / cached credentials.log— Debug logs (may contain tokens/PII)cookies.binarycookies— HTTP cookies
Preferences Review
1
2
3
4
5
6
# Find app-specific preferences
ls /private/var/mobile/Library/Preferences/ | grep com.example
cat /private/var/mobile/Library/Preferences/com.example.app.plist
# Convert binary plist to XML on device
plutil -p /private/var/mobile/Library/Preferences/com.example.app.plist
SQLite Database Review
1
2
3
4
5
6
# On device
sqlite3 /private/var/mobile/Containers/Data/Application/<UUID>/Library/Application\ Support/app.db
.tables
.schema tablename
SELECT * FROM users LIMIT 10;
.quit
Pull to Windows for deeper analysis:
1
2
scp root@iphone:/private/var/mobile/Containers/Data/Application/<UUID>/Library/Application\ Support/app.db C:\pentest\artifacts\
# Open with DB Browser for SQLite
Cookie Extraction
1
2
3
4
5
6
7
8
# Binary cookies parser (install via pip on Windows)
pip install python-binarycookies
# Pull cookies file
scp root@iphone:/private/var/mobile/Library/Cookies/cookies.binarycookies C:\pentest\artifacts\
# Parse on Windows
python -c "import binarycookies; binarycookies.decode('cookies.binarycookies')"
Keychain Extraction
The iOS keychain requires a specialized dumper running on the device. Use keychain-dumper or objection’s built-in command:
1
2
3
4
# Via objection (easiest)
objection -g com.example.app explore
# Inside objection:
ios keychain dump
Output shows:
kSecClass(key type)kSecAttrService(service name — often identifies what the credential is for)kSecValueData(the actual secret)
Note: Keychain access in objection is scoped to the target app’s entitlements. Some items may require
--allflag and running against SpringBoard.
Cache Review
1
2
3
4
5
6
# HTTP cache (NSURLCache)
ls /private/var/mobile/Containers/Data/Application/<UUID>/Library/Caches/
find . -name "*.db" -o -name "Cache.db"
sqlite3 Cache.db
.tables
SELECT * FROM cfurl_cache_response LIMIT 5;
HTTP response caching may contain sensitive data including authentication tokens returned in response bodies.
19. Troubleshooting Reference
Frida Not Detecting Device
Symptom: frida-ps -U returns “Unable to connect to remote frida-server” or no output.
Diagnosis and fixes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. Verify frida-server is running on device
ssh root@iphone
ps aux | grep frida-server
# 2. If not running, start it
/usr/sbin/frida-server & # rootful
/var/jb/usr/sbin/frida-server & # rootless (Dopamine)
# 3. Check version match
frida --version # Windows
frida-server --version # Device (SSH)
# 4. Kill and restart
pkill frida-server
/usr/sbin/frida-server -l 0.0.0.0 &
# 5. Check USB connectivity
ideviceinfo -u # Should show device UDID
SSH Connection Refused
Symptom: ssh root@192.168.1.45 returns “Connection refused” or times out.
Fixes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Verify sshd is running (from NewTerm on device)
ps aux | grep sshd
# Start sshd manually
/usr/sbin/sshd # rootful
/var/jb/usr/sbin/sshd # rootless
# Verify correct IP
# iPhone: Settings → WiFi → (i) → IP Address
# Verify SSH port
ssh root@192.168.1.45 -p 22
# Try connecting via USB (requires iproxy)
iproxy 2222 22 &
ssh root@127.0.0.1 -p 2222
Burp Not Intercepting Traffic
Symptom: App traffic does not appear in Burp HTTP History.
Checklist:
- Burp listener is on
0.0.0.0:8080(not localhost only) - iPhone proxy is set to Windows PC IP and port 8080
- Both devices are on the same WiFi network (same subnet)
- Burp CA certificate is installed AND trusted (Certificate Trust Settings)
- App is not using SSL pinning (Section 12)
- App is not using HTTP/3 or QUIC (Burp doesn’t intercept QUIC by default)
- Windows Firewall is not blocking port 8080
Test with Safari first: If Safari HTTPS works in Burp but the app doesn’t, the app is likely pinning.
Certificate Errors in App
Symptom: App shows SSL error or crashes when Burp is proxying.
If Burp CA is correctly installed: The app is almost certainly SSL pinning. Proceed to Section 12.
If trust isn’t applying:
1
2
Settings → General → About → Certificate Trust Settings
→ Verify PortSwigger CA is toggled ON
On iOS 15+, if the profile was downloaded outside Safari, it may not be trusted properly. Re-download via Safari.
SSL Pinning Not Bypassed
Symptom: After ios sslpinning disable in objection, app still fails.
Advanced bypass steps:
1
2
3
4
5
# Try launching app with objection startup hook
objection -g com.example.app explore --startup-command "ios sslpinning disable"
# Try frida-based bypass simultaneously with app launch
frida -U -f com.example.app -l ssl_bypass.js --no-pause &
If still failing:
- Use Ghidra/strings to find custom pinning implementation class names
- Write targeted Frida hooks for those specific methods
- Check if app uses Alamofire — requires hooking
ServerTrustPolicy - Check if app uses a custom
NSURLProtocol— requires different hook
Frida Server Version Mismatch
Symptom: frida-ps -U connects but throws version error.
1
2
3
4
5
6
7
8
# Find what version is on device
ssh root@iphone "/usr/sbin/frida-server --version"
# Install exact matching version on Windows
pip install frida==VERSION frida-tools==TOOLS_VERSION
# Check frida release compatibility matrix:
# https://github.com/frida/frida/releases
Rootless Jailbreak Path Issues
Symptom: Commands not found; tools installed but inaccessible.
On Dopamine (rootless), all tools install under /var/jb/. Add to PATH:
1
2
# Add to ~/.profile or run manually
export PATH="/var/jb/usr/bin:/var/jb/usr/sbin:/var/jb/bin:$PATH"
Package Installation Failures (Sileo)
Symptom: Package fails to install; dependency errors; “Unable to locate package.”
Fixes:
1
2
3
4
5
6
7
1. Refresh all sources: Sileo → Sources → pull down to refresh
2. Verify repository URL is correct (check for typos)
3. Check if repo is down (visit URL in browser)
4. Free up space: df -h on device
5. Clear Sileo cache: Sileo → Settings → Refresh Caches
6. Try installing via APT from SSH:
apt-get install packagename
Repository Failures
Symptom: Source shows error; package index fails to download.
1
2
3
4
5
# Check repo manually
curl -I https://repo.url/Release
# Remove and re-add in Sileo
# Check if repo requires specific Sileo/APT version
Network Problems
Symptom: iPhone cannot reach proxy; Burp shows no traffic.
Diagnosis:
1
2
3
4
5
6
7
8
9
# On Windows — verify port is listening
netstat -an | findstr 8080
# Check Windows Firewall
# Windows Defender Firewall → Allow an app → Add Burp Suite / Java
# Or add inbound rule: TCP port 8080
# Verify IP is correct
ipconfig | findstr IPv4
20. Lab Validation Checklist
Use this checklist before starting any assessment engagement. Complete all items.
Device Setup
1
2
3
4
5
6
[ ] iPhone is jailbroken and jailbreak persists after reboot
[ ] Jailbreak version noted in test documentation
[ ] iOS version noted in test documentation
[ ] Device passcode is known
[ ] Package manager (Sileo/Zebra) is functional
[ ] All required repositories are added and refreshing successfully
SSH & Connectivity
1
2
3
4
5
6
7
8
9
[ ] OpenSSH installed via Sileo
[ ] SSH connection successful: ssh root@IPHONE_IP
[ ] Root password changed from default 'alpine'
[ ] Mobile user password changed from default 'alpine'
[ ] SSH key authentication configured (optional but recommended)
[ ] WinSCP or SFTP connection verified
[ ] File upload test: SCP file from Windows to iPhone successful
[ ] File download test: SCP file from iPhone to Windows successful
[ ] iproxy USB tunnel tested as fallback
Frida & Objection
1
2
3
4
5
6
7
8
9
10
[ ] Frida server installed on device (via Sileo)
[ ] Frida server is running: ps aux | grep frida-server
[ ] frida-tools installed on Windows: frida --version
[ ] objection installed on Windows: objection --version
[ ] frida-ps -U returns process list (no errors)
[ ] Frida and frida-server versions match exactly
[ ] objection -g <bundle_id> explore connects successfully
[ ] ios sslpinning disable command executes in objection
[ ] ios keychain dump executes in objection
[ ] ios jailbreak disable executes in objection
Burp Suite
1
2
3
4
5
6
7
8
9
10
[ ] Burp Suite installed and launches on Windows
[ ] Proxy listener configured on 0.0.0.0:8080
[ ] Proxy listener status shows Running
[ ] iPhone WiFi proxy set to Windows IP:8080
[ ] Burp CA certificate downloaded to iPhone
[ ] CA certificate profile installed
[ ] CA certificate trusted in Certificate Trust Settings
[ ] HTTP traffic from Safari visible in Burp HTTP History
[ ] HTTPS traffic from Safari visible in Burp HTTP History (no cert errors)
[ ] Target scope configured in Burp
Application Enumeration
1
2
3
4
5
6
[ ] Target app installed on device
[ ] Bundle ID identified: frida-ps -Ua
[ ] App container UUID identified
[ ] Info.plist reviewed for ATS configuration
[ ] Application binary located
[ ] Frameworks directory inventoried
Static Analysis
1
2
3
4
5
6
7
8
9
[ ] IPA extracted/dumped from device
[ ] IPA extracted to filesystem
[ ] Info.plist reviewed
[ ] Strings analysis performed on binary
[ ] Hardcoded secrets search completed
[ ] Hardcoded URLs/endpoints documented
[ ] Third-party libraries identified
[ ] Entitlements reviewed
[ ] NSAppTransportSecurity reviewed
Runtime Analysis
1
2
3
4
5
6
7
[ ] App launches successfully with Frida attached
[ ] NSURLSession hook test executed
[ ] Network requests visible in Burp during app use
[ ] Runtime class enumeration successful
[ ] Method tracing test successful
[ ] Jailbreak detection bypass tested
[ ] SSL pinning bypass tested
Data Storage
1
2
3
4
5
6
7
8
9
10
[ ] App Documents directory reviewed
[ ] App Library/Preferences reviewed
[ ] App Library/Application Support reviewed
[ ] App Library/Caches reviewed
[ ] SQLite databases identified and reviewed
[ ] Plist preferences reviewed
[ ] Keychain dump executed and reviewed
[ ] HTTP cache (Cache.db) reviewed
[ ] Cookies file reviewed
[ ] Sensitive data in storage documented
Cleanup & Documentation
1
2
3
4
5
6
7
8
[ ] Evidence artifacts collected
[ ] Network traffic exports saved from Burp
[ ] Screenshots organized
[ ] SSH logs reviewed
[ ] Frida output saved
[ ] Objection session output saved
[ ] Lab notes completed
[ ] Device state documented for re-testing
21. Daily iOS Pentesting Workflow
This is the production workflow used during professional VAPT engagements. Follow it at the start of each testing session.
Phase 1: Lab Startup (5 minutes)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. Power on iPhone
2. If jailbreak requires re-running after reboot:
- Launch Dopamine/Palera1n app
- Tap Jailbreak
- Wait for respring (device restart)
3. On Windows: Activate Python venv
C:\pentest\ios-env\Scripts\Activate.ps1
4. Verify SSH connectivity:
ssh iphone
exit
5. Verify Frida:
frida-ps -U
6. Launch Burp Suite
7. Verify proxy listener active on 8080
8. Set iPhone WiFi proxy to Windows IP:8080
9. Verify Burp intercepts Safari HTTPS traffic
Phase 2: Application Discovery (10 minutes)
1
2
3
4
5
6
7
8
10. Enumerate installed apps:
frida-ps -Ua
11. Identify target bundle ID
12. Locate app container:
find /private/var/containers/Bundle -name "*.app" | grep AppName
13. Review Info.plist
14. Note iOS version, app version, build number
15. Document in engagement notes
Phase 3: Traffic Interception Setup (10 minutes)
1
2
3
4
5
6
7
8
9
10
11
16. Enable Burp intercept
17. Launch target app
18. Perform basic navigation (login, main menu)
19. Review Burp HTTP History:
- Document all unique hosts
- Identify API base URL
- Note authentication mechanism (JWT, session cookie, API key)
20. If no traffic: test SSL pinning bypass
objection -g com.example.targetapp explore --startup-command "ios sslpinning disable"
21. Re-navigate app with bypass active
22. Confirm traffic flows through Burp
Phase 4: Runtime Analysis (30–60 minutes)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
23. Connect objection:
objection -g com.example.targetapp explore
24. Dump environment paths:
env
25. Dump NSUserDefaults:
ios nsuserdefaults get
26. Dump keychain:
ios keychain dump --json
27. Enable network monitoring:
ios hooking watch class NSURLSession
28. Perform authenticated actions in app
29. Review hooked output for sensitive data in transit
30. Trace cryptographic calls:
(New terminal) frida-trace -U -i "CCCrypt*" com.example.targetapp
Phase 5: Data Storage Review (20–30 minutes)
1
2
3
4
5
6
7
8
9
10
31. Navigate to app data container (objection or SSH)
32. List all files:
find /private/var/mobile/Containers/Data/Application/UUID/ -type f
33. Pull Documents and Library:
scp -r root@iphone:/private/var/mobile/Containers/Data/Application/UUID/ C:\pentest\artifacts\UUID\
34. Review all SQLite databases
35. Review all plist files
36. Review cache database (Cache.db)
37. Review cookies
38. Document all sensitive data found with file paths
Phase 6: Static Analysis (30–60 minutes)
1
2
3
4
5
6
7
8
39. Dump IPA: bagbak -U com.example.targetapp -o C:\pentest\ipas\
40. Extract IPA (rename to .zip, extract)
41. Run strings analysis on binary
42. Search for: API keys, hardcoded secrets, URLs, AWS credentials
43. Review embedded frameworks
44. Check for debug symbols
45. Open in Ghidra for deep analysis (if required)
46. Document findings
Phase 7: Evidence Export (10 minutes)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
47. Export Burp project file (Pro) or save HTTP history (Community: Ctrl+A, Save)
48. Export objection session log
49. Save Frida trace outputs
50. Organize artifacts:
C:\pentest\engagements\ClientName\YYYY-MM-DD\
├── burp\
├── frida-traces\
├── artifacts\
│ ├── databases\
│ ├── preferences\
│ └── ipa\
└── notes\
51. Screenshot key findings
52. Update engagement log
Phase 8: Lab Shutdown
1
2
3
4
5
6
53. Disable SSL Kill Switch (if enabled system-wide)
54. Remove iPhone WiFi proxy setting
55. Kill frida-server on device (optional):
ssh iphone "pkill frida-server"
56. Close Burp Suite (save project if Pro)
57. Commit notes to version control or report
Conclusion
This guide covers the complete setup and operational workflow for a professional iOS mobile application penetration testing lab running entirely on Windows 11 with a jailbroken iPhone. The setup described here is production-grade and suitable for client VAPT engagements, bug bounty work, and security research.
Key Takeaways
macOS is not required. The Windows + iPhone combination, with the right toolchain, provides full access to every essential iOS security testing capability — dynamic instrumentation, traffic interception, filesystem analysis, and runtime hooking.
Frida + Objection is the backbone. Master these two tools and you cover 80% of iOS app security testing scenarios. Custom Frida scripts handle the remaining 20% for app-specific behaviors.
Systemize your workflow. The daily workflow in Section 21 ensures you don’t miss any assessment area. Consistency produces better results and better reports.
Keep tools updated. Frida releases frequently. Mismatches between the Windows package and on-device server are the single most common lab problem. Pin versions and update both together.
Recommended Next Steps
- Practice on OWASP’s DVIA (Damn Vulnerable iOS App): https://github.com/prateek147/DVIA-v2
- Work through the OWASP Mobile Application Security Testing Guide (MASTG): https://mas.owasp.org/MASTG/
- Study the OWASP Mobile Application Security Verification Standard (MASVS): https://mas.owasp.org/MASVS/
- Follow NowSecure’s iOS security research blog for tooling updates
- Monitor Frida releases: https://github.com/frida/frida/releases
This guide is intended for authorized security testing only. Always obtain written permission before conducting any security assessment. The author and publisher are not responsible for misuse.
Author Note: This document reflects the toolchain state as of mid-2025. iOS jailbreak availability changes frequently. Always verify jailbreak support for your specific iOS version and device before beginning a lab setup.
