Trend Micro研究人员7月11日发现一个高风险IE漏洞,研究人员发送漏洞细节给微软并帮助修复了该漏洞。漏洞CVE编号为CVE-2018-8373,影响Windows最新版本的VBScript引擎,因为Windows 10 Redstone 3 (RS3)默认不启用VBScript,所以IE 11未受到影响。
研究人员发现了恶意web流量中的利用,下图是使用的恶意URL:
图1. 使用的恶意URL
研究人员该漏洞利用使用了Heuristics(启发)的思想,而且利用样本使用了与CVE-2018-8174漏洞利用相似的混淆技术,也是VBScript引擎远程代码执行漏洞。
图2. CVE-2018-8373(左)与CVE-2018-8174(右)比较
下面是样本漏洞利用使用的运行shellcode的方法:
图3. CVE-2018-8373(左)与CVE-2018-8174(右)运行shellcode方法比较
研究人员怀疑该漏洞利用样本来自于同一个创建者。研究人员分析样本发现使用了vbscript.dll
的一个新的use-after-free (UAF)漏洞,该漏洞在最新的VBScript引擎中还未修复。
研究原始的漏洞利用是经过混淆的,本文通过POC解释漏洞被利用的过程:
图4. IE漏洞PoC
PoC定义了MyClass
类,其中有一个叫做array
的成员变量和2个成员函数,Class_Initialize
和Default Property Get P
。Class_Initialize
是一种不建议使用的方法,现在已经被新的过程所替代。当对象初始化的时候,会被自动唤醒。在PoC中,Class_Initialize
是重载的,当调用VBScriptClass::InitializeClass
时,处理的是重载的函数。
默认属性是一个不需要特殊说明就开源访问的类属性。在PoC中,默认的Default Property Get
函数会重载MyClass
的默认属性。当调用被用来访问cls时,也会处理重载的函数。
漏洞的触发流会简化为下面三步:
1. 设置cls = New MyClass
设置会调用重载的函数Class_Initialize
。在Class_Initialize
中, ReDim array(2)
会调用vbscript!RedimPreservearray
来创建元素数是3的数组:
图5. 内存中的ReDim array(2)
2.cls.array(2)
调用vbscript!Accessarray
来获取数组元素的地址。在vbscript!Accessarray
中,首先会检查数组元素的索引是否越界:
图6. 检查vbscript!Accessarray
中的元素索引
然后计算元素的地址,保存到栈中,并返回下面的值:
图7. 在栈中保存元素地址
3. cls.array(2)=cls
cls.array(2)=cls
会调用vbscript!AssignVar
来设置MyClass
的默认属性值为cls.array(2)
。获取MyClass
的默认属性值后,会调用 Public Default Property Get P
并执行Public Default Property Get P
中的ReDim array(1)
脚本,释放原来的`array.pvData``:
图8.释放原来的pvData
array(2)的地址仍然保存在栈中,Public Default Property Get P
的返回值会访问释放的内存,并触发vbscript!AssignVar
中的use-after-free (UAF)漏洞:
图9. vbscript!AssignVar
中的奔溃
vbscript!Accessarray
会检查数组元素索引是否越界。在获取类的默认属性值后,会差法脚本回调函数Default Property Get
修改数组的长度,然后在vbscript!AssignVar
中访问时就不需要检查数组的元素了。
漏洞的利用过程可以简化为以下三个步骤:
0x0FFFFFFF
;CONTEXT
结构,执行shellcode。下面详细分析以下漏洞的利用:
首先,漏洞会定义两个数组,在下图中标记为array1
和array2
。array1
就是前面PoC中描述的数组,array2
是一个二维数组,其中每个元素的值都是3。
图10. 定义array2
然后使用脚本回调函数Default Property Get
释放原来的array1.pvData
,设置array2
为新的array1.pvData
。因为原来array1.pvData
的大小和array2.SAFEARRAY
结构是相同的,在内存中是0x30
字节。一些array2.SAFEARRAY
结构会服用array1.pvData
释放的内存。同时,Default Property Get
的返回值0x0FFFFFFFF
会覆盖array2.SAFEARRAY
的结构SAFEARRAYBOUND
,并修改二维数组的长度为0x0FFFFFFF
。
图11. 定义Default Property Get
图12. 修改数组长度的步骤
然后得到数组array1 (index_vuln)(0x0FFFFFFE, 2)
,其长度被UAF修改过了。通过索索array1
的元素,可以在下面的脚本中找到index_vuln
:
图13. 搜索array1 (index_vuln)(0x0FFFFFFE, 2)
然后使用array1(index_vuln)(0x0FFFFFFE, 2)
实现out-of-bounds (OOB),并找出2个用于类型混淆的数组元素。
图14、15. 搜索两个数组的元素
然后漏洞就得到了两个数组元素:array1(index_B)(0, 0)
和array1(index_vuln)(index_A, 0)
,在内存中的距离为8字节。在内存中搜索的完全利用如下:
图16. 在内存中搜索的方法说明
最后,使用2个数组元素来实现read and write
原语:
图17. RW原语的实现
使用原语来泄露模块的地址:
图18. 泄露模块的地址
通过修改一些变种的VarType
为0x4d
,并把值修改为0
,可以调用vbscript!VAR::Clear
,然后调用栈会修改返回地址为NtContinue
的地址和假的CONTEXT
结构来运行shellcode:
图19. 修改变种
图20. 运行shellcode
基于以上分析,该漏洞很容易就可以利用。而且这是今年发现的第二个VB引擎漏洞利用,因此,研究人员认为很快会有其他的VB引擎漏洞利用出现。
IoC
哈希值 (SHA256):
0d6fe137790e2ebdf4fac2dd500656f3a6f74c0d1598251929ea3558f965675f – detected as HTML_EXPLOIT.YYRV