ios-pentesting-tricks
Installation
SKILL.md
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:
- mobile-ssl-pinning-bypass for in-depth SSL pinning bypass (SecTrust hooks, SSL Kill Switch, framework-specific techniques)
- android-pentesting-tricks when also testing the Android version of the same app
- api-sec for backend API security testing once traffic is intercepted
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
# 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)
Weekly Installs
20
Repository
yaklang/hack-skillsGitHub Stars
69
First Seen
1 day ago
Security Audits
Installed on
opencode20
gemini-cli20
deepagents20
antigravity20
github-copilot20
codex20