进击的恶意文档之 VBA 进阶之旅

2019-07-27 18:03:17 浏览数 (1)

Office 版本历经十几年的变迁,现已趋于成熟,但仍存在着新老版本交替使用的问题。Office 97-2003 Word 的文件后缀为 doc,新版本的 Office 文件后缀为 docx,包含宏的文档后缀为 docm。微软是不会允许将包含宏的文档命名为 docx,但是可以被命名为老版的 doc。例如一个 docm 文件,文件头的魔数是 504b0304(ZIP 文件的魔数),修改其后缀为 doc 后,文件头的魔数不变,且能够正常执行。而老版的 doc 文件头的魔数是d0cf11e(docfile 的十六进制表示 ^_^),所以我们可以通过文件后缀和魔数是否匹配来判断一个文档是不是恶意的。

随着这几年 APT 攻击的兴起,诱饵文档越来越多,对 MACRO 的研究自然也达到了新的高度,很多未公开的特性可以用来规避和绕过杀软,对威胁分析员造成了巨大的挑战。下面我就以威胁分析员的角度来介绍几种技术

VBA stomping

VBA 在 Office 文档中可以以下面三种形式存在

1、源代码: 宏模块的原始源代码被压缩,并存储在模块流的末尾。可以删除源代码,并不影响宏的执行

2、P-Code: 与 VB 语言相同,VBA 同样有 P-Code,通过内置的 VB 虚拟机来解释 P-Code 并执行,平常我们 Alt F11 打开所看到的正是反编译的 P-Code。

3、ExeCodes: 当 P-Code 执行一次之后,其会被一种标记化的形式存储在 __SRP__ 流中,之后再次运行时会提高 VBA 的执行速度,可以将其删除,并不影响宏的执行。

每一个流模块中都会存在一个未被文档化的 PerformanceCache,其中包含了被编译后的 P-Code 代码,如果 _VBA_PROJECT 流中指定的 Office 版本与打开的 Office 版本相同,则会忽略流模块中的源代码,去执行 P-Code 代码

官方文档解释 _VBA_PROJECT 流

一定为(Must be)0xFFFF,而在实际文件中,以 Office 2010(32 位)为例

emmm,微软还是秀啊……

这种特性很适合用于定向攻击,且不容易被发现。通过信息收集得知目标的 Office 版本,利用 VBA stomping 使宏被特定版本的 Office 打开时才会执行恶意行为宏代码,除此之外的 Office 版本打开时执行正常宏代码

目前 VBA stomping 已有利用工具 EvilClippy

https://github.com/outflanknl/EvilClippy

通过目前主流的宏分析工具(oletools,oledump,Pcodedmp)来探究分析此类样本的方法:

首先创建一个带宏的文档

准备一个伪造的 VBA 文件 fakecode_word_vba.txt

执行命令, -t 参数指定 Office 版本

EvilClippy.exe -s fakecode_word_vba.txt -t 2010x64 x-encounter.doc

使用 Office2010(64 位)打开生成后的文档

VBA 编辑器

与原来的文档没有任何区别,接下来使用 Office2013(64 位)打开

VBA 编辑器

可以看到流模块中反编译的源代码被替换成了伪造的 VBA 代码,下面使用工具进行分析

OleTools

Olevba 识别出来了所有的宏并给出 VBA stomping 警告

Oledump

Oledump 并没有识别出含有宏的流模块

Pcodedmp

Pcodedmp 精准的识别了真正的宏代码,忽略了伪造的 VBA

通过 VBA stomping 原理可知,真正的代码存为了 P-Code,所以 olevba 输出的结果中反编译形式的 VBA 即为真正的代码。可以通过 Olevba 判断是否使用了 VBA stomping,如果是则直接使用 Pcodedmp 获取 P-Code 代码。静态看即可

如果想要调试,那么需要使用对应版本的 Office,我这里通过 _VBA_PROJECT 中 Version 结构总结了一下 32 位下的版本号,64 位研究方法一样。

2007(x86) 8800

2010(x86) 9700

2013(x86) A300

2016(x86) AF00

在 VBA 编辑器中隐藏宏

可以在 VBA 编辑器中隐藏真正的宏,只需要修改 PROJECT 流(可以将 PROJECT 流理解为 VBA 编辑器的配置文件)中的 Module=NewMacros,将其抹零即可

在 VBA 编辑器中,NewMacros 已经消失了,宏正常执行

还可以使项目锁定且不可看,需要修改 PROJECT 流 ProjectProtectionState 和 ProjectVisibilityState 这两个属性

虽然这两个属性的内容都是被加密的内容,但是经过实验,将其内容改为任意值(更改时注意长度)

会使得 VBA 工程被锁定且不可看,如果只修改 ProjectVisibilityState,VBA 工程目录可看,但单个代码模块不可看

理论上该过程是不可逆的,但通过实验发现将相关属性改为有效值并模拟密码保护即可解除锁定

代码语言:javascript复制
ID = {00000000-0000-0000-0000-000000000000}CMG = CAC866BE34C234C230C630C6 DPB = 94963888C84FE54FE5B01B50E59251526FE67A1CC76C84ED0DAD653FD058F324BFD9D38DED37 GC = 5E5CF2C27646414741474

可以使用 EvilClippy 解除锁定

EvilClippy -uu 目标文件

上述两种方法所隐藏的宏都可以通过工具检测出来。

使用旧版宏警告

新版本的宏警告

而旧版的宏警告提示更加的显眼

启动旧版宏警告步骤很简单

1、将 .xlsm 重命名为 .zip 并解压缩

2、将 visibility =“hidden”属性添加到 xl / workbook.xml 文件中的 workbookView 元素。

3、将所有文件再次压缩回一个 xlsm 文件

问题在于只有 excel 能弹出这种宏警告框,如何让 Word 也弹出类似的警告框呢?

研究一个样本:ffaa6e86c13b9bb1952b42d07d9c94882e27bc3b0cfe51e81b310a7fd0a5b29b

该 word(RTF)文档内嵌了五个带有旧版宏警告的 Excel 表格

当启动 word 时,会启动 excel 并弹出 excel 旧版宏警告,点击禁用宏后还会启动第二个 excel,一共启动五次,用户体验极差,当 excel 处理完成之后才会弹出 Word 文档

分析此类样本时可以使用 rtfobj 来查看 Ole 对象

-s 和 -d 参数 dump 出指定的嵌入对象,接着使用 Olevba 快速分析

内嵌的宏使用了 VBA Stomping,接着使用 Pcodedmp 将 P-Code 反编译出来,解混淆找到 URL 即可

常用的规避杀软的手法

一、目前杀软查杀 VBA 基本上都是静态查杀,所以静态免杀至关重要,从源头上讲 Word 是一个 zip 文件,解压之后的 vbaProject.bin 包含着要执行的宏信息,也是杀软的重点关注对象,可以修改该文件名用于规避检测,步骤分以下三步

1、将“vbaProject.bin”重命名为“no_macros_here.txt”

2、更新“word / _rels / document.xml.rels”中的关系

3、在“[Content_Types] .xml”中,将“bin”替换为“txt”

二、很多诱饵文档喜欢在 VBA 中启动脚本程序执行 ps 或者从网络上下载一段 shellcode 或恶意程序等等,这样非常容易被杀软的行为拦截拦住,同时沙箱可以根据进程链和流量判定该 word 文档是恶意的,安全分析人员可以轻易的通过监控进程树的方式观察恶意行为。

推荐使用 WMI 来执行后续攻击链,由 WMI 启动的进程的父进程为 wmiprvse.exe 而不是 word.exe 这样就可以与恶意 word 文档取消关联,规避检测

三、动态检测沙箱可以利用 dotnet 属性以及 WMI 来检测 Office:是否含有最近的文档,正在运行的任务数,特定进程检查(vbox,vmware 等等),检测备用数据流(ADS),判断计算机是否是域的一部分(Win32_ComputerSystem 类中 PartOfDomain 对象),检测 Bios 信息,检测即插即用信息(Win32_PnPEntity),检查用户名,检测文件名 hash,检测文件名是否被易名,检测 CPU 核心(Win32_Processor),检测应用及个数。

在 vmware 虚拟机中运行结果

0 人点赞