SKILL.md
$27
1. JAILBREAK VS NON-JAILBREAK TESTING
Capability
Jailbroken
Non-Jailbroken
SSL pinning bypass
Frida, SSL Kill Switch 2, Objection
Network debugging proxy, MITM profiles (limited)
Keychain access
keychain-dumper, Frida dump
Only via backup extraction (limited)
Filesystem inspection
Full access to app sandbox
Only via ideviceinstaller + backup
Runtime manipulation
Frida, Cycript, LLDB attach
Frida on sideloaded apps (re-signed)
Binary analysis
Class-dump, Hopper on-device
Decrypt IPA on Mac, analyze offline
Method hooking
Full Frida/Cycript capability
Limited (needs re-signed app + Frida gadget)
Non-Jailbreak Testing Setup
# Extract IPA from device
ideviceinstaller -l # List installed apps
ios-deploy --id <UDID> --download --bundle_id com.target.app
# Or use frida-ios-dump for decrypted IPA (jailbroken)
python dump.py com.target.app
# Sideload with Frida gadget (non-jailbreak runtime hooking)
# 1. Extract IPA, 2. Insert FridaGadget.dylib into Frameworks/
# 3. Re-sign with valid profile, 4. Install via ios-deploy
2. KEYCHAIN EXTRACTION
2.1 Keychain Protection Classes
Protection Class
Availability
Use Case
Risk Level
kSecAttrAccessibleWhenUnlocked
Only when device unlocked
Passwords, tokens
Medium
kSecAttrAccessibleAfterFirstUnlock
After first unlock until reboot
Background tokens
High (persists across locks)
kSecAttrAccessibleAlways
Always (deprecated iOS 12+)
Legacy apps
Critical
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
Passcode set + unlocked
High-value secrets
Low
2.2 Extraction Methods
# Jailbroken: keychain-dumper
/path/to/keychain-dumper -a # Dump all accessible items
/path/to/keychain-dumper -g password # Generic passwords only
/path/to/keychain-dumper -i # Internet passwords
# Frida / Objection
objection -g com.target.app explore
> ios keychain dump
> ios keychain dump --json # JSON output for parsing
# Frida script for keychain enumeration
frida -U -f com.target.app -l keychain_dump.js
2.3 What to Look For
Item Type
Keychain Class
Typical Content
kSecClassGenericPassword
genp
App tokens, API keys, user credentials
kSecClassInternetPassword
inet
HTTP auth credentials, OAuth tokens
kSecClassCertificate
cert
Client certificates
kSecClassIdentity
idnt
Cert + private key pair
kSecClassKey
keys
Encryption keys
3. URL SCHEME HIJACKING
3.1 Custom URL Scheme Discovery
# From IPA/app bundle — check Info.plist
plutil -p /path/to/Payload/Target.app/Info.plist | grep -A 10 CFBundleURLTypes
# Example output:
# "CFBundleURLSchemes" => ["targetapp", "fb123456789"]
3.2 Hijacking Attack
Scenario: Target app registers "targetapp://" for OAuth callback
1. Attacker app also registers "targetapp://" URL scheme
2. User initiates OAuth login in target app
3. OAuth provider redirects to targetapp://callback?code=AUTH_CODE
4. iOS may open attacker's app instead (non-deterministic scheme resolution)
5. Attacker captures OAuth authorization code
Attack Vector
Technique
Impact
OAuth callback interception
Register same scheme
Steal authorization codes
Deep link hijacking
Register same scheme
Phishing, data interception
Payment callback interception
Register payment scheme
Transaction manipulation
3.3 URL Scheme vs Universal Links Security
Feature
Custom URL Scheme
Universal Links
Registration
Any app can claim any scheme
Requires AASA file on domain
Uniqueness
Not guaranteed (multiple apps)
One app per domain path
Validation
None
Cryptographic (AASA signed)
Recommended for
Non-sensitive navigation
OAuth callbacks, sensitive actions
Hijackable
Yes (duplicate registration)
Only via AASA misconfiguration
4. UNIVERSAL LINKS EXPLOITATION
4.1 AASA (Apple-App-Site-Association) Misconfiguration
# Fetch AASA file
curl -s "https://target.com/.well-known/apple-app-site-association" | jq .
curl -s "https://target.com/apple-app-site-association" | jq .
# Check for wildcard patterns (overly broad)
# Bad: "paths": ["*"] ← captures ALL URLs
# Bad: "paths": ["/NOT *"] ← poorly written exclusion
Misconfiguration
Risk
Exploitation
Wildcard paths (*)
App claims all URLs on domain
Redirect chain may break UL → fallback to URL scheme
Missing AASA file
Universal Links won't work
App falls back to less-secure URL scheme
AASA on wrong domain
Links not associated
Scheme hijacking possible
AASA not served as application/json
Parsing failure
Links won't associate
CDN caching stale AASA
Outdated associations
Inconsistent behavior
4.2 Breaking Universal Links → URL Scheme Fallback
Technique: Force Universal Link to not open app, causing fallback to URL scheme
1. User long-presses link → "Open in Safari" (disables UL for that domain)
2. Redirect chain: domain A → domain B → target (UL breaks on redirect)
3. JavaScript redirect instead of 302 (UL only works on server-side redirects)
4. App not installed → URL scheme fallback → hijackable
5. RUNTIME MANIPULATION
5.1 Frida on iOS
# Connect to app on jailbroken device
frida -U -f com.target.app --no-pause
# Basic ObjC exploration
> ObjC.classes # List all classes
> ObjC.classes.NSURLSession # Check if class exists
> ObjC.classes.AppDelegate.$methods # List methods
> ObjC.classes.AppDelegate['- isLoggedIn'].implementation # Read method
# Hook method and modify return value
Interceptor.attach(ObjC.classes.AuthManager['- isAuthenticated'].implementation, {
onLeave: function(retval) {
retval.replace(ptr(1)); // Force return TRUE
}
});
5.2 Objection iOS Commands
objection -g com.target.app explore
# Keychain
> ios keychain dump
# Cookies
> ios cookies get
# Pasteboard
> ios pasteboard monitor
# Jailbreak detection bypass
> ios jailbreak disable
# SSL pinning bypass
> ios sslpinning disable
# Binary info
> ios info binary
# Hooking
> ios hooking watch class AppDelegate
> ios hooking watch method "-[AuthManager isAuthenticated]" --dump-args --dump-return
> ios hooking set return_value "-[AuthManager isJailbroken]" false
5.3 Cycript (Legacy but Useful)
// Attach to running app
cycript -p com.target.app
// Explore UI hierarchy
UIApp.keyWindow.recursiveDescription().toString()
// Find view controllers
[UIWindow.keyWindow().rootViewController _printHierarchy].toString()
// Call methods directly
[AppDelegate.sharedInstance isLoggedIn] // → check return
AppDelegate.sharedInstance.isLoggedIn = true // → modify
// Access singleton instances
var vc = choose(LoginViewController)[0]
vc.bypassLogin()
6. BINARY PROTECTIONS
6.1 Checking Binary Security
# PIE (Position Independent Executable)
otool -hv /path/to/binary | grep PIE
# ARC (Automatic Reference Counting)
otool -I -v /path/to/binary | grep objc_release
# Stack canaries
otool -I -v /path/to/binary | grep __stack_chk_guard
# Encryption (FairPlay DRM)
otool -l /path/to/binary | grep -A 4 LC_ENCRYPTION_INFO
# cryptid 0 = decrypted, cryptid 1 = encrypted
Protection
Check
Missing Impact
PIE
MH_PIE flag in header
ASLR disabled → predictable addresses
ARC
_objc_release symbol
Use-after-free more likely
Stack Canaries
__stack_chk_guard
Buffer overflow exploitation easier
Encryption
cryptid value
Binary readable without decryption
6.2 Decrypting IPA
# frida-ios-dump (preferred, jailbroken device)
python dump.py com.target.app
# Outputs: decrypted IPA in current directory
# bagbak (alternative)
bagbak com.target.app
# Manual via Frida
frida -U -f com.target.app -l dump_memory.js
# Dump decrypted binary from memory, replace encrypted section
6.3 Class-dump for ObjC Analysis
# Dump Objective-C class information
class-dump /path/to/decrypted/binary > classes.h
class-dump -H /path/to/decrypted/binary -o /tmp/headers/
# Search for interesting patterns
grep -r "password\|token\|secret\|apiKey\|isJailbroken\|isRooted" /tmp/headers/
7. DATA STORAGE ISSUES
7.1 Sensitive Data Locations
Location
Path
What to Check
NSUserDefaults
Library/Preferences/<bundle-id>.plist
Tokens, user data, feature flags
Core Data (SQLite)
Library/Application Support/*.sqlite
Cached API responses, user records
Keychain
System keychain database
Credentials, keys (check protection class)
Cookies
Library/Cookies/Cookies.binarycookies
Session cookies
Cache
Library/Caches/
Cached API responses, images with PII
Screenshots
Library/SplashBoard/Snapshots/
App state captured on background
Keyboard cache
Library/Keyboard/
Autocomplete entries with sensitive input
Pasteboard
System pasteboard
Copied passwords, tokens
WebView storage
Library/WebKit/WebsiteData/
LocalStorage, IndexedDB, cookies
7.2 Inspection Commands
# On jailbroken device — app sandbox at:
# /var/mobile/Containers/Data/Application/<UUID>/
# Find app UUID
find /var/mobile/Containers -name "com.target.app" 2>/dev/null
# Check NSUserDefaults
plutil -p Library/Preferences/com.target.app.plist
# Check SQLite databases
sqlite3 Library/Application\ Support/Model.sqlite ".tables"
sqlite3 Library/Application\ Support/Model.sqlite "SELECT * FROM ZUSER;"
# Check for sensitive strings in all files
grep -r "password\|token\|bearer\|api_key" Documents/ Library/
8. TRANSPORT SECURITY (ATS)
8.1 ATS Exception Patterns
<!-- Info.plist — check for ATS exceptions -->
<key>NSAppTransportSecurity</key>
<dict>
<!-- WORST: disables ATS entirely -->
<key>NSAllowsArbitraryLoads</key>
<true/>
<!-- BAD: specific domain exceptions -->
<key>NSExceptionDomains</key>
<dict>
<key>insecure-api.target.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
</dict>
</dict>
</dict>
ATS Setting
Risk
Notes
NSAllowsArbitraryLoads = true
Critical
All HTTP allowed
NSExceptionAllowsInsecureHTTPLoads
High
HTTP for specific domain
NSExceptionMinimumTLSVersion = TLSv1.0
Medium
Weak TLS
NSAllowsArbitraryLoadsInWebContent
Medium
WebView can load HTTP
No ATS exceptions
Low
Proper configuration
9. IOS PENTESTING DECISION TREE
Testing iOS application
│
├── Device jailbroken?
│ ├── Yes → full testing capability
│ │ ├── Keychain dump → ios keychain dump (§2)
│ │ ├── Filesystem inspection → check all data storage (§7)
│ │ ├── Runtime hooks → Frida/Objection (§5)
│ │ └── Binary analysis → class-dump decrypted binary (§6)
│ └── No → limited testing
│ ├── Re-sign with Frida gadget for runtime access
│ ├── Backup extraction for data analysis
│ └── Network-level testing (proxy + SSL bypass)
│
├── SSL pinning blocking proxy?
│ └── Yes → see mobile-ssl-pinning-bypass SKILL.md
│
├── URL schemes registered?
│ ├── OAuth callback via URL scheme? → hijacking risk (§3.2)
│ ├── Universal Links configured? → check AASA (§4.1)
│ └── Scheme used for sensitive actions? → test interception
│
├── Binary protections adequate?
│ ├── Missing PIE? → ASLR disabled (§6.1)
│ ├── No stack canaries? → overflow risk (§6.1)
│ └── Still encrypted? → decrypt first (§6.2)
│
├── Data storage secure?
│ ├── Tokens in NSUserDefaults? → plaintext extraction (§7.1)
│ ├── Keychain protection class? → AfterFirstUnlock = risky (§2.1)
│ ├── Screenshots captured? → check Snapshots dir (§7.1)
│ └── Keyboard cache? → check for sensitive autocomplete (§7.1)
│
├── ATS configured?
│ ├── ArbitraryLoads = true? → HTTP downgrade possible (§8)
│ └── Domain exceptions? → targeted HTTP interception
│
└── Runtime manipulation needed?
├── Jailbreak detection blocking? → ios jailbreak disable (§5.2)
├── Need to bypass auth check? → hook + modify return (§5.1)
└── Need to trace API calls? → method hooking (§5.2)