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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2022-42046 — 针对 CVE-2022-42046 的概念验证漏洞利用,演示了通过直接内核对象操作 wfshbr64.sys 驱动程序中的 EPROCESS Protection 和 SignatureLevel 标志来实现本地权限提升。 | Kitploit
工具/GitHubGitHub/kkent030315/cve-2022-42046
权限提升漏洞分析漏洞利用二进制利用
GitHubkkent030315/cve-2022-42046

CVE-2022-42046

针对 CVE-2022-42046 的概念验证漏洞利用,演示了通过直接内核对象操作 wfshbr64.sys 驱动程序中的 EPROCESS Protection 和 SignatureLevel 标志来实现本地权限提升。

查看仓库
1612623年前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

EvilWfshbr

CVE-2022-42046 wfshbr64.sys 本地权限提升的概念验证

wfshbr64.sys 和 wfshbr32.sys 的特制载荷允许任意用户以任意的 EPROCESS 偏移量和标志值执行位运算,通过操纵 EPROCESS.Protection 和 EPROCESS.SignatureLevel 标志,故意将游戏进程提升到 CodeGen Full 保护级别(将安全漏洞作为功能)。

该驱动程序由通过 Microsoft 硬件计划提交的 Microsoft 硬件兼容发布者签名。

本项目与 @DoranekoSystems 共同研究。

有一个功能丰富的 Rust CLI 版本可在这里获取:此处

  • https://www.virustotal.com/gui/file/b8807e365be2813b7eccd2e4c49afb0d1e131086715638b7a6307cd7d7e9556c
  • https://www.virustotal.com/gui/file/89698cad598a56f9e45efffd15d1841e494a2409cc12279150a03842cd6bb7f3

许可证

MIT。参见 LICENSE

建议(供开发者参考)

  1. 使用 ObRegisterCallbacks 而不是通过直接操作内核对象来强行提升进程保护。在此处有一个很好的示例。

2. IRP

不要在完成后引用 IRP。如果你启用了驱动程序验证器,你就会被捕获。

root@kitploit:~
IofCompleteRequest(Irp, IO_NO_INCREMENT); // IRP is freed here
return Irp->IoStatus.Status;

相反,你应该使用局部变量。

root@kitploit:~
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
IofCompleteRequest(Irp, IO_NO_INCREMENT); // IRP is freed here
return status;

3. 上下文进程

看起来你在检查 IoGetCurrentProcess 返回值是否为空指针,但它在设计上永远不会返回空指针,因此你不必检查它。

root@kitploit:~
PEPROCESS CurrentProcess = IoGetCurrentProcess();
  if ( !CurrentProcess ) // no need to check for null pointer
    break;

技巧

报告发布后不久,开发者实现了偷偷摸摸的“附加验证”,以击败我们的第一个 PoC,而不是放弃将安全漏洞作为功能的做法。

新增了以下检查:

  • IOCTL_WFSHBR_REMOVE_FLAG
  • IOCTL_WFSHBR_ADD_FLAG
  • IOCTL_WFSHBR_AND_FLAG
root@kitploit:~
case IOCTL_WFSHBR_ADD_FLAG: // 0xAA013884
      if ( !KwfsVerifyCaller(Buffer) ) // verify caller
        break;
-     if ( Buffer->ArbitraryEProcessOffset >= 0x1000 ) // offset limitation check
+     if ( !KwfsVerifyOffsetAndFlags(Buffer->ArbitraryEProcessOffset,
+                                    Buffer->DesiredFlags) ) // verify the offset and flags
        break;
      *(ULONG*)(IoGetCurrentProcess() + Buffer->ArbitraryEProcessOffset) |= Buffer->DesiredFlags;

KwfsVerifyOffsetAndFlags

该例程被设计为在客户端每次请求修改 EPROCESS 时调用,并验证此 PoC 中 ArbitraryEProcessOffset 字段提供的 Offset,以及此 PoC 中 DesiredFlags 字段提供的 Flags。

验证相当简单:它计算所提供标志的每个位字段中 1 位的数量,如果数量大于八,则验证失败。

可能的标志模式映射只有四种:

  • 22 00 00 00
  • 00 22 00 00
  • 00 00 22 00
  • 00 00 00 22

也就是说,重复执行以下操作 4 次,可以保证至少有一次尝试会成功:

  • 将 ArbitraryEProcessOffset 字段减去索引:offset - index,
  • 并按索引调整 DesiredFlags 字段中的位:flag << (index * 8)。

偏移量是递减的,因此位域调整会导致偏移量在位运算符中发生相应调整。

root@kitploit:~
*(ULONG*)(IoGetCurrentProcess() + offset) |= flags;
*(ULONG*)(IoGetCurrentProcess() + offset) &= ~flags;

我们添加了 WfsProtectProcessSupreme 和 WfsUnprotectProcessSupreme 函数,它们会执行尝试并击破了这个新技巧。

root@kitploit:~
enum KwfsState {
  KwfsStateOnceCall = 0,
  KwfsStateNeedsValueEquality = 1,
  KwfsStateValueHasBeenSet = 2,
};

bool KwfsVerifyOffsetAndFlags(_In_ ULONG offset, _In_ ULONG offset flags)
{
  if (KwfsState::KwfsState == KwfsState::KwfsStateOnceCall) {
    g_KwfsVerifyState = KwfsState::KwfsStateValueHasBeenSet;
    g_KwfsVerifyStateOffset = offset;
    g_KwfsVerifyStateFlags = flags;
    if (offset < 0x1000) { // offset limitation check moved here
      auto bitcount = 0;
      for (auto i = 0; i < 32; ++i) { // count `1` bits in flags
        if (flags & (1 << i)) {
          ++bitcount;
        }
      }
      if (bitcount <= 8) { // count must less than nine
        g_KwfsVerifyState = 1;
        return true;
      }
    }
  }
  else
  {
    if (g_KwfsVerifyState != KwfsState::KwfsStateValueHasBeenSet
     || offset != g_KwfsVerifyStateOffset
     || flags != g_KwfsVerifyStateFlags) {
      return false;
    }
  }
  return false;
}
下载工具