2531 words
13 minutes

Windows Kernel Exploitation筆記

使用工具#

  • VM: Windows 11 25H2 Pro (Target Machine)
  • Visual Studio 2022 (用來寫WDK)
  • Process Monitor
  • Process Explorer
  • Windbg + KDNet

基礎知識#

Windows Kernel Overview

Process#

  • _EPROCESS: Kernel 中代表 Process 的主要結構
    • PCB (_KPROCESS): 核心 Process 控制區塊, 負責排程、中斷…
      • DirectoryTableBase (CR3):指向 PML4 (Kernel mode)
      • UserDirectoryTableBase:指向 User mode 的 PML4 (用於 KVAS/KPTI)
    • UniqueProcessId (PID)
    • ActiveProcessLinks:雙向鏈結串列, 串接系統中所有 Process, Exploit 常用目標
    • Token:指向 Security Context
    • PEB:指向 User space 的 Process Environment Block
    • ThreadListHead:串接該 Process 下所有 Thread

Thread#

  • _ETHREAD:Kernel 中代表 Thread 的主要結構
    • TCB (_KTHREAD):Thread 控制區塊
      • KernelStack:Context switch 時紀錄當前 Stack
      • TrapFrame:紀錄進入 Kernel mode 時的暫存器狀態
      • Teb:指向 User space 的 Thread Environment Block
      • PreviousMode:0 為 KernelMode, 1 為 UserMode. KernelMode 下會略過大部分權限檢查

Security Machanism#

  • Integrity Level

    • 分為 Untrusted, Low, Medium, High, System, Protected
    • Mandatory Policy
      • No-Write-Up: 低權限無法寫入高權限 Object
      • No-Read-Up: 低權限無法讀取高權限 Process 的 Memory
      • No-Execute-Up: 低權限無法叫高權限 Process 使用 COM
  • 存取控制清單 (ACL)

    • DACL:決定誰可以存取物件, 若為 Null則大家都能存取, 若為 Empty則反之
    • SACL:決定哪些操作需要被紀錄 (Audit)
  • 安全識別碼 (SID)

    • 唯一識別 User 或 Group, 包含 Revision, IdentifierAuthority, Subauthority, RID
    • RID 500 為 Admin, 501 為 Guest
  • 特權 (Privileges)

    • 只有 Local machine 有效
    • Super Privileges
      • SeDebugPrivilege:可 Open 任意 Process
      • SeRestorePrivilege:可覆蓋任意檔案
      • SeTcbPrivilege:可偽裝任意使用者
      • SeLoadDriverPrivilege:可載入 Driver (獲得 Kernel code 執行權限)
      • SeCreateTokenPrivilege:可建立任意 Token
      • SeTakeOwnershipPrivilege:可修改 Object owner (進而修改 DACL)
  • 存取權杖 (Access Token)

    • 包含 SID, Group, Privileges, Integrity Level
    • Primary Token vs Impersonation Token (模擬其他 Security Context)
    • 結構 (_TOKEN):包含 UserAndGroups (SID 陣列), Privileges (Present/Enabled), IntegrityLevelIndex
  • Access Check流程

    • Mandatory Integrity Check (MIC):優先檢查 Integrity Level
    • DACL Check:若無 DACL 則全權限; 若有, 則依序檢查 ACE
      • 遇到 Deny 則直接拒絕
      • 若檢查完所有 ACE 仍無 Match, 則拒絕

Memory Management#

  • Control Register
    • CR2:Page Fault 時的 Virtual Address
    • CR3:存放 PML4 的實體位址 (Page Table Base)
    • CR4:控制 Protected mode 操作 (如 SMEP/SMAP 相關)
    • CR8:當前 IRQL
  • Paging
    • 位址轉換:CPU 透過 MMU 將 Virtual Address (VA) 轉為 Physical Address (PA)
    • Page 狀態:Committed (已分配), Shareable (共享), Free, Reserved
    • Copy-On-Write(CoW):寫入時才複製 Page, 節省記憶體
  • Page Table
    • 4-Level Paging (x64):PML4 -> PDPT -> PD -> PT -> Physical Page
    • PTE (Page Table Entry):包含 PFN (Page Frame Number) 和屬性位元 (NX, R/W, U/S, Valid)
      • Valid (V):0 代表 Page out 或 Invalid
      • U/S:User/Supervisor 權限位
      • NX:No-Execute
    • Self-ref entry:PML4 中指向自己的 Entry,用於定位 Page Table 的 VA (Win10 1607 後位置隨機化)
    • Exploit 技巧:修改 PTE (如清除 NX bit) 使記憶體可執行。_KUSER_SHARED_DATA (0xfffff78000000000) 是一個好目標
  • Page Fault
    • Soft Page Fault:Page 還在物理記憶體中
    • Hard Page Fault:需從 Disk (Page file) 讀回
  • Virtual Address Descriptors (VADs)
    • 管理 User Space 的虛擬記憶體狀態 (Reserved/Committed),紀錄於 AVL Tree (_MMVAD)
  • PFN Database
    • 紀錄每個 Physical Page 的狀態 (_MMPFN),如 Active, Free, Modified, Bad 等

Windows MMU Overview

中斷與排程 (IRQL & DPC)#

  • Interrupt Request Levels (IRQL)
    • Passive Level (0):User mode 運行於此
    • APC Level (1):APC 調用
    • Dispatch/DPC Level (2):Kernel scheduler, Page fault handler. 此層級以上不可發生 Page fault (僅能存取 Non-paged memory)
    • 規則:低 IRQL 不能中斷高 IRQL. Exploit 時若 IRQL 過高需用 KeLowerIrql 降低
  • Deferred Procedure Calls (DPC)
    • 目的:讓高優先級的中斷服務程式 (ISR) 能將較不緊急的任務延後執行,避免長時間佔用 CPU 高 IRQL
    • 執行時機:當 IRQL 降回 Dispatch Level 時處理 DPC Queue
    • 種類
      • Normal DPC:跑在 Dispatch Level
      • Threaded DPC:跑在 Passive Level,由專屬 Thread 執行

Windows Driver#

常見類型#

  • WDM (Windows Driver Model):最傳統且常見的模型, 包含 Bus、Function、Filter driver
  • KMDF (Kernel-Mode Driver Framework):微軟提供的Driver框架, 封裝底層操作以減少錯誤
  • Mini-Filter Drivers:用於攔截 File System 操作 (如防毒軟體)
  • Win32k / GDI:GUI 子系統, 雖然漏洞多但極其複雜

Driver 與 User Mode的互動方式#

  • Driver 載入時建立 Symbolic Link (如 \\.\BitLocker) 供 User Application 溝通
  • 開發者透過 CreateFile 取得 Handle,並使用 DeviceIoControl 發送 I/O Request
  • I/O Request Packet (IRP)
    • I/O Manager 將 User 的請求封裝成 IRP 送給 Driver
    • Driver 處理完後呼叫 IoCompleteRequest 完成操作
    • 關鍵結構
      • Memory Descriptor List (MDL):描述記憶體區塊
      • _IO_STACK_LOCATION:記錄每一層 Driver 的操作 (Major Function, Parameters 等)

資料存取方式#

  • Buffered I/O (METHOD_BUFFERED)
    • 系統分配一塊 Non-paged pool (SystemBuffer)
    • 進入時將 User Input 複製到 SystemBuffer
    • 完成時將 SystemBuffer 內容複製回 User Output Buffer
    • 優點:安全,隔離了 User 記憶體
  • Direct I/O (METHOD_IN/OUT_DIRECT)
    • I/O Manager 建立 MDL 鎖定 User Buffer 的實體頁面
    • Driver 透過 MDL 取得 Kernel Virtual Address 進行存取
    • 特性:Buffer 被鎖在記憶體中 (Locked), 不會被 Page Out
  • Neither Buffered Nor Direct I/O (METHOD_NEITHER)
    • 直接使用 User Space 的指標 (Type3InputBuffer, UserBuffer)
    • 風險:必須極度小心, 存取前需驗證指標是否位於 User Space (ProbeForRead/Write), 且只能在 User Thread 的 Context 下使用

Bug Classes#

記憶體相關漏洞#

  • Buffer Overflow:Stack 或 Heap 溢位
  • Integer Overflow/Underflow:常見於記憶體分配大小的計算, 導致後續的 Heap Overflow 或 OOB
  • Use After Free (UAF)
    • 釋放指標後未設為 NULL,形成 dangling pointer
    • ObDereferenceObject Issue:物件計數歸零後未清空指標
  • Double Free:重複釋放記憶體,或將 Irp->MdlAddress 設為 NULL 導致系統重複釋放
  • Out-of-Bounds (OOB)
    • Irp->IoStatus.Information:在 Buffered I/O 中, 若此值大於 SystemBuffer 大小, 複製回 User Buffer 時會導致越界讀寫
  • Uninitialized Variable:分配記憶體 (如 ExAllocatePool2POOL_FLAG_UNINITIALIZED) 後未清空即使用, 可能導致資訊洩漏

指標驗證問題#

  • User 傳入的指標若未經驗證 (Probe), 攻擊者可傳入 Kernel Address 造成任意讀寫
  • MmProbeAndLockPages:需注意 AccessMode 是否正確設為 UserMode,否則可能鎖定 Kernel Memory

競爭條件 (Race Condition / Double Fetch)#

  • Double Fetch
    • Kernel 從 User 記憶體讀取第一次數值做檢查 (Check)
    • 再次讀取數值進行操作 (Use)
    • 攻擊:User 在兩次讀取之間修改數值 (TOCTOU),繞過檢查
  • Reference Count Issue:多執行緒下對全域物件的操作未加鎖或未使用 Interlocked API

邏輯漏洞#

  • Access Mode Mismatch
    • PreviousModeRequestorMode 的檢查繞過
    • ZwOpenFile 等 Kernel API 預設為 KernelMode,若未正確轉發 User 權限可能導致繞過 ACL
  • CreateFile Issue
    • 使用 IO_NO_PARAMETER_CHECKINGOBJ_KERNEL_HANDLE 可能繞過安全檢查
    • 未正確設置 Security Descriptor (DACL)

類型混淆#

  • ObReferenceObjectByHandle 未指定物件型態, 導致將錯誤的物件當作預期物件處理 (例如將 Event Handle 當作 File Handle)

安全機制與測試工具#

  • ACL
    • IoCreateDeviceSecure 可指定 SDDL 設定權限
    • 常見錯誤:忘記設 FILE_DEVICE_SECURE_OPEN, 導致 Namespace 下的子路徑權限未繼承
  • Special Pool
    • 分配記憶體時夾在無效頁面 (Unmapped pages) 之間
    • 一旦發生 Overflow 或 UAF 存取,立即觸發 Crash (BSOD),方便偵錯

Kernel Exploitation#

Protection#

  • Kernel Address Space Layout Randomization (KASLR)
    • 每次開機時核心記憶體位置隨機化, 不重開機位置不變
    • 需要資訊洩漏(Info Leak)來繞過
  • Supervisor Mode Execution Protection (SMEP)
    • 禁止 Kernel Mode 直接執行 User Space 的程式碼
    • CR4 暫存器的第 20 bit 控制
  • Supervisor Mode Access Prevention (SMAP)
    • 禁止 Kernel Mode 直接存取(讀寫)User Space 的資料
    • CR4 的第 21 bit 和 EFLAG.AC 決定。呼叫 DPC 時通常會啟用
  • Kernel Virtual Address Shadow (KVA Shadow)
    • 針對 Meltdown 漏洞的緩解措施,實現了 Kernel/User Page Table 的隔離
    • 在 Kernel Mode 下, User Space 的 PML4 NX (No-Execute) bit 會被設為 1, 這導致即使關閉 SMEP, 也無法直接在 Kernel Mode 執行 User Space 的 Shellcode
  • Patch Guard (Kernel Patch Protection)
    • 定期檢查關鍵結構(如 SSDT, GDT, IDT, CR4)是否被竄改
    • 若偵測到修改,會觸發 CRITICAL_STRUCTURE_CORRUPTION (0x109) 藍屏
  • Kernel Control Flow Guard (kCFG)
    • 防止間接跳轉(Indirect Jump)被竄改,驗證目標位址是否有效

CR4 Register (0-11)

CR4 Register (12-31)

Information Leak#

  • NtQuerySystemInformation
    • 在 Medium Integrity Level 下, 可用 SystemModuleInformationSystemExtendedHandleInformation 獲取核心模組或物件位址
    • 限制: 從 Windows 11 24H2 開始, 除非擁有 SeDebugPrivilege, 否則此方法失效
  • 漏洞利用: 在 Low Integrity 或新版 Windows 下, 通常需要依賴驅動程式本身的 Info Leak 漏洞

利用現代 Stack Overflow (Ret2usr)#

繞過 SMEP/SMAP#

  • 利用 ROP (Return Oriented Programming) 修改 CR4 暫存器, 清除第 20 (SMEP) 和 21 (SMAP) bit
  • 必須保持 CR4 其他 bits 不變

繞過 KVA Shadow (核心難點)#

由於 KVA Shadow 會將 User Space 標記為不可執行(NX), 直接跳轉會導致 ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY (0xfc)

  • 方法一:利用任意讀寫 (Arbitrary R/W)
    • 計算目標 User Space 位址對應的 Page Table Entry (PTE) 位址
    • 利用 nt!MmPteBase 計算 PTE 虛擬位址
    • 將該 PTE 的 NX bit 清0, 使其變為可執行
size_t PTEBASE = 0xffffcd8000000000;
size_t getpte(size_t addr){
size_t result = 0 ;
result = addr >> 9 ;
result = result & 0x7FFFFFFFF8;
result = PTEBASE + result;
return result;
}
  • 方法二:利用 ROP
    • 若只有 Stack Overflow, 可用 ROP 呼叫 nt!MiGetPteAddress 取得 PTE 位址, 再修改其內容以清除 NX bit
  • 恢復環境: Shellcode 執行完畢返回 User Mode 前, 必須將 PTE 和 CR4 改回原狀, 否則會被 Patch Guard 抓到或導致崩潰

Code Execution to EoP#

Token Stealing#

  • 原理: 將當前 Process 的 Token 替換為 System Process (PID 4) 的 Token
  • 關鍵結構鏈 (GS Segment)
    1. GS:[0x188] -> _KTHREAD (Current Thread)
    2. _KTHREAD->Process (offset 0x220 等, 隨版本變動) -> _EPROCESS (Current Process)
    3. _EPROCESS 透過 ActiveProcessLinks 遍歷所有 Process
    4. 檢查 UniqueProcessId 是否為 4 (System PID)
    5. 找到後, 將 System 的 Token 複製到當前 Process 的 Token 欄位

安全返回 User Mode (處理 TrapFrame 與 APC)#

執行完 Shellcode 後需安全返回, 避免 BSOD

  • TrapFrame 設置
    • 使用 KiSystemServiceExit 返回 User Mode
    • 需將 RBP 指向合法的 TrapFrame
    • 在 20H2 後,RBP 實際上是指向 TrapFrame + 0x80 的位置,設置時需修正 offset
  • 解決 APC_INDEX_MISMATCH (0x01)
    • 因為 DeviceIoControl 會呼叫 KeEnterCriticalRegion (禁用 APC), 若返回時 Thread->KernelApcDisable 不為 0 會崩潰
    • 解法: 在 Shellcode 中手動將 KernelApcDisable 歸零, 或呼叫 KeLeaveCriticalRegion

提高 Exploit 穩定性#

  • 修復 I/O 卡死: 呼叫 IoCompleteRequest(Irp, 0) 讓 I/O 請求完成, 否則 Process 無法結束. IRP 可從 Thread->IrpList 找到
  • 釋放鎖 (Lock): 呼叫 IopReleaseFileObjectLock(FileObject), 否則 Process 結束時會因持有 Lock 而崩潰

Arbitrary R/W to EoP#

若只有任意讀寫能力,無需執行 Shellcode 也能提權

Enabling Privileges#

  • 定位到當前 Process 的 _EPROCESS -> Token
  • 修改 Token 中的 _SEP_TOKEN_PRIVILEGES 結構
  • 將 Present 和 Enabled 欄位寫入 0xffffffffffffffff (全開)
  • 這會給予 SeDebugPrivilege, 允許注入程式碼到 System Process (如 winlogon.exe)

修改 PreviousMode (The “Easy Way”)#

  • 原理: _ETHREAD 有一個 PreviousMode 欄位, 0 代表 Kernel Mode, 1 代表 User Mode
  • 攻擊: 利用任意寫入將 PreviousMode 改為 0
  • 效果: 系統會認為請求來自 Kernel, 從而繞過大多數 API 的權限檢查 (Access Check). 攻擊者可以直接對 System Process 呼叫 OpenProcessDuplicateToken 而不受 ACL 限制
Windows Kernel Exploitation筆記
https://blog.cyberangel.work/posts/winkrnl/
Author
Ethan Lai
Published at
2026-01-11
License
CC BY-NC-SA 4.0

Comments

Table of Contents