Purgalicious VBA:使用 VBA 清除的宏混淆
MS-Ovba文件格式
在深入了解VBA清除之前,了解Microsoft有关VBA宏(MS-OVBA)规范的某些组件很重要。我们专注于使用CFBF文件格式的Microsoft Office 97文档中的MS-OVBA,而不是Microsoft Excel“ .xlsx”和Microsoft Word“ .docx”文档使用的现代Open Office XML(OOXML)格式。
MS-OVBA的文件结构将所有VBA数据存储在一个层次结构中,该层次结构由包含不同类型流的结构化存储组成。Office文档中的VBA代码存储在各种模块流中,该模块流由两部分组成:PerformanceCache(也称为P-code)和CompressedSourceCode。所述PerformanceCache部分是包含已编译VBA代码的字节的阵列。该CompressedSourceCode部分包含了与微软的专有算法压缩VBA源代码。这两个部分之间的边界由MODULEOFFSET确定,该模块存储在dir流中。模块流图如图1所示。
将VBA宏添加到文档后,VBA引擎会将编译后的版本保存在相关模块流的PerformanceCache部分中,以提高性能。但是,如果Office应用程序的版本和体系结构与用于编译原始VBA代码的内容相匹配,则Office应用程序将仅访问PerformanceCache。此版本和实现信息存储在_VBA_PROJECT和__SRP_#
流中。如果版本不匹配,则将压缩的源代码解压缩,编译并运行。
VBA Purging 与 VBA Stomping
2018年,沃尔玛安全团队的研究将一种称为“VBA Stomping”的技术引入了更广泛的公众意识。此技术最初由Vesselin Bontchev博士于2016年发现,此技术使攻击者可以从Office文档中删除压缩的VBA代码,并且仍然可以执行恶意宏,而无需使用AV引擎用来检测的许多VBA关键字。
VBA Stomping 利用了模块流的解释方式,并与非恶意的VBA源代码交换了恶意的CompressedSourceCode,从而使PerformanceCache保持不变。但是,此技术的成功取决于Office版本,这意味着攻击者将不得不对目标进行额外的检查,并了解受害者部署的Office版本。
VBA Purging 以相反的方式修改模块流。代替改变的CompressedSourceCode,VBA清除已完全消除PerformanceCache从模块流和数据_VBA_PROJECT流,改变的值MODULEOFFSET为0,并删除所有SRP流(这是必要的,因为_VBA_PROJECT和 SRP 流包含版本相关在模块流中没有PerformanceCache时将导致运行时错误的 PerformanceCache 数据。这将删除通常在PerformanceCache中找到的字符串许多AV引擎和YARA规则都依赖于检测。一旦删除,攻击者便可以使用更多标准方法并执行可疑功能(即 CreateObject)而不会被检测到。
图2显示了使用oledump提取的普通文档和清除文档的OLE流。在原始文档中,Module1 PerformanceCache为1291字节,而在VBA清除的文档中为0字节。清除的文档没有SRP流,并且_VBA_PROJECT流已减少到7个字节。
测试 VBA Purging 的有效性
Mandiant的Red Team创建了一个名为OfficePurge的命令行 C#工具来测试该技术。OfficePurge支持遵循CFBF文件格式的Microsoft Office Word,Excel和Publisher文档。在以下示例中,我们使用了OfficePurge和公共工具包Unicorn中的VBA有效负载来测试VBA清除包含Base64编码的PowerShell有效负载的Microsoft Office Word文档的有效性(图3)。
原始Word文档的字符串输出(图4)显示了Unicorn的Base64编码的PowerShell负载,许多安全产品都检测到了该负载。另一方面,由于删除了PerformanceCache,VBA清除的文档的输出未完全显示Base64编码的有效负载 。该CompressedSourceCode仍包含Base64编码的有效载荷,但微软的自定义压缩算法拆分字符串,使其更难进行静态分析,以检测它。
这两个文档均已提交到在线沙箱,以测试各种产品的检测功能。在清除VBA(12/61)之后,VirusTotal对原始文件的检测率(36/60)下降了67%。VirusTotal还将未清除的文档分类为“ create-ole”,“ doc”和“ macros”,而清除的文档仅分类为“ doc”。
发现和搜寻机会
使用OfficePurge,我们能够快速擦除已编译的VBA代码并减少公共沙箱中的安全产品检测,但是为什么要停在那里?使用此测试数据,我们的下一步就是以YARA规则之类的格式构建条件检测逻辑,该条件可以识别VBA清除的文档并允许我们寻找以前未检测到的恶意文档。在OfficePurge GitHub存储库中的“ sample-data”文件夹下,我们为每种受支持的文件类型添加了原始文档和已清除文档,并带有将生成calc.exe的宏。SHA256哈希值包含在该帖子的末尾。
如前所述,此技术涉及从_VBA_PROJECT流中删除PerformanceCache数据。MSDN文档显示_VBA_PROJECT 流的最小长度为7个字节,以适合流头中的必填字段。以下YARA规则使用7字节_VBA_PROJECT流搜索CFBF文件:
rule FEYE_OLE_VBAPurged_1 {
meta:
author = “Alyssa Rahman (@ramen0x3f)”
description = “This file has a _VBA_PROJECT stream that has been cleared. This is evidence of VBA purging, a technique where the p-code (PerformanceCache data) is removed from Office files that have an embedded macro.”
strings:
$vba_proj = { 5F 00 56 00 42 00 41 00 5F 00 50 00 52 00 4F 00 4A 00 45 00 43 00 54 00 00 00 00 00 00 00 00 00 }
condition:
uint32(0) == 0xe011cfd0 and ( uint32(@vba_proj[1] + 0x78) == 0x07 )
在VirusTotal上使用此逻辑进行搜索,会发现大量恶意文档,这意味着这种情况非常普遍,攻击者也在使用它。这个规则应该识别大多数公开记录的VBA清除示例,如9fd864e578d8bb985cf71a24089f5e2f (HornetSecurity)。然而,它也可以识别一些误报。正如Didier Stevens之前所确定的,一些公共图书馆,如EPPlus可能生成良性的文档,而没有PerformanceCache数据,并似乎被清除。
此规则的另一个重要限制是,不必完全删除_VBA_PROJECT流数据。因此,尽管在此技术的所有公开记录的示例中流大小均为7,但不必完全为7。
一种解决方案是比较文档宏的压缩版本和编译版本,并查找意外的变化。另一个可能的选择是YARA规则,该规则在_VBA_PROJECT流中搜索关键字或字节,如果p代码有效,则应显示该关键字或字节。
但是,让我们先走简单的道路,然后在OfficePurge中查找异常。代码中有一部分用静态标头覆盖 _VBA_PROJECT流:
// Remove performance cache in _VBA_PROJECT stream. Replace the entire stream with _VBA_PROJECT header.
一点点谷歌搜索显示此标头是根据Microsoft的规范构建的。但是,如果我们比较已清除和未清除的文档,则实际上该标头实际上与规范有所不同(图7)。
此标头不一定证明文件是恶意的或由OfficePurge创建的,但它可以很好地表明该文件是通过程序创建的,而不是使用Office产品创建的。对于此类异常,我们可以开始构建类似于以下内容的规则,该规则将搜索带有“ _VBA_PROJECT小”流和此可疑流头的文档:
rule FEYE_OLE_VBAPurged_2 {
meta:
author = “Michael Bailey (@mykill), Jonell Baltazar, Alyssa Rahman (@ramen0x3f), Joseph Reyes”
description = “This file has a suspicious _VBA_PROJECT header and a small _VBA_PROJECT stream. This may be evidence of the VBA purging tool OfficePurge or a tool-generated document.”
strings:
$vba_proj = { 5F 00 56 00 42 00 41 00 5F 00 50 00 52 00 4F 00 4A 00 45 00 43 00 54 00 00 00 00 00 00 00 00 00 }
$cc61 = {CC 61 FF FF 00 00 00}
condition:
uint32(0) == 0xe011cfd0 and ( uint32(@vba_proj[1] + 0x78) >= 0x07 ) and ( uint32(@vba_proj[1] + 0x78) < 0xff ) and $cc61
通过使用此处共享的两个规则进行搜索,可以发现利用VBA清除(或至少某种类型的自动文档生成)的各种威胁因素和恶意软件类型。在VirusTotal上,您可能会看到许多被该规则捕获的Emotet负载,这是可以理解的,因为它非常依赖恶意电子邮件附件。我们观察到的另一位最高罪犯是特斯拉。
由于这些规则都同时会打开良性文档,因此它们还没有为生产环境做好准备。但是,它们可以作为“弱信号”用于更多的手动威胁搜寻。在识别VBA清除技术时,许多静态检测引擎可能会为准确性而苦苦挣扎。FireEye MVX引擎使用的动态分析技术,即使清除了VBA,仍然可以正确引爆恶意文档并被检测到。
结论
只要公司使用Office文档,攻击者就将试图将恶意宏指令偷运到其中。VBA清除代表了威胁行为者如何不断发明新方法来逃避防御者的最新示例。
Indicators of Compromise
文件名 | 描述 | SHA256哈希 |
---|---|---|
测试文件 | 不清除VBA的Word文档中的Unicorn宏有效负载 | f4431f02fe1e624fdb7bf2243bb72f1899d7eccb1ed7b2b42ed86e001e8bff28 |
test2.doc | 使用VBA清除Word文档中的独角兽宏有效负载 | 98bd119f928e8db4ed45f5426f2c35c5f6d6ccc38af029e7ab4b9cfcc1447c53 |
excel_calc.xls | OfficePurge的“样本数据文件夹”中的样本文档 | de6583d338a8061bb1fc82687c8f5bff9a36ba1e2a87172e696ffaeca32567af |
excel_calc_PURGED.xls | OfficePurge的“样本数据文件夹”中的样本文档 | 914a6cf78fe98e80b1dee87347adbc8f8b37a1dfe672aa5196885daa447e9e73 |
Publisher_calc.pub | OfficePurge的“样本数据文件夹”中的样本文档 | 4bce7c675edde20a3357bc1d0f25b53838ab0b13824ab7a5bbc09b995b7c832f |
Publisher_calc_PURGED.pub | OfficePurge的“样本数据文件夹”中的样本文档 | 36bdfaaf3ea228844507b1129b6927e1e69a2cd5e8af99d507121b1485d85e1e |
word_calc.doc | OfficePurge的“样本数据文件夹”中的样本文档 | 23fa4b77c578470c1635fe20868591f07662b998716c51fbb53d78189c06154f |
word_calc_PURGED.doc | OfficePurge的“样本数据文件夹”中的样本文档 | a7eac98b3477fc97ccfe94f1419a859061ca944dc95372265e922992bd551529 |
