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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2026-29923 — Proof-of-concept exploit for CVE-2026-29923, a BYOVD privilege escalation in pstrip64.sys. Demonstrates physical memory read/write via IOCTL to steal SYSTEM token and spawn elevated shell. | Kitploit
工具/GitHubGitHub/athenasec16/cve-2026-29923
权限提升漏洞分析漏洞利用学习与教育二进制利用实验室与实践
GitHubathenasec16/cve-2026-29923

CVE-2026-29923

Proof-of-concept exploit for CVE-2026-29923, a BYOVD privilege escalation in pstrip64.sys. Demonstrates physical memory read/write via IOCTL to steal SYSTEM token and spawn elevated shell.

查看仓库
25335个月前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-29923 - 通过 pstrip64.sys 进行本地权限提升攻击

免责声明: 本代码仅供教育和防御性研究目的使用。编写本代码的目的是加深对内核利用的理解,并帮助防御者防范类似漏洞。严禁任何未经授权、非法或恶意使用本项目的行为。


描述

哈希值: ab01485bb7c8bc1a9c86096eeea6d31d8fad557bf4d44072b46373d2203faa6e

驱动名称: pstrip64.sys

CVE: CVE-2026-29923

“自带易受攻击驱动”(BYOVD)攻击是一种古老但非常有效的攻击方式,攻击者利用操作系统仍然官方信任的旧版驱动程序来绕过现代 Windows 安全保护。一旦驱动被加载,攻击者就会利用其缺陷,在标准非特权进程与完全的系统级控制之间架起桥梁。

本周早些时候,pstrip64.sys 驱动中披露了一个新漏洞,编号为 CVE-2026-29923。本文详细介绍了该漏洞利用的整个生命周期:从最初的漏洞研究、概念验证(PoC)的开发,到防御者为保护其环境而应采取的可操作缓解策略。

pstrip64.sys 驱动是一个与 EnTech Taiwan PowerStrip(最高版本 3.90.736)相关的旧版内核模式组件。虽然其合法用途是启用高级显卡显示调整,但其深度系统权限使其成为攻击者的高价值目标。


漏洞分析

当该漏洞首次披露时,我开始分析其 DriverEntry 函数。该函数是内核驱动程序的主要初始化例程,用于创建 \Device\PSTRIP64 设备对象,并通过 \DosDevices\PSTRIP64 符号链接将其暴露给用户模式应用程序。更重要的是,它配置了驱动程序的分派表。我立即注意到索引 14(IRP_MJ_DEVICE_CONTROL)处的入口,它将所有用户提供的 IOCTL 请求直接路由到 sub_11340 处理函数,这是我们的主要关注区域。

IDA DriverEntry

sub_11340 函数作为主要的 IOCTL 分发器,解释来自用户模式的请求。

在所有暴露的 IOCTL 中,0x80002008 无疑是最有趣的。默认情况处理微小的 I/O 端口交互,而 0x80002008 则充当通往 sub_11000 的门户,通过直接将 SystemBuffer 传递给该函数。

IDA ioctl

这个 sub_11000 例程是关键。首先,它使用 HalTranslateBusAddress 获取我们用户提供的地址,并将其转换为有效的系统物理地址。然后,它打开 \Device\PhysicalMemory,并使用 ZwMapViewOfSection 将其映射。通过将目标进程句柄硬编码为 (HANDLE)0xFFFFFFFFFFFFFFFFLL(代表 ZwCurrentProcess()),该驱动将此物理内存直接映射到我们调用进程的虚拟地址空间中。关键的是,它随后将这个新映射的虚拟地址写回 SystemBuffer 以返回给用户,从而正式向我们的应用程序提供一个可以直接读写物理内存的指针。

IDA MapViewofSection

在充分理解漏洞并获得物理读写原语后,我已经拥有了所需的所有拼图碎片。现在,是时候开始编写概念验证(PoC)了。


概念验证(PoC)

注意: 该 PoC 专门在 Windows 10 22H2 环境下开发和测试。由于利用依赖于原始物理内存操作,内核结构偏移量和物理内存边界目前针对我的设置是硬编码的。要在你自己的机器上测试,你必须更新 Windows 内核偏移量,并调整物理地址扫描范围,以匹配你的特定操作系统版本和 RAM 配置。

利用的第一步是与驱动程序建立通信。我通过调用 CreateFileA 并传入驱动程序的符号链接(\\.\PSTRIP64)来实现这一点。获得有效句柄后,我需要一种干净的方式来滥用我之前分析的 0x80002008 IOCTL。我创建了一个名为 MapPhysicalMemory() 的包装函数。该函数使用目标物理地址和要读取的内存块长度填充我自定义的 PSTRIP_MAP_REQUEST 结构体。

然后,我通过 DeviceIoControl 将该结构体直接发送给驱动程序。如果成功,驱动程序将该物理内存直接映射到我的用户模式应用程序中,并在 OutputResult 字段中返回虚拟基地址。现在,我可以将这个返回的地址转换为标准 C++ 指针,从而获得对系统物理 RAM 的原始、无特权的访问权限。

在物理读写原语完全运行后,我的目标是找到包含进程权限的内核数据结构。在 Windows 中,每个正在运行的进程都由一个 EPROCESS 结构体表示。

Windows 使用一个特定的 4 字节标识符(称为池标记)在内核池中分配 EPROCESS 结构体。对于进程,该标记是字符串 Proc(十六进制为 0x636F7250)。通过扫描系统的物理 RAM,我可以搜索这个确切的字符串。

我的利用过程从 0x10000000 到 0x140000000 的物理内存空间循环,以 2MB 块(STEP_SIZE = 0x200000)进行映射。我将每个映射的块转换为原始字节数组,并以 16 字节(sizeof(_POOL_HEADER))为步长进行扫描。

然而,仅仅在物理内存中找到 Proc 标记是不够的。内存是混乱的,该标记可能是已终止进程留下的残留物,或者只是恰好匹配该十六进制值的随机数据。如果我盲目地假设每个 Proc 标记都是有效的 EPROCESS 结构体并开始修改内存,我会立即导致蓝屏死机(BSOD)。

为了确保稳定性,我不得不使用启发式方法来验证结构体。首先,我计算 EPROCESS 结构体的起始位置(它位于池标记偏移之后不远处)。然后,我检查运行进程的一些已知常量:

  • PriorityClass: 我验证该值为 0x2(正常优先级)。
  • ProcessLock: 我确保该值为 0x0。
  • ImageFileName: 我检查进程名的第一个字符是否为有效的可打印 ASCII 字符。

如果所有启发式检查均通过,我可以高度确信我正在查看一个有效的活动进程。然后,我读取其唯一进程 ID(PID)。如果 PID 与我自己的利用进程匹配,我保存其令牌指针的物理地址。如果 PID 为 4(Windows System 进程),我提取并保存其高权限令牌的实际值。

最后,我将我的进程令牌指针的物理地址对齐到最近的 4KB 边界,并使用 MapPhysicalMemory() 最后一次映射该特定页面。

接下来,我导航到确切的偏移量,并用 System 令牌值覆盖我的令牌。瞬间,Windows 内核将我的利用进程视为 NT AUTHORITY\SYSTEM。

在取消映射页面以确保系统稳定性后,我只需调用 CreateProcessA 来生成 cmd.exe。由于我当前进程已提升权限,新的命令提示符继承了这些顶级特权,从而成功完成攻击!


备注

注意: 我在早期调试阶段发现的一个关键细节是驱动程序如何处理映射的指针。通过执行 SystemBuffer->LowPart = (unsigned int)BaseAddress;,驱动程序在返回之前将 64 位虚拟基地址转换为 32 位值。这种截断丢失了地址的高位部分,导致我在 64 位利用中尝试解引用时立即出现访问冲突。为了干净地绕过这个问题,我简单地将用户模式 PoC 编译为 32 位应用程序,从而确保返回的指针保持完全有效。

IDA MapViewofSection - Copy

注意: 在初始测试期间,我遇到了一个有趣的边缘情况:我的 PoC 成功在内存中找到了我的利用进程,但未能找到 System 进程(PID 4)。

为了理解原因,我需要直接检查物理内存。我附加了一个内核调试器(WinDbg),并使用命令检索 System 进程的虚拟地址和目录基址。然后,我使用 !vtop 将该虚拟地址转换为其在 RAM 中的确切物理地址。

windbg kernel debbuger system physical address windbg kernel debbuger db system address

我切换回附加到 PoC 的用户模式调试器。我在内存扫描循环上设置了一个条件断点,指示它在我的 MapPhysicalMemory() 函数抓取包含 System 进程物理地址的 2MB 块时暂停执行。

windbg breakpoint

一旦断点被触发,我开始手动检查映射内存的原始字节。在这里,我发现了关于 Windows 内核池分配的一个关键细节。

windbg eprocessBase offset 88000

当 Windows 为进程分配内存时,它以 _POOL_HEADER(包含我们的 Proc 标记)开头,然后是 _OBJECT_HEADER,最后是 EPROCESS 结构体本身。对于标准用户模式应用程序,这些头部包含额外的跟踪数据,这意味着实际的 EPROCESS 结构体在池标记之后 0x80 字节处开始。

offest for use mode process

然而,检查 System 进程的内存揭示了不同的布局。System 进程缺少一些标准跟踪头部。从 Proc 标记到 EPROCESS 结构体起始位置的偏移仅为 0x40 字节!

windbg db 88000 offset windbg db 88000 - 0x40 offset offset for system process

修复方法很简单。我更新了 PoC,使其在处理 Proc 标记时,通过循环遍历一个可能的偏移量数组(0x40 和 0x80)来处理两种池头部大小。

posibileoffset

缓解与检测

网络安全是一场攻击者与防御者之间永无止境的猫鼠游戏。虽然攻击者不断寻找易受攻击的驱动程序,但现代安全产品和蓝队有多种可靠的方法来检测和阻止这种精确操作。

阻止 BYOVD(自带易受攻击驱动)攻击最有效的方法是首先阻止驱动程序加载。

  • 防御者应确保将 pstrip64.sys 的哈希值添加到他们的阻止列表中。
  • 此外,组织应通过 Windows Defender 应用程序控制(WDAC)强制执行微软的易受攻击驱动程序阻止列表,并启用虚拟机监控程序保护的代码完整性(HVCI),以严格限制可以加载的内核组件。
  • 监控新服务创建事件,寻找意外的内核模式驱动程序安装。

如果驱动程序已加载,安全产品仍可在令牌操作阶段检测到利用行为。

  • 高级监控检测进程令牌的异常。一个标准用户模式进程在没有合法身份验证链的情况下将其初始主令牌提升为 NT AUTHORITY\SYSTEM 是一个巨大的危险信号。
  • 此外,安全团队可以创建规则来检测低完整性或中等完整性进程生成高特权子进程(例如 cmd.exe)的情况,尤其是当父进程没有理由以 SYSTEM 身份运行时。

演示

poc_demo

下载工具