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 有内存溢出的问题 开发人员 ...
随机推荐
- React函数式组件和类组件[Dan]
一篇对Dan的 How Are Function Components Different from Classes? 一文的个人阅读总结,内容来自于此.强烈推荐阅读 Dan Abramov.的博客. ...
- 03----python入门----函数相关
一.前期知识储备 函数定义 你可以定义一个由自己想要功能的函数,以下是简单的规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 () 任何传入参数和自变量必须放在圆括号中间,圆括号 ...
- IDEA中便捷内存数据库H2的最简使用方式
在IDEA中有时候为了练习,需要使用到数据库,但如果自己工作或开发机子上本来没有安装数据库,也没有可用的远程数据库时,我们可以直接在IDEA环境上使用便捷式的内存数据库H2,关于H2更多知识就自己去找 ...
- apicloud打包的ios证书的获取方法
apicloud云编译的时候,需要测试证书或者正式证书进行编译. 那么这个证书是怎么来的呢?通过什么渠道可以获取呢? 这里我介绍下使用香蕉云编这个在线工具来生成: 1.登录香蕉云编,生成证书的csr文 ...
- 2020 年安装 FreeBSD 系统的基础视频
B 站搜索 BV14i4y137mh 包含了下载,虚拟机安装,配置 SSH 等教程. https://www.bilibili.com/video/BV14i4y137mh
- SpringBoot自动配置原理源码级别分析
SpringBoot自动配置原理 前言 后面还会讲到SpringBoot自动配置原理,会主要讲解@EnableAutoConfiguratuon注解帮助我们做了什么事情,是如何自动把自动配置类扫描到容 ...
- C# 基础 - string 和 Datetime
1. string 1. 格式化填充 string str = "this {0} a {1}"; Console.WriteLine(string.Format(str, &qu ...
- JAVA使用Collator对中文排序
首先创建一个集合 public static List<String> init() { List<String> list = new ArrayList<String ...
- Raft共识算法详解
Raft共识算法 一.背景 拜占庭将军问题是分布式领域最复杂.最严格的容错模型.但在日常工作中使用的分布式系统面对的问题不会那么复杂,更多的是计算机故障挂掉了,或者网络通信问题而没法传递信息,这种情况 ...
- 谜题(JAVA语言)
package 第三章习题; /* * 有一个5*5的网络,其中恰好有一个格子是空的,其他格子各有一个字母. * 一个有4种指令:A, B, L, R, 分别表示把空格上.下.左.右的相邻字母移到 ...