【漏洞分析】CVE–2017–11826 样本分析报告(包含补丁分析)

https://p5.ssl.qhimg.com/t018db5045b0eb2bf42.png

 

0x00 事件描述

 

2017年9月28日,360核心安全事业部高级威胁应对团队捕获了一个利用Office 0day漏洞(CVE-2017-11826)的在野攻击。该漏洞几乎影响微软目前所支持的所有office版本,在野攻击只针对特定的office版本。攻击者以在rtf文档中嵌入了恶意docx内容的形式进行攻击。微软在2017年10月17日发布了针对该漏洞的补丁。

本文我们将对该样本进行漏洞分析,主要是通过调试来探究漏洞形成的原因。

 

0x01 事件影响面

操作系统:Windows 7 sp1 32位

Microsoft Word版本:Word 2010  sp2  32位

wwlib.dll 版本:

http://p3.qhimg.com/t01453231cbb3209af2.png

调试工具:Windbgx86_v6.12.2.633.1395371577、Process Explorer、oletools工具包

 

0x02 样本分析

 

样本文件SHA-256值为:

cb3429e608144909ef25df2605c24ec253b10b6e99cbb6657afa6b92e9f32fb5

下载样本后,用winhex打开可以发现是一个rtf文件,并嵌入了ole对象,我们可以用oletools工具包中的rtfobj.py进行查看:

http://p8.qhimg.com/t0175a719393d5c2394.png

可以看到该RTF样本中包含了3个嵌入对象。

2.1 第一个ole对象

用winhex打开RTF样本并搜索“object”字符串可以找到第一个对象:

http://p1.qhimg.com/t01cee3638232afe34e.png

Oleclsid后面跟的一串字符为该COM对象的CLASSID,在注册表对应的是C:Windowssystem32msvbvm60.dll,通过ProcessExplorer也可以看到word加载了msvbvm60.dll,用于绕过ASLR。

http://p5.qhimg.com/t019db41c2dedc75c1e.png

因为该dll没有随机化,加载后也不会被随机化。从Office 2013起,微软已经强制使用ASLR,即使DLL没有随机化,但是一旦加载,模块地址也会被随机化了,所以这次的野外攻击只对Office 2010和之前的版本起作用。(尽管这次攻击对新版本没有影响,我们还是建议用户尽快安装官方提供的补丁。)

2.2 第二个ole对象

继续将剩下的两个对象提取出来,解压第二个嵌入的ole对象,是一个word对象,通过查看解压目录下的[Content_Types].xml,可以看到该样本插入了40个ActiveX对象:

http://p4.qhimg.com/t01c29706242173055e.png

同时我们也可以在/word/activeX目录里找到40个activeX*.xml文件和一个 activeX1.bin,这些文件是用来堆喷的。其中ActiveX1.bin为堆喷的内容。

http://p2.qhimg.com/t01b9cfb01358dc3cc0.png

通过堆喷来控制内存布局,使[ecx+4]所指的地址上填充上shellcode,最后通过shellcode调用VirtualProtect 函数来改变内存页的属性,使之拥有执行权限以绕过DEP保护。

具体做法:将EIP设置为0x088883EC,最后一个“popeax; retn”将0x729410d0填入eax中,这是VirtualProtect函数的地址,调用 VirtualProtect(0x8888C90,0x201, 0x40, 0x72A4C045)。

我们通过IDA静态反汇编msvbvm60.dll,可以找到导出的VirtualProtect函数:

http://p0.qhimg.com/t016852a5b51ff1d0ce.png

2.3 第三个ole对象

提取第三个ole对象,也是一个word对象,在word目录中的document.xml中可以找到崩溃字符串”LincerCharChar”:

http://p1.qhimg.com/t01fa867b65d9fc14c4.png

用winhex打开该文件,字符串中间乱码的为”E8 A3 AC E0 A2 80”:

http://p6.qhimg.com/t011173fe05cafab476.png

但是我们在dump出来的内存中找到却是“EC 88 88 08”

http://p5.qhimg.com/t01ee8781322f5baaa3.png

这是由于编码转换的问题,“E8 A3 AC E0 A2 88”为ASCII形式,而“EC 88 88 08”是Unicode形式。验证如下:

http://p6.qhimg.com/t01db077398109c3341.png

根据参考文章中的分析,我们可以知道该样本攻击的大体流程:

样本在RTF 中嵌入了 3 个OLE 对象, 第一个用来加载msvbvn60.dll 来绕过系统ASLR,第二个用来堆喷,做内存布局,第三个用来触发漏洞。

 

0x03 漏洞分析

3.1 漏洞文件分析

我们新建一个doc文件,修改后缀名为.zip,用压缩工具打开,修改word目录下的document.xml,修改如下:

http://p0.qhimg.com/t016bb0b630e1fa7899.png

其实就是将样本文件中提取出来覆盖即可。然后重新修改后缀名为.doc。这样我们直接用word打开就可以触发漏洞,方便调试:

http://p4.qhimg.com/t01c940e175160731a2.png

通过栈回溯可以发现漏洞发生在wwlib.dll(文件位置:C:Program FilesMicrosoft OfficeOffice14WWLIB.DLL)中:

http://p1.qhimg.com/t01ccc316131098b20f.png

并且是发生在wwlib!DllGetLCID+0x2cfcdc,所以我们用IDA来分析一下wwlib.dll,并跳转到相对应的位置:(通过实际调试发现,wwlib.dll过一段时间地址是会改变的,所以以下相对偏移地址读者要根据实际的情况调整)

http://p1.qhimg.com/t0180062629a87b680c.png

崩溃点是发生在call dword ptr[ecx+4],如果有之前有堆喷操作进行内存布局,在0x88888ec上放置shellcode,那就可以跳转去执行,进行样本下一步的攻击。

在call    wwlib!DllGetClassObject+0x430c (69469960)(即callsub_316d9960)下的第二个mov中取出的值为0x88888ec,此时查看eax的内存如下:

http://p3.qhimg.com/t01e48433d2ee7f6745.png

说明0x88888ec是样本里写死的。

我们将崩溃点所在的函数重命名为漏洞函数重名为vul_319B0280,其上级函数重命名为upfunc_3170F32A,函数调用关系如下:

http://p2.qhimg.com/t013534478f7fadb82f.png

接下来我们就从漏洞函数开始分析:(两个vul函数地址不同是因为wwlib.dll的地址变了,调的是同一个wwlib.dll)

http://p9.qhimg.com/t01fe924ef222f5a100.png

http://p6.qhimg.com/t01827d22dd8807426c.png

可以看到esi为漏洞函数的第一个参数,eax为漏洞函数的第二个参数。

通过调试跟踪,我们可以看到漏洞函数的第二个参数+18h的位置是一个指向Unicode字符串的指针,[eax+1Ch]的位置是一个指向字符串个数的指针,打印出来如下图:

http://p3.qhimg.com/t01999168b9a37898ec.png

“shapedefaults”即xml中的一个标签名,我们可以使用条件断点将经过漏洞函数处理的标签打印出来,条件断点:bp wwlib+2dc0c0 “dd poi(esp + 4) + 894 L1; du poi(poi(esp + 8)+ 18) Lpoi(poi(esp + 8) + 1c); g;”。打印结果如下:

http://p9.qhimg.com/t01cf3a9d71ea4f0ab7.png

可以看到列出的标签里有OLEObject、idmap但没有font,说明font标签并没有在漏洞函数里处理。所以我们在上级函数下断点,看是否能够断到font标签?

断点:bp wwlib+3f40e “dupoi((edi)+18) lpoi(edi+1c);g;”

发现可以断到:

http://p6.qhimg.com/t01c4735bf5f8161648.png

在崩溃前处理的标签分别是OLEObject、font、idmap,和样本的攻击代码一致。所以我们先在漏洞函数处理idmap时断下,看看处理过程中发生了什么?

触发漏洞时:

http://p7.qhimg.com/t01fba1b9eb87a14173.png

eax 的值为6,edx的值为4,其中ecx保存的是第一个参数+17F0,即esi存储的值。

http://p5.qhimg.com/t01e7d4db13e2715733.png

http://p0.qhimg.com/t0173b395a888233205.png

该值表示当前处理标签的层数,6对应着就是攻击代码中的o:idmap标签。之后对ecx的值进行计算,获取font标签里的地址:

http://p6.qhimg.com/t013f781436bc9668ca.png

接下来我们要看看标签嵌套层数这个值是怎么变化的?

重新启动调试器,我们可以先在漏洞函数开始处下断点:bp wwlib+2E0280,然后在漏洞函数的上级函数开始处下条件断点:bp wwlib+3f32a “dd poi(esp + 4) + 894 L1; du poi(poi(esp + 8) +18) Lpoi(poi(esp + 8) + 1c); g;”。当处理到font标签时,对存储标签嵌套层数的位置继续下访问断点:ba w4 poi(poi(esi+17f0)):

第一次触发访问断点时:

http://p0.qhimg.com/t011542af6e461f69b6.png

此时eax为5,并且上层函数显示正在处理font标签。继续执行,访问断点再次被触发。

第二次触发访问断点时:

http://p5.qhimg.com/t0106b98d4060ae0bfe.png

此时已经显示正在处理idmap标签了,而此时的嵌套层数为6。

3.2 正常文件分析

新建一个正常doc文件,将document.xml中的font标签闭合。像上面那样继续下断点调试。font的嵌套层数变成5后,遇到font闭合标签还会再减去1变成4:

http://p5.qhimg.com/t013a7b054804ce4ca9.png

继续运行,处理下一个标签idmap:

http://p2.qhimg.com/t017e3d39f4c66e9fdc.png

可以看到font标签闭合后,idmap的嵌套层数为5。得到正常的内存布局,漏洞没有被触发:

http://p3.qhimg.com/t018fb7f28b60911199.png

3.3 分析总结

上面得到标签嵌套层数后,接下来就会根据嵌套层数来计算地址:

计算地址函数为:

http://p2.qhimg.com/t01d16d292d4f59cde1.png

这里eax为标签的嵌套层数,edx为eax-2的值,ecx为漏洞函数参数1 +17F0h存储的值。所以地址的计算和参数1以及嵌套层数相关。正常文件处理idmap时,嵌套层数为5,edx为3,处理的是OLEObject标签的内存空间。漏洞文件处理idmap标签时,嵌套层数为5,edx为4,此时处理的是font标签的内存空间。这也可以通过分析补丁得到验证。

总结:通过上面的调试可以发现漏洞原因在于font标签没有闭合,在处理idmap标签时,操作的还是font标签的内存布局。

 

0x04 补丁分析

 

在虚拟机我们首先保存原先版本的快照,方便以后复原,然后提出wwlib.dll。再找到相应的补丁打上,提出wwlib.dll,针对调试环境打的补丁版本为KB3213630。在IDA中搜索关键指令,找到漏洞函数,打过补丁的wwlib.dll如下:

http://p3.qhimg.com/t01072ae922bfc173fd.png

没有打过补丁的wwlib.dll如下:

http://p6.qhimg.com/t01d883df5707a27145.png

打过补丁之后,可以看到多了一个判断分支。调试补丁到这发现:

http://p7.qhimg.com/t01537ffcd7b529006d.png

两个值相等,跳转到右边分支,漏洞就无法被触发了。

根据动态跟踪调试发现[eax+48h]保存着一个地址指针,这里猜测[eax+48h]为当前对象处理函数的指针,调试中发现offsetsub_31e94a4a返回的是一个处理函数地址,而上级函数处理font标签时调用了该处理函数,所以可以猜想此处补丁是将当前对象处理函数的指针和font对象处理函数指针进行比较,相同就表明处理idmap标签时实际上处理的是font标签,跳转到右边分支,就不会执行到漏洞触发点了

 

0x05 处理建议

 

1、建议用户通过以下的补丁地址,尽快更新微软补丁

2、下载360安全卫士,尽快更新针对该漏洞的补丁

补丁下载地址:https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-11826

 

0x06 时间线

 

2017-09-28         360安全团队捕获漏洞的在野攻击

2017-10-10         微软官方公布针对该漏洞的补丁

2017-11-02         360CERT完成了基本分析报告

 

0x07 参考

 

1、https://bbs.pediy.com/thread-221995.htm

2、https://paper.seebug.org/351/

3、https://www.greyhathacker.net/?p=894

(完)