ios-pentesting-tricks

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SKILL: iOS Pentesting Tricks — Expert Attack Playbook

SKILL: iOS渗透测试技巧 — 专家攻击手册

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.
AI加载说明:专业iOS应用安全测试技术,涵盖越狱与非越狱测试方法论、keychain提取、URL scheme/Universal Links滥用、Frida/Objection运行时钩子、二进制保护检查以及数据存储分析。基础模型会遗漏保护类的细节差异和AASA配置错误模式。

0. RELATED ROUTING

0. 相关关联资源

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
深入学习前,可考虑加载以下内容:
  • mobile-ssl-pinning-bypass 用于深入学习SSL pinning绕过(SecTrust钩子、SSL Kill Switch、框架专属技术)
  • android-pentesting-tricks 当你同时测试同一款应用的Android版本时使用
  • api-sec 用于拦截流量后开展后端API安全测试

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

当你需要以下内容时,也可以加载 IOS_RUNTIME_TRICKS.md
  • iOS专属钩子的Frida脚本模板(ObjC类枚举、方法交换)
  • iOS版Objection命令参考
  • 运行时钩子模式和绕过模板

1. JAILBREAK VS NON-JAILBREAK TESTING

1. 越狱VS非越狱测试

CapabilityJailbrokenNon-Jailbroken
SSL pinning bypassFrida, SSL Kill Switch 2, ObjectionNetwork debugging proxy, MITM profiles (limited)
Keychain accesskeychain-dumper, Frida dumpOnly via backup extraction (limited)
Filesystem inspectionFull access to app sandboxOnly via
ideviceinstaller
+ backup
Runtime manipulationFrida, Cycript, LLDB attachFrida on sideloaded apps (re-signed)
Binary analysisClass-dump, Hopper on-deviceDecrypt IPA on Mac, analyze offline
Method hookingFull Frida/Cycript capabilityLimited (needs re-signed app + Frida gadget)
功能越狱设备非越狱设备
SSL pinning绕过Frida、SSL Kill Switch 2、Objection网络调试代理、MITM配置文件(能力有限)
Keychain访问keychain-dumper、Frida导出仅可通过备份提取(能力有限)
文件系统查看完整访问应用沙箱仅可通过
ideviceinstaller
+备份查看
运行时操纵Frida、Cycript、LLDB附着侧载应用上使用Frida(需重签名)
二进制分析设备上直接运行Class-dump、Hopper在Mac上解密IPA,离线分析
方法钩子完整的Frida/Cycript能力能力受限(需重签名应用+Frida gadget)

Non-Jailbreak Testing Setup

非越狱测试环境搭建

bash
undefined
bash
undefined

Extract IPA from device

从设备导出IPA

ideviceinstaller -l # List installed apps ios-deploy --id <UDID> --download --bundle_id com.target.app
ideviceinstaller -l # 列出已安装应用 ios-deploy --id <UDID> --download --bundle_id com.target.app

Or use frida-ios-dump for decrypted IPA (jailbroken)

或者使用frida-ios-dump导出解密后的IPA(需越狱)

python dump.py com.target.app
python dump.py com.target.app

Sideload with Frida gadget (non-jailbreak runtime hooking)

注入Frida gadget侧载(非越狱运行时钩子)

1. Extract IPA, 2. Insert FridaGadget.dylib into Frameworks/

1. 解压IPA,2. 将FridaGadget.dylib放入Frameworks/目录

3. Re-sign with valid profile, 4. Install via ios-deploy

3. 用有效配置文件重签名,4. 通过ios-deploy安装


---

---

2. KEYCHAIN EXTRACTION

2. KEYCHAIN提取

2.1 Keychain Protection Classes

2.1 Keychain保护等级

Protection ClassAvailabilityUse CaseRisk Level
kSecAttrAccessibleWhenUnlocked
Only when device unlockedPasswords, tokensMedium
kSecAttrAccessibleAfterFirstUnlock
After first unlock until rebootBackground tokensHigh (persists across locks)
kSecAttrAccessibleAlways
Always (deprecated iOS 12+)Legacy appsCritical
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
Passcode set + unlockedHigh-value secretsLow
保护等级可用条件使用场景风险等级
kSecAttrAccessibleWhenUnlocked
仅设备解锁时可用密码、令牌
kSecAttrAccessibleAfterFirstUnlock
首次解锁后到重启前可用后台令牌高(锁屏后仍可访问)
kSecAttrAccessibleAlways
始终可用(iOS12+已废弃)legacy应用极高
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
设置密码+设备解锁高价值机密信息

2.2 Extraction Methods

2.2 提取方法

bash
undefined
bash
undefined

Jailbroken: keychain-dumper

越狱设备: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
/path/to/keychain-dumper -a # 导出所有可访问的条目 /path/to/keychain-dumper -g password # 仅导出通用密码 /path/to/keychain-dumper -i # 互联网密码

Frida / Objection

Frida / Objection

objection -g com.target.app explore
ios keychain dump ios keychain dump --json # JSON output for parsing
objection -g com.target.app explore
ios keychain dump ios keychain dump --json # 输出JSON格式便于解析

Frida script for keychain enumeration

用于keychain枚举的Frida脚本

frida -U -f com.target.app -l keychain_dump.js
undefined
frida -U -f com.target.app -l keychain_dump.js
undefined

2.3 What to Look For

2.3 重点检查内容

Item TypeKeychain ClassTypical 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

条目类型Keychain分类典型内容
kSecClassGenericPassword
genp
应用令牌、API密钥、用户凭证
kSecClassInternetPassword
inet
HTTP认证凭证、OAuth令牌
kSecClassCertificate
cert
客户端证书
kSecClassIdentity
idnt
证书+私钥对
kSecClassKey
keys
加密密钥

3. URL SCHEME HIJACKING

3. URL SCHEME劫持

3.1 Custom URL Scheme Discovery

3.1 自定义URL Scheme发现

bash
undefined
bash
undefined

From IPA/app bundle — check Info.plist

从IPA/应用包中查看Info.plist

plutil -p /path/to/Payload/Target.app/Info.plist | grep -A 10 CFBundleURLTypes
plutil -p /path/to/Payload/Target.app/Info.plist | grep -A 10 CFBundleURLTypes

Example output:

示例输出:

"CFBundleURLSchemes" => ["targetapp", "fb123456789"]

"CFBundleURLSchemes" => ["targetapp", "fb123456789"]

undefined
undefined

3.2 Hijacking Attack

3.2 劫持攻击

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 VectorTechniqueImpact
OAuth callback interceptionRegister same schemeSteal authorization codes
Deep link hijackingRegister same schemePhishing, data interception
Payment callback interceptionRegister payment schemeTransaction manipulation
场景:目标应用注册了"targetapp://"作为OAuth回调地址

1. 攻击者应用也注册"targetapp://" URL scheme
2. 用户在目标应用中发起OAuth登录
3. OAuth提供方跳转至targetapp://callback?code=AUTH_CODE
4. iOS可能会优先打开攻击者的应用(scheme解析不唯一)
5. 攻击者获取OAuth授权码
攻击向量技术手段影响
OAuth回调拦截注册相同scheme窃取授权码
深链接劫持注册相同scheme钓鱼、数据拦截
支付回调拦截注册支付scheme篡改交易信息

3.3 URL Scheme vs Universal Links Security

3.3 URL Scheme与Universal Links安全性对比

FeatureCustom URL SchemeUniversal Links
RegistrationAny app can claim any schemeRequires AASA file on domain
UniquenessNot guaranteed (multiple apps)One app per domain path
ValidationNoneCryptographic (AASA signed)
Recommended forNon-sensitive navigationOAuth callbacks, sensitive actions
HijackableYes (duplicate registration)Only via AASA misconfiguration

特性自定义URL SchemeUniversal Links
注册规则任何应用可声明任何scheme需要域名下托管AASA文件
唯一性不保证(多个应用可注册相同scheme)每个域名路径对应唯一应用
校验机制加密校验(AASA签名)
推荐使用场景非敏感跳转OAuth回调、敏感操作
是否可被劫持是(重复注册即可)仅可通过AASA配置错误劫持

4. UNIVERSAL LINKS EXPLOITATION

4. UNIVERSAL LINKS利用

4.1 AASA (Apple-App-Site-Association) Misconfiguration

4.1 AASA(Apple-App-Site-Association)配置错误

bash
undefined
bash
undefined

Fetch AASA file

获取AASA文件

Check for wildcard patterns (overly broad)

检查通配符规则(范围过宽)

Bad: "paths": ["*"] ← captures ALL URLs

错误示例:"paths": ["*"] ← 匹配域名下所有URL

Bad: "paths": ["/NOT *"] ← poorly written exclusion

错误示例:"paths": ["/NOT *"] ← 排除规则编写错误


| 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 |

| 配置错误 | 风险 | 利用方式 |
|---|---|---|
| 通配符路径(`*`) | 应用声明域名下所有URL的所有权 | 跳转链可能破坏UL → 回退到URL scheme |
| AASA文件缺失 | Universal Links无法生效 | 应用回退到安全性更低的URL scheme |
| AASA放在错误域名下 | 关联失败 | 可能发生scheme劫持 |
| AASA返回的Content-Type不是`application/json` | 解析失败 | 链接无法关联应用 |
| CDN缓存了过期的AASA | 关联规则过时 | 行为不一致 |

4.2 Breaking Universal Links → URL Scheme Fallback

4.2 破坏Universal Links → 回退到URL scheme

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

技术:强制Universal Links不打开应用,触发回退到URL scheme

1. 用户长按链接 → 选择「在Safari中打开」(禁用该域名的UL)
2. 跳转链:域名A → 域名B → 目标地址(跳转过程中UL失效)
3. 使用JavaScript跳转而非302跳转(UL仅支持服务端跳转)
4. 未安装应用 → 回退到URL scheme → 可被劫持

5. RUNTIME MANIPULATION

5. 运行时操纵

5.1 Frida on iOS

5.1 iOS上使用Frida

bash
undefined
bash
undefined

Connect to app on jailbroken device

连接越狱设备上的应用

frida -U -f com.target.app --no-pause
frida -U -f com.target.app --no-pause

Basic ObjC exploration

基础ObjC探索

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
ObjC.classes # 列出所有类 ObjC.classes.NSURLSession # 检查类是否存在 ObjC.classes.AppDelegate.$methods # 列出方法 ObjC.classes.AppDelegate['- isLoggedIn'].implementation # 读取方法实现

Hook method and modify return value

钩子方法并修改返回值

Interceptor.attach(ObjC.classes.AuthManager['- isAuthenticated'].implementation, { onLeave: function(retval) { retval.replace(ptr(1)); // Force return TRUE } });
undefined
Interceptor.attach(ObjC.classes.AuthManager['- isAuthenticated'].implementation, { onLeave: function(retval) { retval.replace(ptr(1)); // 强制返回TRUE } });
undefined

5.2 Objection iOS Commands

5.2 iOS Objection命令

bash
objection -g com.target.app explore
bash
objection -g com.target.app explore

Keychain

Keychain相关

ios keychain dump
ios keychain dump

Cookies

Cookie相关

ios cookies get
ios cookies get

Pasteboard

剪贴板相关

ios pasteboard monitor
ios pasteboard monitor

Jailbreak detection bypass

越狱检测绕过

ios jailbreak disable
ios jailbreak disable

SSL pinning bypass

SSL pinning绕过

ios sslpinning disable
ios sslpinning disable

Binary info

二进制信息

ios info binary
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
undefined
ios hooking watch class AppDelegate ios hooking watch method "-[AuthManager isAuthenticated]" --dump-args --dump-return ios hooking set return_value "-[AuthManager isJailbroken]" false
undefined

5.3 Cycript (Legacy but Useful)

5.3 Cycript(过时但实用)

javascript
// 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()

javascript
// 附着到运行中的应用
cycript -p com.target.app

// 探索UI层级
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. 二进制保护

6.1 Checking Binary Security

6.1 检查二进制安全配置

bash
undefined
bash
undefined

PIE (Position Independent Executable)

PIE(位置无关可执行文件)

otool -hv /path/to/binary | grep PIE
otool -hv /path/to/binary | grep PIE

ARC (Automatic Reference Counting)

ARC(自动引用计数)

otool -I -v /path/to/binary | grep objc_release
otool -I -v /path/to/binary | grep objc_release

Stack canaries

栈金丝雀

otool -I -v /path/to/binary | grep __stack_chk_guard
otool -I -v /path/to/binary | grep __stack_chk_guard

Encryption (FairPlay DRM)

加密(FairPlay DRM)

otool -l /path/to/binary | grep -A 4 LC_ENCRYPTION_INFO
otool -l /path/to/binary | grep -A 4 LC_ENCRYPTION_INFO

cryptid 0 = decrypted, cryptid 1 = encrypted

cryptid 0 = 已解密, cryptid 1 = 已加密


| 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 |

| 保护机制 | 检查项 | 缺失的影响 |
|---|---|---|
| PIE | 头部存在`MH_PIE`标志 | ASLR禁用 → 地址可预测 |
| ARC | 存在`_objc_release`符号 | 更容易出现释放后重用漏洞 |
| 栈金丝雀 | 存在`__stack_chk_guard` | 缓冲区溢出利用难度更低 |
| 加密 | `cryptid`值 | 无需解密即可读取二进制内容 |

6.2 Decrypting IPA

6.2 解密IPA

bash
undefined
bash
undefined

frida-ios-dump (preferred, jailbroken device)

frida-ios-dump(首选,需越狱设备)

python dump.py com.target.app
python dump.py com.target.app

Outputs: decrypted IPA in current directory

输出:当前目录下生成解密后的IPA

bagbak (alternative)

bagbak(替代方案)

bagbak com.target.app
bagbak com.target.app

Manual via Frida

手动通过Frida解密

frida -U -f com.target.app -l dump_memory.js
frida -U -f com.target.app -l dump_memory.js

Dump decrypted binary from memory, replace encrypted section

从内存中导出解密后的二进制,替换加密段

undefined
undefined

6.3 Class-dump for ObjC Analysis

6.3 使用Class-dump做ObjC分析

bash
undefined
bash
undefined

Dump Objective-C class information

导出Objective-C类信息

class-dump /path/to/decrypted/binary > classes.h class-dump -H /path/to/decrypted/binary -o /tmp/headers/
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/

---
grep -r "password|token|secret|apiKey|isJailbroken|isRooted" /tmp/headers/

---

7. DATA STORAGE ISSUES

7. 数据存储问题

7.1 Sensitive Data Locations

7.1 敏感数据存储位置

LocationPathWhat 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
KeychainSystem keychain databaseCredentials, 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
PasteboardSystem pasteboardCopied passwords, tokens
WebView storage
Library/WebKit/WebsiteData/
LocalStorage, IndexedDB, cookies
位置路径检查内容
NSUserDefaults
Library/Preferences/<bundle-id>.plist
令牌、用户数据、功能开关
Core Data(SQLite)
Library/Application Support/*.sqlite
缓存的API响应、用户记录
Keychain系统keychain数据库凭证、密钥(检查保护等级)
Cookies
Library/Cookies/Cookies.binarycookies
会话Cookie
缓存
Library/Caches/
缓存的API响应、含PII的图片
截图
Library/SplashBoard/Snapshots/
应用切后台时捕获的状态
键盘缓存
Library/Keyboard/
含敏感输入的自动补全条目
剪贴板系统剪贴板复制的密码、令牌
WebView存储
Library/WebKit/WebsiteData/
LocalStorage、IndexedDB、Cookie

7.2 Inspection Commands

7.2 检查命令

bash
undefined
bash
undefined

On jailbroken device — app sandbox at:

越狱设备上,应用沙箱路径为:

/var/mobile/Containers/Data/Application/<UUID>/

/var/mobile/Containers/Data/Application/<UUID>/

Find app UUID

查找应用UUID

find /var/mobile/Containers -name "com.target.app" 2>/dev/null
find /var/mobile/Containers -name "com.target.app" 2>/dev/null

Check NSUserDefaults

检查NSUserDefaults

plutil -p Library/Preferences/com.target.app.plist
plutil -p Library/Preferences/com.target.app.plist

Check SQLite databases

检查SQLite数据库

sqlite3 Library/Application\ Support/Model.sqlite ".tables" sqlite3 Library/Application\ Support/Model.sqlite "SELECT * FROM ZUSER;"
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/

---
grep -r "password|token|bearer|api_key" Documents/ Library/

---

8. TRANSPORT SECURITY (ATS)

8. 传输安全(ATS)

8.1 ATS Exception Patterns

8.1 ATS异常配置模式

xml
<!-- 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 SettingRiskNotes
NSAllowsArbitraryLoads = true
CriticalAll HTTP allowed
NSExceptionAllowsInsecureHTTPLoads
HighHTTP for specific domain
NSExceptionMinimumTLSVersion = TLSv1.0
MediumWeak TLS
NSAllowsArbitraryLoadsInWebContent
MediumWebView can load HTTP
No ATS exceptionsLowProper configuration

xml
<!-- Info.plist — 检查ATS异常配置 -->
<key>NSAppTransportSecurity</key>
<dict>
  <!-- 最差:完全禁用ATS -->
  <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配置风险说明
NSAllowsArbitraryLoads = true
极高允许所有HTTP请求
NSExceptionAllowsInsecureHTTPLoads
指定域名允许HTTP请求
NSExceptionMinimumTLSVersion = TLSv1.0
使用弱TLS版本
NSAllowsArbitraryLoadsInWebContent
WebView可加载HTTP内容
无ATS异常配置配置正确

9. IOS PENTESTING DECISION TREE

9. iOS渗透测试决策树

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)
测试iOS应用
├── 设备是否越狱?
│   ├── 是 → 完整测试能力
│   │   ├── Keychain导出 → ios keychain dump(§2)
│   │   ├── 文件系统检查 → 检查所有数据存储位置(§7)
│   │   ├── 运行时钩子 → Frida/Objection(§5)
│   │   └── 二进制分析 → 解密二进制后class-dump(§6)
│   └── 否 → 有限测试能力
│       ├── 注入Frida gadget重签名获取运行时访问权限
│       ├── 提取备份做数据分析
│       └── 网络层测试(代理+SSL绕过)
├── SSL pinning是否阻断代理?
│   └── 是 → 参考mobile-ssl-pinning-bypass SKILL.md
├── 是否注册了URL scheme?
│   ├── 通过URL scheme做OAuth回调? → 存在劫持风险(§3.2)
│   ├── 是否配置了Universal Links? → 检查AASA配置(§4.1)
│   └── scheme用于敏感操作? → 测试拦截可能性
├── 二进制保护是否足够?
│   ├── 缺失PIE? → ASLR禁用(§6.1)
│   ├── 无栈金丝雀? → 溢出风险(§6.1)
│   └── 仍处于加密状态? → 先解密(§6.2)
├── 数据存储是否安全?
│   ├── 令牌存储在NSUserDefaults? → 可明文提取(§7.1)
│   ├── Keychain保护等级? → AfterFirstUnlock风险高(§2.1)
│   ├── 存在应用截图? → 检查Snapshots目录(§7.1)
│   └── 键盘缓存? → 检查敏感输入自动补全(§7.1)
├── ATS配置是否正确?
│   ├── ArbitraryLoads = true? → 可降级到HTTP(§8)
│   └── 存在域名异常配置? → 针对性HTTP拦截
└── 是否需要运行时操纵?
    ├── 越狱检测阻断测试? → ios jailbreak disable(§5.2)
    ├── 需要绕过认证检查? → 钩子+修改返回值(§5.1)
    └── 需要追踪API调用? → 方法钩子(§5.2)