Post

iOS Pentesting Complete Guide by SurajSharma

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:

ToolPrimary Benefit
FridaDynamic instrumentation; hook any function at runtime without recompiling
ObjectionFrida automation; common pentesting tasks with single commands
Burp SuiteHTTP/HTTPS proxy; intercept, modify, replay traffic
SSHRemote shell access to the device filesystem
OpenSSH/SFTPFile 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

ItemSpecificationNotes
Windows PCWindows 11 (22H2+)16GB RAM recommended; 8GB minimum
iPhoneSee table belowMust support current jailbreak
USB CableLightning or USB-C (device native)Data-capable cable — not charge-only
WiFi RouterAny 2.4GHz/5GHz routerPC and iPhone on same subnet
USB HubOptionalUseful if port conflicts arise

iPhone Compatibility Matrix

DeviceMax iOSJailbreakTool SupportRecommendation
iPhone XiOS 16.xDopamine (rootless)Full★★★★ Good
iPhone XS/XS MaxiOS 16.xDopamine (rootless)Full★★★★ Good
iPhone 11 / ProiOS 17.xDopamine 2.x (beta)Full★★★★★ Excellent
iPhone 12 / ProiOS 17.xDopamine 2.x (beta)Full★★★★★ Excellent
iPhone 13iOS 17.xDopamine 2.x (beta)Full★★★★★ Excellent
iPhone SE (2nd)iOS 16.xDopamine (rootless)Full★★★★ Good
iPhone 6s/7/8iOS 15.xPalera1n (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 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:

  1. Download Dopamine IPA from GitHub releases
  2. Sideload using TrollStore (if available on your iOS version) or AltStore
  3. Run Dopamine from home screen
  4. Tap “Jailbreak” — device will respring
  5. Verify: Sileo/Zebra appear on home screen

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

AspectRootfulRootless
FilesystemWrites to /Writes to /var/jb/
FridaFull supportFull support (adjusted paths)
SSH/usr/bin/ssh/var/jb/usr/bin/ssh
CompatibilityMaximumGrowing ecosystem
StabilityVery stableIncreasingly stable
Modern devicesA11 and older onlyA12+ 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 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:

  1. Open your current package manager (Zebra may be present)
  2. Add the Sileo repository: https://repo.sileoapps.com/
  3. 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:

  1. Open Sileo
  2. Navigate to Sources tab
  3. Tap the + button (top right)
  4. Add required repositories (see Section 5)
  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

RepositoryURLPurposeKey Packages
Charizhttps://repo.chariz.com/Premium tweaks, utilitiesVarious system tweaks
Havochttps://havoc.app/Curated packagesVarious tools
Procursus (Dopamine)https://apt.procurs.us/Core Unix toolsOpenSSH, curl, wget, vim
BigBosshttps://apt.thebigboss.org/repofiles/cydia/Legacy packagesAppSync Unified
Fridahttps://build.frida.re/Frida serverfrida, frida-server
RootHide Bootstraphttps://roothidejb.github.io/repo/Rootless essentialsBootstrap packages
Checkra1n (legacy)https://apt.bingner.com/Elucubratus toolsCore binaries

How to Add a Repository

In Sileo:

  1. Open Sileo → Sources tab
  2. Tap Edit+
  3. Enter the repository URL exactly as shown
  4. Tap Add Source
  5. Wait for index refresh

In Zebra:

  1. Open Zebra → Sources tab
  2. Tap + icon
  3. 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.

  1. Download from https://winscp.net/
  2. Install with default settings
  3. 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 alpine is 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

  1. Open WinSCP
  2. New Session → SFTP → Host: 192.168.1.45 → Username: root → Password: (your new password)
  3. Connect
  4. Navigate iPhone filesystem on the right panel; Windows on left
  5. 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

  1. Launch Burp Suite
  2. Navigate to Proxy → Options (or Proxy → Proxy Settings in newer versions)
  3. Under Proxy Listeners, click Add:
    • Bind to port: 8080
    • Bind to address: All interfaces (or your specific WiFi IP)
  4. Click OK
  5. 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

  1. On iPhone: Settings → Wi-Fi → (i) next to your network
  2. Scroll to HTTP PROXY section
  3. Select Manual
  4. Server: Your Windows PC’s IP address (e.g., 192.168.1.100)
  5. Port: 8080
  6. Authentication: Off (unless you’ve configured Burp auth)
  7. 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:

  1. Target → Scope → Add target domain/IP
  2. 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:

  1. On iPhone Safari: Navigate to http://burpsuite or http://YOUR_PC_IP:8080
  2. Tap CA Certificate
  3. iOS will prompt: “This website is trying to download a configuration profile”
  4. Tap Allow

Step 2: Install the Profile

  1. Go to Settings → General → VPN & Device Management
  2. Under “Downloaded Profile” you will see PortSwigger CA
  3. Tap it → Tap Install (top right)
  4. Enter your iPhone passcode if prompted
  5. Tap Install on the warning screen
  6. Tap Done

Step 3: Trust the Certificate

Installing alone is insufficient — you must explicitly trust it for SSL:

  1. Settings → General → About → Certificate Trust Settings
  2. Under “Enable Full Trust For Root Certificates”
  3. Toggle on PortSwigger CA
  4. 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

ErrorCauseFix
“Cannot Verify Server Identity”Certificate not trustedComplete Step 3
“Safari Cannot Open the Page”Proxy not set / Burp not runningVerify listener, verify WiFi proxy
Certificate shows but HTTPS failsApp uses SSL pinningSee Section 12
Profile install failsiOS 15+ requires Safari for profile downloadUse 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

MethodImplementationHook Target
Certificate pinningHard-coded .der cert in bundleSecTrustEvaluate
Public key pinningPinned public key hashSSL handshake validation
TrustKitThird-party libraryTrustKit evaluate methods
AlamofireServerTrustPolicyAlamofire evaluation
OkHttp (React Native)CertificatePinnerOkHttp3 methods
Native NSURLSessionCustom URLAuthenticationChallengeURLSession delegate

Bypass Approaches Overview

There are three primary approaches for authorized testing:

  1. Objection (automated): Single command leverages Frida scripts to hook common pinning implementations
  2. Custom Frida scripts: Target app-specific pinning logic discovered through static analysis
  3. 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:

  1. Launch target app
  2. Perform an action that makes a network request
  3. Check Burp HTTP History — HTTPS requests should now appear
  4. 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)

  1. Add Frida repo: https://build.frida.re/
  2. Sileo → Search → “Frida” → Install
  3. 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

ErrorCauseFix
Failed to enumerate processesfrida-server not runningSSH → start frida-server
Unable to connect to remote frida-serverVersion mismatchMatch versions
Frida is not installed on this devicePackage missingInstall via Sileo
Access deniedServer not running as rootRun as root: sudo frida-server &
Spawn failed: unable to find processBundle ID wrongVerify 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 domain
  • NSAllowsLocalNetworking → 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)

  1. Download Ghidra from https://ghidra-sre.org/
  2. Launch Ghidra → New Project → Import File → Select Mach-O binary
  3. Ghidra will detect ARM64 architecture automatically
  4. Run auto-analysis
  5. 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
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 --all flag 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.

  • 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.

This post is licensed under CC BY 4.0 by the author.