首页
社区
课程
招聘
[原创]MS11-081中IE9导致的一个CHM漏洞简单分析
2011-10-12 21:35 8192

[原创]MS11-081中IE9导致的一个CHM漏洞简单分析

2011-10-12 21:35
8192
这个漏洞只存在于IE9,会导致无法下载CHM中内嵌的文件,在没有安装KB2586448更新的机器上测试
首先新建一个1.html文件,内容如下
<a href = "1.rar">1.rar</a>

然后和一个1.rar文件用HTML Help Workshop一起编译成CHM
打开CHM点击1.rar链接,也可以在IE地址栏输入mk:@MSITStore:XXX(具体路径)\1.chm::/1.rar,报错调试
停在CDownloadUtilities::MarshalBindContextToStream函数内,这个函数为下载1.rar文件做一些准备工作
声明如下
HRESULT CDownloadUtilities::MarshalBindContextToStream(CInterThreadMarshal **ppITM<eax>, CDownloadThreadParam *pDTP, wchar_t *szURL, IBindCtx *pBC)
简单分析下其代码
CDownloadUtilities::MarshalBindContextToStream(CInterThreadMarshal **ppITM<eax>, CDownloadThreadParam *pDTP, wchar_t *szURL, IBindCtx *pBC):
7003D23A  mov         edi,edi  
7003D23C  push        ebp  
7003D23D  mov         ebp,esp  
7003D23F  sub         esp,0Ch  ;HRESULT hr<[ebp-4h]>, IUnknown *pUnk<[ebp-8h]>, IEUserBroker *pIEUB<[ebp-0Ch]>
7003D242  push        ebx  
7003D243  push        esi  
7003D244  push        edi  
7003D245  lea         edx,[ebp-8]  ;edx = &pUnk
7003D248  push        edx  ;&pUnk
7003D249  mov         edi,eax  ;edi = ppITM
7003D24B  mov         eax,dword ptr [ebp+10h]  ;eax = pBC
7003D24E  mov         ecx,dword ptr [eax]  ;ecx = pBC->lpVtbl
7003D250  push        offset __GUID_0000000e_0000_0000_c000_000000000046 (6FF65DA8h)  ;&IID_IUnknown
7003D255  push        eax  ;pBC
7003D256  call        dword ptr [ecx]  ;eax = pBC->lpVtbl->QueryInterface(pBC, &IID_IUnknown, &pUnk)
7003D258  xor         ebx,ebx  
7003D25A  mov         dword ptr [ebp-4],eax  ;hr = eax
7003D25D  cmp         eax,ebx  
7003D25F  jl          CDownloadUtilities::MarshalBindContextToStream+0C6h (7003D300h)  ;if (FAILED(hr)) goto 7003D300h
7003D265  push        3  
7003D267  push        offset string L"mk:" (70019BB4h)  
7003D26C  push        dword ptr [ebp+0Ch]  
7003D26F  call        dword ptr [__imp___wcsnicmp (6FE91364h)]  
7003D275  add         esp,0Ch  
7003D278  test        eax,eax  
7003D27A  jne         CDownloadUtilities::MarshalBindContextToStream+74h (7003D2AEh)  ;if (_wcsnicmp(szURL, L"mk:", 3)) goto 7003D2AEh
7003D27C  mov         eax,dword ptr [ebp-8]  ;eax = pUnk
7003D27F  mov         ecx,dword ptr [eax]  ;ecx = pUnk->lpVtbl
7003D281  push        eax  ;pUnk
7003D282  call        dword ptr [ecx+8]  ;pUnk->lpVtbl->Release(pUnk)
7003D285  push        ebx  ;0
7003D286  lea         eax,[ebp+10h]  ;eax = &pBC
7003D289  push        eax  ;&pBC
7003D28A  push        ebx  ;0
7003D28B  push        ebx  ;0
7003D28C  push        ebx  ;0
7003D28D  push        ebx  ;0
7003D28E  mov         dword ptr [ebp-8],ebx  ;pUnk = 0
7003D291  call        dword ptr [__imp__CreateAsyncBindCtxEx@24 (7023B14Ch)]  ;eax = CreateAsyncBindCtxEx(0, 0, 0, 0, &pBC, 0)
7003D297  mov         esi,dword ptr [edi]  ;esi = *ppITM
7003D299  mov         dword ptr [ebp-4],eax  ;hr = eax
7003D29C  cmp         esi,ebx  
7003D29E  je          CDownloadUtilities::MarshalBindContextToStream+74h (7003D2AEh)  ;if (*ppITM == 0) goto 7003D2AEh
7003D2A0  call        CInterThreadMarshal::~CInterThreadMarshal (701D7894h)  ;(*ppITM)->~CInterThreadMarshal()(this<esi>)
7003D2A5  push        esi  
7003D2A6  call        operator delete (6FEA35D9h)  ;delete *ppITM
7003D2AB  pop         ecx  
7003D2AC  mov         dword ptr [edi],ebx  ;*ppITM = 0
7003D2AE  cmp         dword ptr [ebp-4],ebx  
7003D2B1  jl          CDownloadUtilities::MarshalBindContextToStream+0C6h (7003D300h)  ;if (FAILED(hr)) goto 7003D300h
7003D2B3  mov         eax,dword ptr [edi]  ;eax = *ppITM
7003D2B5  cmp         eax,ebx  
7003D2B7  je          CDownloadUtilities::MarshalBindContextToStream+89h (7003D2C3h)  ;goto 7003D2C3h
7003D2B9  mov         ecx,dword ptr [ebp+8]  ;ecx = pDTP
7003D2BC  mov         dword ptr [ecx+18h],eax  ;*(pDTP + 18h) = eax
7003D2BF  mov         dword ptr [edi],ebx  ;*ppITM = 0
7003D2C1  jmp         CDownloadUtilities::MarshalBindContextToStream+0BDh (7003D2F7h)  
7003D2C3  push        4  
7003D2C5  call        operator new (6FE9E771h)  ;eax = new LPSTREAM
7003D2CA  pop         ecx  
7003D2CB  cmp         eax,ebx  
7003D2CD  je          CDownloadUtilities::MarshalBindContextToStream+99h (7003D2D3h)  ;if (eax == 0) goto 7003D2D3h
7003D2CF  mov         dword ptr [eax],ebx  ;[eax] = 0
7003D2D1  jmp         CDownloadUtilities::MarshalBindContextToStream+9Bh (7003D2D5h)  
7003D2D3  xor         eax,eax  
7003D2D5  mov         ecx,dword ptr [ebp+8]  ;ecx = pDTP
7003D2D8  mov         dword ptr [ecx+18h],eax  ;*(pDTP + 18h) = eax
7003D2DB  mov         dword ptr [ebp-4],8007000Eh  ;hr = 8007000Eh
7003D2E2  cmp         eax,ebx  
7003D2E4  je          CDownloadUtilities::MarshalBindContextToStream+0BDh (7003D2F7h)  ;if (eax == 0) goto 7003D2F7h
7003D2E6  push        eax  
7003D2E7  push        dword ptr [ebp-8]  ;pUnk
7003D2EA  push        offset _IID_IBindCtx (6FF2AB8Ch)  
7003D2EF  call        _CoMarshalInterThreadInterfaceInStream@12 (701FF7F2h)  ;eax = CoMarshalInterThreadInterfaceInStream(&IID_IBindCtx, pUnk, eax)
7003D2F4  mov         dword ptr [ebp-4],eax  ;hr = eax
7003D2F7  mov         eax,dword ptr [ebp-8]  ;eax = pUnk
7003D2FA  mov         ecx,dword ptr [eax]  ;ecx = pUnk->lpVtbl
7003D2FC  push        eax  ;pUnk
7003D2FD  call        dword ptr [ecx+8]  ;pUnk->lpVtbl->Release(lpVtbl)
7003D300  call        LCIEUnifiedFrame (6FF9CD1Fh)  
7003D305  test        al,al  
7003D307  je          CDownloadUtilities::MarshalBindContextToStream+128h (7003D362h)  
7003D309  lea         eax,[ebp-0Ch]  
7003D30C  push        eax  
7003D30D  call        dword ptr [__imp_CoCreateUserBroker (6FE925A4h)]  
7003D313  test        eax,eax  
7003D315  js          CDownloadUtilities::MarshalBindContextToStream+128h (7003D362h)  
7003D317  lea         eax,[ebp+0Ch]  
7003D31A  push        eax  
7003D31B  push        dword ptr [ebp-0Ch]  
7003D31E  push        offset _IID_IEUserBroker (6FF37F6Ch)  
7003D323  call        dword ptr [__imp__CoMarshalInterThreadInterfaceInStream@12 (6FE91FECh)]  
7003D329  mov         dword ptr [ebp-4],eax  
7003D32C  cmp         eax,ebx  
7003D32E  jne         CDownloadUtilities::MarshalBindContextToStream+11Fh (7003D359h)  
7003D330  mov         edi,dword ptr [ebp+8]  
7003D333  mov         eax,dword ptr [edi+14h]  
7003D336  mov         esi,dword ptr [ebp+0Ch]  
7003D339  cmp         eax,ebx  
7003D33B  je          CDownloadUtilities::MarshalBindContextToStream+109h (7003D343h)  
7003D33D  mov         ecx,dword ptr [eax]  
7003D33F  push        eax  
7003D340  call        dword ptr [ecx+8]  
7003D343  mov         dword ptr [edi+14h],esi  
7003D346  cmp         esi,ebx  
7003D348  je          CDownloadUtilities::MarshalBindContextToStream+116h (7003D350h)  
7003D34A  mov         eax,dword ptr [esi]  
7003D34C  push        esi  
7003D34D  call        dword ptr [eax+4]  
7003D350  mov         eax,dword ptr [ebp+0Ch]  
7003D353  mov         ecx,dword ptr [eax]  
7003D355  push        eax  
7003D356  call        dword ptr [ecx+8]  
7003D359  mov         eax,dword ptr [ebp-0Ch]  
7003D35C  mov         ecx,dword ptr [eax]  
7003D35E  push        eax  
7003D35F  call        dword ptr [ecx+8]  
7003D362  mov         eax,dword ptr [ebp-4]  
7003D365  pop         edi  
7003D366  pop         esi  
7003D367  pop         ebx  
7003D368  leave  
7003D369  ret         0Ch  
7003D36C  nop  
7003D36D  nop  
7003D36E  nop  
7003D36F  nop  
7003D370  nop  

简单改写成C++代码
HRESULT CDownloadUtilities::MarshalBindContextToStream(CInterThreadMarshal **ppITM<eax>, CDownloadThreadParam *pDTP, wchar_t *szURL, IBindCtx *pBC)
{
	IEUserBroker *pIEUB;
	IUnknown *pUnk;
	HRESULT hr;
	if (SUCCEEDED(hr = pBC->QueryInterface(&IID_IUnknown, &pUnk)))
	{
		if (!_wcsnicmp(szURL, L"mk:", 3))
		{
			pUnk->Release();
			pUnk = NULL;
			hr = CreateAsyncBindCtxEx(0, 0, 0, 0, &pBC, 0);
			if (*ppITM)
			{
				(*ppITM)->~CInterThreadMarshal();
				delete *ppITM;
				*ppITM = NULL;
			}
		}
		if (SUCCEEDED(hr))
		{
			if (*ppITM)
			{
				*(pDTP + 18h) = *ppITM;
				*ppITM = NULL;
			}
			else
			{
				IStream **ppStm = new LPSTREAM;
				if (ppStm)
				{
					*ppStm = 0;
				}
				else
				{
					ppStm = NULL;
				}
				*(pDTP + 18h) = ppStm;
				hr = 8007000Eh;
				if (ppStm)
				{
					hr = CoMarshalInterThreadInterfaceInStream(&IID_IBindCtx, pUnk, ppStm);
				}
			}
			pUnk->Release();
		}
	}
	//omit
	return hr;
}

首先函数调用pBC->QueryInterface获得pBC对象的IUnknown接口pUnk,由于IBindCtx只继承自IUnknown,所以IUnknown接口和IBindCtx接口地址实际相同,当下载CHM内嵌的文件时,CDownloadUtilities::MarshalBindContextToStream函数的szURL参数为形如mk:XXX的字符串,所以函数调用pUnk->Release又设pUnk=NULL,而pUnk原本的计数应为1,pUnk->Release彻底释放了pBC对象,于是函数调用CreateAsyncBindCtxEx重新获得pBC对象,pBC是更新了但pUnk仍然为NULL,此外函数又彻底释放了*ppITM对象并设*ppITM=NULL,于是之后函数会调用CoMarshalInterThreadInterfaceInStream列集接口指针,但调用时第二个参数为pUnk,但pUnk=NULL,实际应为pBC,这还不是大问题,紧跟着的pUnk->Release才是祸根,由于pUnk=NULL,取pUnk的虚函数表指针造成访问违例,程序报错,不过幸好之前pUnk设为了NULL,不然后果就更糟糕了,解决方法应该是换用pBC。当szURL参数不是形如mk:XXX的字符串时就不会产生问题了。
附件是编译好的一个CHM,其中的1.rar是本人写的一个小工具,说明见本人博客http://hi.baidu.com/promised_lu

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

上传的附件:
收藏
点赞5
打赏
分享
最新回复 (6)
雪    币: 589
活跃值: (119)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
promsied 4 2011-10-13 22:55
2
0
KB2586448把CreateAsyncBindCtxEx(0, 0, 0, 0, &pBC, 0);改成了CreateAsyncBindCtxEx(0, 0, 0, 0, &pUnk, 0);解决了问题
函数声明改成了HRESULT CDownloadUtilities::MarshalBindContextToStream(IBindCtx *pBC<eax>, CInterThreadMarshal **ppITM<ecx>, CDownloadThreadParam *pDTP, wchar_t *szURL)
代码如下
.text:101AD3AA                 mov     edi, edi
.text:101AD3AC                 push    ebp
.text:101AD3AD                 mov     ebp, esp
.text:101AD3AF                 sub     esp, 0Ch
.text:101AD3B2                 push    ebx
.text:101AD3B3                 push    esi
.text:101AD3B4                 push    edi
.text:101AD3B5                 lea     edx, [ebp+pUnk]
.text:101AD3B8                 push    edx
.text:101AD3B9                 push    offset stru_100D5E20
.text:101AD3BE                 mov     edi, ecx
.text:101AD3C0                 mov     ecx, [eax]
.text:101AD3C2                 push    eax
.text:101AD3C3                 call    dword ptr [ecx]
.text:101AD3C5                 xor     ebx, ebx
.text:101AD3C7                 mov     [ebp+var_4], eax
.text:101AD3CA                 cmp     eax, ebx
.text:101AD3CC                 jl      loc_101AD46D
.text:101AD3D2                 push    3               ; MaxCount
.text:101AD3D4                 push    offset aMk      ; "mk:"
.text:101AD3D9                 push    [ebp+szURL]     ; Str1
.text:101AD3DC                 call    ds:__imp__wcsnicmp
.text:101AD3E2                 add     esp, 0Ch
.text:101AD3E5                 test    eax, eax
.text:101AD3E7                 jnz     short loc_101AD41B
.text:101AD3E9                 mov     eax, [ebp+pUnk]
.text:101AD3EC                 mov     ecx, [eax]
.text:101AD3EE                 push    eax
.text:101AD3EF                 call    dword ptr [ecx+8]
.text:101AD3F2                 push    ebx             ; reserved
.text:101AD3F3                 lea     eax, [ebp+pUnk]
.text:101AD3F6                 push    eax             ; ppBC
.text:101AD3F7                 push    ebx             ; pEnum
.text:101AD3F8                 push    ebx             ; pBSCb
.text:101AD3F9                 push    ebx             ; dwOptions
.text:101AD3FA                 push    ebx             ; pbc
.text:101AD3FB                 mov     [ebp+pUnk], ebx
.text:101AD3FE                 call    CreateAsyncBindCtxEx
.text:101AD404                 mov     esi, [edi]
.text:101AD406                 mov     [ebp+var_4], eax
.text:101AD409                 cmp     esi, ebx
.text:101AD40B                 jz      short loc_101AD41B
.text:101AD40D                 call    sub_10347BB6
.text:101AD412                 push    esi             ; lpMem
.text:101AD413                 call    sub_100135D9
.text:101AD418                 pop     ecx
.text:101AD419                 mov     [edi], ebx
.text:101AD41B
.text:101AD41B loc_101AD41B:                           ; CODE XREF: sub_101AD3AA+3Dj
.text:101AD41B                                         ; sub_101AD3AA+61j
.text:101AD41B                 cmp     [ebp+var_4], ebx
.text:101AD41E                 jl      short loc_101AD46D
.text:101AD420                 mov     eax, [edi]
.text:101AD422                 cmp     eax, ebx
.text:101AD424                 jz      short loc_101AD430
.text:101AD426                 mov     ecx, [ebp+arg_0]
.text:101AD429                 mov     [ecx+18h], eax
.text:101AD42C                 mov     [edi], ebx
.text:101AD42E                 jmp     short loc_101AD464
.text:101AD430 ; ---------------------------------------------------------------------------
.text:101AD430
.text:101AD430 loc_101AD430:                           ; CODE XREF: sub_101AD3AA+7Aj
.text:101AD430                 push    4               ; dwBytes
.text:101AD432                 call    sub_1000E771
.text:101AD437                 pop     ecx
.text:101AD438                 cmp     eax, ebx
.text:101AD43A                 jz      short loc_101AD440
.text:101AD43C                 mov     [eax], ebx
.text:101AD43E                 jmp     short loc_101AD442
.text:101AD440 ; ---------------------------------------------------------------------------
.text:101AD440
.text:101AD440 loc_101AD440:                           ; CODE XREF: sub_101AD3AA+90j
.text:101AD440                 xor     eax, eax
.text:101AD442
.text:101AD442 loc_101AD442:                           ; CODE XREF: sub_101AD3AA+94j
.text:101AD442                 mov     ecx, [ebp+arg_0]
.text:101AD445                 mov     [ecx+18h], eax
.text:101AD448                 mov     [ebp+var_4], 8007000Eh
.text:101AD44F                 cmp     eax, ebx
.text:101AD451                 jz      short loc_101AD464
.text:101AD453                 push    eax             ; szURL
.text:101AD454                 push    [ebp+pUnk]      ; pUnk
.text:101AD457                 push    offset stru_1009ABFC ; riid
.text:101AD45C                 call    CoMarshalInterThreadInterfaceInStream
.text:101AD461                 mov     [ebp+var_4], eax
.text:101AD464
.text:101AD464 loc_101AD464:                           ; CODE XREF: sub_101AD3AA+84j
.text:101AD464                                         ; sub_101AD3AA+A7j
.text:101AD464                 mov     eax, [ebp+pUnk]
.text:101AD467                 mov     ecx, [eax]
.text:101AD469                 push    eax
.text:101AD46A                 call    dword ptr [ecx+8]
.text:101AD46D
.text:101AD46D loc_101AD46D:                           ; CODE XREF: sub_101AD3AA+22j
.text:101AD46D                                         ; sub_101AD3AA+74j
.text:101AD46D                 call    sub_1010CD9F
.text:101AD472                 test    al, al
.text:101AD474                 jz      short loc_101AD4CF
.text:101AD476                 lea     eax, [ebp+var_C]
.text:101AD479                 push    eax
.text:101AD47A                 call    ds:iertutil_58
.text:101AD480                 test    eax, eax
.text:101AD482                 js      short loc_101AD4CF
.text:101AD484                 lea     eax, [ebp+szURL]
.text:101AD487                 push    eax             ; szURL
.text:101AD488                 push    [ebp+var_C]     ; pUnk
.text:101AD48B                 push    offset stru_100A7FDC ; riid
.text:101AD490                 call    ds:__imp_CoMarshalInterThreadInterfaceInStream
.text:101AD496                 mov     [ebp+var_4], eax
.text:101AD499                 cmp     eax, ebx
.text:101AD49B                 jnz     short loc_101AD4C6
.text:101AD49D                 mov     edi, [ebp+arg_0]
.text:101AD4A0                 mov     eax, [edi+14h]
.text:101AD4A3                 mov     esi, [ebp+szURL]
.text:101AD4A6                 cmp     eax, ebx
.text:101AD4A8                 jz      short loc_101AD4B0
.text:101AD4AA                 mov     ecx, [eax]
.text:101AD4AC                 push    eax
.text:101AD4AD                 call    dword ptr [ecx+8]
.text:101AD4B0
.text:101AD4B0 loc_101AD4B0:                           ; CODE XREF: sub_101AD3AA+FEj
.text:101AD4B0                 mov     [edi+14h], esi
.text:101AD4B3                 cmp     esi, ebx
.text:101AD4B5                 jz      short loc_101AD4BD
.text:101AD4B7                 mov     eax, [esi]
.text:101AD4B9                 push    esi
.text:101AD4BA                 call    dword ptr [eax+4]
.text:101AD4BD
.text:101AD4BD loc_101AD4BD:                           ; CODE XREF: sub_101AD3AA+10Bj
.text:101AD4BD                 mov     eax, [ebp+szURL]
.text:101AD4C0                 mov     ecx, [eax]
.text:101AD4C2                 push    eax
.text:101AD4C3                 call    dword ptr [ecx+8]
.text:101AD4C6
.text:101AD4C6 loc_101AD4C6:                           ; CODE XREF: sub_101AD3AA+F1j
.text:101AD4C6                 mov     eax, [ebp+var_C]
.text:101AD4C9                 mov     ecx, [eax]
.text:101AD4CB                 push    eax
.text:101AD4CC                 call    dword ptr [ecx+8]
.text:101AD4CF
.text:101AD4CF loc_101AD4CF:                           ; CODE XREF: sub_101AD3AA+CAj
.text:101AD4CF                                         ; sub_101AD3AA+D8j
.text:101AD4CF                 mov     eax, [ebp+var_4]
.text:101AD4D2                 pop     edi
.text:101AD4D3                 pop     esi
.text:101AD4D4                 pop     ebx
.text:101AD4D5                 leave
.text:101AD4D6                 retn    8
雪    币: 62
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
凭凡 2011-10-16 00:14
3
0
真及时啊,我一直想不通这个问题!谢谢楼主!
雪    币: 1675
活跃值: (594)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
djxh 2011-10-16 13:07
4
0
支持学习。。。
雪    币: 82
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
哈哈天下 2011-10-17 10:42
5
0
顶啊  强烈支持
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
eyestu 2011-10-18 15:05
6
0
看完一遍还是有点晕晕的
雪    币: 237
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zuoyefeng 2011-10-19 10:35
7
0
markkkkkkkk
游客
登录 | 注册 方可回帖
返回