操作系统:Windows 7 sp1 32位
浏览器:IE10.0.9200.16438
调试器: IDA、windbg、x64dbg
下面是我自己修改的一份简单的poc,为了方便调试
windbg开启堆调试支持:
打开cmd输入gflags.exe /i iexplore.exe +hpa
windbg附加IE运行poc时异常信息:
异常时eip = 66bd1a87,看指令就知道是读取esi内存时出错了,下面再看下esi指向的内存是哪里申请的
下面是当前栈回溯信息
经过上面分析,内存是
RedimPreserveArray
函数申请的,在函数中又调用了oleaut32模块中的SafeArrayRedim函数实现内存重新分配,先对参数做一次分析得知,第一个参数类型是SAFEARRAY,第二个参数类型是SAFEARRAYBOUND,前者是待调整的数组,后者是待调整的数组大小。
SAFEARRAY用来描述数组的详细信息
SAFEARRAYBOUND用来描述数组下标详细信息
关闭堆调试支持使用x64dbg分析:
打开cmd输入gflags.exe /i iexplore.exe -hpa
关闭堆调试支持
x64dbg下载符号表:
运行poc用x64dbg附加先下载符号表
符号表下载完成后重启POC再次附加,对0x6A8E476E处下断,断下来后观察ESI指向的结构,pvData字段在偏移0xC处,紧随其后是0x00000006,一看就是描述数组长度的数据,暂且给其后的数据起名为dataSize吧,pvData =
0x0297DEF0
,dataSize = 0x6。
再观察下eax指向的内存,其中存着0x1D,那么现在确定待调整的大小是0x1D
F8后再观察SAFEARRAY,这时pvData变成了 0x0298DDE0,之前是
0x0297DEF0
,大小也变成了预期的0x1D
下面结合poc代码看一下,调试器现在断在第一次调整arrayA的时候,按F9后再断下来一次就是第二次调整了
在第二次断到SafeArrayRedim,可以看到调整的大小是0x0800001D,这是一个超大的数值,内存是肯定申请不到的,那么接下来看下ESI指向的SAFEARRAY
当前的pvData是0x0298DDE0,大小是0x1D,那么直接F8看接下来的表现
F8后数组大小被改变了,但是数组首地址却没有变,这时候其实是重定义数组大小失败了,在执行SafeArrayRedim前对HeapAlloc下断调试下就知道了,
HeapAlloc 申请大小为0x0800001D的内存时会返回失败,因为这个空间太大了,可以想象这时候数组真正占用的空间其实时0x1D,而由于在校验申请内存的成功或之前就过早的更改了数组长度,现在的长度已经被改成了
0x0800001D
,这也就说明这个数组读写的范围可以在0-0x0800001D之间,这明显越界读写了,关于在执行
SafeArrayRedim
函数时HeapAlloc申请内存失败的过程,各位看官可以自己动手调试下,现在漏洞成因清楚了,那么就可以开始接下来的利用环节了。
在利用前还需要对VARIANT这个结构有所了解,因为VBS虚拟机往数组中存储数据时,默认使用VARIANT结构来存储,在脚本语言和com组件中,这个结构会被比较频繁的使用到,记得多年前用VBS写脚本调用C++的com组件时,组建接口参数类型就使用了
VARIANT, 为什么使用
VARIANT呢?因为不同类型的数据都可以用VARIANT这个结构来存储,这样接口就非常的灵活,以下是VBS虚拟机使用的VARIANT结构体。
现在对数据结构有一定的了解了,还需要动手调试下VBS数组在内存中的布局,在调试前需要稍微修改下poc中的Over函数,在函数中添加一个弹框来给调试提供便利,弹框后是对arrayA这个数组赋值,索引分别是1、2、3
修改poc后用IE运行,等待弹出"test"消息框后附加
在VBS模块中对数组或变量的赋值是由函数AssignVar函数来完成的
现在用x64dbg对AssignVar函数地址0x6AA01B0E下断,断下来后看下各个寄存器以及内存情况
F8执行到0x6AA01B29处,这时已经完成VARIANT的拷贝了,现在可以观察下esi指向的内存
在arrayA(3) = 2执行完成后,可以看到内存布局变成下面这样了
有了上面的信息作为铺垫后,接下来就再稍微修改下poc构造一个可以利用的内存布局,并获取CScriptEntryPoint对象
下面运行poc,观察下CScriptEntryPoint
对象的构造过程吧,首先看看执行arrayB(0) = 0 的时候,esi指向
arrayB(0)
,由于两个数组内存位置相邻,通过arrayB就可以算出arrayA
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-1-11 19:20
被kanxue编辑
,原因: