Documentation Index
Fetch the complete documentation index at: https://mintlify.com/HackTricks-wiki/hacktricks/llms.txt
Use this file to discover all available pages before exploring further.
iOS Security Fundamentals
Sandbox & Privilege Separation
iOS apps run under the mobile user identity while core system processes run as root. Each app operates in its own sandbox (private/var/mobile/Applications/{random ID}) with strict restrictions enforced by the Trusted BSD (MAC) Mandatory Access Control Framework.
Data Protection Classes
iOS provides four protection classes using AES encryption tied to the device UID and user passcode:
| Class | Accessibility |
|---|
NSFileProtectionComplete | Only when device is unlocked |
NSFileProtectionCompleteUnlessOpen | After first unlock, even if locked again |
NSFileProtectionCompleteUntilFirstUserAuthentication | After first post-boot unlock (default from iOS 7) |
NSFileProtectionNone | Protected only by device UID |
The Keychain
The Keychain is an encrypted container for sensitive data (tokens, passwords, certificates). Encrypted with AES using a key derived from PBKDF2(user passcode, device UID). Access is controlled by securityd based on app entitlements.
Important: Keychain data persists after app uninstallation. Always clear Keychain items on first launch.
// Clear Keychain on first launch
let userDefaults = UserDefaults.standard
if userDefaults.bool(forKey: "hasRunBefore") == false {
// Remove Keychain items here
userDefaults.set(true, forKey: "hasRunBefore")
userDefaults.synchronize()
}
Keychain access levels (kSecAttrAccessible):
kSecAttrAccessibleWhenUnlocked — only when device is unlocked
kSecAttrAccessibleAfterFirstUnlock — after first post-reboot unlock
kSecAttrAccessibleAlways — always (not recommended for sensitive data)
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly — requires device passcode, not in backups
IPA Structure
An IPA is a ZIP file. Rename to .zip and unzip to explore:
<AppName>.app/
Info.plist — configuration (permissions, URL schemes, ATS settings)
_CodeSignature/ — digital signatures for all bundle files
Assets.car — compressed graphical assets
Frameworks/ — native libraries (.dylib, .framework)
PlugIns/ — app extensions (.appex)
<AppBinary> — main executable
Info.plist Key Areas
# Convert binary plist to XML
plutil -convert xml1 Info.plist # macOS
apt install libplist-utils
plistutil -i Info.plist -o Info_xml.plist # Linux
# Find sensitive entries
grep -i CFBundleURLTypes Info.plist # Custom URL schemes
grep -i NSAppTransportSecurity Info.plist # ATS config
grep -i UsageDescription Info.plist # Permission strings
Data Paths
# Bundle path (read-only, not backed up)
/var/containers/Bundle/Application/<UUID>/<AppName>.app
# Data paths (backed up by default)
/var/mobile/Containers/Data/Application/<UUID>/Documents/
/var/mobile/Containers/Data/Application/<UUID>/Library/
/var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/
/var/mobile/Containers/Data/Application/<UUID>/tmp/
# Use objection to get paths easily
env
Static Analysis
Binary Security Properties
# PIE (randomized load address)
otool -hv <app-binary> | grep PIE
# Stack canaries
otool -I -v <app-binary> | grep stack_chk
# ARC (Automatic Reference Counting)
otool -I -v <app-binary> | grep objc_release
# Encryption check
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT
Disassembly & Decompilation
# Basic binary inspection
otool -Vh DVIA-v2 # Compilation attributes
otool -L DVIA-v2 # Third-party libraries
otool -tV DVIA-v2 # Disassemble text section
otool -oV DVIA-v2 # Objective-C segment
# Extract class declarations
class-dump <app-binary>
# Best options for full decompilation:
# Hopper: https://www.hopperapp.com
# IDA Pro / IDA Free: https://hex-rays.com
# Malimite: https://github.com/LaurieWired/Malimite
# Ghidra: https://ghidra-sre.org
Insecure Function Detection
# Weak hashing
otool -Iv <app> | grep -w "_CC_MD5"
otool -Iv <app> | grep -w "_CC_SHA1"
# Insecure random functions
otool -Iv <app> | grep -w "_random"
# Dangerous memory functions
otool -Iv <app> | grep -w "_gets"
otool -Iv <app> | grep -w "_sprintf"
Dynamic Analysis
Setup & Listing Apps
# List installed apps and bundle IDs
frida-ps -Uai
# Find app data directory
find /private/var/containers -name "<AppName>*"
# Process info
ps -ef | grep -i <app-name>
lsof -p <pid> | grep -i "/containers" | head -n 1
Jailbreak & Anti-Debug Detection Bypass
Jailbreak Detection
Anti-Debug Detection
Apps check for:
- Presence of
/Applications/Cydia.app, /Library/MobileSubstrate/MobileSubstrate.dylib
- Ability to call
fork() or system()
- Known jailbreak processes (
Cydia, Substrate)
- URL schemes like
cydia://
DYLD_INSERT_LIBRARIES environment variable
Apps check for:
sysctl queries for debugger attachment
ptrace(PT_DENY_ATTACH, 0, 0, 0) calls
- Timing discrepancies during debugging
- Mach exception ports
Data Storage Testing
# Dump NSUserDefaults
ios nsuserdefaults get
# Read plist via objection
ios plist cat /private/var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/com.app.bundle.plist
# Dump cookies
ios cookies get --json
# Dump keychain
ios keychain dump
# Dump credentials from NSURLCredentialStorage
ios nsurlcredentialstorage dump
Snapshot Protection
When an app is backgrounded, iOS saves a screen snapshot. Prevent sensitive data leakage:
func applicationDidEnterBackground(_ application: UIApplication) {
let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage"))
myBanner.frame = UIScreen.main.bounds
window?.addSubview(myBanner)
}
Local Authentication Bypass
Objection Biometrics Bypass
This hooks evaluatePolicy via Frida to always return True.
Frida Hook (DVIA-v2 Example)
// Hook evaluatePolicy to always succeed
var hook = ObjC.classes["LAContext"]["- evaluatePolicy:localizedReason:reply:"];
Interceptor.attach(hook.implementation, {
onEnter: function (args) {
// Modify reply block to always call with YES
var block = new ObjC.Block(args[4]);
var originalImpl = block.implementation;
block.implementation = function (error, success) {
return originalImpl(null, true);
};
}
});
Network Communication
Certificate Pinning Bypass
# Using Objection
ios sslpinning disable
# Find pinning indicators in binary
rabin2 -zz <binary> | grep -i "pinning\|certificate\|sha256"
Proxy Setup
- Install Burp CA certificate on the device (Settings > General > VPN & Device Management)
- Trust the certificate (Settings > General > About > Certificate Trust Settings)
- Configure the device to use Burp as HTTP proxy
- For certificate pinning, use Objection or a Frida script to bypass
Memory Analysis
# Dump memory with Objection
memory dump all mem.dump
# Analyze strings
strings mem.dump > strings.txt
rabin2 -ZZ mem.dump > strings.txt
# Real-time memory search with r2frida
r2 frida://usb//<app_name>
[0x00000000]> /\ <search_term>
Automated Analysis with MobSF
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
Upload your IPA for automatic static analysis covering binary properties, Info.plist, URL schemes, ATS settings, and more.
References