天天看点

CVE-2017-11882 Office漏洞

简介

CVE-2017-11882属于缓冲区溢出类型漏洞,造成漏洞的原因是,EQNEDT32.EXE(微软office自带公式编辑器)进程在读入包含MathType的ole数据时,在拷贝公式字体名称(Font Name数据)时没有对名称长度进行校验,导致缓冲区溢出。通过覆盖函数的返回地址,可执行任意代码。

深究其中的具体原因还要对ole文件的数据格式以及EQNEDT32.EXE的文件格式进行了解:

ole文件

首先我们需要了解的是什么是OLE,OLE代表的是链接与嵌入(Object Linking and Embedding),用我们日常得话来讲,就是用户在使用Office文档的过程中的一些数据的插入,可以是图片音乐之类的。而且需要注意的是OLE对象是基于COM组件的,也就是说OLE是一个COM组件的子集。这也就导致了在带来极大便利的同时,也给黑客带来了可乘之机,事实上Office的很多0day漏洞也都是由于OLE对象引起或者是基于对OLE对象的利用导致的。抛开题外话不谈,我们专注于这个漏洞。

事实上,不同的文件格式会使用不同版本的OLE文件格式:

OLE格式的结构一共有两种:OLE1.0和OLE2.0 详细情况可以参考微软的官方文档:

OLE文件格式1.0

同时我们需要知道,当用户在office文档中插入公式编辑器的时候,在用户打开文件的时候,会调用EQNEDT32.EXE来执行这个功能,这个功能是微软自带的,在用户插入公式编辑器数据之后会在OLE文件中新增一个Equation Native流数据,因此,下一步我们的工作就是对Equation Native流的数据格式进行解析

Equation Native流的数据格式

Equation Native Stream Data 的结构为

Equation Native Stream Data= EQNOLEFILEHDR+ MTEF Data
           

其中

MTEF Data=MTEF header + MTEF Byte Stream
           

EQNOLEFILEHDR的结构如下:

struct EQNOLEFILEHDR
{
	WORD cbhdr;    //EQNOLEFILEHDR的长度,恒为0x1C
	DORD version;  //恒为0x00020000
	WORD cf;      //剪切板格式
	DWORD cbobject;//MTEF数据长度,不包括EQNOLEFILEHDR
	DWORD reserved1;//未公开
	DWORD reserved2;//未公开
	DWORD reserved3;//未公开
	DWORD reserved4;//未公开
};
           

MTEF Byte Stream如下:

struct MTEF header
{
	BYTE MTEF version;        //MTEF的主版本号
	BYTE generating plntform;  //该数据生成的平台
	BYTE generating product;   //该数据生成的产品 0x00表示由MathType生成,0x01表示由公式编辑器生成
	BYTE product version;      //生成产品的版本号
	BYTE product subversion;    //产品的子版本号
}
           

MTEF Byte Stream的结构由SizeRecord和FontRecord两个结构构成,具体的结构如下

Struct SizeRecord
{
	BYTE lsize;
	BYTE dsize;
}
struct FontRecord
{
	BYTE bTag;
	BYTE bTypeFace;
	BYTE bStyle;
	BYTE bFontName;
}
           

FontRecord的主要成员及其意义:

CVE-2017-11882 Office漏洞

接下来对漏洞样本进行分析:

样本分析

首先是简单的动态分析,开启日志监控软件和进程监控软件,查看进程运行过程中的异常进程情况以及异常的文件操作:

该样本在运行之后弹出计算机的界面,因此将注意力主要集中放在新进程的开启以及进程树的观察:

CVE-2017-11882 Office漏洞

根据上图可以知道,新的计算机进程是由EQNEDT32.EXE通过CMD命令启动的,具体的命令行如下:

CVE-2017-11882 Office漏洞

通过查看命令行,再结合该漏洞的原理可以大概知道,产生栈溢出之后,程序所执行的ShellCode可能就是这行命令,这个还要后边去看。

通过上边的基本观察,可以知道,新进程的开启是通过EQNEDT32.EXE来进行的,因此栈溢出漏洞的产生应该也是在EQNEDT32.EXE进程中产生的,所以我们的下一步的任务就是去调试EQNEDT32.EXE

通过查看进程启动的日志信息,可以发现EQNEDT32.EXE启动CMD调用的API是Winexec

CVE-2017-11882 Office漏洞

接下来目标就很明确了,我们直接用OD附加EQNEDT32.EXE,然后到WinExec去下断点(在当前系统已经存在EQNEDT32.EXE进程的时候,系统不会再创建新的EQNEDT32.EXE进程,所以可以通过OD直接附加,之后下断点再运行一次,可以直接断下来)

但是这块有一个问题,通过 bp WinExec或者设置条件断点断下来之后,通过栈回溯查看最近的返回地址:

CVE-2017-11882 Office漏洞

同时通过栈回溯,也可以发现这个CALL的过程来自0x004115A7,这样的话通过IDA直接可以过去进行反编译分析:

函数0x004115A7的函数内容如下:

CVE-2017-11882 Office漏洞

根据栈溢出的原理,我们可以直接将造成漏洞的点定位到函数41160F上边(因为字符串比较函数和计算字符串长度的函数不可能造成栈溢出),查看sub_41160F:

CVE-2017-11882 Office漏洞

那么造成漏洞的点大概已经定位好了,接下来我们的目标就很明确了,通过动态调试来捕捉这个点:

在OD中对函数sub_41160F下断点:

CVE-2017-11882 Office漏洞

执行到字符串复制操作的语句:(这里需要注意,在调试的过程中,比较容易将原来的EQNEDT32.EXE和呗漏洞修改过的EQNEDT32.EXE混淆,事实上我自己在调试的过程中也发生了这种情况,建议在进行动态调试的时候,先将环境恢复一下,然后直接用OD附加EQNEDT32.EXE,按F9先让程序跑起来,然后再到目标函数的位置下断点,之后再运行样本文件,这个时候就会在目标函数的位置断下来)如下图所示:

CVE-2017-11882 Office漏洞

现在的目的就是分析它实现栈溢出的过程:

可以看到字符串的复制过程,复制勒0x30大小的数据:

CVE-2017-11882 Office漏洞
CVE-2017-11882 Office漏洞

对返回地址进行覆盖:

CVE-2017-11882 Office漏洞

可以看到,修改之后的返回地址被覆盖成为0x00430C12,尝试跳过去分析:

CVE-2017-11882 Office漏洞

跳过去之后不难看到,这个地址的指令就是WinExec,也就是说接下来当程序执行return指令的时候,程序就会跳转到Winexec指令的地方继续执行,接下来,我们直接让程序执行到这个函数retn的地方,查看一下栈空间的返回地址,以及WinExec的参数:

CVE-2017-11882 Office漏洞
CVE-2017-11882 Office漏洞

以上其实就是整个漏洞中最重要的过程的分析,其实整个过程很简单,就是制造exploit,接下来写入恶意代码,执行恶意代码,上边是写入和执行过程的分析,接下来简要的介绍一下,Exploit的分析。

Exploit的分析

1:首先就是溢出点的选择,这个也就是这个漏洞的基本,没有这个点这个漏洞也就不会产生,所以这个点已经找到了,就是在拷贝公式字体名称(Font Name数据)时没有对名称长度进行校验,导致缓冲区溢出。

2:填入数据,在确定了“爆破点”之后,要往该“爆破点”填入数据进行“爆破”,填入数据的时候需要注意,要覆盖的返回地址要填充的数据是什么,其他地方的数据可以任意填写。这里我们的返回地址是WinExec指令的地址,是固定的,这个还要取决于该程序是否开启了ASLR等安全机制,当然这个程序显然是没有开启:

CVE-2017-11882 Office漏洞

3:相对来说这一步应该是一个精细活儿,我们需要计算要填入的数据的长度和Buffer的大小,保证能正常的执行我们的命令,而且还不会将我们的返回地址覆盖掉。

CVE-2017-11882 Office漏洞

通过前边的分析,我们知道在进行覆盖的时候,一共覆盖了0x30个大小的数据,除了4字节的WinExec的地址,还剩0x2C的大小,也就是说构造的命令的长度不能超过0x2C个字节,

接下来的工作就是:

手动构造POC

手动构造POC的思路很简单,新建一个Word文档,在文档中插入公式编辑器,然后输入相应的数据,通过OLE流数据查看工具,查找对应的Equation Native Stream Data,之后将我们都遭好的ShellCode替换进去,保存就好.

1:新建一个.docx的文档,之后打开,插入一个公式编辑器的对象,在其中插入一些数据,保存关闭文档

CVE-2017-11882 Office漏洞

2:用7z以压缩包的方式(因为.docx文件本身就是一个压缩包文件)打开这个文档,把压缩包中的.bin文件复制出来,准备修改:

CVE-2017-11882 Office漏洞

3:修改之前可以使用微软的官方软件offvis.exe来定位一下我们要修改的数据的位置(Equation Native Stream Data):

CVE-2017-11882 Office漏洞

4:接下来,用010打开.bin文件,开始替换数据(这里还采用原样本的实现方式,即运行计算器程序,当然也可以构造其他命令,可以访问链接或者可以通过释放PE文件的方式来执行而已命令)

CVE-2017-11882 Office漏洞
CVE-2017-11882 Office漏洞

5:替换之后,将文件保存,再复制回原来的.docx文件中去,之后手动构造POC就结束了,接下来运行一下看一下结果:

CVE-2017-11882 Office漏洞

6:其实这里手动构造的POC还是有点缺陷,因为,不能自动更新,也就是说,再打开文件之后不会自动弹出计算机程序,需要点击一下,这个问题可以通过一下方式来解决:

新建rtf文件之后,将上述POC构造过程重新做一遍之后,将rtf文件的下边的字段增加一个objupdate字段

CVE-2017-11882 Office漏洞

之后保存打开就完成了.

同时采用这种方法做的话还涉及到怎么从rtf文件中将ole对象文件提取出来,可以使用oletools工具将对象文件提取出来.之后就和上边的步骤一样去构造Exploit就好.至于oletools的用法,我的工具使用过程中不太配合(提取了半天不太成功),这里就不介绍了.

最后,其实这个Exploit的利用不仅仅可以使用Winexec来完成恶意指令的执行,还可以使用文章中说过的利用rtf文件的特性(释放文件)来进行恶意文件的执行,或者是访问恶意链接的形式来进行而已活动.

后记:

当我喜欢你的时候

我们直接就产生了阶层,我仰望着你

是我自己给了你俯视我的权利

当这层窗户纸捅破,而答案又是否定的时候

我们就不可能成为朋友了,如果还和你做朋友

就相当于我自己又把刀子递到了你手上,给了你伤害我的权利

我给别人机会,也是给我自己机会

如果我还能喜欢上别人,我才有机会和你再次站在同一个台阶上

那个时候 再做朋友吧

继续阅读