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 |