Skip to content
8 min read

Macros won't die: red-team lessons from Office exploitation

  • #security
  • #red-teaming
  • #research

For one of my cybersecurity specialisations I spent a semester going deep on a question that sounds almost dated: are Office macros still worth anything to an attacker in 2026? Microsoft has spent years hardening them, the security press keeps writing their obituary, and yet red teams still reach for them. I wanted to know why, so I read the literature, built a lab, and validated the techniques hands-on instead of taking anyone's word for it.

The short answer: macros aren't dead, they just changed shape. The longer answer is a story about how defenders raise the cost of an attack and attackers route around it, which is really the whole story of offensive security in miniature.

What a macro actually is

A macro is a small script embedded in an Office document. In Word and Excel that script is written in VBA (Visual Basic for Applications); older Excel files use a separate macro language called XLM. They exist for a genuinely good reason: automating repetitive work. Someone in finance can press one button and have a spreadsheet reformat itself, pull data, and build a report.

The problem is that the same capability that makes macros useful makes them dangerous. VBA has direct access to the Windows API and the shell, so a macro can do essentially anything the logged-in user can. And a macro can be set to run automatically the moment a document opens, through triggers like AutoOpen() in Word or Workbook_Open() in Excel. Combine automatic execution with a convincing phishing email, add a victim who clicks "Enable content," and you have code running on a target machine. From there a malicious macro can download a payload, run PowerShell, harvest system data, set up persistence, or open a reverse shell.

A short history, because the trajectory matters

You can't understand where macro attacks are without seeing how they got here.

  • 2019 to 2021, the comeback. Malware families like TrickBot and QakBot leaned heavily on macros, often the old XLM kind, to deliver payloads through weaponised spreadsheets. Detection rates were low and the technique was cheap, so it spread.
  • 2022, the turning point. Microsoft started blocking VBA macros in files that carry the Mark of the Web, the hidden tag Windows stamps on anything downloaded from the internet. Suddenly a document from an email or a website would refuse to run its macro at all. Macro-based phishing dropped off a cliff almost overnight, and a lot of people declared the technique dead.
  • 2023 to 2024, the adaptation. Attackers did what attackers always do. They treated the block as a routing problem and went around it.

If the story ended in 2022 the obituaries would be correct. It didn't.

How attackers adapted

Blocking the easy path just moves the water downhill. My research kept surfacing the same handful of adaptations, and they fit a clear theme: stop relying on the macro to carry the danger, and stop letting the dangerous file get tagged.

  • Container smuggling. Wrapping the payload inside an .ISO, .IMG, or an archive like .ZIP or .RAR, frequently paired with an .LNK shortcut. The Mark of the Web lands on the container, not on the file the victim ends up running, so the macro warning never appears.
  • Trusted location abuse. Dropping a document straight into a folder Office already trusts, such as the templates directory under %AppData%, where macro warnings and the Mark of the Web don't apply.
  • Living off the land (LOLBins). Instead of dropping new tools that antivirus might flag, attackers abuse legitimate signed Windows binaries: mshta.exe, regsvr32.exe, wscript.exe, powershell.exe. Because the OS trusts these, a lot of endpoint protection waves them through. A classic example is using regsvr32.exe to load a remote scriptlet, which needs no admin rights and looks like normal system behaviour.
  • Cloud delivery. Hosting the next stage on OneDrive or SharePoint and fetching it through trusted, authenticated APIs (even the Microsoft Graph API) bypasses a lot of URL filtering and reputation scoring, because the request goes to a domain everyone already trusts.
  • Multi-stage payloads. The document carries nothing incriminating. It's just a downloader. Stage one pulls stage two, which pulls the real malware, which might be ransomware or a command-and-control beacon. That separation means the attacker can swap the real payload without ever touching the document, and each hop can hide behind a trusted service. Families like QakBot and Emotet used exactly this structure.

The pattern is consistent: the macro stops being the weapon and becomes the delivery van.

Evasion is the whole game

The other half of my research was evasion, the art of staying invisible to scanners. This is where the cleverness lives, and a few techniques stood out because they're conceptually simple and disproportionately effective.

VBA stomping. This one genuinely surprised me. Tools like EvilClippy exploit a quirk of how Office stores macros: there's the human-readable VBA source, and there's the compiled "p-code" that actually executes. If the Office version matches, Office will run the p-code and ignore the source entirely. So EvilClippy strips or replaces the visible source while leaving the working p-code intact. Static analyzers and many antivirus engines read the source, find nothing suspicious, and move on, while the real logic still runs.

Obfuscation, in layers. The academic literature breaks this into a neat taxonomy, and each layer defeats a different kind of detection:

  • Random obfuscation: replacing meaningful names with gibberish like COHdDxBvIVN, which defeats keyword and signature matching without changing behaviour.
  • Split obfuscation: breaking a command string into pieces and reassembling it at runtime, so a scanner looking for powershell or a known URL finds only fragments.
  • Encoding obfuscation: hiding a payload as Base64 or a byte array, so the malicious content looks like meaningless data until it's decoded in memory.
  • Call obfuscation: invoking methods indirectly, for example through CallByName, so direct API calls that antivirus flags never appear literally.
  • Logical obfuscation: burying the real logic among large amounts of harmless filler code so a human analyst drowns in noise.

LOLBins again. Worth repeating because it's the connective tissue. Once you're executing, leaning on trusted binaries instead of dropping files keeps the whole chain quiet.

What the lab actually showed

Theory is cheap, so I tested it. I built a malicious test document with a reverse shell and ran it through VirusTotal: 46 engines flagged it as malicious. Then I ran the same file through a single VBA-stomping pass with EvilClippy and submitted it again. The detections dropped by roughly a third to a half. The logic never changed. Only its appearance did, and that was enough to walk past a wall of antivirus engines. That result is the entire argument in one number.

I also reproduced the Mark-of-the-Web bypass end to end. I made a macro-enabled spreadsheet, hosted it, and confirmed that a downloaded copy shows the expected "untrusted source" warning. Then I wrapped the same file in a self-extracting executable. Now the Mark of the Web lands on the executable, and once it extracts, the spreadsheet inside has no such tag. The only thing standing between the victim and execution is the ordinary "enable content" prompt. It only works if the social engineering is convincing enough to get someone to run the installer, which is exactly the point: the technical control is intact, and the human is the bypass.

I built a separate demo with a custom tool that generates obfuscated PowerShell reverse shells, planted the command behind AutoOpen(), and watched a "victim" machine connect back the instant the document opened. Seeing full remote control fall out of a Word file you'd happily double-click in a real inbox makes the risk concrete in a way no slide deck does.

The defenses that actually move the needle

The most uncomfortable finding is how mundane the effective fixes are:

  1. Disable macros entirely if your organisation doesn't use them. Removing the attack surface beats every detection trick.
  2. Train people. Almost every chain in my research started with a human enabling content or running an installer. Awareness is not a soft, optional control here. It is the control.
  3. Patch and update, so the known evasion tricks and version-specific quirks lose their footing.
  4. Layer your detection. Good email security plus EDR catches a meaningful share of obfuscated payloads even when a single antivirus engine misses, and monitoring for LOLBin abuse closes the gap that signature scanning leaves open.

The takeaway

Microsoft genuinely made macros harder, and that's a real win. But "harder" is not "gone." As long as a document can ask a human to click one button, and as long as trusted binaries and trusted clouds exist to hide behind, macros stay relevant. What the semester really taught me is the rhythm of the whole field: a defender raises the cost, attackers find the next cheapest path, and the human in front of the screen stays the most reliable way in. The best defenses aren't clever. They are the boring, consistent ones, applied to the boring, consistent ways people actually get compromised.