针对IE VbScript 引擎的漏洞分析,后续会补充CVE-2018-8174和CVE-2018-8373的分析。第一次发帖,如有错误,请指正。
VBScript 变量在内存中占用0x10个字节,其定义是VARIANT结构体,结构如下
其中前两个字节用来标识变量类型,结构为VARTYPE。
定义如下的类型,我们在内存中进行查看;
上面调试输出日志可以看出变量在Vbscript 中存储的内存布局。
在Vbscript引擎中,数组的结构定义为SAFEARRAY 和 SAFEARRAYBOUND
我们使用如下的代码来查看数据在VBScript中的内存分布情况
windbg调试数据如下
经过第二次断点断下,我们来看下两个数组的内存分布,通过下面的数据可以看出,数组越界可以影响其他数据。
VBScript 在IE中的权限是受限的,可以通过修改SafeMode标识符来控制,具体在COleCscript对象的偏移0x174地址处。正常的情况下,该值为0x0e,既运行在SafeMode下,但是如果通过漏洞利用可以将该值修改为0x00,VBScript便可以执行我们想要执行的系统命令。DVE技术的精髓:通过修改关键数据结构来获取任意数据操纵的能力。
我们先通过如下的代码来验证SafeMode
windbg调试数据如下
通过如上的数据我们可以看出,i的类型虽然是vbNull,但是通过赋值函数地址,其实i的值域已经保存了CScriptEntryPoint的地址。于是就存在如下的关系
POC 中主要使用如下的代码获得读写内存的权限,我们来看漏洞的成因以及如何获得读写内存的权限。
redim函数最终调用OLEAUT32.dll里的SafeArrayRedim函数来实现。SafeArrayRedim函数定义如下
我们主要来看下aa数组重新分配的过程。
这样就可以通过数组越界来读写内存了。
我们来看下Over函数执行完毕之后,aa和ab内存布局
ab的pvData在aa的8个字节之后,只是一种可能性,如何判断内存布局确是如此呢? ab(0)=1.123456789012345678901234567890,此浮点数值编码后在内存里就是d3746f66,3ff1f9ad。02dac988即是ab(0)的内存,ab(0)赋值浮点数使02dac990开始的连续8个字节分别是d3746f66和3ff1f9ad。而02dac990算是aa(a1)元素,该元素的类型应该是0x6f66,但VarType函数取该值后会和0xBFFF逻辑与,0x6f66&0xBFFF=0x2F66,所以用 type1=&h2f66作为aa和ab确实错位重叠的依据。
在完成内存的布局后,exploit就可以借助ab数组元素的赋值操作来aa数组元素的Type字段进行更改,从而实现类型的混淆,接下去我们将分析exploit中用到的类型混淆手法以及由此得到的Read primitive。
来看下Mydata()函数,它会通过如下代码将testaa函数对象指针赋给i:
这里面会进行两次类型混淆处理,首先由于变量i的类型为null(0x01),因此需要将其转成longinteger(0x03)后再返回,该函数对象指针事实上就是CScriptEntryPoint对象的指针。而myarray中则保存着精心构造的SAFEARRAY结构,最初赋给aa(a1+2)时其类型为string(0x08),需要将其类型改为Variant数组,这在后面获取Write primitive时会用到。对应的调试过程如下:
对ab(0)赋值,ab(0)=1.69759663316747E-313,其内存布局是0800000008000000,恰好把aa(a1)类型修改为VT_BSTR,也即vbscript此后会把aa(a1)看做BSTR类型,将内存地址004ced9c看做执行字符串内存的地址,认为004ced9c向前四个字节(004ced98)就是存放字符串长度的地址,lenB就可以读取该地址4个字节的数据。最后可以读取到COleScriptObject;
例如 i=readmemo(i+8) 是读取CScriptEntryPoint+8处的地址,
修改SafeMode,开启上帝模式.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-1-14 09:55
被Heavenml编辑
,原因: