首页
论坛
专栏
课程

[原创]CVE-2012-1856 Office ActiveX控件MSCOMCTL.OCX UAF漏洞分析

2018-1-8 12:49 3030

[原创]CVE-2012-1856 Office ActiveX控件MSCOMCTL.OCX UAF漏洞分析

2018-1-8 12:49
3030

从一篇博客说起

最近我看了cisco talos的一篇博客:http://blog.talosintelligence.com/2017/03/how-malformed-rtf-defeats-security.html
这篇博客有一个很严重的技术问题,写文章的人很显然没有搞清楚自己分析的是哪个漏洞,他的逻辑是因为ActiveX XML文件中的classid 1EFB6596-857C-11D1-B16A-00C0F0283628和MSCOMCTL.OCX对应,所以该样本利用了ActiveX控件MSCOMCTL.OCX中的UAF漏洞CVE-2012-1856。

其实ActiveX喷射是Office漏洞利用中的一种常见heap spray技巧,CVE-2013-3906(TIFF解析中的整数溢出),CVE-2015-1641(RTF解析中的类型混淆),CVE-2016-7193(RTF解析中的数组越界),CVE-2017-11826(OOXML解析中的类型混淆)等等无一不是利用了ActiveX喷射获取程序控制流,它们的ActiveX XML文件差不多都是这样的。大概4年前Mcafee在CVE-2013-3906的野外0day样本中最早发现了这种技巧[6]。我给cisco talos写了邮件不过目前还没有收到回复。
更新:他们终于改过来了。

CVE-2016-7193

那么这个样本到底利用了哪个漏洞呢?我发现样本中的RTF控制字匹配CVE-2016-7193,并且进一步在调试器中验证了这一点。关于CVE-2016-7193,[4][5]已经分析得比较细致了,我就不再画蛇添足了。

CVE-2012-1856

那么CVE-2012-1856到底是一个什么样的漏洞呢?网上几乎到处都是CVE-2012-0158的分析,关于CVE-2012-1856的分析少之又少。不过我还是找到了一个利用该漏洞的样本[2]。这篇文章里面也没有说清楚漏洞成因,只是简单说了下shellcode。而在另一篇看起来像是启明星辰写的关于这个漏洞的分析报告里几乎都是正向分析,没有快速从崩溃现场定位漏洞发生处,显得十分繁琐[1]。

漏洞原理

调试环境:XP/Win7+Office2007
资料下载:https://github.com/houjingyi233/office-exploit-case-study
另外要说一句,[3]中提供了MSCOMCTL.OCX的符号文件。貌似微软多年以前是提供MSCOMCTL.OCX的符号的,现在已经不提供了。虽然版本比较高的MSCOMCTL.OCX在IDA中不能直接加载它,但是可以先用版本比较低的MSCOMCTL.OCX在IDA中加载它,再通过bindiff得到版本比较高的MSCOMCTL.OCX的符号。在接下来的分析中符号起到了非常重要的作用。
Office中的内存破坏型漏洞由于软件版本众多,利用起来大多不太稳定。没有成功利用时出错信息如图所示。

根据所示的偏移在IDA中找到对应的位置。

那么通过符号文件我们可以知道函数名是CObj::Clear。通过调试可以发现在call dword ptr [ecx+8]处调用了CColumnHeader::AddRef。


在调试器中看到的某次崩溃时的现场如下所示。

因此下内存访问断点,果然[esi+24]=18aeff70处的内存被释放了。
在IDA中可以看到是因为调用了CTab::~CTab和CObj::~Cobj两个析构函数,并且因为CTab::~CTab是先被调用的,所以CTab应该是继承CObj对象的一个对象。那么结合CObj::Clear这个函数名和函数逻辑我们也应该知道这个函数的作用大概就是依次释放所有CTab对象,这也是打开文件没有报错,反而是在关闭时出错的原因。


接下来我们还是通过符号找到构造函数和析构函数,在这两个地方下断点,观察对象分配和释放的流程。因为太长了不好截图,所以附上调试记录。
Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is: 
ModLoad: 30000000 31118000   C:\Program Files\Microsoft Office\Office12\EXCEL.EXE
(714.a8): Break instruction exception - code 80000003 (first chance)
eax=7ffde000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=09a7ffcc ebp=09a7fff4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\ntdll.dll - 
ntdll!DbgBreakPoint:
7c92120e cc              int     3
0:006> sxe ld:mscomctl
0:006> g
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\MSCOMCTL.OCX - 
ModLoad: 27580000 27685000   C:\WINDOWS\system32\MSCOMCTL.OCX
eax=c0c0c0c0 ebx=00000000 ecx=00000086 edx=0000021a esi=00000000 edi=00000000
eip=7c92e4f4 esp=0013ad20 ebp=0013ae14 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!KiFastSystemCallRet:
7c92e4f4 c3              ret
0:000> bu MSCOMCTL!DllGetClassObject+0x14ebb ".printf \"Create:0x%08x\\n\",ecx;g;"
breakpoint 0 redefined
0:000> bu MSCOMCTL!DllGetClassObject+0x15197 ".printf \"Delete:0x%08x\\n\",ecx;g;"
breakpoint 1 redefined
0:000> bl
 0 e 2759bbff     0001 (0001)  0:**** MSCOMCTL!DllGetClassObject+0x14ebb ".printf \"Create:0x%08x\\n\",ecx;g;"
 1 e 2759bedb     0001 (0001)  0:**** MSCOMCTL!DllGetClassObject+0x15197 ".printf \"Delete:0x%08x\\n\",ecx;g;"
0:000> g
Create:0x0a852f70
Delete:0x0a852f70
Create:0x0b376f70
Delete:0x0b376f70
Create:0x0b384f70
Create:0x0c21ef70
Create:0x0c20af70
Create:0x0c210f70
Create:0x0c232f70
Create:0x0c1d0f70
Create:0x0c1d6f70
Create:0x0c278f70
Create:0x0c27ef70
Create:0x0c284f70
Create:0x0c28af70
Create:0x0c1e6f70
Create:0x0c1ecf70
Create:0x0c1f2f70
Create:0x0c1f8f70
Create:0x0c1fef70
Create:0x0b2fcf70
Create:0x0b318f70
Create:0x0b340f70
Create:0x0c1b2f70
Create:0x0b388f70
Create:0x0c236f70
Create:0x0c28ef70
Create:0x0c228f70
Create:0x0c240f70
Create:0x0c246f70
Create:0x0c24cf70
Create:0x0c252f70
Create:0x0c258f70
Create:0x0c25ef70
Delete:0x0c25ef70
(714.13c): Break instruction exception - code 80000003 (first chance)
eax=7ffde000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=0cabffcc ebp=0cabfff4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
7c92120e cc              int     3
0:010> bp 2758FCAE
0:010> g
Breakpoint 2 hit
eax=0b368f84 ebx=00000000 ecx=0b368f3c edx=2762d000 esi=0b368f3c edi=0b368f84
eip=2758fcae esp=0013d7d4 ebp=0013d870 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
MSCOMCTL!DllGetClassObject+0x8f6a:
2758fcae 53              push    ebx
0:000> g
Delete:0x*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\PROGRA~1\COMMON~1\MICROS~1\VBA\VBA6\VBE6.DLL - 
0b384f70
Delete:0x0c21ef70
Delete:0x0c20af70
Delete:0x0c210f70
Delete:0x0c232f70
Delete:0x0c1d0f70
Delete:0x0c1d6f70
Delete:0x0c278f70
Delete:0x0c27ef70
Delete:0x0c284f70
Delete:0x0c28af70
Delete:0x0c1e6f70
Delete:0x0c1ecf70
Delete:0x0c1f2f70
Delete:0x0c1f8f70
Delete:0x0c1fef70
Delete:0x0b2fcf70
Delete:0x0b318f70
Delete:0x0b340f70
Delete:0x0c1b2f70
Delete:0x0b388f70
Delete:0x0c236f70
Delete:0x0c28ef70
Delete:0x0c228f70
Delete:0x0c240f70
Delete:0x0c246f70
Delete:0x0c24cf70
Delete:0x0c252f70
Delete:0x0c258f70
(714.570): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0c25ef8c ebx=00000000 ecx=002d0065 edx=01165000 esi=0b368f3c edi=0038002d
eip=2758fce3 esp=0013d7c4 ebp=0013d870 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
MSCOMCTL!DllGetClassObject+0x8f9f:
2758fce3 ff5108          call    dword ptr [ecx+8]    ds:0023:002d006d=????????
有趣的是0x0c25ef70这个对象,明明已经被释放了,而崩溃时eax为0x0c25ef70+0x1c,为什么在CObj::Clear还会尝试去释放它呢?通过回溯可以很快定位0x0c25ef70被delete掉的位置。


该函数是对CTab依次初始化的过程,首先有0x1f个对象(这一点也可以从调试记录中数出来)。

进一步发现CTabs::LoadBinaryStateFromMemory调用了CTab::LoadBinaryStateFromMemory,就在关于0x0c25ef70这个对象调用CTab::LoadBinaryStateFromMemory时返回了和其它情况不一样的值8007000Eh。
 
这里是因为调用SysAllocStringLen时传递的长度esi=80000044太大了导致调用失败,8007000Eh应该是一个错误码。随后就把这个对象释放了。听起来好像一切合理,但是CTabs::LoadBinaryStateFromMemory中还调用了CObjColl::AddItem,应该是把对象加入一个类似链表的结构,但是释放对象之后却并没有把对象从中删除。在函数列表中是可以看到有像CObjColl::RemoveItem这样的函数的。

在样本中也可以找到0x80000044这样构造的恶意数据,可以猜测这些结构应该都是CTab对象,正常的对象长度都是0x44,恶意构造的对象长度是0x80000044。

shellcode

stage1的shellcode首先还是通过egg-hunting技术定位stage2的shellcode。


stage2的shellcode也很简单,简而言之就是获取一系列的API之后下载一个远程文件并执行之。




本人在github上整理的有关于Office漏洞的资料,在那里你可以找到本文用到的所有文件:https://github.com/houjingyi233/office-exploit-case-study,这份资料也会持续更新,欢迎关注。

参考资料



[推荐]看雪企服平台,提供安全分析、定制项目开发、APP等级保护、渗透测试等安全服务!

最后于 2018-6-20 20:51 被houjingyi编辑 ,原因:
上一主题 下一主题
最新回复 (4)
ktkitty 2018-1-25 20:19
2
0
CVE-2012-1856目录下的样本打开不了?环境是win7  +  word2007
ktkitty 2018-1-25 20:22
3
0
CVE-2012-0158的也不行。。。
houjingyi 8 2018-2-11 10:12
4
0
ktkitty CVE-2012-0158的也不行。。。
文件应该都没问题吧,你检查下hash就知道了。是不是没改后缀名?
ktkitty 2018-5-19 13:31
5
0
houjingyi 文件应该都没问题吧,你检查下hash就知道了。是不是没改后缀名?
我知道什么原因了。。。那个是xls文件,我误以为是doc文件,所以改成doc后缀就肯定打开不正常了,尴尬了。。。那个样本应该是hackingteam的demo
游客
登录 | 注册 方可回帖
返回