🔍 What is Dynamic Analysis in iOS?
Dynamic analysis involves inspecting the behavior of an iOS application while it is running on a device or emulator. This method helps uncover real-time vulnerabilities such as insecure API communication, insecure data storage, runtime manipulations, and more.
Unlike static analysis, which examines code or binaries, dynamic testing focuses on observing the app’s live behavior, interactions with the system, and network communications.
🛠️ Essential Tools for iOS Dynamic Analysis
- Frida: Dynamic instrumentation toolkit for manipulating app behavior at runtime
- Cycript / Objection: For interacting with apps on jailbroken devices
- Charles Proxy / Burp Suite: Intercept and modify HTTPS traffic
- SSL Kill Switch 2: Bypass SSL pinning on jailbroken devices
- tcpdump: Monitor network traffic at packet level
🚀 Step-by-Step iOS Dynamic Testing Workflow
Step 1: Prepare the Environment
- Use a jailbroken iOS device (e.g., via Checkra1n)
- Install
Cydia
and required packages likeFrida
,OpenSSH
, andSSL Kill Switch 2
- Ensure USB tunneling or Wi-Fi SSH access is configured
Step 2: Monitor App Network Traffic
Use a proxy tool like Burp Suite or Charles:
# On your Mac:
sudo ifconfig en0 | grep "inet " # Get IP address
# On iOS (proxy settings):
Settings > Wi-Fi > HTTP Proxy > Manual > Enter Mac IP and Port 8080
# In Burp:
- Enable proxy listener on 8080
- Install Burp CA on device for HTTPS interception
This lets you see API endpoints, sensitive data in transit, tokens, and more.
Step 3: Bypass SSL Pinning
Many modern iOS apps implement SSL pinning. Use SSL Kill Switch 2 or Frida scripts to bypass it.
# Disable SSL pinning using SSL Kill Switch 2
Install via Cydia, then reboot the device
# Or use Frida:
frida -U -n TargetApp -l ios-sslpinning-bypass.js
Step 4: Hook App Functions using Frida
Example: Hooking NSUserDefaults
read/write actions
frida -U -n TargetApp -l hookNSUserDefaults.js
// hookNSUserDefaults.js
ObjC.classes.NSUserDefaults["- stringForKey:"].implementation = function(key) {
console.log("[*] Reading key: " + key.toString());
return this.stringForKey_(key);
};
⚙️ Advanced Techniques
- Use Objection to explore the app’s file system and keychain
- Perform memory analysis for sensitive data (e.g., tokens, passwords)
- Analyze dynamic libraries (dylibs) loaded at runtime
- Look for insecure permissions or misused entitlements
🌐 Real-World Use Case
Scenario: Testing an iOS banking app revealed that after login, an auth token was stored in NSUserDefaults
, which is insecure.
Using Frida, the token was intercepted during runtime:
[*] Reading key: auth_token
[*] Value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
This token could then be reused in API requests via Burp to simulate authenticated user actions.
💡 Tips for Effective Dynamic Analysis
- Always test on non-production apps or sandbox environments
- Combine static + dynamic analysis for better coverage
- Log all Frida scripts, intercepted requests, and modified behavior
- Use snapshot tools to capture before/after states of files or keychain entries