漏洞成因:类型混淆漏洞。Word在处理displacedByCustomXml
属性时未对customXml
标签对象进行有效性验证,可以通过传入其他标签对象,由类型混淆进而达到任意内存写。故可以借由精心构造的标签对象及对应属性值实现RCE。
影响版本:Microsoft Word 2007 SP3, Office 2010 SP2, Word 2010 SP2, Word 2013 SP1, Word 2013 RT SP1, Word for Mac 2011, Office Compatibility Pack SP3, Word Automation Services on SharePoint Server 2010 SP2 & 2013 SP1, Office Web Apps Server 2010 SP2 & 2013 SP1
样本信息及分析环境如下:
MD5:A69F778D1F511268019B1080F5E3B98B
OS版本:Windows 7 SP1(x86)
Word版本:2007
WWLIB.DLL版本:12.0.4518.1014
通过rtfobj查看该文档的OLE对象:
手动提取出来2号对象存为一RTF文档,Windbg附加Word 2007并打开该文档,崩溃点如下:
之后将0号与2号对象提取出来存为一RTF文档:
设断bp wwlib!DllGetClassObject+0x50e6 ".if(ecx=7c38bd50){}.else{gc}"
:
待执行call wwlib!DllGetClassObject+0x50fe
前查看栈中参数如下:
通过rtfobj.py -s 2
将2号对象存为一Word文档,查看其word
目录下document.xml
:
可以看到smartTag标签属性值与栈中参数对应关系。
根据微软文档,displacedByCustomXml
属性指定替换标签应为customXml:
继续跟进分析,计算写入地址:
计算公式为[[Parameter 1]+0x8]*[Parameter 2]+[[Parameter 1]+0xC]+[Parameter 1],具体参数值见图5。直接步过该函数,可以看到其结果与公式结果无异:
跟进,查看其memcpy
传递参数:
向0x7c38bd74地址处写入0xffffe696,该值用于第二次计算Dst Address。
重新设断bp wwlib!DllGetClassObject+0x50e6 ".if(ecx=7c38bd68){}.else{gc}"
,断下之后跟进到其计算Dst Address函数:
可以看到[[Parameter 1]+0xC]为之前写入值。第二次写入覆盖MSVCR71.DLL虚函数表中函数调用地址:
第三次写入:
该值用于第四次计算Dst Address:
第四次写入:
继续向下执行,崩溃点如下:
重新载入RTF文档,于0x7c376fc4处设断:
由上图可知第二次内存写入——覆盖MSVCR71.DLL虚函数表中函数调用地址,第四次内存写入——覆盖传递参数。
将1号对象加入后存为RTF文档,重新载入分析,bp 0x7c376fc8
设断:
可以看到堆喷布局如上,该布局由1号对象\word\activeX
目录中activeX1.bin
完成:
根据其布局,不断执行ret
,到0x7c3651EB
处开始ROP链:
执行VirtualProtect以绕过DEP保护:
然后开始执行activeX1.bin
内Shellcode部分:
遍历当前进程中打开文件句柄,查找其Size符合如下条件的文件:
映射到内存中:
通过文件头与FEFEFEFE FEFEFEFE FFFFFFFF
判断是否为样本文件及Shellcode起始位置:
复制Shellcode到VirtualAlloc开辟空间内,之后跳转到第二部分Shellcode执行。
解密后续Shellcode:
由ANY.RUN可见其后续行为(有兴趣的读者请自行下载样本分析):
正常情况下,Word在解析customXml标签时会开辟一新空间:
而在解析smartTag时:
故借此可以控制目标写入地址。
MD5:2C22EA1CED258346351EAD09B1DC6074
查看OLE对象:
0号对象用以加载OTKLOADR.DLL以引入MSVCR71.DLL绕过ASLR;
1号对象用以完成堆喷及Shellcode布局;
2号对象用以触发CVE-2015-1641漏洞,触发点位于styles.xml
中:
载入RTF文档,bp 0x7c376fc8
设断,执行ROP链后调用VirtualProtect更改内存属性,跳转到Shellcode:
通过jmp
+call
+pop
给传参,解密后续Shellcode:
解密逻辑如下:
开辟内存空间,复制加密Shellcode并解密:
通过call
指令为函数传递参数:
后续仍有数次解密Shellcode过程,不再一 一列出。于C:\Users\xxx\AppData\Roaming\Microsoft\Templates
目录下创建文件:
写入文件内容:
之后于相同目录下创建~$Normal.dat
并写入内容:
该文件具有隐藏属性:
于HKEY_CURRENT_USER
下创建注册表项:
设置注册表键值:
删除注册表禁用项:
后续将由wscript.exe
执行C:\Users\xxx\AppData\Roaming\Microsoft\Templates\Normal.domx
,该文件实际为VBE格式:
可借由scrdec18工具解密:
该文件本质为VBE格式,可由wscript.exe
正常加载。分析时需通过工具解密出VBS脚本。
读取~$Normal.dat
第一部分内容并解密,写入%USERPROFILE%\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.Word\PLAs_NEW_ORBAT.doc
:
该文档用于迷惑受害者:
之后释放三个PE文件并设置隐藏属性:
执行MicroScMgmt.exe
并删除自身以及~$Normal.dat
:
查看导入表:
该文件为带有数字签名的白文件:
其用于加载恶意DLL——jli.dll
。
MD5:051573B9173DE6886E0575F81778EA03
查看其导出函数:
该文件带有无效签名:
其与Patchwork组织之前使用过的BADNEWS木马存在相似性,此处暂不展开分析。完整攻击链如下:
Microsoft Docs——displacedByCustomXml?redirectedfrom=MSDN)