CVE-2012-1876:Internet Exporter MSHTML.DLL CaculateMinMax 堆溢出简单分析
0x01 2012 Pwn2Own 黑客大赛
- Pwn2Own 是世界上最著名的黑客大赛,意在激励白帽黑客们进行顶尖的安全研究。在 2012 年 Pwn2Own 大赛上,来自法国著名的安全团队 Vupen 利用两个 0day 漏洞,成功攻破了 Window7 下的 IE9 浏览器,其中一个是绕过 IE 安全沙盘的漏洞,另外一个就是编号为 CVE-2012-1876 的堆溢出漏洞
- 一般 Pwn2Own 大赛用于攻破厂商的 0day 漏洞质量都是非常高的,而且漏洞利用也构造的极为精妙,具有很大的学习价值。CVE-2012-1876 漏洞的成因是 MSHTML.DLL 中处理 table 元素的 CaculateMinMax 函数没有对 span 属性大小做限制,导致以 span 的大小作为循环计数,能够将相对可控的字节写到堆空间之外,在开启堆页的情况下会导致异常
- 这个就是触发漏洞的 POC 样本,看起来非常简单,首先 span 的值为 1,之后调用过 over_trigger 函数之后 span 的值变为 1000,造成溢出
0x02 分析环境
虚拟机:Windows7
漏洞软件:IE8
分析工具:Windbg + IDA
POC 样本:exploit.html + poc.html(提取码:wof6)
0x03 调试分析漏洞成因
- 在 Debugger Tools for Windows 目录下使用 gflag.exe -i IExplore.exe +hpa -htc 开启堆页保护,目的是在堆溢出时能够断下,便于调试
- 开启 windbg 后使用 .childdbg 1 命令开启多线程调试(因为在 IE 读取样本 POC 时会多开一个线程去处理),载入 IE 运行后拖入 POC,之后选择允许执行控件之后会断下,这个是一个很简单的汇编指令,将 ecx 中的内容复制到 edi 的地址,很显然 0x0a902018 这个地址触发了堆页保护异常
- 通过查看栈信息,可以看出在 mshtml!CTableLayout::CaculateMinMax 在相对偏移 0x52f 的地方调用了 mshtml!CTableColCalc::AdjustForCal 函数,而刚才触发的异常就在这个函数里面
- 根据栈溯源在结合 IDA 分析可以很清楚看出(在 Windows7 非管理员账户启动 IDA 分析系统 dll,需要以管理员账户启动 IDA)
- 漏洞点异常的原因知道了,那么函数是怎么调用的呢,经过多次调试分析,在 IE8 加载 POC 之后的流程图是这样的
- 选择控件之后会第二次进入 CaculatcMinMax 函数,下面来调试看看
- 首先这个取传入 CaculateMinMax 的第一个参数放入 ebx,第一个参数是 CTableLayout::vftable 对象也就是 table 元素在内存中的对象
- 继续向下调试,对象偏移 54h 保存着 table 元素的大小
- 之后取 CAryKeyValues::vftalbe 的对象存放在 [ebp-84h] 中,继续向下调试
- 这里对 EnsureSizeWorker 函数下断点,运行两次后到此处。EnsureSizeWorker 这个函数的功能是分配堆空间供函数使用,并且将分配过的堆空间首地址存放在 edi+c 中,此时分配的堆空间首地址为 0x0c4b9f90
- 分配完堆空间之后,会取 span 属性的大小放入 eax 中,此时还没有调用 over_trigger 函数,所以此时 span 的值为 1
- 断下 GetAAspan 函数,运行后再次到达这个函数,此时 span 属性的值已经变为 1000(3e8),和 3e8 作比较说明 span 的值最大不能超过 1000
- 之后调用 GetPixelWidth 函数取 width ,经计算后将值的地址存储在 eax 中(这里会将 width * 100 + 9)
- 之后执行 AdjustForCol,可以看到 esi 保存着分配的堆空间的首地址,而 0x098d6f80 中储存着计算过的 width 的值(42765 * 100 + 9)
- 进入异常触发点,此时 edi 的值就为 0x0c4b9f90 + 18h = 0x0c4b9fa8
- 这时查询一下位于 0c4b9fa8 的堆空间信息,发现大小为 70h
- 在向下调试后发现 ebp-20h 为循环计数,初始化为 0,每次循环加 1Ch,ebp+10h 储存着 span 的值(1000),只要 ebp-20h 不大于 ebp+10h,循环就会继续
- 之后堆空间首地址会在每次循环后加上 1Ch,有点复杂,所以直接看 IDA。在每次循环结束后,循环计数 var_20 每次会加 1Ch,而 esi 控制着堆空间的指针,而 esi 由 eax 传入,eax 为堆空间的首地址,ecx 为循环计数 var_20。所以也就是为什么堆空间的指针会每次循环后加上 1Ch
- 所以在第四次次循环后,将堆指针偏移 18 + 4*1C = 88h 的大小,就超出了 70h 的堆空间大小,导致堆页访问异常(0x0c4b9f90 + 88h = 0x0c4ba018)
0x04 漏洞利用
- 首先别忘了关堆页保护,不然就卡在那了
- 这个就是 exploit.html 的样本 ,循环构造了 3 个 0x100 大小的结构 + 1 个 button 对象
- 之后构造了 132 个 table 元素,span 的值为 9,width 的值为 41
- 如下图所示,释放 EEEE… 堆块就是为了能将漏洞堆块插入,然后控制 span 的大小修改 button 对象的头部信息,等再次调用 button 对象时,便能够控制虚表指针,执行任意位置的代码
- 但漏洞堆块真的这么巧的插入精心构造的堆块当中吗,答案是肯定的,而且在 Windows7+IE8 的环境下成功几率几乎为 100%,下面来验证一下
- 已知 javascript 调用 CollectGarbage() 释放堆空间时会调用 ntdll.dll 中的 RtlFreeHeap 函数,而刚刚创建漏洞堆块调用的函数是 EnsureSizeWorker,所以下这两个断点,第一个断点是释放堆块的首地址 free heap,第二个断点是漏洞堆块的首地址 vulheap
>>> bu ntdll!RtlFreeHeap ".echo free heap;db poi(esp+c) l10;g"
>>> bu mshtml!CTableLayout::CalculateMinMax+0x16d ".echo vulheap;dd poi(ebx+9c) l4;g" - 断下这两个断点之后,使用 .openlog + log存放地址 命令将打印出来的值存放在文件中
注:这两个断点的意思是,在到达指定位置后,打印出当前的信息,比如 esp+c,就是打印出 esp+c 的值
- 运行完后,查看 log 信息,首先查找对后一个 vulheap,复制地址往上搜索
- 成功找到释放的堆块,表明漏洞堆块确实已经插入了进入精心构造的堆空间当中
- 之后会将第 132 个 table 元素的 span 值改为 19,照成第一次溢出,目的之通过信息泄露获取 mshtml 的基址来构造 ROP(返回导向编程),目的是绕过 ASLR 和 DEP 保护,由于篇幅原因不再多述
这里为什么要更改第 132 个 table 元素的值,而且上面为什么构造 132 个 table 元素呢,很简单这里是为了加大插入的概率,也就是说前面的 131 个 table 元素只是给第 132 个 table 元素加大插入概率的
- 这个就是用于构造 ROP 的指令
- 以及利用 Heap Spray 将 shellcode 喷射到指定地址
- 最后将第 132 个 table 元素的 span 的值改为 29 并且将 width 的值改为 0x615145,造成第二次溢出,这次溢出会覆盖掉 button 对象的头部,目的是控制虚表指针
- 接着上面查询 vulheap 堆信息
- 可以看到 button 对象的头 4 个字节的信息已经更改为计算过后的 width 的值
注:值得注意的是这个计算过的 width 值与没有计算过的 width 值是 125 倍的关系,就是 615145 * 125 = 0x04954bc5,与上面的 width *100+9 不同
- 之后再调用 button 对象时就会触发虚表指针,那么 eax 就是 button 对象的头 4 个字节 0x04954bc5
- 因为数据太多,所以无法在调用虚表指针时断下,所以下这两个断点记录 eax 和 ecx 的值
bu mshtml!NotifyElement+0x35 “.echo EAX;r eax ;g”
bu mshtml!NotifyElement+0x35 ".echo ECX;r ecx ;g" - 重新运行之后,可以看到 eax 的值确实是 0x04954bc5,之后就会 call [0x04954bc5 + 8],最后只需要将 shellcode 喷射到此地址便可执行任意代码,也达到了完美利用漏洞的目的
0x05 后续…
- CVE-2012-1876 作为能攻下 Windows7 下 IE8 的漏洞,质量果然是非常的高,无论是漏洞分析还是漏洞利用,都体现出 Vupen 安全团队的顶尖技术水准;由于 IE8 的版本不一样可能导致一些参数也不一样,本文利用到的 exploit.html 也是做了一些修改才能达到精准的溢出效果
- 参考资料:0day安全:软件漏洞分析技术 + 漏洞战争
对 CVE-2012-1876 的分析到此结束,如有错误,欢迎指正(天哪终于分析完了)
CVE-2012-1876:Internet Exporter MSHTML.DLL CaculateMinMax 堆溢出简单分析的更多相关文章
- CVE-2010-2883Adobe Reader和Acrobat CoolType.dll栈缓冲区溢出漏洞分析
Adobe Acrobat和Reader都是美国Adobe公司开发的非常流行的PDF文件阅读器. 基于Window和Mac OS X的Adobe Reader和Acrobat 9.4之前的9.x ...
- Windows系统文件mshtml.dll
今天,在vista 32bit,sp 2,IE7的机器上跑开发的软件产品,打开IE,被测系统总是崩溃,换了一台机器,同样的配置环境,却没有重现. 同事的分析很详细,学习了 I tried this c ...
- Strong name signature not valid for this assembly Microsoft.mshtml.dll
Strong name signature not valid for this assembly Microsoft.mshtml.dll http://social.msdn.microsoft ...
- Microsoft.mshtml.dll 添加引用及类型选择错误问题解决办法
在比较早的文章中,提到使用 Microsoft.mshtml.dll 进行模拟浏览器点击的例子. 1.添加引用的问题 一般在开发环境下会在三个地方存有microsoft.mshtml.dll文件.所以 ...
- CVE-2012-1876Microsoft Internet Explorer Col元素远程代码执行漏洞分析
Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏览器. Microsoft Internet Explorer 6至9版本中存在漏 ...
- CVE-2012-0003:Microsoft Windows Media Player winmm.dll MIDI 文件堆溢出漏洞调试分析
0x01 蜘蛛漏洞攻击包 前言:2012 年 2月,地下黑产中流行着一款国产名为蜘蛛漏洞的攻击包 -- "Zhi-Zhu Exploit Pack",该工具包含 5 个漏洞,都是在 ...
- CVE-2013-0077:Microsoft DirectShow quartz.dll m2p 文件堆溢出漏洞简单分析
0x01 前言 2012 年 10 月 5 日,exploit-db 漏洞公布站点上发布了 QQplayer.exe 3.7.892 m2p quartz.dll Heap Pointer OverW ...
- 关于形如--error LNK2005: xxx 已经在 msvcrtd.lib ( MSVCR90D.dll ) 中定义--的问题分析解决
转自:http://hi.baidu.com/qinfengxiaoyue/item/ff262ccfb53b4c2ba0b50a89 引自:http://blog.csdn.net/sptoor/a ...
- [日常工作] 并行计算引发Microsoft.jscript.ni.dll的内存溢出问题的分析解决. .net framework 的版本说明
1. 性能组进行 单点性能测试时发现 商务智能的 并行分析有问题. 效率很低, 开发人员查看iis 的日志 发现错误原因是 Microsoft.jscript.ni.dll 有内存溢出的问题 开发人员 ...
随机推荐
- Python3基础-目录
Python3基础-目录(Tips:长期更新Python3目录) 第一章 初识Python3 1.1 Python3基础-前言 1.2 Python3基础-规范 第二章 Python3内置函数&a ...
- 将samba共享目录映射为本地文件夹(百度网盘直接下载到samba共享目录下)
将samba共享目录映射为本地文件夹(百度网盘直接下载到samba共享目录下) 前面淘了一个蜗牛星际的矿机,打算拿来做个个人云盘,就装上了Linux用smb把硬盘共享出来 访问倒是很爽,就是发现下东西 ...
- WPF 应用 - 在 web 中启动 exe
以下 F:/Debug/xx.exe 为客户端路径. 1. Web 调用 1.1 IE 内核的浏览器调用方式 js 函数调用如下: var a=new ActiveXObject("Wscr ...
- 关于Java中Collections.sort和Arrays.sort的稳定性问题
一 问题的提出 关于Java中Collections.sort和Arrays.sort的使用,需要注意的是,在本文中,比较的只有Collections.sort(List<T> ele ...
- HDU(1420)Prepared for New Acmer(JAVA语言)【快速幂模板】
思路:快速幂裸题. //注意用long,否则会超范围 Problem Description 集训进行了将近2个礼拜,这段时间以恢复性训练为主,我一直在密切关注大家的训练情况,目前为止,对大家的表现相 ...
- ch1_6_5求解旋转词问题
import java.util.Scanner; public class ch1_6_5求解旋转词问题 { public static void main(String[] args) { // ...
- PTA 两个有序链表序列的合并
6-5 两个有序链表序列的合并 (15 分) 本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列. 函数接口定义: List Merge( List L1, List L ...
- python中gzip模块的使用
gzip模块能够直接压缩和解压缩bytes-like类型的数据,同时也能实现对应格式文件的压缩与解压缩 一.数据压缩与解压缩 压缩 函数-gzip.compress(data, compresslev ...
- js 一数组分割成若干个数组,并装换成字符串赋个li标签
success: function (datas) { //请求成功后处理函数. var htmltext = ''; var data = datas.result; console.log(dat ...
- Windows上Docker Toolbox修改镜像源
https://blog.csdn.net/weixin_36242811/article/details/90515835