一名独立研究人员在 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] 处复制数据时发生堆溢出。
该漏洞利用一系列步骤绕过内核保护措施,获得系统级权限:
- 内存操纵: 攻击者在内核非分页池中命名的管道对象之间制造间隙,从而更容易利用溢出。
- 任意内存访问: 通过破坏相邻的命名管道,攻击者可获得任意读写能力。
- 令牌重写: 攻击者修改当前进程令牌以获得 SYSTEM 权限,从而完全控制机器。
该漏洞已通知微软,但微软声称这是一个已经解决的重复问题。尽管有这些保证,但研究人员发现该漏洞仍可在 Windows 11 23H2 上被利用。迄今为止,尚未提供 CVE 编号或详细的补丁信息。
该漏洞体现了与内核级漏洞相关的风险。通过驱动程序升级权限的能力凸显了内核代码严格验证的重要性。正如 SSD Secure Disclosure 所指出的,由于涉及的分配大小和数据是可控的,因此利用这个漏洞 “并不难”,这使它成为高级威胁行为者的潜在工具。
要阅读技术细节和概念验证(PoC)代码,请访问 SSD 安全披露的官方公告。