VBScript引擎中的漏洞会影响,Internet Explorer运行Shellcode

曲速未来安全区
企业专栏
热度: 31883

作为第一道防线,建议在可用时应用最新的安全补丁以防止漏洞利用。用户还可以使用可以抵御可能漏洞攻击的解决方案。主动,多层次的安全方法是利用漏洞(来自网关,端点,网络和服务器)的威胁的关键。

在7月11日的时候发现了一个高风险的Internet Explorer(IE)漏洞,就在微软7月补丁周二的第二天。虽然此漏洞(现在指定为CVE-2018-8373)会影响最新版Windows中的VBScript引擎,但Internet Explorer 11并不容易受到攻击,因为默认情况下Windows 10 Redstone 3(RS3)中的VBScript已被有效禁用。

然后发现了恶意网络流量中的漏洞。URL如下所示:

火星专栏

图1.使用的恶意URL

发现了这种漏洞之后,从而进行了更深入的分析。有趣的是,发现此漏洞利用示例使用与CVE-2018-8174相同的混淆技术,CVE-2018-8174是5月份修补的VBScript引擎远程执行代码漏洞。

火星专栏

图2. CVE-2018-8373(左侧)和CVE-2018-8174(右侧)的比较


此外,这是用于运行shellcode的示例exploit的方法:

火星专栏

图3. CVE-2018-8373(左侧)和CVE-2018-8174(右侧)如何运行shellcode的比较


经过调查怀疑这个漏洞利用样本来自同一个创建者。因为经过分析显示它在vbscript.dll中使用了一个新的use-after-free(UAF)漏洞。

漏洞根本原因分析

现在详细介绍对此漏洞的分析,该漏洞已在微软周二的八月补丁中得到解决。由于原始漏洞被严重混淆,就进行演示了一个概念验证(PoC)来解释如何利用此漏洞:

火星专栏

图4. IE漏洞PoC

这个PoC定义了一个名为MyClass的类,它有一个名为array的成员变量和两个名为Class_Initialize和Default Property Get P的成员函数。Class_Initialize是一个不推荐使用的方法,现在由New过程替换。首次实例化对象时会自动调用它。在该PoC中,Class_Initialize函数被重载,以及何时呼叫VBScriptClass::InitializeClass后,它会被分派到重载函数。

默认属性是一个类属性,可以在不指定的情况下访问它。在此PoC中,Default Property Get函数重载MyClass的默认属性。当调用访问cls时,它将被调度到重载函数。

漏洞的触发流程可以简化为以下三个步骤:

1.设置cls = New MyClass

这将调用重载函数Class_Initialize。在Class_Initialize中,ReDim数组(2)将调用vbscript!RedimPreserveArray来创建一个元素的计数为3的数组:

火星专栏

图5.内存中的ReDim数组(2)

2. cls.array(2)

它将调用vbscript!AccessArray来获取数组元素的地址。在vbscript!AccessArray中,它将首先检查数组元素的索引是否超出边界:

火星专栏

图6.在vbscript中检查元素索引!AccessArray

然后计算元素的地址,将其保存在堆栈中,并返回以下内容:

火星专栏

图7.在堆栈上保存元素地址

3. cls.array(2)= cls

这将调用vbscript!AssignVar将MyClass默认属性值设置为cls.array(2)。获取MyClass默认属性值时,调用公共默认属性Get P并在公共默认属性Get P中执行脚本ReDim数组(1),这将导致原始array.pvData被释放:

彩色文字火星专栏

图8.释放原始pvData

但是,如第二步所述,数组(2)的地址仍保存在堆栈中。公共默认属性Get P的返回值将访问释放的内存,从而触发vbscript中的use-after-free(UAF)漏洞!AssignVar:

火星专栏

图9. vbscript中的崩溃!AssignVar

如前所述,vbscript!AccessArray检查数组元素的索引是否超出边界。但是当获取类的默认属性值时,它将触发脚本回调函数Default Property获取修改数组的长度,而不是在vbscript!AssignVar中访问时再次检查数组的元素。

剥削分析

可以通过以下三个步骤简化利用:

  • 使用此漏洞将二维数组的长度修改为0x0FFFFFFF。
  • 实现读/写原语。
  • 伪造CONTEXT结构并执行shellcode。

让我们详细谈谈利用:

1.修改二维数组的长度

首先,漏洞定义了两个数组,在下图中将其标记为array1和array2的数组1是先前在PoC中描述的阵列,且数组2是一个二维阵列,其中每个元素的值是3。

火星专栏

图10. array2的定义

然后它使用脚本回调函数Default Property Get释放原始array1.pvData并将array2设置为new array1.pvData。因为原来的大小array1.pvData,这是的0x30字节在存储器中,相同array2.SAFEARRAY结构,一些的array2.SAFEARRAY结构将重用在原释放的内存array1.pvData。同时,Default Property Get的返回值0x0FFFFFFFF将覆盖array2.SAFEARRAY的SAFEARRAYBOUND结构,并将二维数组的长度修改为0x0FFFFFFF。

火星专栏

图11.默认属性Get的定义

火星专栏

图12.修改数组长度的步骤

2. RW原语

这里得到一个数组,array1(index_vuln)(0x0FFFFFFE,2),其长度由UAF调节。通过搜索array1的元素,可以在以下脚本中找到index_vuln:

火星专栏

图13.搜索array1(index_vuln)(0x0FFFFFFE,2)

然后它使用array1(index_vuln)(0x0FFFFFFE,2)来实现越界(OOB)并找到两个数组元素混淆的元素。

火星专栏

图14.搜索第一个数组的元素


火星专栏

图15.搜索第二个数组的元素

这里漏洞获取两个数组的元素:array1(index_B)(0,0)和array1(index_vuln)(index_A,0),它们在内存中的距离为8字节。在内存中搜索的充分利用如下所示:

火星专栏

图16.在内存中搜索方式的演示

最后,它使用两个数组的元素来实现类型混淆的读写原语:

火星专栏

图17. RW基元的实现


3.运行shellcode

它使用read原语来泄漏模块的地址:

火星专栏

图18.泄漏模块的地址


通过将一些VARIANT的VarType修改为0x4d并将值修改为0,将调用vbscript!VAR :: Clear,然后将调用堆栈返回地址修改为NtContinue的地址并伪造CONTEXT结构以运行shellcode:

火星专栏

图19.修改VARIANT


火星专栏

图20.运行shellcode


经过一系列的分析,可以稳定地利用此漏洞。此外,由于它是今年在野外发现的第二个VB引擎漏洞利用,因此预计未来VB引擎中的其他漏洞发现并非遥不可及。

总结

作为第一道防线,建议在可用时应用最新的安全补丁以防止漏洞利用。用户还可以使用可以抵御可能漏洞攻击的解决方案。主动,多层次的安全方法是利用漏洞(来自网关,端点,网络和服务器)的威胁的关键。


文章声明:本文为MarsBit专栏作者作品,版权归作者所有,不代表MarsBit观点。

声明:本文为入驻“火星财经 专栏”作者作品,不代表火星财经官方立场。
转载请联系网页底部:内容合作栏目,邮件进行授权。授权后转载时请注明出处、作者和本文链接。未经许可擅自转载本站文章,将追究相关法律责任,侵权必究。
提示:投资有风险,入市须谨慎,本资讯不作为投资理财建议。
本内容旨在传递行业动态,不构成投资建议或承诺。