* 原创作者:nickchang
最近收到了一个带word附件的垃圾邮件。office附件基本也玩不出什么花来,一般就是带宏吐PE。所以我平时对这种邮件看都不看就直接删掉了,但是这两天正好闲的蛋疼,就检查下看看有没有什么新姿势。
该word附件名为invoice.doc。打开发现只有如下内容,说该文件是被保护的文档,只有点击“Enable Editing” (允许编辑) 和”enable content” (启用内容)后才能显示正真的内容。
当然,如果点了“启用内容”的话,那就启用宏了,运行宏命令从而让用户电脑被感染。
从截屏上看,这个附件和freebuf前不久的另一文,《PowerWare:勒索软件如何温柔地借刀杀人》, ( http://www.freebuf.com/articles/system/101464.html )里介绍的PowerWare是一模一样的。可是,近一步的分析发现他们用的是完全不同的技术。
先用 oledump.py 列出该文档包含的所有数据流。 结果第8和9行显示该行有VBA模块。另外,值得注意的是,12行的数据流虽然没有VBA模块,但是它的内容却长达76.9k。对于就这点内容的文档而言,也太可疑了吧。
remnux@remnux:~/Downloads$ oledump.py -v invoice.doc 1: 114 '/x01CompObj' 2: 284 '/x05DocumentSummaryInformation' 3: 404 '/x05SummaryInformation' 4: 8494 '1Table' 5: 17159 'Data' 6: 483 'Macros/PROJECT' 7: 65 'Macros/PROJECTwm' 8: M 1726 'Macros/VBA/Module1' 9: M 4059 'Macros/VBA/ThisDocument' 10: 2998 'Macros/VBA/_VBA_PROJECT' 11: 563 'Macros/VBA/dir' 12: 76998 'ObjectPool/_1522685681//x01Ole10Native' 13: 6 'ObjectPool/_1522685681//x03ObjInfo' 14: 4142 'WordDocument'
于是导出数据流8,9里的VBA代码开始分析,然而代码中的变量名和函数名都被混淆过了。读起来有点麻烦,好在代码不是太长,从AutoOpen()开始debug两遍,基本就明白了,主要有以下3个步骤。
1.用ActiveDocument.SaveAs将当前打开的word文档另存为两个RTF文件,名为“fhew.rtf” and “hrbs.rtf”。文件保存路径是在%TEMP%路径。
2.用CreateObject(“Word.Application”) and Document.Open打开 “fhew.rtf”。
3.在%TEMP%路径下运行一个名为“t2.tmp” 的程序 (Shell(“t2.tmp”,0))
如此看来,“t2.tmp”是个恶意PE文件,该word文档的目的就是将其释放并执行。然而宏代码有执行“t2.tmp” 的部分,却没有释放“t2.tmp” 的部分。那么它是怎么被释放的呢?
考虑到前面的那个奇怪的12号数据流,很可能是一个内嵌的PE文件。试着在里面找找PE签名
(“MZ.”) 果然。。。
remnux@remnux:~/Downloads$ oledump.py -v -s 12 -x invoice.doc | grep "4D 5A 90" 5C 74 32 2E 74 6D 70 00 00 2C 01 00 4D 5A 90 00
把12号数据流dump出来用HexViewer看看,发现该PE以OLE对象的形式嵌在该数据流里。 “0200” 是 OLE 数据头签名,而“00000300” 表示的是该对象是个嵌入式对象。从截图里,你还能看到原始路径,文件名信息等等。
这下就清楚了,攻击者利用RTF会释放临时文件的特性来释放“t2.tmp”。因为一个RTF文件被打开时,该RTF文件所包含的OLE对象将会被自动释放至用户的%TEMP%文件夹下,并保留其原始的文件名。这么做原本的目的是优化性能,比如OLE对象重用,可是也可以被攻击者所利用。攻击者可以通过ActiveX控件包含很容易的把自己的恶意PE嵌入到Doc文件中,并且加上一段宏代码。
当用户打开该恶意Doc文件时, 有5个步骤。
1.宏代码启动
2.宏代码把该Doc文档另存为RTF文档
3.宏代码打开RTF文档
4.作为一个OLE对象,RTF内嵌的恶意PE被自动释放到%TEMP%文件夹下
5.宏代码执行刚释放的恶意PE
下面就该来分析这个恶意PE文件了,PEiD没有检测出任何已知壳。然而 .rdata 段的熵值高达 7.7,说明了 .rdata 里有大量的随机数据。这些随机数据很可能是加密过的指令,在运行时才会被解开。导入表里面也没有看到什么特别可疑的API , 除了调用一些反调试函数,比如 SetUnhandledExcetionFiler, IsDebugPresent, 等。
果然,反调试完以后,该程序马上开了一片有 RWE 权限的内存区 (从 009F0000开始). 然后载入crypt32.dll解密,并且将解密的代码写入这片内存,接着让EIP跳入执行。
.text段里面的一部分旧代码也会被替换掉。 新代码里面插入了大量的垃圾数据用来阻止分析人员分析。当然,EIP不会真的跳到垃圾数据里面,但是作者用了大量的”CALL EAX”之类的指令。由于反编译器无法在运行前预知这一刻EAX的值,也就无法知道EIP会跳到哪里去,下一段指令究竟会从哪里开始。导致反编译试图把垃圾数据和正常指令混在一起一并翻译,结果往往产生了一段完全诡异的指令。这给我们的debug,特别是单步运行带来麻烦。
以下是一个例子
CALL EAX 此时 EAX 为 4045E7, 所以EIP会跳转到4045E7
原本4045E7的内容(该PE刚刚被调入内存的时候)
4045E7 的新内容 (EIP 从 A08903跳转过来的时候)
注意新内容里,有些指令前有问号,说明ollyDBG无法理解这些指令,其实它们是垃圾数据。有时单步运行会出错,这时必须修改debugging选项,允许”单步运行未知指令”。
在新指令和垃圾数据的空间里跳转,穿越n次以后, 它终于来到主题: 创建一个explorer.exe 进程。注意创建的时候,该explorer.exe进程被设为挂起状态。
然后它使用进程挖空技术,把该进程里的数据释放掉然后替换恶意代码。进程挖空的主要目的是伪装。比如当用户用进程管理器查看进程的时候,有多少非专业用户会怀疑那些常见的系统进程呢?比如explore.exe和svchost.exe。尤其是这些进程都运行在正确的目录下,windows 或者system32。殊不知我们看到的只是一个进程的”壳子”而已,里面的”心”早就被换掉了。
我们可以看见它先用ZwQueryInformationProcess()查询了explore.exe进程的信息,特别是explore.exe进程PEB的基地址。
接下来,它依次调用 ZwCreateSection(), ZwMapViewOfSection() 和 ZwUnmapViewOfSection()在 explore.exe进程中创建新段,把恶意代码映射到新创建的段中。
最后用ResumeThread让挂起的进程继续执行。
比较一下真假explore.exe。 注意,左边是假的,右边是真的。
接下来的任务就是继续debug这个假的explore.exe进程了。可是问题来了,单步执行resumeThead()以后,explore.exe进程如同流星一样在眼前一闪而过,根本没有时间把进程加到ollydbg里。而explore.exe里的恶意代码是动态生成,映射的,没有本地文件,所以也不能以打开PE文件的形式debug。有两种方法可以解决这个问题。
1.把进程代码dump到本地,然后重建IAT。再用OllyDbg调入。
2.直接修改进程的入口点,改成”CC” (也就是INT3)。然后把OllyDbg设置成即时(just-in-time)调试器,(它会挂接出错程序,并停在程序产生异常的地方)。接下来可以单步resumeThead()。这时explore.exe进程会在入口点执行INT3指令,导致一个异常,系统就会捕捉这个异常从而停在断点处,并弹出一个错误窗口,这时只要我们选择debug,Ollybug便会启动并将其载入。当然我们还需要将断点处的CC指令恢复成原来的指令。然后就可以调试了。
如上图所式,我使用了第二种方法,INT3中断。
explorer.exe进程的第一步是毁尸灭迹,删除其父进程的文件以起到隐藏的目的。
它还会创建一个随机名的事件(event),用来和它的子进程通信。
最后它用类似的的进程挖空技术又创建一个假的 “svchost.exe”进程。
svchost.exe进程会用事件和其父进程,exeplore.exe,通信。
它会准备以下域名,发出DNS请求,并且测试连接。
查询注册表和硬盘目录收集系统信息
然后把搜集的信息放在一个字符串里,比如UUID, 操作系统编号,等等。这个字符串被加密了以后,以POST方法发到 C&C 服务器。这些数据每5秒钟发一次,有点像心跳包。
目前 C&C 服务器还可以连接, 但是请求 /h/gate.php 的时候总是返回 404。此次debug就到此为止了。 值得一提的是在debug过程中,该恶意软件没有修改注册表,也没有在系统关键位置比如windows 和system32目录下留下任何文件。只要我们把那个假冒的svchost.exe 结束掉,系统基本就安全了。
总的来说,这个恶意软件还是用了不少已知技术,比如利用打开嵌入OLE对象的RTF文件吐出PE文件,进程自己加载新代码运行,把代码和垃圾数据混在一起,以及进程挖空技术。虽然都不是新技术,但是还是蛮有效的。
【1】Debugging Hollow Processes, http://hooked-on-mnemonics.blogspot.se/2013/01/debugging-hollow-processes.html
【2】PowerWare:勒索软件如何温柔地借刀杀人 http://www.freebuf.com/articles/system/101464.html
【3】Using RTF Files as a Delivery Vector for Malware, http://phishme.com/rtf-malware-delivery/
* 作者:nickchang,本文属FreeBuf原创奖励计划文章,未经许可禁止转载