| name | ios-pentesting-tricks |
| description | iOS pentesting playbook. Use when testing iOS applications for keychain extraction, URL scheme hijacking, Universal Links exploitation, runtime manipulation, binary protection analysis, data storage issues, and transport security bypass during authorized mobile security assessments. |
SKILL: iOS Pentesting Tricks — Expert Attack Playbook
AI LOAD INSTRUCTION: Expert iOS application security testing techniques. Covers jailbreak vs non-jailbreak methodology, keychain extraction, URL scheme/Universal Links abuse, Frida/Objection runtime hooks, binary protection checks, and data storage analysis. Base models miss protection class nuances and AASA misconfiguration patterns.
0. RELATED ROUTING
Before going deep, consider loading:
Advanced Reference
Also load IOS_RUNTIME_TRICKS.md when you need:
- Frida recipes for iOS-specific hooks (ObjC class enumeration, method swizzling)
- Objection command reference for iOS
- Runtime hooking patterns and bypass templates
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
ideviceinstaller -l
ios-deploy --id <UDID> --download --bundle_id com.target.app
python dump.py com.target.app
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
/path/to/keychain-dumper -a
/path/to/keychain-dumper -g password
/path/to/keychain-dumper -i
objection -g com.target.app explore
> ios keychain dump
> ios keychain dump --json
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
plutil -p /path/to/Payload/Target.app/Info.plist | grep -A 10 CFBundleURLTypes
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
curl -s "https://target.com/.well-known/apple-app-site-association" | jq .
curl -s "https://target.com/apple-app-site-association" | jq .
| 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
frida -U -f com.target.app --no-pause
> ObjC.classes
> ObjC.classes.NSURLSession
> ObjC.classes.AppDelegate.$methods
> ObjC.classes.AppDelegate['- isLoggedIn'].implementation
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
> ios keychain dump
> ios cookies get
> ios pasteboard monitor
> ios jailbreak disable
> ios sslpinning disable
> ios info binary
> 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)
cycript -p com.target.app
UIApp.keyWindow.recursiveDescription().toString()
[UIWindow.keyWindow().rootViewController _printHierarchy].toString()
[AppDelegate.sharedInstance isLoggedIn]
AppDelegate.sharedInstance.isLoggedIn = true
var vc = choose(LoginViewController)[0]
vc.bypassLogin()
6. BINARY PROTECTIONS
6.1 Checking Binary Security
otool -hv /path/to/binary | grep PIE
otool -I -v /path/to/binary | grep objc_release
otool -I -v /path/to/binary | grep __stack_chk_guard
otool -l /path/to/binary | grep -A 4 LC_ENCRYPTION_INFO
| 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
python dump.py com.target.app
bagbak com.target.app
frida -U -f com.target.app -l dump_memory.js
6.3 Class-dump for ObjC Analysis
class-dump /path/to/decrypted/binary > classes.h
class-dump -H /path/to/decrypted/binary -o /tmp/headers/
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
find /var/mobile/Containers -name "com.target.app" 2>/dev/null
plutil -p Library/Preferences/com.target.app.plist
sqlite3 Library/Application\ Support/Model.sqlite ".tables"
sqlite3 Library/Application\ Support/Model.sqlite "SELECT * FROM ZUSER;"
grep -r "password\|token\|bearer\|api_key" Documents/ Library/
8. TRANSPORT SECURITY (ATS)
8.1 ATS Exception Patterns
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<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)