APT攻击利器-Word漏洞CVE

Stella981
• 阅读 993

一、概述

近期,百度安全实验室反高级威胁团队截获多封利用Microsoft Office Word漏洞进行攻击的恶意邮件。

通过对邮件附件样本进一步分析发现,其利用的漏洞为澳洲国防部计算机应急响应中心提交的CVE-2016-7193。该漏洞为RTF文件解析漏洞,成功利用该漏洞可以远程执行任意代码。我们拦截的样本双击打开后会在本地释放后门程序,从而完全控制目标主机。

微软已经于2016年10月11日发布了该漏洞的相关补丁(参见微软安全公告 MS16-121)。公告显示,该漏洞影响的Office版本非常广泛,几乎全版本Word都会受到该漏洞影响,包括最新的Word 2016。可以预见的将来,本漏洞将和CVE-2012-0158、CVE-2015-1641等经典Word内存破坏型漏洞一起,作为黑客进行APT渗透的标准工具包核心成员。虽然微软已经针对该漏洞发布了补丁,但由于多数用户安全意识薄弱,不倾向于打Office补丁,导致此类漏洞会长期威胁这批用户。通过进一步样本筛选以及情报确认,黑色产业地下市场已经有很成熟的利用该漏洞生成Exploit的工具在售(见附录参考链接)。

从2017年3月份开始,该漏洞利用样本首次在VirusTotal上出现。如下图所示,多家安全厂商虽然可以识别该样本,但命名均不准确,显然并未深入了解该漏洞的本质,可能误导用户对于漏洞针对性地防范。通过百度安全实验室数据监测显示,利用该漏洞进行的远程攻击事件数量正在不断增长,广大网民和安全从业者要提高警惕,做好相应的防范措施。

APT攻击利器-Word漏洞CVE

受影响的Word版本:

Microsoft Word 2007 Service Pack 3

Microsoft Word 2010 Service Pack 2

Microsoft Word 2013 Service Pack 1

Microsoft Word 2013 RT Service Pack 1

Microsoft Word 2016

Microsoft Word for Mac 2011

Microsoft Word 2016 for Mac

Microsoft Office 兼容包 Pack Service Pack 3

Microsoft Word Viewer

Microsoft SharePoint Server 2010 Service  Pack 2 上的 Word Automation Services

Microsoft SharePoint Server 2013 Service  Pack 1 上的 Word Automation Services

Microsoft Office Web Apps 2010 Service  Pack 2

Microsoft Office Web Apps Server 2013  Service Pack 1

二、漏洞成因分析

1. 分析环境

文件信息:wwlibversion:12.0.4518.1014

2. 分析过程

经测试发现,该样本在一些特定的操作步骤下打开会利用失败,我们在这种情形下得到了如下的崩溃现场:

APT攻击利器-Word漏洞CVE

APT攻击利器-Word漏洞CVE

可见崩溃点位于wwlib.dll中,而负责RTF解析的逻辑正是位于该模块。通过进一步回溯,edi的值来源于 [obj_xx+0x761c],相关的调用点如下:

APT攻击利器-Word漏洞CVE

关于这里用到的ROP链及shellcode本文最后将单独说明。这里继续查找地址edi+0x761c中0x09c00c0c的来源。我们定位到了如下关键代码:

APT攻击利器-Word漏洞CVE

很显然,关键代码位于一个大的switch结构中。应该是解析某种“bytecode”对应的handler部分。从这段代码来看,eax+0x75f8开始是一个字节数组(不是数组指针),而位于eax+0x7618处是当前数组元素个数。每解析对应的“bytecode”时,该数组附加一个字节。数组最大长度被限制为0x40字节。按代码逻辑来看,数组起始于eax+0x75f8,终止于eax+0x7638。而表示数组当前元素个数的变量位于该数组范围内,即eax+0x7618。

这似乎很不科学!

在wwlib的反汇编中搜索所有对75f8的引用代码,也就是对该数组的引用。结果有些意外,只有一处有效的。关键代码如图:

APT攻击利器-Word漏洞CVE

可以看出这个代码是复制该数组数据的逻辑,从拷贝大小参数来看该数组实际分配的大小为0x20字节。而在为该数组附加字节的逻辑中限制写成了0x40字节,发生数组越界写入,进而导致数组之后的类成员变量被改写。

重新加载样本,仔细观察该数组的数据赋值过程:

0:000> bp 315EB380 "db @edi+75f8;"

*** ERROR: Symbol  file could not be found.  Defaulted to  export symbols for C:\Program Files\Microsoft Office\Office12\wwlib.dll -

0:000> g

//第1次附加字节

(1e0.610):  Unknown exception - code e0000002 (first chance)

03bb75f8  09 00 00 00  00 00 00 00-00 00 00 00 00 00 00 00   ................

03bb7608  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7618  01 00 00 00 60 59 57 01-00 00 00 00 00 00 00 00   ....`YW.........

03bb7628  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7638  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7648  00 00 00 00 60 59 57 01-00 00 00 00 00 00  00 00  ....`YW.........

03bb7658  01 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7668  ff ff ff ff ff ff ff ff-00 00 00 00 00 00  00 00  ................

eax=03bb0000  ebx=00000009  ecx=00000000  edx=02000000  esi=03bb0948  edi=03bb0000

eip=315eb380   esp=00127b9c  ebp=00128124  iopl=0  nv up ei pl nz na po cy

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000  efl=00000203

wwlib!wdGetApplicationObject+0x2977a:

315eb380  e968c8a500  jmp  wwlib!DllCanUnloadNow+0x5598ab  (32047bed)

0:000> g

//第2次附加字节

03bb75f8  09 c0 00 00  00 00 00 00-00 00 00 00 00 00 00 00   ................

03bb7608  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7618  02 00 00 00 60 59 57 01-00 00 00 00 00 00 00 00   ....`YW.........

03bb7628  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7638  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7648  00 00 00 00 60 59 57 01-00 00 00 00 00 00  00 00  ....`YW.........

03bb7658  01 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7668  ff ff ff ff ff ff ff ff-00 00 00 00 00 00  00 00  ................

eax=03bb0000  ebx=000000c0 ecx=00000001 edx=02000000 esi=03bb0948 edi=03bb0000

eip=315eb380  esp=00127b9c ebp=00128124 iopl=0   nv up ei pl nz na po cy

cs=001b  ss=0023   ds=0023  es=0023  fs=003b   gs=0000    efl=00000203

wwlib!wdGetApplicationObject+0x2977a:

315eb380  e968c8a500  jmp  wwlib!DllCanUnloadNow+0x5598ab  (32047bed)

0:000> g

……略

0:000> g

//第0x20次附加字节

03bb75f8  09 c0 0c 0c 0c c0  09 0c-0c c0 09 0c 0d c0 09 0c   ................

03bb7608  0c 09 c0 0b 18 20  17 15-0c 0c c0 09 c0 09 0c 20   ..... .........

03bb7618  20 00 00 00  60 59 57 01-00 00 00 00 00 00 00 00    ...`YW.........

03bb7628  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7638  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7648  00 00 00 00 60 59 57 01-00 00 00 00 00 00  00 00  ....`YW.........

03bb7658  01 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7668  ff ff ff ff ff ff ff ff-00 00 00 00 00 00  00 00  ................

eax=03bb0000  ebx=00000020 ecx=0000001f  edx=02000000  esi=03bb0948 edi=03bb0000

eip=315eb380  esp=00127b9c  ebp=00128124  iopl=0  nv up ei pl nz ac po cy

cs=001b  ss=0023   ds=0023  es=0023  fs=003b  gs=0000  efl=00000213

wwlib!wdGetApplicationObject+0x2977a:

315eb380  e968c8a500  jmp  wwlib!DllCanUnloadNow+0x5598ab  (32047bed)

0:000> g

//第0x21次附加字节,注意,该次要正确覆盖偏移为7618处的变量(计数器变量,表示当前字节数组的字符个数),不然之后会无法覆盖到目标指针,恶意代码作者提供的数据为0x23,计数器加1后恰好为0x24,这个可以保证后续正确覆盖对象指针!

03bb75f8  09 c0 0c 0c 0c c0  09 0c-0c c0 09 0c 0d c0 09 0c   ................

03bb7608  0c 09 c0 0b 18 20  17 15-0c 0c c0 09 c0 09 0c 20   ..... .........

03bb7618  24 00 00 00 60 59 57 01-00  00 00 00 00 00 00 00  $...`YW.........

03bb7628  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7638  00 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7648  00 00 00 00 60 59 57 01-00 00 00 00 00 00  00 00  ....`YW.........

03bb7658  01 00 00 00 00 00 00 00-00 00 00 00 00 00  00 00  ................

03bb7668  ff ff ff ff ff ff ff ff-00 00 00 00 00 00  00 00  ................

eax=03bb0000  ebx=00000023ecx=00000020 edx=02000000  esi=03bb0948 edi=03bb0000

eip=315eb380  esp=00127b9c ebp=00128124 iopl=0  nv up ei pl nz na pe cy

cs=001b  ss=0023   ds=0023  es=0023  fs=003b   gs=0000   efl=00000207

wwlib!wdGetApplicationObject+0x2977a:

315eb380  e968c8a500  jmp  wwlib!DllCanUnloadNow+0x5598ab  (32047bed)

0:000> dps  1575960

之后将覆盖我们关心的偏移为0x761c处的值0x01575960,而该值为mso模块创建的一个对象指针,覆盖完成后该值被替换成了0x09c00c0c。

最终“0x40”字节的数组内容如下:

APT攻击利器-Word漏洞CVE

这些附加的字节又从哪里来呢?由于有针对RTF格式混淆技术的运用,现有工具无法满足提取ole对象的目的,我们人工仔细分析了该RTF文档发现,该RTF文档包括如下几个部分:

1)文件头(被混淆过,会影响一些工具或者杀毒引擎的解析)

2)一个ocx控件(用于加载OTKLOADR、msvcr71等)

3)一个内嵌的word文档(用于进行堆喷射)。0x09c00c0c就指向堆喷射的数据区域

4)关键控制字区域。(用于数组越界写,劫持控制流)

5)overlay数据。(编码payload和伪word文档)

通过分析第4部分的关键控制字区域,我们看到了如下的敏感数据:

APT攻击利器-Word漏洞CVE

很明显,数据源于控制字\dfrxst。查阅RTF格式文档,相关说明如下:

APT攻击利器-Word漏洞CVE

该控制字用于构造RevsionMark相关的字符串,参数为字节。即构造unicode字符串也是以单字节的形式进行的。然而文档中对控制字 \dfrxst 对应的内部字节数组是多长并未明确指出。详细查看该部分其它的控制字,我们发现了一个类似的控制字有这样的描述:

APT攻击利器-Word漏洞CVE

根据此处的描述我们推断对于\dfrxst,内部分配的字节数组长度为0x20字节。然而在解析该控制字的代码中,控制数组字节数的常量被认为是0x20(32)个Unicode字符,写成了 0x20* sizeof(wchar_t),结果为0x40,大于内存分配的长度0x20,结果导致数组越界写入。

之后进一步的分析我们发现,被0x09c00c0c替换掉的偏移0x761c处的对象与\shp控制字相关。因而该控制字在样本中是必要的。还有两个控制字\shpbxignore和\shpbyignore用于操作\shp对应的对象过程中执行流的调整(位于wwlib.31fd6d99处的函数调用中),以避免相关的逻辑执行导致对象数据构造复杂化。当然,这里样本中这么做取决于作者开发漏洞利用的方法。我们调试发现,控制了\shp对象数据后,还有其它劫持控制流的路径,本文不再详述。

3. 原理及利用流程总结

Word(wwlib.dll)在解析RTF文档的控制字 “\dfrxst”时发生内存越界写,导致紧邻的对象指针被覆盖。通过堆喷射技术,精心构造被覆盖的对象,可以达到劫持控制流,从而执行任意代码的目的。CVE-2016-7193漏洞原理的伪码表示如下:

#define MAX_CHARS  0x20

class CParserObj

{

public:

BYTE m_ByteArray[MAX_CHARS]; //offs 75f8h

DWORD m_NrOfChars;//offs 7618h

CXXObj *m_pShpObj; //offs 761ch

……

RESULT ParseControlWord(BYTE ByteCode,PVOID Params);

}

RESULT  CParserObj:: ParseControlWord(BYTE ByteCode,PVOID Params)

{

……;

switch(ByteCode)

{

case BYTE_CODE_ dfrxst:

if(m_NrOfChars < MAX_CHARS * sizeof(WCHAR) //0x40

{

m_ByteArray[m_NrOfChars++] = (BYTE)Params;

}

break;

case ……:

break;

default:

break;

}

return RESULT_ERROR_CODE;

}

三、ROP链、shellcode和payload简要分析

首先,样本在劫持控制流后,首先运行ROP链(基于msvcr71构造)将shellcode所在内存区修改为可执行属性,对应的代码和ROP链的信息如下:

APT攻击利器-Word漏洞CVE

Memory

Address

rop

09C00C0C

09C00C0C

09C00C10

7C366BD4

add  esp,100/retn

padding

CCCCCCCC

09C00C4C

09C00C0C

09C00C50

CCCCCCCC

09C00C54

09C00C0C

padding

CCCCCCCC

09C00D14

7C3651EB

pop  ebp/retn

09C00D18

7C3651EB

pop  ebp/retn

09C00D1C

7C372B02

pop  ebx/retn

09C00D20

00000201

dwSize

09C00D24

7C344364

pop  edx/retn

09C00D28

00000040

flNewProtect

09C00D2C

7C351A28

pop  edx/retn

09C00D30

7C390FC7

lpflOldProtect

09C00D34

7C342E9E

pop  edi/retn

09C00D38

7C34A40F

retn

09C00D3C

7C3650DC

pop  esi/retn

09C00D40

7C3415A3

jmp  dword ptr  [eax]; kernel32.VirtualProtect

09C00D44

7C347F97

pop  eax/retn

09C00D48

7C37A151

7C37A151+0xEF =>kernel32.VirtualProtect

09C00D4C

7C378C4D

Pushad/add  al,0EF/retn

09C00D50

7C345C30

push  esp/retn  => return to  0x09C00D54

09C00D54

90909090

shellcode

09C00D58

90909090

09C00D5C

90909090

09C00D60

90909090

09C00D64

90909090

09C00D68

90909090

09C00D6C

90909090

09C00D70

00011FE9

09C00D74

CCCCCC00

padding

CCCCCCCC

09C00E70

7C376FC3

pop  esi/pop  ebx/mov  esp,ebp/pop  ebp/mov  esp,ebx/pop  ebx/retn

09C00E74

7C376FC3

09C00E78

7C376FC3

内存属性修改成功后,接着跳入shellcode

APT攻击利器-Word漏洞CVE

然后执行解码器解码shellcode。该解码器很简单仅仅是xor解码。

APT攻击利器-Word漏洞CVE

最后执行解码后的shellcode,其功能包括:

1)暴力遍历句柄,寻找当前进程中对应RTF文档的句柄。

2)创建RTF文档的内存映射。

3)通过 egg hunt 技术定位位于RTF文档Overlay部分的大型shellcode,并跳入执行,加载执行payload。

APT攻击利器-Word漏洞CVE

本文分析的Payload中包含一个正常doc文件用于覆盖当前文档迷惑用户和一个要释放的商业远控木马用于控制目标主机。当然,这里的payload可以很方便地替换成其它的恶意程序,满足黑客个性化的需求。

四、结语

如今越来越多的APT攻击使用Office套件中的Nday甚至0day漏洞进行攻击,虽然微软提供了该漏洞相应的修复补丁,但大部分用户对于此类应用补丁的不重视造成了漏洞威胁依然存在。百度安全实验室建议用户提高安全意识,及时更新如Office、Flash、浏览器等常被漏洞利用的应用程序,对于安全性未知的程序应谨慎执行。

参考链接:

1、微软 MS16-121 安全公告

https://technet.microsoft.com/library/security/ms16-121

2、exploit生成器的相关信息

http://www.tuicool.com/articles/BNnqArU

https://www.youtube.com/watch?v=D3hwTBD0xE4

3、RTF官方文档

https://www.microsoft.com/en-us/download/details.aspx?id=10725

APT攻击利器-Word漏洞CVE

本文分享自微信公众号 - 百度安全实验室(BaiduX_lab)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
警惕!GitLab 严重漏洞在野被广泛利用,企业需立即自查
1.前言近日,微步在线旗下微步情报局利用捕获到GitLab未授权远程命令执行漏洞(CVE202122205)在野利用,攻击成功后攻击者会植入挖矿木马进行挖矿。该漏洞无需进行身份验证即可进利用,危害极大。GitLab是GitLabInc.开发用于代码仓库管理系统的开源项目。GitLab广泛应用于多个企业,该漏洞影响范围较广。2.事件详情在2
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Linux应急响应(三):挖矿病毒
0x00前言随着虚拟货币的疯狂炒作,利用挖矿脚本来实现流量变现,使得挖矿病毒成为不法分子利用最为频繁的攻击方式。新的挖矿攻击展现出了类似蠕虫的行为,并结合了高级攻击技术,以增加对目标服务器感染的成功率,通过利用永恒之蓝(EternalBlue)、web攻击多种漏洞(如Tomcat弱口令攻击、WeblogicWLS组件漏洞、Jboss
Stella981 Stella981
3年前
Linux提权的几种常用方式
在渗透测试过程中,提升权限是非常关键的一步,攻击者往往可以通过利用内核漏洞/权限配置不当/root权限运行的服务等方式寻找突破点,来达到提升权限的目的。1、内核漏洞提权提起内核漏洞提权就不得不提到脏牛漏洞(DirtyCow),是存在时间最长且影响范围最广的漏洞之一。低权限用户可以利用该漏洞实现本地提权,同时可以通过该漏洞实现D
Stella981 Stella981
3年前
Hadoop Yarn REST API未授权漏洞利用挖矿分析
HadoopYarnRESTAPI未授权漏洞利用挖矿分析一、背景情况5月5日腾讯云安全曾针对攻击者利用HadoopYarn资源管理系统RESTAPI未授权漏洞对服务器进行攻击,攻击者可以在未授权的情况下远程执行代码的安全问题进行预警,在预警的前后我们曾多次捕获相关的攻击
Wesley13 Wesley13
3年前
JAVA 反序列化攻击
Java反序列化攻击漏洞由FoxGlove的最近的一篇博文爆出,该漏洞可以被黑客利用向服务器上传恶意脚本,或者远程执行命令。由于目前发现该漏洞存在于Apachecommonscollections,Apachexalan和Groovy包中,也就意味着使用了这些包的服务器(目前发现有WebSphere,WebLogic,
微步在线 微步在线
3年前
GitLab 严重漏洞在野被广泛利用,企业需立即自查
1.前言近日,微步在线旗下微步情报局利用捕获到GitLab未授权远程命令执行漏洞(CVE202122205)在野利用,攻击成功后攻击者会植入挖矿木马进行挖矿。该漏洞无需进行身份验证即可进利用,危害极大。GitLab是GitLabInc.开发用于代码仓库管理系统的开源项目。由于GitLab广泛应用于多个企业,该漏洞影响范围较广。公众号后台回
Stella981 Stella981
3年前
FreeType 2.4.9之前版本多个远程漏洞(CVE
漏洞描述FreeType是一个流行的字体函数库。FreeType2.4.9之前版本在实现上存在多个堆缓冲区溢出漏洞、栈缓冲区溢出漏洞和拒绝服务漏洞,远程攻击者可利用这些漏洞执行任意代码或造成拒绝服务。解决方法以下是各Linux/Unix发行版系统针对此漏洞发布的安全公告,可以参考对应系统的安全公告修复该漏洞:Ubuntu\