DarkSword -- iOS 18 Full-Chain Exploit
DarkSword is a full-chain iOS exploit targeting iOS 18.4-18.7, using 6 vulnerabilities (including 3 zero-days) to achieve full device takeover. Analyzed by Google GTIG in 2026. Notable because it targets iOS 18 – the generation with SPTM + TXM + Exclaves.
Overview
| Field | Detail |
|---|---|
| Discovered by | Google Threat Intelligence Group (GTIG) |
| Published | March 2026 |
| iOS range | 18.4 – 18.7 |
| CVE count | 6 (3 zero-days) |
| Delivery | Watering hole (compromised websites, zero-click in browser) |
| Threat actors | UNC6748 (Saudi Arabia targeting), multiple other threat actors adopt |
| Patched | iOS 26.1 (kernel), iOS 26.3 (full chain) |
Exploit Chain – 6 Stages
Step 1: WebKit RCE
│ CVE-2025-31277 (iOS 18.4-18.5): JIT type confusion in JavaScriptCore
│ CVE-2025-43529 (iOS 18.6-18.7): Garbage collection flaw in JSC
▼
Step 2: WebContent → GPU Sandbox Escape
│ CVE-2025-14174: ANGLE out-of-bounds memory corruption (WebGL/WebGPU)
│ → Pivot from WebContent sandbox into GPU process
▼
Step 3: GPU → mediaplaybackd Sandbox Escape
│ CVE-2025-43510: Copy-on-Write bug
│ → Arbitrary function call primitives in mediaplaybackd
│ → mediaplaybackd has broader permissions than GPU process
▼
Step 4: Load JavaScriptCore in mediaplaybackd
│ Not a vulnerability -- technique:
│ → Load JSC framework into mediaplaybackd
│ → Execute JavaScript in elevated context
▼
Step 5: Kernel Exploit
│ CVE-2025-43520: XNU VFS race condition
│ → Physical + virtual memory read/write primitives
▼
Step 6: User-Mode PAC Bypass
│ CVE-2026-20700: dyld user-mode PAC bypass
│ → Defeat pointer authentication for code injection
│ → Inject in-memory JavaScript implants into system processes
▼
Full Device Compromise
Deep Dive: Each CVE
CVE-2025-31277 – JavaScriptCore JIT Type Confusion
Component: JavaScriptCore JIT compiler
Type: Type confusion
Target: iOS 18.4-18.5
JIT compiler makes incorrect type assumptions:
1. Attacker crafts JavaScript triggering JIT compilation
2. JIT generates native code assuming variable is Type A
3. At runtime, variable is actually Type B
4. Type confusion → read/write outside intended bounds
→ Arbitrary read/write in WebContent process
CVE-2025-43529 – JavaScriptCore GC Flaw
Component: JavaScriptCore garbage collector
Type: Use-after-free (via GC timing)
Target: iOS 18.6-18.7 (alternative entry when 31277 patched)
Garbage collector frees object while still referenced:
1. Trigger specific GC timing via JS allocation patterns
2. Object freed prematurely
3. Dangling reference → UAF
→ Same end result: arbitrary r/w in WebContent
CVE-2025-14174 – ANGLE OOB Memory Corruption
Component: ANGLE (Almost Native Graphics Layer Engine) — WebGL/WebGPU
Type: Out-of-bounds memory corruption
Role: First sandbox escape (WebContent → GPU process)
WebGL/WebGPU processing crosses process boundary:
1. Malicious WebGL commands craft bad GPU command buffer
2. GPU process parses command buffer → OOB write
3. Code execution in GPU process
→ GPU process runs with fewer restrictions than WebContent
CVE-2025-43510 – Copy-on-Write Bug
Component: XPC / memory management
Type: COW bypass
Role: Second sandbox escape (GPU → mediaplaybackd)
Copy-on-Write should isolate memory between processes:
1. Shared memory page between GPU process and mediaplaybackd
2. COW bug: modification visible in both processes
3. Attacker corrupts data in mediaplaybackd context
4. → Arbitrary function call primitive in mediaplaybackd
CVE-2025-43520 – XNU VFS Race Condition
Component: XNU kernel — Virtual File System layer
Type: Race condition (TOCTOU)
Role: Kernel privilege escalation → physrw
VFS race condition between check and use:
1. Two threads race on VFS operations
2. Thread A: check permission/state of vnode
3. Thread B: change vnode state between check and use
4. Thread A: use stale state → incorrect kernel behavior
5. → Physical + virtual memory read/write primitives
CVE-2026-20700 – dyld User-Mode PAC Bypass
Component: dyld (dynamic linker)
Type: PAC bypass
Role: Defeat pointer authentication for code injection
Patched: iOS 26.3
Exploits a flaw in dyld's handling of PAC-signed pointers:
- Bypass user-mode PAC to gain arbitrary code execution
- Enable injection of JavaScript implants into system processes
- Load JSC into target processes
- Execute JS in elevated context
- Extract data from multiple processes simultaneously
Attack Architecture: Double Sandbox Escape
Particularly worth studying: DarkSword uses 2 sequential sandbox escapes instead of 1:
WebContent (very restricted sandbox)
│
├── CVE-2025-14174 (ANGLE OOB)
▼
GPU Process (less restricted, but still sandboxed)
│
├── CVE-2025-43510 (COW bug)
▼
mediaplaybackd (broad permissions, can load frameworks)
│
├── Load JavaScriptCore
├── CVE-2025-43520 (kernel VFS race)
▼
Kernel (full control)
│
├── CVE-2026-20700 (dyld PAC bypass for code injection)
▼
Full Device Compromise
Why 2 sandbox escapes:
- The WebContent sandbox (iOS 18) is extremely restricted
- Cannot reach the kernel attack surface directly
- GPU process is a stepping stone – more permissions, more reachable kernel interfaces
- mediaplaybackd – even more permissions, can load arbitrary frameworks
- The exploit “hops” through multiple processes to reach the kernel
JavaScript-Based Post-Exploitation
Novel technique: Instead of a native code implant, DarkSword injects JavaScript:
After obtaining kernel r/w:
1. Inject JSC framework into target system processes
2. Execute JavaScript in the context of each process
3. JavaScript code:
├── Extract Safari history, cookies, passwords
├── Read WhatsApp/Signal databases
├── Access photos, contacts, location
└── Exfiltrate to C2 server
Advantages:
- No persistent binary on disk
- Hard to detect (in-memory only)
- Easy to update payloads (just change JS)
- But: does not survive reboot
Real-World Deployment
November 2025:
Saudi Arabian users visiting fake Snapchat messaging site
→ UNC6748 operates site
→ Full device compromise in minutes, zero-click
Subsequently:
Multiple threat actors adopt DarkSword
→ Watering hole attacks across 4 countries
→ Targeting journalists, activists, political figures
Technical Lessons
1. Multi-hop Sandbox Escape
iOS 18 sandbox is too tight for a direct WebContent → kernel path
→ Must chain multiple sandbox escapes
→ Each hop gradually increases permissions
→ Attack surface analysis: trace accessible services at EACH privilege level
2. User-Mode PAC Bypass via dyld
dyld (dynamic linker) handles PAC-signed pointers:
- Complex pointer signing/verification logic
- Flaws in dyld can bypass PAC without forging signatures
- Cross-process memory sharing = COW bugs
→ dyld and GPU/media drivers are high-value targets
3. VFS Race Conditions
VFS layer (file system) in XNU:
- Multi-threaded by nature
- Complex locking semantics
- Race windows between check and use
→ Fruitful area for kernel bug hunting
4. JavaScript Post-Exploitation
Native implant vs JS implant:
Native: persistent, performant, harder to update
JS: in-memory only, flexible, easy to update, hard to forensics
→ Trend: fileless, memory-only exploitation