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 堆溢出简单分析的更多相关文章

  1. CVE-2010-2883Adobe Reader和Acrobat CoolType.dll栈缓冲区溢出漏洞分析

       Adobe Acrobat和Reader都是美国Adobe公司开发的非常流行的PDF文件阅读器. 基于Window和Mac OS X的Adobe Reader和Acrobat 9.4之前的9.x ...

  2. Windows系统文件mshtml.dll

    今天,在vista 32bit,sp 2,IE7的机器上跑开发的软件产品,打开IE,被测系统总是崩溃,换了一台机器,同样的配置环境,却没有重现. 同事的分析很详细,学习了 I tried this c ...

  3. 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 ...

  4. Microsoft.mshtml.dll 添加引用及类型选择错误问题解决办法

    在比较早的文章中,提到使用 Microsoft.mshtml.dll 进行模拟浏览器点击的例子. 1.添加引用的问题 一般在开发环境下会在三个地方存有microsoft.mshtml.dll文件.所以 ...

  5. CVE-2012-1876Microsoft Internet Explorer Col元素远程代码执行漏洞分析

    Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏览器.         Microsoft Internet Explorer 6至9版本中存在漏 ...

  6. CVE-2012-0003:Microsoft Windows Media Player winmm.dll MIDI 文件堆溢出漏洞调试分析

    0x01 蜘蛛漏洞攻击包 前言:2012 年 2月,地下黑产中流行着一款国产名为蜘蛛漏洞的攻击包 -- "Zhi-Zhu Exploit Pack",该工具包含 5 个漏洞,都是在 ...

  7. 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 ...

  8. 关于形如--error LNK2005: xxx 已经在 msvcrtd.lib ( MSVCR90D.dll ) 中定义--的问题分析解决

    转自:http://hi.baidu.com/qinfengxiaoyue/item/ff262ccfb53b4c2ba0b50a89 引自:http://blog.csdn.net/sptoor/a ...

  9. [日常工作] 并行计算引发Microsoft.jscript.ni.dll的内存溢出问题的分析解决. .net framework 的版本说明

    1. 性能组进行 单点性能测试时发现 商务智能的 并行分析有问题. 效率很低, 开发人员查看iis 的日志 发现错误原因是 Microsoft.jscript.ni.dll 有内存溢出的问题 开发人员 ...

随机推荐

  1. 在windows 下查看ip 地址和 在ubundu 下查看IP地址

    在windows 下查看ip 地址和 在ubundu 下查看IP地址 1.在windows 下查看 IP地址:ipconfig 2.在 ubundu 下查看IP地址:ifconfig

  2. 分布式session实现方式

    一.背景 在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理. 如果不做任何处理的话,用户将出现频繁登录的现象,比如集群中存在A.B两台服务器,用户在第一次访问网站时,N ...

  3. FreeBSD 宣布 2020 年第 4 季度状态报告

    FreeBSD 宣布 2020 年第 4 季度状态报告● 继续努力从 FreeBSD 基本系统中移除 GPL 协议的软件,以实现 FreeBSD 项目基本目标.● Linux 二进制兼容层的 Linu ...

  4. FreeBSD 12.2 阿里云镜像使用说明

    目前直接从阿里云 12.1 升级 12.2 会导致错误.镜像非本人制作.FreeBSD 12.2 阿里云镜像使用说明镜像下载地址: http://t.cn/A6taB5jO修改内容:对 /usr/sr ...

  5. visual studio 2019 + cmake 实现windows linux跨平台开发环境搭建

    visual studio 2019开始支持cmake跨平台开发. 以前cmake项目需要先生成vs项目,然后vs直接使用vs项目开发.现在可以直接用vs2019创建或打开cmake项目. 使用vis ...

  6. BIMFACE二次开发SDK 开源C#版

    [ BIMFace.SDK.CSharp ] 是基于微软.NET 技术封装的用于 BIMFACE 二次开发的通用类库.其中封装了BIMFace服务端API,包含基础API.文件上传API.文件转换AP ...

  7. java 面试经典题

    面向对象编程(OOP) Java是一个支持并发.基于类和面向对象的计算机编程语言.下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改. 代码复用. 增强代码的可靠性和灵活性. 增加代码 ...

  8. css实现一个电影卡片

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  9. python编写自己的base64加解密工具

    0x00 Base64编码的用途 在网络传输中,不是所的的内容都是可打印字符,其中绝大多数数据是不可见字符,base64可以基于64个可打印字符来表示这些带有不可打印字符的传输数据. 0x01 Bas ...

  10. 干掉前端!3分钟纯 Java 注解搭个管理系统

    大家好,我是小富~ 最近接触到个新项目,发现它用了一个比较有意思的框架,可以说实现了我刚入行时候的梦想,所以这里马不停蹄的和大家分享下. 在我刚开始工作接触的项目都还没做前后端分离,经常需要后端来维护 ...