CVE-2026-20700 How DarkSword Defeated Apple's Hardware Security — The dyld PAC-TPRO Bypass
Executive Summary
CVE-2026-20700 is a memory corruption vulnerability in dyld — Apple’s dynamic linker, the very first piece of code that executes when any iOS application launches. This flaw served as Stage 2 of the DarkSword exploit chain: after Stages 1a/1b (CVE-2025-31277 or CVE-2025-43529) provided arbitrary memory read/write inside Safari’s WebContent process, CVE-2026-20700 was weaponized to defeat Pointer Authentication Codes (PAC) and Trusted Path Read-Only (TPRO) — two of Apple’s most critical hardware-enforced security mitigations.
Without this bypass, the memory write capability from Stage 1 would be largely useless — any forged code pointer would be cryptographically rejected by Apple Silicon hardware. CVE-2026-20700 was the key that made arbitrary code execution possible on modern iPhones.
Discovered and reported to Apple by Google Threat Intelligence Group (GTIG), first patched in Apple’s February 11, 2026 security release, and later also patched for legacy iOS versions. Added to CISA’s Known Exploited Vulnerabilities catalog. Apple described exploits using this flaw as “extremely sophisticated attacks against specific targeted individuals.”
CVE Summary
| Field | Detail |
|---|---|
| CVE ID | CVE-2026-20700 |
| Product | Apple dyld (Dynamic Linker) |
| Affected Platforms | iOS/iPadOS < 26.3 (and < 18.7.5 for legacy), macOS Tahoe < 26.3, macOS Sequoia < 15.7.4, macOS Sonoma < 14.8.4, watchOS/tvOS/visionOS < 26.3 |
| Vulnerability Type | Memory Corruption / Improper State Management (CWE-119) |
| CVSS v3.1 Score | 7.8 (High) |
| CVSS Vector | AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Attack Vector | Local (requires prior memory write from Stage 1) |
| Role in DarkSword | Stage 2 — PAC + TPRO bypass → arbitrary code execution |
| Reported By | Google Threat Intelligence Group (GTIG) |
| Disclosed | February 11, 2026 |
| Patched In | iOS 26.3, iOS 18.7.5 (legacy), macOS Tahoe 26.3 |
| Fix | Improved state management |
| CISA KEV | Yes — deadline March 5, 2026 for federal agencies |
| Apple Description | “Exploited in extremely sophisticated attacks against specific targeted individuals” |
Why dyld Is the Perfect Target
What dyld Does
dyld (the dynamic linker or “dynamic link editor”) is the foundational bootstrapping component of every iOS process. When the kernel starts a new process, it hands control directly to dyld before any application code runs.
dyld’s job:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Kernel starts process
↓
dyld entry point executes FIRST
↓
dyld self-bootstraps (sets up its own minimal state)
↓
dyld loads all dependent dynamic libraries (dylibs)
- Locates and maps frameworks (UIKit, Foundation, etc.)
- Parses Mach-O headers
- Applies ASLR slides (rebasing)
- Resolves symbols (binding)
- Processes fixups
↓
dyld applies code signing verification
↓
dyld runs static initializers
↓
dyld hands control to app's main()
Critical insight: dyld executes during a bootstrap window before sandboxing is fully enforced, before all ASLR has been applied, and before the security state of the process is fully established. A vulnerability here can affect everything that happens afterward.
The dyld Shared Cache
iOS uses a dyld shared cache — a single large prelinked file containing essentially all system frameworks (UIKit, CoreFoundation, libsystem, etc.). This cache is mapped into every process’s address space at a fixed ASLR slide that is chosen once per device boot and shared across all processes.
This design has a critical security implication: if an attacker can determine the shared cache’s ASLR slide, they can predict the addresses of millions of code pointers across the entire system — a massive advantage for exploit chaining.
PAC: Apple’s Hardware Defense That CVE-2026-20700 Defeated
What Pointer Authentication Codes Are
PAC (Pointer Authentication Codes) is an ARM hardware security feature introduced in ARMv8.3-A, implemented in Apple’s A12 chip and all subsequent Apple Silicon. It is designed to make memory corruption exploits dramatically harder by cryptographically signing code pointers.
The fundamental problem PAC solves:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Without PAC:
Attacker has arbitrary memory write
↓
Overwrite function pointer at address 0x1234:
*(uint64_t*)0x1234 = attacker_shellcode_addr
↓
When code calls the function pointer → executes attacker's code
[RCE ACHIEVED]
With PAC:
Function pointer is signed before storing:
signed_ptr = PACIA(real_ptr, signing_key, context_modifier)
*(uint64_t*)0x1234 = signed_ptr
Attacker overwrites the pointer:
*(uint64_t*)0x1234 = attacker_shellcode_addr ← INVALID PAC
When code uses the pointer → AUTIA instruction checks PAC
→ Authentication FAILS → CPU generates exception → CRASH
[EXPLOIT BLOCKED]
How PAC Works Technically
PAC embeds a cryptographic signature in the unused high-order bits of a 64-bit pointer (bits 48–63 are typically unused for addressing):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
64-bit pointer with PAC:
[63 48][47 0]
┌────────┬──────────────────────────┐
│ PAC │ Actual Address │
│(16 bits│ (used for addressing) │
│ HMAC) │ │
└────────┴──────────────────────────┘
PAC is computed as:
PAC = QARMA-64(pointer_value, secret_key, context_modifier)
Where:
secret_key = hardware-stored 128-bit key (unreadable by software)
context_modifier = usually stack pointer or another register
(makes PAC path-dependent)
ARM PAC Instructions:
; PACIA: Sign instruction pointer with Key A
PACIA X30, SP ; Sign X30 (link register / return address) using SP as context
; AUTIA: Authenticate instruction pointer with Key A
AUTIA X30, SP ; Verify X30's PAC using SP — CRASH if tampered
; PACIB: Sign with Key B (used for function pointers, vtables)
PACIB X16, X17 ; Sign X16 (function pointer) using X17 as context
; RETAB: Authenticate and return (combined auth + branch)
RETAB ; Authenticate return address before branching
Five distinct PAC key types in iOS:
- Key IA / IB: For instruction pointers (code pointers, return addresses)
- Key DA / DB: For data pointers
- Generic Key: For arbitrary data signing
Each user-space process has unique keys stored in hardware registers. The kernel has its own separate key set. No software can read these keys directly — they are only accessible to the PAC instructions.
TPRO: Trusted Path Read-Only
TPRO (Trusted Path Read-Only) is a complementary Apple-specific security feature that marks certain critical code/data regions as read-only through hardware-enforced page permissions — even for the process that owns them. This prevents attackers with memory write capability from modifying trusted code paths.
Together, PAC + TPRO form a layered defense:
- PAC prevents forged pointers from executing
- TPRO prevents critical code regions from being overwritten
The Vulnerability: Improper State Management in dyld
Root Cause
CVE-2026-20700 is classified as memory corruption due to improper state management within dyld’s dynamic library loading process. Apple’s fix description — “improved state management” — is deliberately minimal.
Based on the vulnerability class and dyld’s architecture, the likely root cause involves a state inconsistency window during the library loading and fixup process that allows an attacker with existing memory write to corrupt dyld’s internal structures in a way that bypasses PAC validation.
The key insight: PAC relies on the integrity of the pointer-signing infrastructure itself. If dyld’s internal state used to manage the PAC signing/verification process can be corrupted, the cryptographic guarantee breaks down.
The Exploit Window: Why dyld Is Uniquely Vulnerable
dyld’s initialization process has a specific sequence vulnerability:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Normal dyld initialization sequence:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 1: dyld self-setup (minimal, no PAC context yet)
Step 2: Load system libraries (libdyld.dylib, libsystem_c.dylib, etc.)
Step 3: Establish PAC context (signing keys initialized)
Step 4: Load app dependencies with PAC-protected pointers
Step 5: Perform rebasing and binding (fixup code pointers)
Step 6: Code signing verification
Step 7: Run static initializers
Step 8: Hand off to main()
Vulnerability window:
━━━━━━━━━━━━━━━━━━━
During Step 5 (rebasing/binding), dyld reads fixup metadata
and applies pointer updates. If internal state tracking the
PAC context or the fixup validation state is improperly managed:
→ Attacker can corrupt dyld's pointer-validation state
→ dyld proceeds with AUTIA/AUTIB checks disabled or bypassed
→ Attacker can plant forged (unsigned) code pointers
→ PAC authentication skipped for those pointers
→ Arbitrary code execution achieved
How CVE-2026-20700 Fits Into DarkSword Stage 2
After Stage 1 (CVE-2025-31277 or CVE-2025-43529) provides arbitrary memory R/W within the WebContent process, the exploit uses CVE-2026-20700 as follows:
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
[Stage 1 provides: arbitrary memory R/W in WebContent process]
│
▼
[Read memory: locate dyld's internal state structures]
- dyld is mapped at known offset from ASLR slide
- Use addrof/read64 to find dyld's fixup state variables
- Locate the internal state that controls PAC validation
│
▼
[Trigger CVE-2026-20700: corrupt dyld's PAC/TPRO state]
- Write crafted value to dyld's internal state
- Corrupt the state used to validate PAC tokens
- OR: corrupt the signing context used by AUTIA/AUTIB
│
▼
[PAC + TPRO protections now neutralized]
- Forged code pointers are no longer rejected by hardware
- TPRO-protected regions may now be writable
│
▼
[Arbitrary code execution achieved in WebContent process]
- Plant shellcode/ROP chain at attacker-controlled address
- Overwrite a function pointer to shellcode address (no valid PAC needed)
- When pointer is called → execution redirected to attacker code
│
▼
[Proceed to Stage 3: Sandbox Escape (CVE-2025-14174)]
The Execution Context: Before Security Is Fully Established
The particularly dangerous aspect of CVE-2026-20700 is dyld’s privileged execution context. When exploitation occurs via dyld manipulation:
1
2
3
4
5
6
7
8
9
10
11
12
13
dyld's capabilities during bootstrapping:
─────────────────────────────────────────
✗ Sandbox NOT yet fully active
✗ Library validation can be circumvented
✗ Code signing verification not yet complete
✗ ASLR slides not yet fully applied to all regions
✓ Full access to process memory map
✓ Can influence which libraries are loaded
✓ Can modify how library symbols are resolved
✓ Runs with initial privileges before security hardening
→ Compromise dyld = compromise the foundation of the entire process
→ All security built on top of dyld can be undermined
Distinguishing CVE-2026-20700 From Other PAC Bypasses
CVE-2026-20700 is a software-based, user-mode PAC bypass — distinct from hardware-level attacks:
| Bypass Type | Example | How It Works | Requires |
|---|---|---|---|
| Hardware speculative (PACMAN) | MIT CSAIL research | Uses speculative execution to brute-force PAC values | Physical device access, specific hardware |
| Timing side-channel | 2024 research | Mathematical weakness in QARMA-64 | Complex timing analysis |
| Signing gadget abuse | Various exploits | Trick legitimate code into signing forged pointers | Existing arbitrary R/W |
| CVE-2026-20700 (user-mode state corruption) | DarkSword Stage 2 | Corrupt dyld state to neutralize PAC checks | Existing memory write only |
| Kernel-mode PAC bypass | Advanced kernel exploits | Overwrite kernel PAC key registers | Kernel code execution |
CVE-2026-20700 is notable for being accessible from user-mode with only an existing memory write primitive — no hardware access, no timing analysis, no complex gadget chains required. This made it ideal for DarkSword’s pure-JavaScript approach.
Impact: What Breaking PAC Unlocks
Before CVE-2026-20700, DarkSword’s Stage 1 arbitrary R/W primitive was powerful but limited:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Without PAC bypass (after Stage 1 only):
─────────────────────────────────────────
✓ Can read any memory in WebContent process
✓ Can write to data (non-PAC-protected) regions
✗ Cannot forge function pointers (PAC rejects them)
✗ Cannot overwrite return addresses (PAC rejects them)
✗ Cannot modify TPRO-protected code regions
✗ Cannot achieve real code execution — only data manipulation
→ Limited impact: can read secrets but can't run code
After CVE-2026-20700 (PAC + TPRO bypassed):
─────────────────────────────────────────────
✓ Can forge arbitrary function pointers
✓ Can overwrite return addresses
✓ Can inject ROP chains
✓ Can plant shellcode at executable memory
✓ Full code execution in WebContent process
✓ Platform for further exploitation (Stages 3-6)
→ Full RCE achieved — DarkSword chain continues
Timeline: CVE-2026-20700 Patched Before DarkSword Disclosure
An important timeline detail:
1
2
3
4
5
6
7
February 11, 2026 → Apple patches CVE-2026-20700 in iOS 26.3
(without public disclosure of DarkSword connection)
March 17-19, 2026 → Google GTIG, iVerify, Lookout, Zimperium disclose DarkSword
Public now learns CVE-2026-20700 was in the DarkSword chain
March 20, 2026 → CISA adds related CVEs to KEV
This means Apple was aware of active exploitation in “extremely sophisticated attacks” by February 2026, and patched it out-of-band before the full DarkSword disclosure. The disclosure gap shows how intelligence about targeted attacks is shared between threat researchers and Apple before public release.
Detection
For Security Researchers
CVE-2026-20700 exploitation occurs during the dyld bootstrapping phase, which runs extremely early:
Crash logs:
1
2
3
4
5
6
Settings → Privacy & Security → Analytics → Analytics Data
Look for:
- dyld-related crash logs (dyld_sim, dyld3, etc.)
- Crashes with PAC authentication failure signatures
(EXC_BAD_ACCESS with specific PAC error codes)
- Abnormal dyld crash patterns around suspicious web browsing
iVerify and Mobile Threat Defense:
- iVerify monitors for post-exploitation anomalies resulting from successful Stage 2 completion
- Behavioral detection: unusual process spawning patterns from WebContent after Safari loads specific URLs
Network indicators: After Stage 2 completes, DarkSword proceeds rapidly to Stage 3 — unusual HTTPS POST requests immediately following a Safari session are a secondary indicator.
MITRE ATT&CK Mapping
| Tactic | Technique | ID |
|---|---|---|
| Privilege Escalation | Exploitation for Privilege Escalation | T1068 |
| Defense Evasion | Subvert Trust Controls | T1553 |
| Defense Evasion | Exploitation for Defense Evasion | T1211 |
| Execution | Exploitation for Client Execution (chained) | T1203 |
Mitigation & Affected Versions
Patch Table
| Platform | Vulnerable Range | Fixed Version |
|---|---|---|
| iOS / iPadOS | < 26.3 (and legacy < 18.7.5) | iOS 26.3 or 18.7.5 |
| macOS Tahoe | < 26.3 | macOS Tahoe 26.3 |
| macOS Sequoia | < 15.7.4 | 15.7.4 |
| macOS Sonoma | < 14.8.4 | 14.8.4 |
| watchOS | < 26.3 | 26.3 |
| tvOS | < 26.3 | 26.3 |
| visionOS | < 26.3 | 26.3 |
Full DarkSword protection requires iOS 18.7.6 / iOS 26.3.1 which patch all 6 CVEs in the chain.
Actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. Update immediately:
Settings → General → Software Update → Install Now
2. Enable Automatic Updates to prevent future gaps:
Settings → General → Software Update → Automatic Updates → ON
3. High-risk users: Lockdown Mode
Settings → Privacy & Security → Lockdown Mode
→ Prevents Stage 1 (JIT bugs) → entire chain blocked before Stage 2
4. Enterprise MDM:
Enforce minimum iOS version 18.7.6 / 26.3.1
5. For macOS: also patch to Tahoe 26.3 / Sequoia 15.7.4 / Sonoma 14.8.4
CVE-2026-20700 affects all Apple platforms, not just iOS
CVE-2026-20700 in the Full DarkSword Architecture
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
┌─────────────────────────────────────────────────────────────────┐
│ DARKSWORD FULL CHAIN │
│ │
│ Stage 1a: CVE-2025-31277 (iOS < 18.6) │
│ Stage 1b: CVE-2025-43529 (iOS 18.6-18.7) │
│ JavaScriptCore JIT/GC memory corruption │
│ → Arbitrary R/W in WebContent process │
│ │ │
│ ▼ │
│ ★ Stage 2: CVE-2026-20700 (dyld PAC/TPRO bypass) ★ │
│ Corrupt dyld state management │
│ → PAC + TPRO protections neutralized │
│ → Arbitrary code execution unlocked │
│ │ │
│ ▼ │
│ Stage 3: CVE-2025-14174 (ANGLE OOB write) │
│ GPU process sandbox escape │
│ │ │
│ ▼ │
│ Stage 4: XPC injection → mediaplaybackd pivot │
│ │ │
│ ▼ │
│ Stage 5: CVE-2025-43510 (kernel COW race) │
│ Kernel arbitrary memory R/W │
│ │ │
│ ▼ │
│ Stage 6: CVE-2025-43520 (kernel privilege escalation) │
│ Full ROOT access → GHOSTBLADE/GHOSTKNIFE/GHOSTSABER │
└─────────────────────────────────────────────────────────────────┘
Conclusion
CVE-2026-20700 is the hinge point of the DarkSword chain. Without it, Stages 1-6 cannot proceed — arbitrary memory read/write without code execution is dangerous but limited. With it, every hardware and software security boundary in modern iOS becomes negotiable.
The vulnerability’s location in dyld is no accident. dyld is the foundational layer of process bootstrapping — it executes before the security state is established, it manages the fixup metadata that PAC depends on, and it has privileged access to the process’s memory layout. Attacking dyld is attacking the trust anchor.
Apple’s February 2026 patch — “improved state management” — stopped the bleeding for updated devices. But for the hundreds of millions of iPhones that hadn’t updated before DarkSword was disclosed in March 2026, this vulnerability was a key in a lock that attackers had been using for months.
PAC is a genuinely strong security feature. CVE-2026-20700 reminds us that hardware security guarantees are only as strong as the software infrastructure that initializes and manages them.
References
- Google Threat Intelligence — DarkSword iOS Exploit Chain
- NVD — CVE-2026-20700
- Apple Security Update — February 11, 2026
- Lookout — CVE-2026-20700 Update
- Security Week — Apple Patches iOS Zero-Day
- Bleeping Computer — Apple Fixes Zero-Day
- SentinelOne — CVE-2026-20700
- HivePro — Apple Zero-Day CVE-2026-20700
- ARM — Introduction to PAC
- WebKit Blog — Speculation in JavaScriptCore
- CISA KEV Catalog
- PACMAN Attack
This post is intended for security researchers, iOS security engineers, and mobile threat analysts. All technical details are based on publicly disclosed research from Apple, Google GTIG, and the broader security community.