支持本站 — 捐款将帮助我们持续运营

目标: 1000 元,已筹: 1000

100.0%

POC详情: 56926f84b4ddeee198bef2305dbb7ade04bbfbd1

来源
关联漏洞
标题:Microsoft Office 安全漏洞 (CVE-2017-0261)
Description:Microsoft Office是美国微软(Microsoft)公司开发的一款办公软件套件产品。常用组件有Word、Excel、Access、Powerpoint、FrontPage等。 Microsoft Office中存在远程代码执行漏洞。远程攻击者可通过构建特制的EPS文件利用该漏洞在受影响的应用程序上下文中执行任意代码或造成拒绝服务。以下版本受到影响:Microsoft Office 2010 SP2,Office 2013 SP1,Office 2016。
Description
CVE-2017-8570 Exp及利用样本分析
介绍
# CVE-2017-0261及利用样本分析

## 0x01 漏洞描述

- 成因:打开Office文档时,FLTLDR.EXE将被用于渲染包含该漏洞的嵌入式EPS文件。该文件是由PostScript语言编写而成,可以被攻击者通过"save-restore"操作利用,其本质为一UAF漏洞。 当用户打开包含格式错误的图形图像的文件时,或者当用户将格式错误的图形图像插入到 Office 文件时,该漏洞可能会受到利用。
- 影响版本:Microsoft Office 2010 Service Pack 2、Microsoft Office 2013 Service Pack 1、Microsoft Office 2016

- POC:[kcufId's Github](https://github.com/kcufId/eps-CVE-2017-0261)

## 0x02 POC分析

> 笔者在网上寻找许久,并未找到包含EPSIMP32.FLT的Office安装包。幸而kcufId师傅提供了一LoadEps.exe用以加载EPS文件,感谢kcufId师傅。

`LoadEps.exe`先是加载`EPSIMP32.FLT`:

![图片1 加载EPSIMP32.FLT](https://s1.ax1x.com/2020/08/10/aqSGy8.png)

之后调用`ImportGr`开始加载EPS文件:

![图片2 ImportGr](https://s1.ax1x.com/2020/08/10/aqS8Qf.png)

于此处直接F7跟进,然后就可以成功断在EPSIMP32.FLT内所设断点。

---

在进入正题之前,先来铺陈下Postscript对象结构。

```
// PostScript Object
struct PostScript object
{
    dword    type;
    dword    attr;
    dword    value1;
    dword    value2;    // if array, point to userdict where store the array object
}ps_obj;
```

其中不同`type`对应数值如下:

```
0x0       	nulltype
0x3       	integertype
0x5       	realtype
0x8       	booleantype
0x10      	operatortype
0x20      	marktype
0x40      	savetype
0x300     	nametype
0x500     	stringtype
0x900     	filetype
0x30000   	arraytype          
0x0B0000 	packedarraytype
0x70000 	packedarraytype
0x110000  	dicttype
0x210000  	gstatetype
```

以字符串为例,阐述其存储结构。对`forall`函数设置断点,便可以进一步查看其如何处理字符串(如何定位`forall`函数,可参阅https://paper.seebug.org/368/)。

![图片3 字符串存储结构](https://s1.ax1x.com/2020/08/10/aqScmF.png)

1号图片对应`ps_obj`,其`value2`项指向索引列表中所对应项(2号图片);索引项指向一大小为0x30的结构,该结构0x24位置保存一指向大小为0x28结构(5号图片)的指针的指针,0x2C位置保存字符串大小(3号图片);5号图片中结构0x4位置存储该结构于索引列表中对应项的地址(即4号图片的0x01DB5E94),0x20位置指向字符串最终存储位置(6号图片),0x24位置为实际所占内存大小——字符串大小+1。

大小为0x30结构:

```
+0x0  dword   
+0x4  dword
+0x8  dword
+0xc  dword
+0x10 dword
+0x14 dword
+0x18 dword
+0x1c dword
+0x20 dword
+0x24 dword   pp_struct      //指向大小为0x28结构的指针的指针
+0x28 dword 
+0x2c dword   size           //字符串实际大小
```

大小为0x28结构(换作数组,该结构大小为0x2C,且0x28位置指向数组元素,每一元素都是`ps_obj`):

```
+0x0  dword
+0x4  dword					//存储该结构于索引列表中对应项的地址
+0x8  dword
+0xc  dword
+0x10 dword
+0x14 dword
+0x18 dword
+0x1c dword
+0x20 dword  ptr_object 	//指向字符串最终存储位置
+0x24 dword  size      		//实际所占内存大小,字符串实际大小+1
```

---

漏洞第一次触发:

![图片4 第一次](https://s1.ax1x.com/2020/08/10/aqS3SP.png)

首先是将VM状态保存在`l62`变量内,之后对于`l63`变量内每一字符调用`l61`——>>`l59`——>>`l56`处理过程;`l62 restore`恢复之前的状态,如此一来,`/l62 save def `语句后面`l63`申请的内存空间会被释放,从而成为悬挂指针。

![图片5 l95-l99](https://s1.ax1x.com/2020/08/10/aqSlWt.png)

`l95-l99`变量决定了后续流程,其值均为0(即32位):

![图片6 exch_proc](https://s1.ax1x.com/2020/08/10/aqSJOS.png)

漏洞第二次触发,首先是申请0x27大小(实际会占用0x28)的内存空间存储`l63`:

![图片7 l63](https://s1.ax1x.com/2020/08/10/aqSNwQ.png)

之后`l62 restore`恢复之前的状态,导致`l63`申请的内存空间被释放,从而成为悬挂指针;接下来执行`l100`,之前`l63`所占用内存空间会用来存储`l102`(即`l136`)字符串的0x28结构(这就解释了`l63`为何会申请0x27大小内存空间):

![图片8 l102](https://s1.ax1x.com/2020/08/10/aqSUoj.png)

分别获取该结构0x4、0x20、0x24位置的数值:

![图片9 获取值](https://s1.ax1x.com/2020/08/10/aqSteg.png)

最后修改`l136`字符串内容(图中仅展示了部分修改之处):

![图片10 构造字符串](https://s1.ax1x.com/2020/08/10/aqSwYn.png)

这些修改内容是精心构造的,会于第三次触发漏洞时用到。

漏洞第三次触发,申请包含0x37个元素的数组,之后在循环到第0x34个元素时执行`l62 restore`:

![图片11 第三次触发流程](https://s1.ax1x.com/2020/08/10/aqSdFs.png)

执行完`restore`之后,数组的0x30结构被`l193`字符串内容覆盖:

![图片12 覆盖内容](https://s1.ax1x.com/2020/08/10/aqS0Wq.png)

如此一来,最后一次(0x36)`forall`过程所执行的对象便成为上图中0x30结构,而获取其第0x36个元素便会来到第二次漏洞触发时所精心构造的字符串处:

![图片13 获取数组元素](https://s1.ax1x.com/2020/08/10/aqSrlV.png)

而其获取到的数组元素是一大小为4的数组,该数组首元素是一起始地址为0,大小为0x7FFFFFFF的字符串:

![图片14 数组元素内容](https://s1.ax1x.com/2020/08/10/aqSDS0.png)

该数组会存储在`l159`变量中,其首元素——起始地址为0,大小为0x7FFFFFFF的字符串会存储在`l201`变量中,之后便可通过`l201`变量获取任意地址的值。

获取kernel32.dll基址:

![图片15 获取基址-1](https://s1.ax1x.com/2020/08/11/aON9AK.png)

![图片16 获取基址-2](https://s1.ax1x.com/2020/08/11/aONCtO.png)

如此一来,`l314`变量内存储的便是EPSIMP32.FLT基址。

![图片17 获取基址-3](https://s1.ax1x.com/2020/08/11/aONPhD.png)

注:`search `命令语法如下:

![图片18 search](https://s1.ax1x.com/2020/08/12/aj7kxU.png)

查找指定gadget:

![图片19 gadget-1](https://s1.ax1x.com/2020/08/12/ajgpLV.png)

![图片20 gadget-2](https://s1.ax1x.com/2020/08/12/ajT5bd.png)

构造`file`类型结构:

```
	l199 l201 get_dword                          
    /l487 exch def
    l487 l201 get_dword
    /l488 exch def
    l488 36 my_add l201 get_dword
    /l489 exch def
    l489 l201 get_dword
    /l490 exch def
    l490 32 my_add l201 get_dword
    /l491 exch def
    l199 l491 l201 put_data_to_array
    l199 12 my_sub 2304 l201 put_data_to_array
```

![图片21 构造file type](https://s1.ax1x.com/2020/08/12/ajgPdU.png)

向`l492`地址(`l491`+0x32)处写入构造数据:

```
		l492 0 l201 put_data_to_array                 %% 0x00 0
        l492 4 my_add l375 l201 put_data_to_array     %% 0x04 Address of <5E C3>
        l492 8 my_add l373 l201 put_data_to_array     %% 0x08 Address of <94 00 00 00 00 5E C3> 
        l492 12 my_add l377 l201 put_data_to_array    %% 0x0C Address of <C2 0C 00>
        l492 16 my_add l370 l201 put_data_to_array    %% 0x10 Address of VirtualProtect()
        l492 20 my_add 0 l201 put_data_to_array       %% 0x14 0
        l492 24 my_add 0 l201 put_data_to_array       %% 0x18 0
        l492 28 my_add 0 l201 put_data_to_array       %% 0x1C 0
        l492 32 my_add l368 l201 put_data_to_array    %% 0x20 Address of Shellcode
        l492 36 my_add l368 l201 put_data_to_array    %% 0x24 Address of Shellcode——lpAddress
        l492 40 my_add l349 l201 put_data_to_array    %% 0x28 Size of Shellcode——dwSize
        l492 44 my_add 64 l201 put_data_to_array      %% 0x2C PAGE_EXECUTE_READWRITE——flNewProtect
        l492 48 my_add l493 l201 put_data_to_array    %% 0x30 lpflOldProtect
```

最后,执行`closefile`指令时跳转至Shellcode:

![图片22 closefile](https://s1.ax1x.com/2020/08/12/ajgCZT.png)

## 0x03 样本分析

EPS利用脚本位于`\word\media`目录下,解压之后即可看到。该漏洞利用样本除Shellcode部分,其余基本一致,故以Patchword组织某样本为例进行分析。

> 文件名:Cyber_Secure_Pakistan.docx
>
> MD5:DD89BBB916A2C909630EC78CBB0E13E5

跳转到Shellcode,恢复堆栈:

![图片23 恢复堆栈](https://s1.ax1x.com/2020/08/13/dpkuf1.png)

申请内存:

![图片24 VirtualAlloc](https://s1.ax1x.com/2020/08/13/dpkMSx.png)

获取函数调用地址:

![图片25 函数调用地址](https://s1.ax1x.com/2020/08/13/dpk1OO.png)

调试过程中,可能是因为环境问题导致`CreateToolhelp32Snapshot`函数调用地址未成功获取:

![图片26 CreateToolhelp32Snapshot](https://s1.ax1x.com/2020/08/13/dpkl6K.png)

手动填入地址并打开Word以继续分析。枚举进程,查找WINWORD.exe:

![图片27 枚举进程](https://s1.ax1x.com/2020/08/13/dpkQl6.png)

于`C:\ProgramData\Microsoft\DeviceSync`目录下创建一名为MSBuild.exe的程序:

![图片28 创建MSBuild.exe](https://s1.ax1x.com/2020/08/13/dpkG0e.png)

写入文件内容,其内容存储于EPS脚本的`payload_32`变量内:

![图片29 WriteFile](https://s1.ax1x.com/2020/08/13/dpk8mD.png)

![图片30 payload_32](https://s1.ax1x.com/2020/08/13/dpktkd.png)

创建vmtools.dll文件:

![图片31 创建vmtools.dll](https://s1.ax1x.com/2020/08/13/dpkJTH.png)

写入文件内容,其内容存储于EPS脚本的`payload_32_f2`变量内:

![图片32 WriteFile](https://s1.ax1x.com/2020/08/13/dpkNtA.png)

![图片33 payload_32_f2](https://s1.ax1x.com/2020/08/13/dpkUfI.png)

创建VMwareCplLauncher.exe文件:

![图片34 创建VMwareCplLauncher.exe](https://s1.ax1x.com/2020/08/13/dpkw1P.png)

其内容存储于EPS脚本的`payload_32_f1`变量内:

![图片35 payload_32_f1](https://s1.ax1x.com/2020/08/13/dpkdpt.png)

该文件是具有Vmware签名的白文件:

![图片36 Vmware签名](https://s1.ax1x.com/2020/08/13/dpk06f.png)

注入如下内容到explorer.exe中:

![图片37 注入explorer.exe](https://s1.ax1x.com/2020/08/13/dpkrnS.png)

其功能为创建VMwareCplLauncher.exe进程:

![图片38 创建VMwareCplLauncher.exe进程](https://s1.ax1x.com/2020/08/13/dpkBX8.png)

之后流程于360此篇[报告](https://www.freebuf.com/vuls/157694.html)有提及,本文暂不涉及其分析部分:

![图片39 流程](https://s1.ax1x.com/2020/08/13/dpzpaq.png)

有兴趣的读者可以进一步阅读该报告。

注:该漏洞的利用样本基本相似,不同之处在于最后的MSBuild.exe载荷,其存储于EPS脚本的`payload_32`变量内,可直接dump出来,填补完DOS文件头之后便可以拖进IDA分析。

## 0x04 参阅链接

- [EPS Processing Zero-Days Exploited by Multiple Threat Actors](https://www.fireeye.com/blog/threat-research/2017/05/eps-processing-zero-days.html)
- [CVE-2015-2545 Word 利用样本分析](https://paper.seebug.org/368/)
- [PostScript LANGUAGE REFERENCE](https://web.archive.org/web/20170218093716/https://www.adobe.com/products/postscript/pdfs/PLRM.pdf)
- [摩诃草组织最新漏洞攻击样本分析及预警](https://www.freebuf.com/vuls/157694.html)
文件快照

[4.0K] /data/pocs/56926f84b4ddeee198bef2305dbb7ade04bbfbd1 ├── [4.0K] POC │   ├── [4.0K] done │   │   ├── [ 772] eps.conf │   │   ├── [435K] EPSIMP32.FLT │   │   ├── [3.5K] LoadEps.exe │   │   └── [ 55K] poc.eps │   ├── [6.9M] EPSIMP32.idb │   ├── [4.0K] LoadEps │   │   ├── [3.5K] LoadEps.asm │   │   ├── [ 863] Macro.inc │   │   └── [ 211] Makefile │   └── [ 413] README.md └── [ 11K] README.md 3 directories, 10 files
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮件到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对 POC 代码进行快照,为了长期维护,请考虑为本地 POC 付费/捐赠,感谢您的支持。