Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Windows XP SP2 緩衝區溢出防護機制深度剖析(上):PEB 隨機化、SEH 保護與堆 Cookie 防禦

編輯:XP 系統基礎知識

前言:SP2 如何從根上斷開傳統 Exploit 鏈條

Windows XP SP2 不僅修補漏洞,更在記憶體管理、例外處理、堆分配器三大核心機制植入主動防禦邏輯,使得傳統「覆蓋 SEH→跳轉 Shellcode」「利用 PEB 固定地址定位模組」「偽造堆區塊頭」等經典利用手法失效或大幅增加難度。本文基於核心層逆向分析,詳細拆解 SP2 引入的四大緩解技術:PEB 基址隨機化、頂層 SEH (TOP SEH) 保護、向量化例外處理鏈表 (VEH) 指標保護、堆區塊 Cookie 保護。

一、PEB 基址隨機化:打破 0x7FFDF000 固定地址假設

1.1 背景:為何 PEB 地址至關重要

進程環境塊 (PEB) 位於使用者模式地址空間,包含載入模組鏈表 (`InLoadOrderModuleList`)、進程參數、環境變數等關鍵結構。傳統 Exploit 常通過 `fs:[0x30]` 讀取 PEB 基址,進而遍歷模組鏈表獲取 `kernel32.dll`/`ntdll.dll` 基址,繼而解析導出函數地址構建 ROP 鏈或直接呼叫 `LoadLibrary`/`WinExec`。XP SP1 及之前版本,PEB 固定映射於 `0x7FFDF000`,攻擊者可硬編碼此地址。

1.2 核心邏輯:`MiCreatePebOrTeb` 中的隨機化分支

進程創建流程:`NtCreateProcessEx` → `PspCreateProcess` → `MmCreateProcessAddressSpace` → `MmCreatePeb` → `MiCreatePebOrTeb`。關鍵參數 `0x210` 作為隨機化開關被壓入堆疊:

PAGE:004B4AB7 push eax
PAGE:004B4AB8 push 210h          ; 隨機化旗標
PAGE:004B4ABD push esi
PAGE:004B4ABE call MiCreatePebOrTeb@12

在 `MiCreatePebOrTeb` 內部:

  1. 呼叫 `KeQueryTickCount` 獲取系統啟動以來的滴答計數(不可預測)。
  2. 取計數值低 4 位元 (`and eax, 0Fh`),得到 0~15 的隨機值 `R`。
  3. 若 `R == 1` 則強制改為 2(避免計算出原固定地址 `0x7FFDF000`)。
  4. 最終 PEB 基址 = `0x7FFE0000 - (R << 12)`,即以 4KB 為粒度向下偏移。

1.3 可能的 PEB 基址分佈表

隨機值 RPEB 基址機率
0, 1, 20x7FFDE0003/16 ≈ 18.75%
30x7FFDD0001/16 = 6.25%
40x7FFDC0001/16
50x7FFDB0001/16
60x7FFDA0001/16
70x7FFD90001/16
80x7FFD80001/16
90x7FFD70001/16
0xA0x7FFD60001/16
0xB0x7FFD50001/16
0xC0x7FFD40001/16
0xD0x7FFD30001/16
0xE0x7FFD20001/16
0xF0x7FFD10001/16

雖然熵僅 4 位元(16 種可能),且 `0x7FFDE000` 機率最高,但已足以讓硬編碼 PEB 地址的 Exploit 失效,迫使攻擊者採用資訊洩露漏洞動態解析 PEB 位址。

二、頂層 SEH (TOP SEH) 保護:封鎖 `SetUnhandledExceptionFilter` 劫持

2.1 背景:傳統 SEH 覆蓋利用鏈

使用者模式例外處理鏈以 `fs:[0]` 為頭,每個框架包含 `Next`、`Handler`。當例外發生,系統依序呼叫 `Handler`,若返回 `ExceptionContinueSearch` 則繼續下一個。頂層 SEH 由 `kernel32!UnhandledExceptionFilter` 提供,負責彈出錯誤對話框、生成傾印、啟動 Dr. Watson。攻擊者常覆蓋頂層 SEH 的 `Handler` 指向 Shellcode,或呼叫 `SetUnhandledExceptionFilter` 註冊惡意回調函數劫持流程。

2.2 SP2 的重大變更:`SetUnhandledExceptionFilter` 內部加密驗證

SP2 重寫 `kernel32!SetUnhandledExceptionFilter`:

  • 新回調地址在寫入全域變數 `BasepTopLevelExceptionFilter` 前,先經過 指標編碼:`EncodedPtr = Ptr ^ Cookie`,其中 `Cookie` 為進程啟動時由 `RtlGenRandom` 生成的隨機值,儲存於 PEB 的 `EncodingPointer` 欄位。
  • 呼叫時同樣解碼:`RealPtr = EncodedPtr ^ Cookie`。
  • 若攻擊者直接覆蓋 `BasepTopLevelExceptionFilter` 為 Shellcode 地址,解碼後將變成亂碼地址導致崩潰;若攻擊者嘗試呼叫 `SetUnhandledExceptionFilter(Shellcode)`,編碼後寫入的值同樣無法在解碼還原為原始 Shellcode 地址(因 Cookie 未知)。

此機制同樣保護 `RtlAddVectoredExceptionHandler`、`RtlAddVectoredContinueHandler` 註冊的 VEH 節點指標。

三、VEH 鏈表指標 `_RtlpCalloutEntryList` 保護

向量化例外處理 (VEH) 允許在 SEH 鏈之前插入全域例外處理器。SP2 對 VEH 節點鏈表頭指標 `_RtlpCalloutEntryList` 採用相同指標編碼保護,防止攻擊者直接修改鏈表頭插入惡意節點或取消合法節點。

四、堆區塊 Cookie 保護:偵測堆元資料竄改

SP2 在 `_HEAP_ENTRY` 區塊頭引入 Cookie 欄位:

  • 分配時:`Cookie = HeapBaseAddress ^ BlockAddress ^ RandomValue`。
  • 釋放/重新分配/擴展時:重新計算並驗證 Cookie,不匹配即觸發 `RtlHeapCorruption` 快速失敗。
  • 有效防禦:Unlink 攻擊、覆蓋 `Size`/`Flags` 欄位、偽造區塊頭等經典堆利用手法。

注意:堆管理核心演算法(前向/後向鏈表、Lookaside List、Free List)未大幅變更,主要防禦在元資料完整性驗證層面。

本文不涵蓋內容

  • 繞過上述防禦的具體技術(資訊洩露、ROP 鏈構造、堆噴灑配合 DEP 繞過等)。
  • 堆管理器內部演算法細節(Free List 操作、Lookaside 分配邏輯、Segment 管理)。

下篇預告

下一篇將深入分析:資料執行防護 (DEP) 核心實現、ASLR 前身:映像載入基址隨機化、SafeSEH 編譯器支援與執行時驗證、GS 編譯器堆疊 Cookie 擴展,並結合實戰案例展示 SP2 綜合緩解體系對實際漏洞利用的阻斷效果。

Copyright © Windows教程網 All Rights Reserved