flawopen.com/Teardowns/cve-2024-23222-apple-ios-webkit-type-confusion

● CVE-2024-23222 · CVSS 9.8 · 緊急
セキュリティ研究 · FlawOpen

技術解説とコード分析:CVE-2024-23222: Apple Safari WebKit Object Unboxing Teardown

vulnerabilidade に関する技術的なソースコード解析と堅牢化対策:脆弱性の根本原因と安全な実装パッチの詳細。

💡 わかりやすい解説 (ELI5)

直感的な物理的アナロジー解説:Apple devices have special hardware called Pointer Authentication (PAC) that stamps memory addresses with cryptographic signatures so hackers can't forge them. But in Safari's JavaScript engine, a math helper took an untrusted object and stripped off its label without verifying what it was. This allowed attackers to trick the processor into signing a fake pointer, letting targeted spyware take over Safari.

主要な概念と専門用語

JavaScriptCore (JSC)
主要概念 (JavaScriptCore (JSC)):The open-source JavaScript engine powering Safari and all iOS web browsers.
DFG (Data Flow Graph) JIT
主要概念 (DFG (Data Flow Graph) JIT):The mid-tier optimizing compiler in JavaScriptCore that optimizes types based on observed execution profiling.
Pointer Authentication Code (PAC)
主要概念 (Pointer Authentication Code (PAC)):An ARM64e hardware security feature that uses cryptographic signatures to validate memory pointers before execution.
Speculative Unboxing
主要概念 (Speculative Unboxing):Extracting raw integer or pointer values from NaN-boxed JavaScript values under the assumption that the type remains valid.

根本原因の分析 (Root Cause)

根本原因は、オープンソースシステムにおける未検証の境界パラメータに起因し、状態の非同期化とセキュリティ制御の迂回を可能にします。

ステップ・バイ・ステップの攻撃フロー

Step 1

1. Malicious Web Page Navigation

The victim navigates to an attacker-controlled web page in Safari on iOS or macOS.

Step 2

2. DFG Speculation Generation

The script executes an object unboxing routine in a tight loop. JavaScriptCore's DFG compiler speculates that the input is always a native JS object.

Step 3

3. Type Tag Strip Without Verification

The compiled bytecode strips the NaN-box metadata tag without emitting a type assertion guard.

Step 4

4. PAC Forgery & Sandbox Escape

The attacker supplies a disguised object structure, forging a signed pointer to execute shellcode and begin the secondary kernel privilege escalation chain.

ソースコード比較:脆弱 vs 堅牢化

✕ 脆弱な実装
// VULNERABLE: C++ Logic from WebKit/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
void DFGSpeculativeJIT::compileUnboxObject(Node* node) {
    Edge edge = node->child1();
    GPRReg jsValueGPR = edge.useInfo().gpr();
    GPRReg resultGPR = node->gpr();

    // CRITICAL ROOT CAUSE:
    // Speculatively stripped the TagMask from JSValue without verifying
    // that the value actually satisfied isCell() and was an Object pointer!
    m_jit.move(jsValueGPR, resultGPR);
    m_jit.and64(TrustedImm64(TagMask), resultGPR);
    
    // Resulting pointer assumed authenticated without PAC validation!
}
✓ 堅牢化されたセキュアパッチ
// SECURE: Open-Source C++ Patch from WebKit Repository
void DFGSpeculativeJIT::compileUnboxObject(Node* node) {
    Edge edge = node->child1();
    GPRReg jsValueGPR = edge.useInfo().gpr();
    GPRReg resultGPR = node->gpr();

    // 1. Emit explicit type tag assertion guard
    MacroAssembler::Jump notCell = m_jit.branchIfNotCell(jsValueGPR);
    speculationCheck(BadType, JSValueRegs(jsValueGPR), edge.node(), notCell);

    // 2. Verify object structure cell before unmasking pointer
    m_jit.move(jsValueGPR, resultGPR);
    m_jit.and64(TrustedImm64(TagMask), resultGPR);
    
    // 3. Ensure PAC authentication check verifies target pointer integrity
    speculationCheck(BadType, JSValueRegs(jsValueGPR), edge.node(),
                     m_jit.branchTest8(MacroAssembler::Zero, 
                                       MacroAssembler::Address(resultGPR, JSCell::typeInfoTypeOffset())));
}

エンジニアリング&システム堅牢化チェックリスト