Post

CVE-2025-43520 The XNU Kernel Buffer Overflow That Gave DarkSword ROOT

CVE-2025-43520 The XNU Kernel Buffer Overflow That Gave DarkSword ROOT

Executive Summary

CVE-2025-43520 is the sixth and final vulnerability in the DarkSword exploit chain — a classic buffer overflow in the XNU kernel (CWE-120) that, when exploited using the kernel arbitrary R/W primitive obtained from Stage 5 (CVE-2025-43510), delivers the ultimate objective: full kernel privilege escalation to root.

This is the stage where DarkSword crosses the finish line. After five prior stages broke through every user-space and hardware security boundary, CVE-2025-43520 corrupts specific kernel memory structures to:

  • Elevate the process’s effective user ID to 0 (root)
  • Remove the process’s sandbox restrictions
  • Grant platform application entitlements
  • Enable unrestricted access to all device data and hardware

Once Stage 6 completes, DarkSword deploys GHOSTBLADE, GHOSTKNIFE, or GHOSTSABER — the spyware payloads that exfiltrate iMessages, photos, passwords, crypto wallets, and location history — all within seconds, before self-deleting.

Discovered by Google GTIG, iVerify, and Lookout. Patched in iOS 18.7.2 and iOS 26.1. CISA mandated federal patching by April 3, 2026.


CVE Summary

FieldDetail
CVE IDCVE-2025-43520
ProductApple iOS/iPadOS, macOS, watchOS, tvOS, visionOS
ComponentXNU Kernel
Vulnerability TypeClassic Buffer Overflow (CWE-120)
CVSS VectorAV:L/AC:L/Au:S/C:N/I:C/A:C
Role in DarkSwordStage 6 — Final kernel privilege escalation → ROOT
Triggered FromJavaScript (pe_main.js) inside mediaplaybackd
Required Pre-conditionKernel arbitrary R/W from CVE-2025-43510 (Stage 5)
FixImproved memory handling
Patched IniOS 18.7.2, iOS 26.1, macOS Sonoma 14.8.2, Sequoia 15.7.2, Tahoe 26.1
CISA KEVYes — Federal deadline: April 3, 2026
OutcomeRoot access → GHOSTBLADE/GHOSTKNIFE/GHOSTSABER deployed

What Root Access Means on a Modern iPhone

Before diving into the technical details, it’s worth clarifying what “root” means on iOS in 2026 — and why it matters.

iOS Process Privilege Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
iOS Privilege Hierarchy:
─────────────────────────────────────────────────────────────────

kernel (UID 0, no sandbox)
  │
  ├── Root daemons (UID 0, restricted by sandbox profiles)
  │     launchd, configd, etc.
  │
  ├── System services (various UIDs, various sandboxes)
  │     imagent, springboard, smsfilter, etc.
  │
  ├── Platform applications (special entitlements)
  │     FaceTime, Messages, Health, etc.
  │
  └── User applications (UID 501, strict sandbox)
        App Store apps
        
After CVE-2025-43520:
  Compromised process (originally running as mediaplaybackd):
  → UID: 0 (root)
  → Sandbox: disabled
  → Entitlements: platform application level
  → Access: EVERYTHING

What Full Kernel Control Enables

With root access and no sandbox:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
File System Access:
✓ Read any file (/var/mobile/Library/SMS, photos, documents)
✓ Write/delete any file
✓ Access app containers (all third-party apps' data)
✓ Read iCloud sync data

Hardware Access:
✓ Microphone (record audio)
✓ Camera (take photos/video)
✓ GPS (track location)
✓ Network (exfiltrate data)

Credential Access:
✓ Keychain (all saved passwords)
✓ Apple ID credentials
✓ Certificate stores

Process Control:
✓ Inject code into any running process
✓ Kill/suspend processes
✓ Read other processes' memory
✓ Establish persistent backdoors

Technical Deep Dive: Kernel Buffer Overflow and Privilege Escalation

The Pre-condition: Kernel Arbitrary R/W from Stage 5

CVE-2025-43520 is not a standalone vulnerability — it requires the kernel arbitrary R/W primitive established by Stage 5 (CVE-2025-43510). Without that primitive, this stage cannot be reached.

From Stage 5, DarkSword’s pe_main.js has:

  • kernelRead(address) — read any 64-bit value from kernel memory
  • kernelWrite(address, value) — write any 64-bit value to kernel memory

These are the tools used to find and exploit the CVE-2025-43520 buffer overflow.

Root Cause: Classic Buffer Overflow in XNU Kernel

CVE-2025-43520 is a classic buffer overflow (CWE-120) in the XNU kernel — a specific memory region is written beyond its allocated size. The buffer overflow is not triggered by user input directly; instead, it is carefully crafted using the kernel R/W primitive from Stage 5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// CONCEPTUAL — simplified pattern of the class of vulnerability (NOT actual XNU source)

// Vulnerable kernel code path:
kern_return_t vulnerableKernelFunction(uint64_t* user_supplied_data, 
                                        size_t count) {
    // Fixed-size kernel buffer
    uint64_t kernelBuffer[FIXED_SIZE];  // e.g., 8 elements
    
    // count is attacker-controlled (via kernel R/W primitive)
    // No bounds check on count
    for (size_t i = 0; i < count; i++) {
        kernelBuffer[i] = user_supplied_data[i];  // OOB write when i >= FIXED_SIZE
    }
    
    // Overflow writes past kernelBuffer into adjacent kernel structures
}

Using the kernel R/W primitive from Stage 5, DarkSword:

  1. Finds the vulnerable kernel buffer in memory (using kernelRead to traverse kernel structures)
  2. Manipulates count or the call parameters by directly writing to the kernel data structures that control the function call
  3. Triggers the buffer overflow to write past the buffer into precisely chosen adjacent kernel memory

The Target: Process Credentials in the XNU Kernel

The buffer overflow is weaponized to overwrite specific kernel structures that control process security:

The proc structure — every process has a proc structure in the kernel containing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// XNU struct proc (simplified):
struct proc {
    // ... many fields ...
    
    struct proc_ro *p_proc_ro;    // Points to read-only credentials
    // ... 
    
    // p_proc_ro contains:
    //   kauth_cred_t p_ucred;   // Process credentials (UID, GID, entitlements)
    //   void* syscall_filter_mask; // Syscall restrictions
    //   sandbox_t sandbox;       // Sandbox profile
};

// kauth_cred structure:
struct ucred {
    uid_t  cr_uid;       // Effective user ID ← target: change to 0 (root)
    gid_t  cr_gid;       // Effective group ID
    // ... entitlements, sandbox reference, etc.
};

The Exploit Sequence

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// CONCEPTUAL — pe_main.js Stage 6 sequence (illustrative)

// Step 1: Find our own proc structure in kernel memory
// Use kernelRead to traverse the process list
let allProcs = kernelRead(KERNEL_PROC_LIST_ADDR);
let ourProc = findOurProc(allProcs);
console.log("Found proc at:", ourProc.toHex());

// Step 2: Read current credentials
let procRo = kernelRead(ourProc + PROC_RO_OFFSET);
let ucred = kernelRead(procRo + UCRED_OFFSET);
let currentUID = kernelRead(ucred + UID_OFFSET);
console.log("Current UID:", currentUID);  // e.g., 501 (user)

// Step 3: Trigger CVE-2025-43520 buffer overflow
// Use kernel R/W to set up conditions for the overflow
// The overflow is aimed at the kernel buffer adjacent to our proc's credentials
setupBufferOverflowConditions(ourProc);

// Step 4: Trigger the overflow — write past the buffer
// The overflow overwrites our ucred structure
triggerCVE_2025_43520_overflow(
    target: ourProc,
    overflowPayload: {
        cr_uid: 0,           // ← Become root
        cr_gid: 0,           // ← Root group
        sandbox: NULL,       // ← No sandbox
        entitlements: PLATFORM_ENTITLEMENTS  // ← Platform app level
    }
);

// Step 5: Verify privilege escalation
let newUID = kernelRead(ucred + UID_OFFSET);
console.log("New UID:", newUID);  // → 0 (root!)

// Step 6: Additional hardening — disable PPL/SPTM restrictions
// for current process
disableCodeSigningChecks(ourProc);
removeEntitlementRestrictions(ourProc);

// Stage 6 complete → ROOT achieved
// Deploy GHOSTBLADE/GHOSTKNIFE/GHOSTSABER

What Happens After Root Is Achieved

Once privilege escalation completes, DarkSword’s JavaScript runtime (still running in mediaplaybackd, now as root) deploys the selected spyware payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
GHOSTBLADE (for UNC6353 / Russia):
─────────────────────────────────
→ Open /var/mobile/Library/SMS/sms.db → dump all iMessages
→ Open /var/mobile/Media/DCIM/ → enumerate all photos
→ Read iOS Keychain → all saved passwords
→ Open wallet apps (Coinbase, Binance, MetaMask, etc.)
→ Read /var/mobile/Library/Caches/locationd/ → location history
→ Open WhatsApp/Telegram message databases
→ HTTP POST all data to C2 server
→ Delete crash logs and exit traces
→ Self-terminate

GHOSTKNIFE (for UNC6748 / Saudi Arabia):
─────────────────────────────────────────
→ Inject persistent listener into a surviving process
→ Establish encrypted C2 channel (custom binary protocol)
→ Begin ongoing surveillance: audio recording, screenshots
→ Continue data exfiltration on command from C2

GHOSTSABER (for PARS Defense customers):
─────────────────────────────────────────
→ Install remote access trojan as root-level process
→ Enable full device control for law enforcement clients
→ Establish persistent backdoor surviving reboots
→ Execute commands remotely on demand

The Complete DarkSword Journey: Stages 1-6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[Attacker's compromised website]
         │
Stage 1: CVE-2025-31277 or CVE-2025-43529
  Safari JIT vulnerability
  → Arbitrary R/W in WebContent process
         │
Stage 2: CVE-2026-20700  
  dyld PAC/TPRO bypass
  → Code execution in WebContent
         │
Stage 3: CVE-2025-14174
  ANGLE OOB write
  → GPU process sandbox escape
         │
Stage 4: XPC Injection (no CVE)
  GPU → mediaplaybackd
  → JavaScriptCore + pe_main.js loaded
         │
Stage 5: CVE-2025-43510
  AppleM2ScalerCSCDriver COW race
  → Kernel arbitrary R/W established
         │
★ Stage 6: CVE-2025-43520 ★
  XNU kernel buffer overflow
  → proc credential overwrite
  → Sandbox disabled
  → UID = 0 (ROOT)
         │
[GHOSTBLADE / GHOSTKNIFE / GHOSTSABER]
  → Data exfiltration in seconds
  → Self-deletion / persistence
  → Device fully compromised

iOS Security Mechanisms That CVE-2025-43520 Defeated

CVE-2025-43520 operates at the kernel level, making it capable of defeating:

1. Application Sandbox

The sandbox isolates apps into restricted environments. By overwriting sandbox = NULL in the process credentials, DarkSword removes the sandbox profile entirely — the process can now access anything.

2. Mandatory Access Control (MAC) / TrustCache

iOS uses MAC frameworks to restrict what processes can do. Root access with platform entitlements bypasses these restrictions.

3. Code Signing Enforcement

Code signing normally ensures only Apple-approved code runs. With kernel R/W and root access, DarkSword can disable code signing verification for injected payloads.

4. proc_ro (Read-Only Process Structures)

Apple introduced proc_ro to make process credential structures read-only at the kernel level. CVE-2025-43520 bypasses this by using the kernel R/W primitive to find and overwrite the writable pointers to the read-only structures, replacing them with attacker-controlled credential structures.

1
2
3
4
5
6
7
8
9
Normal iOS 18.x process credentials:
  proc → proc_ro (READ-ONLY in kernel)
               → p_ucred (protected, UID=501, sandbox active)

After CVE-2025-43520:
  proc → [replaced proc_ro pointer] → attacker's fake ucred
                                        (UID=0, sandbox=NULL)
  
The proc_ro itself isn't modified — the POINTER to it is replaced

Comparison With CVE-2025-43510

AspectCVE-2025-43510 (Stage 5)CVE-2025-43520 (Stage 6)
What it providesKernel arbitrary R/W primitiveFull privilege escalation → ROOT
MechanismCOW race condition via kernel driverClassic buffer overflow in XNU kernel
Input requiredmediaplaybackd’s driver accessKernel R/W from Stage 5
OutputCan read/write kernel memoryRoot credentials, no sandbox
Analogy“Get the master key to the vault”“Use the key to take the crown”
Standalone?No (needs Stage 4)No (needs Stage 5’s R/W primitive)

Historical Pattern: XNU Kernel Buffer Overflows

CVE-2025-43520 belongs to a recurring class of XNU kernel exploits:

CVEYearTypeUsed For
CVE-2019-72872019IOKit heap buffer overflowKernel R/W primitive
CVE-2024-232252024Kernel R/W bypassPrivilege escalation
CVE-2024-232962024Memory protection bypassPaired with CVE-2024-23225
CVE-2025-241182025Credential race conditionproc_ro p_ucred corruption
CVE-2025-435202025Classic buffer overflow → credential overwriteDarkSword ROOT stage

The persistence of buffer overflow vulnerabilities in the XNU kernel reflects the challenge of securing a large, complex C-language codebase where bounds checking must be comprehensive across millions of code paths.


Detection

Kernel-Level Indicators

1
2
3
4
5
6
Post-Stage-6 detection (kernel artifacts):
- Process running with UID 0 that should have UID 501
  (mediaplaybackd, WebContent, or other unexpected processes)
- proc_ro credential structures pointing to non-standard memory regions
- Sandbox profile unexpectedly NULL for a process
- Unusual entitlement sets on processes (platform entitlements on non-platform apps)

Behavioral Detection

1
2
3
4
5
6
7
8
9
10
11
After ROOT is achieved:
- Rapid access to protected file paths:
  /var/mobile/Library/SMS/
  /var/mobile/Library/Keychains/
  /var/mobile/Media/DCIM/
  App container paths (/var/mobile/Containers/Data/Application/)

- Unusual process spawning from mediaplaybackd (as root)
- Large outbound data transfer (GHOSTBLADE exfiltration burst)
- Crash log deletions (GHOSTBLADE cleanup)
- JavaScriptCore remaining loaded in mediaplaybackd after Safari closed

iVerify

  • iVerify’s kernel behavioral monitoring specifically detects post-exploitation credential anomalies
  • Unusual entitlement patterns in running processes
  • Kernel memory structure inconsistencies consistent with proc credential manipulation

Mitigation

Patch Immediately

PlatformFixed Version
iOS / iPadOS18.7.2 (and 26.1)
macOS Sonoma14.8.2
macOS Sequoia15.7.2
macOS Tahoe26.1
watchOS / tvOS / visionOS26.1

Full DarkSword protection: iOS 18.7.6 / iOS 26.3.1 — patches all 6 CVEs in the chain.

Lockdown Mode

Enables the most aggressive protection by blocking Stage 1 (JIT):

1
2
3
Settings → Privacy & Security → Lockdown Mode → Turn On
→ Disables Safari JIT → CVE-2025-31277/43529 cannot fire
→ Entire DarkSword chain blocked before Stage 6 is ever reached

Apple’s Fix

“Improved memory handling” — specifically: the buffer that is overflowed in CVE-2025-43520 has been given proper size validation and bounds checking. DarkSword’s crafted overflow payload is now rejected with a kernel panic (controlled) rather than silently succeeded.


Conclusion

CVE-2025-43520 is the punctuation mark at the end of the DarkSword sentence. By the time Stage 6 runs, five prior stages have broken through every browser, hardware, and process-level security boundary. Stage 6’s job is simply to convert the kernel arbitrary R/W primitive into the most powerful outcome possible: root credentials.

The buffer overflow technique itself is almost anticlimactic — a classic CWE-120 pattern that has existed since the first buffer overflows were discovered decades ago. But in context, triggered from JavaScript running inside a media daemon, using kernel R/W from a color conversion driver race condition, having already defeated hardware pointer authentication and graphics sandboxes — it represents the apex of an extraordinary engineering achievement in offensive iOS exploitation.

The entire DarkSword chain is a masterclass in systematically mapping iOS’s layered security model and finding the minimum set of vulnerabilities needed to traverse each layer. Six vulnerabilities, each targeting a different boundary, each building on the previous — culminating in total device control.

The defense is simple: update. The attack is exceptionally complex. This asymmetry — where defense is straightforward but offense requires extraordinary skill — is exactly why software updates are worth installing immediately.


References


This post is intended for security researchers, iOS kernel engineers, and mobile threat analysts. Technical details are based on publicly disclosed research.

This post is licensed under CC BY 4.0 by the author.