首页
社区
课程
招聘
[原创]CVE-2014-6332 修改浏览器安全属性开启Godmode
发表于: 2018-12-7 21:15 9091

[原创]CVE-2014-6332 修改浏览器安全属性开启Godmode

2018-12-7 21:15
9091

操作系统: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编辑 ,原因:
收藏
免费 4
支持
分享
最新回复 (3)
雪    币: 26588
活跃值: (63252)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
感谢分享!
2018-12-10 09:36
0
雪    币: 2016
活跃值: (1071)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
牛!
2018-12-11 15:45
0
雪    币: 11716
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
#寻宝大战#祝看雪19岁快乐!
2019-1-11 20:08
0
游客
登录 | 注册 方可回帖
返回
//