发布 PoC:Windows 驱动程序中的整数溢出漏洞可导致权限升级

Windows 11 22H2 security updates

一名独立研究人员在 ksthunk.sys 驱动程序中发现了一个关键漏洞,该驱动程序是 Windows 操作系统中负责促进 32 位到 64 位进程通信的一个组件。该漏洞允许本地攻击者利用整数溢出实现权限升级,该漏洞已在著名的 TyphoonPWN 2024 活动中被成功演示和强调,并获得了第二名的好成绩。

该漏洞存在于 CKSAutomationThunk::ThunkEnableEventIrp 函数中,该函数分配缓冲区用于管理内核中的输入和输出数据。问题源于在缓冲区大小对齐计算过程中缺乏整数溢出验证。这一疏忽导致分配大小不当,引发堆溢出,使攻击者能够覆盖相邻内存。

// Only Called when the calling process is 32bit.
__int64 __fastcall CKSAutomationThunk::ThunkEnableEventIrp(__int64 a1, PIRP a2, __int64 a3, int *a4)
{
  ...
  inbuflen = CurrentStackLocation->Parameters.DeviceIoControl.InputBufferLength;
  outbuflen = CurrentStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
  // [1]. Align the length of output buffer
  outlen_adjust = (outbuflen + 0x17) & 0xFFFFFFF8;
  if ( a2->AssociatedIrp.MasterIrp )
    return 1i64;

  if ( (unsigned int)inbuflen < 0x18 )
    ExRaiseStatus(-1073741306);

  ProbeForRead(CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer, inbuflen, 1u);
  if ( (*((_DWORD *)CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer + 5) & 0xEFFFFFFF) == 1
    || (*((_DWORD *)CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer + 5) & 0xEFFFFFFF) == 2
    || (*((_DWORD *)CurrentStackLocation->Parameters.DeviceIoControl.Type3InputBuffer + 5) & 0xEFFFFFFF) == 4 )
  {
    // [2]. Validate the Length
    if ( (unsigned int)outbuflen < 0x10 )
      ExRaiseStatus(-1073741306);
    if ( outlen_adjust < (int)outbuflen + 16 || outlen_adjust + (unsigned int)inbuflen < outlen_adjust )
      ExRaiseStatus(-1073741306);

    // [3]. Allocate the buffer to store the data
    // 0x61 == POOL_FLAG_USE_QUOTA | POOL_FLAG_RAISE_ON_FAILURE POOL_FLAG_NON_PAGED
    a2->AssociatedIrp.MasterIrp = (struct _IRP *)ExAllocatePool2(
                                                   0x61i64,
                                                   outlen_adjust + (unsigned int)inbuflen,
                                                   1886409547i64);
    a2->Flags |= 0x30u;
    ProbeForRead(a2->UserBuffer, outbuflen, 1u); // [*] 
    data = (__int64)a2->AssociatedIrp.MasterIrp;
    ...
    // [4]. Copy the Data
    if ( (unsigned int)outbuflen > 0x10 )
      memmove((void *)(data + 0x20), (char *)a2->UserBuffer + 16, outbuflen - 16);
    memmove(
      (char *)a2->AssociatedIrp.MasterIrp + outlen_adjust,
      CurrentStackLocation->Parameters.FileSystemControl.Type3InputBuffer,
      inbuflen);
    ...
}

SSD Secure Disclosure 技术团队解释说: “在 [1] 处,计算 outbuflen + 0x17 时没有整数溢出验证。因此,outlen_adjust 可能被设置为一个较小的值,导致分配不足,最终在 [4] 处复制数据时发生堆溢出。

该漏洞利用一系列步骤绕过内核保护措施,获得系统级权限:

  1. 内存操纵: 攻击者在内核非分页池中命名的管道对象之间制造间隙,从而更容易利用溢出。
  2. 任意内存访问: 通过破坏相邻的命名管道,攻击者可获得任意读写能力。
  3. 令牌重写: 攻击者修改当前进程令牌以获得 SYSTEM 权限,从而完全控制机器。

该漏洞已通知微软,但微软声称这是一个已经解决的重复问题。尽管有这些保证,但研究人员发现该漏洞仍可在 Windows 11 23H2 上被利用。迄今为止,尚未提供 CVE 编号或详细的补丁信息。

该漏洞体现了与内核级漏洞相关的风险。通过驱动程序升级权限的能力凸显了内核代码严格验证的重要性。正如 SSD Secure Disclosure 所指出的,由于涉及的分配大小和数据是可控的,因此利用这个漏洞 “并不难”,这使它成为高级威胁行为者的潜在工具。

要阅读技术细节和概念验证(PoC)代码,请访问 SSD 安全披露的官方公告。

免责声明:文章内容不代表本站立场,本站不对其内容的真实性、完整性、准确性给予任何担保、暗示和承诺,仅供读者参考,文章版权归原作者所有。如本文内容影响到您的合法权益(内容、图片等),请及时联系本站,我们会及时删除处理。查看原文

为您推荐