一个利用姿势清奇的11882格式溢出文档的分析

日前无意中得到一个很有意思的rtf文档,沙箱里行为一大堆,文档本身又混淆的很清奇,所以花了一点时间分析了这个样本。大致理清样本的攻击手法和攻击链后,公开部分分析过程,样本和数据,供大家参考。

特别感谢Flygend提供的情报和银雁冰在分析过程中关于shellcode解混淆的支持

0x00 样本基本信息

样本是一个rtf文档,首次上传VT时间是10月24日,由位于中国的用户通过web方式上传。

使用编辑器查看样本可以得知样本嵌入的OLE对象经过混淆。

在无法使用工具提取OLE对象的前提下,采用银雁冰告知的方法,成功获取Equation.3对象,并在stream流中发现部分疑似shellcode的数据。

分析整理样本落地进程链如下:

Winword.exe
    EQNEDT32.EXE
        MSCLTPAA.exe
            DXDriver.dll
                _XDSFA_XVGVGGH.dmp

 

0x01 doc文档分析过程

首先可以看到文档的ole对象是严重混淆的。这时需要让内存加载ole对象,并dump出来,方法见下面的调试内容:

为Eqnedt32.exe注册调试器,运行rtf文档,发现doc文件会触发cve-2017-11882漏洞,具体的复制的内容见下图(红框圈出的部分会触发漏洞):

栈帧结构如下(方框和红圈圈出的部分分别为函数返回地址和压入的第一个参数):

下面的截图可以得知,strlen返回结果为0x30,而要复制到栈中的位置为ebp-0x28,所以会有8个字节的溢出,替换函数返回地址为0x410db7。而0x410db7位置的指令是ret,所以第二次弹栈,EIP被赋值为这个函数的第一个参数,也就是0x18f354.

程序运行至下图时,执行第一段shellcode。这一段的shellcode的行为是:跳转到当前esp+0x2c8(0x18f4a4)指向的内存区域(0x5a88f0)。

解密完毕后跳转到真正的shellcode

通过上图得知,shellcode在堆中,所以只有未开启dep的环境中才能运行第二段shellcode。

第二段shellcode首先进行异或解密,解密完成后,跳转到函数入口。这段shellcode硬编码了很多字符串和API地址,并进行加密。前半段通过大量的字符串拼接和填充方法,生成将要释放的文件目录以及要加载的dll名称。

访问注册表项,设置开机启动:

枚举进程抗调试:

释放文件:

对MSCLTLAA.exe进行string2Byte解密后,得到PE文件。

创建MSCLTPAA.exe然后写入解密的数据。

最后将可执行文件加入开机启动项。

至此shellcode部分分析完毕。(调试过程加过注释的部分IDA数据库可通过结尾链接获取)

 

0x02 MSCLTPAA.exe

文件名称: MSCLTPAA.exe
文件大小: 263 KB (269,824 字节)
文件时间: 2018-10-31 16:45:45
时 间 戳: 5B6DDABC->2018-08-11 02:34:36
文件 MD5: 019A56601EF675D1E8BDF6DB8B3BD195
文件 CRC: E81E80FD
文件SHA1: 38C45F8F4902A9E30F4E7610AD9E8744E3EB53E8

MSCLTPAA.exe是UPX加壳,脱壳后进行分析,主要行为如下:

解密并释放”压缩包文件名+_XDSFA_XVGVGGH.dmp”然后创建Google Service注册表项并写入相应键值。

释放压缩包到临时目录下,命名为DXDriver.dll

带参数加载dll导出函数

部分动态调试细节如下:
释放压缩文件

调用expand.exe 进行压缩包解压

创建Google Service注册表项,用于配置后面的dropper

主机杀软检测:枚举进程,查找是否有avgui.exe,avastSvc.exe,bka.exe和诺顿的杀毒进程 

 移动临时文件中的dll

调用Rundll32执行dll的导出函数。

 

0x03 DXDriver.dll

文件名称: DXDriver.dll
文件大小: 77 KB (78,848 字节)
文件时间: 2018-08-10 11:13:20
时 间 戳: 5B6DD5BE->2018-08-11 02:13:18
文件 MD5: 333CA047BC6738121EB70DACCDB0EF2C
文件 CRC: D832D38
文件SHA1: 8EDC25E62932B726E4E81F80A1681700918E001E

导出函数如下:

根据父进程传进的参数,看一下sub_10002232。这个函数的行为是重新加载自身到10000000虚拟地址,并带参数”{SKALXCDJKWJS-123K-XFKQ-PAOS-DJSKAXSDFSQKWJ}”执行到处函数。如图:

加载自身后带参数重新执行flush导出函数。

参数不同,所以执行另一个分支,创建新线程。

ThreadProc的行为是:

1.    枚举Bka进程(bkav的杀软进程)和系统服务进程
2.    获取系统版本
3.    带参数执行父进程释放的_XDSFA_XVGVGGH.dmp的“BeginApp”导出函数。

静态分析结果如下:

加载dll的代码如下:

 

0x04 _XDSFA_XVGVGGH.dmp

文件名称: ~D76154_tmp_XDSFA_XVGVGGH.dmp
文件大小: 155 KB (158,720 字节)
文件时间: 2018-08-10 11:13:20
时 间 戳: 5B6DD5BF->2018-08-11 02:13:19
文件 MD5: 18BAA05DC4AE90ACA0F30EAEAA6ECB44
文件 CRC: 1CB67B0F
文件SHA1: 4E04C04A690AFA1843B294BD23AB225C6D57A513

Dll被加载时,会复制CWorkerThread类的虚表,并创建名称为NULL的事件,创建Google Download Service互斥量保证系统唯一实例运行。

获取主机信息并进行MD5散列,这个hash会作为上线包的一部分。

Dll同样会加载自身:

这个dll执行过程中基本上都是利用虚表和硬编码API进行跳转的

跳转到kernel32.dll中,生成http头部信息,并调用InternetOpen函数

然后获取http api的地址

发送上线包是虚表跳转的方式,寻址到之前获取的API地址,进行跳转的。比如调用InternetSetOptionW函数。

上线包

url数据如下

发送上线包

根据代码逻辑,如果成功连接服务端,会下载压缩包,命名为”_Google_Cloud.TMP”,判断下载数据为压缩格式后,写入本地文件,并执行expand.exe解压文件。

然后将对应文件路径写入注册表当中,上层函数的参数为“SEC_COMP”

从代码逻辑上来看,payload应该是一个dll,因为成功释放文件后,代码会通过注册表项查找payload路径,并且获取“PythonThreadStart”导出函数的地址,并且运行执行这个函数。

 

0x04 小结

从沙箱跑的结果看,样本好像还嵌入了可以出发CVE-2018-0802漏洞的Equation对象,这部分内容后续确定。

这个样本的漏洞利用方法,存在一定的局限性,在开启了DEP的windows环境中,这个样本就无法顺利执行,但是同以往11882的漏洞利用姿势来看,还是有一些新意的,至少从shellcode的布局来看,作者对公式编辑器解析Equation.3对象的流程十分熟稔。由于C2失活,无法取得更深层次的payload。但是截至到最后的这个dropper部分,这个样本从文档混淆的方法,到对抗杀软和调试的耐心都是可圈可点的。另外,C2的IP地址,根据我所知的情报渠道,并没有查到这个IP有发送垃圾邮件的迹象,而’отлаживать ‘这个俄语单词,好像也能说明一些问题。同时,从样本针对的杀软来看,不像是针对国内普通用户的,更像是针对采购了avast,bkav和诺顿等厂商杀软的用户。至于是不是针对性的攻击,由于暂时不能获取更多信息,就无从得知了。

由于时间有限,并没能够完全理解样本作者设计混淆Equation.3对象的思路,只是把攻击链条做了部分还原,在调试过程中耐着性子找API地址,虽然有些费时,但是也是一件很有意思的事情。因为代码静态分析难度比较大,所以分享了一部分样本的IDA数据库,在结尾的参考链接中。

根据VT情报,该文档首次由中国的用户在10月24日提交,大约记得彼时只有BitDefender,kaspersky和360这三家引擎能够查杀。如果最早获取此样本的人能够看到这篇文章,希望他能够结合自身所处环境,对主机进行深层次的病毒扫描,排除威胁吧。

 

0x05 部分IoC和参考链接

IoC:

180.150.226.18

参考链接:

注释后的IDA数据库:

https://github.com/rofmia/IDB_Share

[翻译]RTF恶意软件如何躲避基于特征的静态检测

https://bbs.pediy.com/thread-224222.htm

(完)