<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: analyzing-macro-malware
description: >-
  Extract, deobfuscate, and analyze malicious VBA/XLM macros embedded in Office
  documents using olevba, oledump, and dynamic analysis techniques.
domain: cybersecurity
subdomain: malware-analysis
tags:
  - macro-malware
  - vba
  - xlm-macros
  - office-documents
  - olevba
  - maldoc
  - malware-analysis
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1059.005", "T1566.001"]
---

# Analyzing Macro Malware

## Overview

Macro malware uses VBA (Visual Basic for Applications) or XLM (Excel 4.0) macros embedded in Microsoft Office documents to execute malicious payloads. Common delivery involves phishing emails with `.doc`, `.docm`, `.xlsm`, or `.xls` attachments that prompt users to "Enable Content." Macros typically download second-stage payloads, execute PowerShell commands, or drop executables. Analysis requires OLE stream extraction, VBA deobfuscation, and dynamic execution monitoring.

## Prerequisites

- oletools (`olevba`, `oledump.py`, `oleid`) for OLE/VBA extraction
- XLMDeobfuscator for Excel 4.0 macro analysis
- ViperMonkey for VBA emulation
- Python 3.10+ with `olefile`, `yara-python`
- LibreOffice (headless mode) or Office sandbox for dynamic analysis
- REMnux analysis distribution

## Key Concepts

### Macro Execution Triggers

| Trigger | Function Name | Description |
|---------|-------------|-------------|
| Document Open | `AutoOpen()`, `Document_Open()` | Runs when document opens |
| Workbook Open | `Workbook_Open()`, `Auto_Open()` | Runs when workbook opens |
| Document Close | `AutoClose()`, `Document_Close()` | Runs on close |
| Content Enable | `AutoExec()` | Runs when macros enabled |

### Common Obfuscation Patterns

- **String concatenation**: `"pow" & "ersh" & "ell"`
- **Chr() encoding**: `Chr(112) & Chr(111) & Chr(119)` → "pow"
- **Environment variables**: `Environ("COMSPEC")` → cmd.exe path
- **CallByName**: Dynamic method invocation
- **XLM macros**: Legacy Excel 4.0 formulas in hidden sheets

## Workflow

### Step 1: Document Triage

```bash
# Identify file type and OLE structure
file suspicious.doc
oleid suspicious.doc

# Quick VBA indicator scan
olevba --detect suspicious.doc

# Check for macros, encrypted content, external links
olevba -a suspicious.doc
```

### Step 2: Extract and Analyze VBA Code

```bash
# Extract all VBA macros
olevba suspicious.doc

# Decode obfuscated strings
olevba --deobf suspicious.doc

# Extract with oledump (stream-level analysis)
oledump.py suspicious.doc
oledump.py -s 8 -v suspicious.doc   # Dump VBA stream #8

# Extract XLM macros from Excel files
XLMDeobfuscator -f suspicious.xlsm
```

### Step 3: Deobfuscate VBA Code

```python
#!/usr/bin/env python3
"""Deobfuscate common VBA obfuscation patterns."""
import re

def deobfuscate_chr(code: str) -> str:
    """Resolve Chr() calls to characters."""
    def replace_chr(match: re.Match) -> str:
        return f'"{chr(int(match.group(1)))}"'
    return re.sub(r"Chr\w?\((\d+)\)", replace_chr, code)

def deobfuscate_concat(code: str) -> str:
    """Merge string concatenation."""
    return re.sub(r'"([^"]*?)"\s*&\s*"([^"]*?)"', r'"\1\2"', code)

def deobfuscate_vba(code: str) -> str:
    """Apply all deobfuscation passes."""
    result = code
    for _ in range(10):  # Multiple passes for nested obfuscation
        prev = result
        result = deobfuscate_chr(result)
        result = deobfuscate_concat(result)
        if result == prev:
            break
    return result

# Usage
vba_code = open("extracted_macro.vba").read()
print(deobfuscate_vba(vba_code))
```

### Step 4: Emulate Macro Execution

```bash
# ViperMonkey — VBA emulation without executing
vmonkey suspicious.doc

# Monitor with process tracing (sandbox)
# Execute in isolated Windows VM with Procmon
# Filter: Process Name contains WINWORD.EXE
# Watch for: cmd.exe, powershell.exe, wscript.exe child processes

# LibreOffice headless macro analysis (Linux)
soffice --headless --norestore --macro suspicious.doc
```

### Step 5: Extract IOCs from Macro

```bash
# Extract URLs, IPs, file paths from VBA code
olevba --decode suspicious.doc | grep -iE "http|https|ftp|\.exe|\.dll|\.ps1"

# Extract with pattern matching
python3 -c "
import re
code = open('macro_output.txt').read()
urls = re.findall(r'https?://[^\s\"'\\']+', code)
ips = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', code)
files = re.findall(r'[A-Za-z]:\\\\[^\s\"]+\.\w{3}', code)
print('URLs:', urls)
print('IPs:', ips)
print('File paths:', files)
"
```

## YARA Rule

```yara
rule Maldoc_VBA_Downloader {
    meta:
        description = "Detects Office document with VBA download and execute macro"
        author = "NERF"
        date = "2026-03-17"
        mitre_attack = "T1204.002"
        severity = "high"
    strings:
        $ole = { D0 CF 11 E0 A1 B1 1A E1 }
        $auto1 = "AutoOpen" ascii nocase
        $auto2 = "Document_Open" ascii nocase
        $auto3 = "Workbook_Open" ascii nocase
        $dl1 = "URLDownloadToFile" ascii nocase
        $dl2 = "XMLHTTP" ascii nocase
        $dl3 = "WinHttp" ascii nocase
        $exec1 = "Shell" ascii nocase
        $exec2 = "WScript.Shell" ascii nocase
        $exec3 = "powershell" ascii nocase
    condition:
        $ole at 0 and
        any of ($auto*) and
        any of ($dl*) and
        any of ($exec*)
}
```

## Detection

```yaml
title: Macro Malware Detection
id: 6239f4aa-805f-46f7-8301-8e2cbadc24b4
status: experimental
description: Detects suspicious activity related to analyzing macro malware techniques in malware analysis context
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    CommandLine: "*analyzing*macro*"
  condition: selection
level: high
tags:
  - attack.t1059.005
  - attack.t1566.001
  - attack.execution
falsepositives:
  - Sandbox detonation environments analyzing submitted samples
```

## Verification

- [ ] Document triaged (file type, OLE structure, macro presence)
- [ ] VBA/XLM macro code fully extracted
- [ ] Obfuscation layers removed and code readable
- [ ] Auto-execution triggers identified
- [ ] Payload delivery mechanism documented (download URL, drop path)
- [ ] IOCs extracted (URLs, IPs, file hashes, registry keys)
- [ ] YARA rule written and validated against clean document set

## References

- [MITRE ATT&CK T1204.002 — Malicious File](https://attack.mitre.org/techniques/T1204/002/)
- [oletools — OLE/VBA Analysis](https://github.com/decalage2/oletools)
- [ViperMonkey — VBA Emulator](https://github.com/decalage2/ViperMonkey)
- [XLMDeobfuscator](https://github.com/DissectMalware/XLMDeobfuscator)
