Office macro malware works because a macro is a real program that runs with all your permissions as soon as you click Enable Content, and attackers only need to convince you the document is broken until you do. The macro fetches and runs a payload. Microsoft now blocks macros in files from the internet by default, so current campaigns use containers, shortcuts and templates to get around the block.

Why a button in a document is dangerous

Visual Basic for Applications is a complete programming language embedded in Word, Excel, PowerPoint and Access. It can read and write any file you can, run any command you can, call Windows APIs and download from the internet. It exists so that finance teams can automate spreadsheets, and it is exactly as powerful as a program you downloaded and double-clicked, with one difference: it arrives inside something that looks like a document, and it is one click away. That click is the yellow bar labelled Enable Content, and the entire craft of macro malware is persuading you to press it.

The persuasion is called a lure. The document opens to a page that says the content is protected, encrypted, created in an older version, or requires you to enable editing and then enable content to view. None of that is how Office works, but it is plausible enough. Once enabled, an auto-run procedure such as AutoOpen, Document_Open or Workbook_Open executes without any further interaction. For a wider view of where this fits among attachment threats, start at the malware scanning hub.

Anatomy of a macro dropper

Almost all macro malware is a dropper: its job is to fetch and start the real payload, keeping the document itself small and easy to regenerate. A typical decoded macro reduces to three lines of intent, wrapped in hundreds of lines of noise:

Sub AutoOpen()
    Dim s As String
    s = "powershell -w hidden -enc " & Base64Blob()
    CreateObject("WScript.Shell").Run s, 0
End Sub

The noise matters. Variable names are random, strings are split and reassembled, characters are built from Chr() calls, and the real command is base64 inside base64. That obfuscation defeats signatures written on the previous campaign and is itself a signal: no legitimate finance macro hides its own commands. The payload the PowerShell fetches is usually a banking trojan, an infostealer or a loader for ransomware, which is why a macro click has historically been the first step of many corporate ransomware incidents. The malware types guide describes what arrives at the other end.

Where the macro lives inside the file

Knowing the structure lets you check a document without opening it. Modern Office files (.docx, .xlsx, .pptx and the macro-enabled .docm, .xlsm, .pptm) are zip archives following the OOXML standard, ECMA-376. Unzip one and you get folders of XML. If the file contains VBA, there is one extra part:

$ unzip -l quarterly_report.docm
  Length      Name
  ---------   ----
     1,542   [Content_Types].xml
       590   _rels/.rels
    18,204   word/document.xml
    27,648   word/vbaProject.bin      <-- the macro project (OLE2 container)
       412   word/_rels/vbaProject.bin.rels
     7,331   word/styles.xml

The vbaProject.bin part (under xl/ for Excel and ppt/ for PowerPoint) is an OLE2 compound file holding the compressed VBA source and compiled p-code. A plain .docx cannot hold this part; Word refuses to save macros into one, which is why attackers must use .docm or the legacy binary .doc format, where the VBA sits directly in the OLE2 container's Macros storage. A scanner looks for exactly these structures, and Scan.now reports them as Office document contains macros. Whether that finding is a problem depends entirely on who sent the file.

Legacy .doc and .xls files deserve extra suspicion. They can hold macros without a telltale "m" in the extension, and they are the format Office most often opens with fewer warnings on old configurations.

What changed in 2022, and what attackers did next

In 2022 Microsoft changed the default in Word, Excel, PowerPoint, Access and Visio: macros in a file that carries the Mark of the Web are blocked outright, with a red bar and no Enable button. The mark is a small alternate data stream, Zone.Identifier, that browsers and mail clients attach to anything downloaded from the internet. The change worked; commodity macro campaigns dropped sharply. Attackers responded by attacking the mark rather than the block:

TechniqueHow it evadesScan.now finding
ISO, IMG, VHD containersFiles extracted from a mounted image historically lost the mark (Windows now propagates it into ISO contents, but not all tools do)Archive contains an executable
Windows shortcuts (.lnk)The shortcut runs PowerShell directly; no macro, no documentWindows shortcut file
Password-protected zipsThe scanner cannot open it; the password is in the emailPassword-protected archive
OneNote (.one) filesEmbedded scripts behind a fake "open" button; Microsoft added blocking in 2023Embedded executable / script findings
XLL add-insA native DLL Excel loads as an add-in; blocked from the internet by Microsoft in 2023Executable program file
Remote template injectionA macro-free .docx whose settings point at a .dotm on an attacker's server; the template carries the macroLoads a remote template
HTML smugglingAn HTML attachment assembles the real file in the browser, so the download never crossed the mail filterHTML file assembles a download

Two of these deserve a closer look because they are macro attacks that do not involve a macro in the file you receive. Remote template injection exploits the fact that a Word document can declare an attached template by URL in word/_rels/settings.xml.rels. The delivered .docx is clean, scanners pass it, and when opened Word fetches the template, which is a .dotm with the macro, and applies the usual prompt. Excel 4.0 macros (XLM) predate VBA entirely: they are formulas in a hidden macro sheet, stored in the workbook rather than in vbaProject.bin, and they can call EXEC and CALL to run programs. Microsoft now disables them by default, but old Excel versions and misconfigured policies still run them.

Inspecting a document yourself

The open-source oletools package (by Philippe Lagadec) is the standard analyst's kit. olevba extracts macro source from both OLE2 and OOXML files, decodes common obfuscation and summarises what it found:

$ olevba quarterly_report.docm
VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin - OLE stream: 'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub AutoOpen()
...
+----------+--------------------+---------------------------------------------+
|Type      |Keyword             |Description                                  |
+----------+--------------------+---------------------------------------------+
|AutoExec  |AutoOpen            |Runs when the Word document is opened        |
|Suspicious|Shell               |May run an executable file or a system cmd   |
|Suspicious|powershell          |May run PowerShell commands                  |
|Suspicious|Base64 Strings      |Base64-encoded strings were detected         |
|IOC       |http://203.0.113.9/ |URL                                          |
+----------+--------------------+---------------------------------------------+

Auto-exec plus Shell plus an encoded PowerShell string is the dropper signature, and you do not need to understand the rest of the macro to act on it. Scan.now's file scanner performs the equivalent structural analysis in memory: it opens the container, locates the VBA project, remote-template relationships and embedded objects, applies heuristics for auto-run and shell keywords, runs signature matching, and then discards the file. It never opens the document in Office or executes anything.

Reading a macro finding on a real document

A scanner that says "contains macros" has told you a fact, not a verdict, and the decision is yours. Three questions settle most cases. First, does the file type match the claim? A supplier who normally sends PDFs and now sends a .docm, or an "invoice" that is a macro-enabled spreadsheet, has changed something that suppliers rarely change. Second, does the document work without the macro? Open it in Protected View, which is read-only and blocks execution; if the content is visible and complete, you can read it there and never enable anything. If it is blank apart from instructions, that emptiness is the whole design. Third, what does the macro do? Auto-run plus shell, PowerShell, URLDownloadToFile, WScript.Shell or a wall of base64 is a dropper. A macro that formats cells and sums columns, with readable variable names, is what a colleague's spreadsheet looks like. When the answers are mixed, ask the sender through a channel the document did not arrive on, and if that is not possible, the correct default for a document from outside your organisation is to not enable content at all.

Reducing the risk in Office itself

  1. Leave the internet-macro block on. If a legitimate workflow needs macros from outside, unblock specific files through the file's Properties rather than changing the policy.
  2. Keep Protected View enabled for files from the internet, attachments and unsafe locations. It opens documents read-only in a sandbox where macros and external content cannot run.
  3. Disable Excel 4.0 macros via Trust Center or policy if your version has not already done so.
  4. Use Attack Surface Reduction rules on managed Windows fleets, particularly "Block all Office applications from creating child processes" and "Block Win32 API calls from Office macros". They stop the dropper's next step even when the macro runs.
  5. Treat the lure as the tell. No real document requires you to enable content in order to read it. If the page you see is instructions for enabling something, close it and check the sender by another channel, using the tests in how to spot phishing.
"Enable Editing" and "Enable Content" are different buttons. The first leaves Protected View; the second runs macros. Lures ask for both in sequence precisely because the first alone is harmless and familiar.