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

Resources