Skip to content
Malwagon
Sign up

Document analysis

What this module is

Malwagon document analysis takes one document file, from the office, portable document, rich text, notebook, compiled help or markup families, and opens it in a virtual machine under the application that owns the format. It returns a structural reading of the file, the recorded behaviour of that application, an ATT&CK-mapped finding list, a score and a verdict.

A document built to carry an attack is what analysts call a maldoc, and maldoc analysis is the work this module does. The defining property of a maldoc is that its code belongs to the application: the macro, the embedded object, the field command and the attached template all fire because the office application, the reader or the help viewer does what the format asks of it. Every design decision on this page follows from that. The file is read apart on the analysis host first, then opened in the guest the way the person who received it would open it, and the report keeps those two readings as separate grades of the same claim.

Submission
One upload, or one link the analysis host downloads for you. 128 MB from the console, 100 MB on the public landing scan, empty files refused. A download that fails refunds the credit.
Formats
29 extensions across the OLE, OOXML, RTF, PDF, notebook, compiled-help and web-container families. Content decides admission; the name decides it only where the format has no trustworthy header.
Protected delivery
An archive is refused unless you supply its password or ask for automatic unpack, because that is the phishing case. The document inside is what detonates; the wrapper is packaging.
Supporting files
Up to 10 more, 32 MB each and 64 MB together, written into the same guest folder as the document before the machine is powered on: a template, a data file, a dependency.
Image
One, and it is not a preference. The Windows build carrying the office applications, enforced on the submission itself, so a hand-built request cannot reach another image.
Run length
10 s to 600 s, capped by plan at 120 s free and 300 s on Pro. Opened automatically, or left for you to open by hand over the live view.

What the module takes in, and what it refuses

The name on a submission decides nothing. Acceptance is settled on content first: the portable document header, the {\rtf opening group, the OLE compound-file signature, the notebook file-data-store GUID, the compiled help signature, and a ZIP only when it also carries an OOXML part marker. Formats that have no header worth trusting, which in practice means the markup containers and the older publishing formats, are admitted on extension alone and the report says so by leaving their format unclassified.

Refusal matters as much as admission. A submission whose header reads as a native executable or a shebang script is rejected outright, with the error naming the module it should have gone to. An invoice.docx carrying a PE does not become a run titled Document analysis: the header decides where it goes, and the error points at the file module.

The 29 accepted extensions, how each family is recognised, and what reads it
Family and extensions Recognised by Format-specific analysis Opened
Legacy OLE documents
.doc .dot .xls .xlt
.ppt .pps .pot
Compound-file signature Macro project, auto-execution triggers, legacy macro sheets, the embedded object pool, container encryption Yes
OOXML packages
.docx .docm .dotm
.xlsx .xlsm .xlsb .xltm
.pptx .pptm .ppsx .potm
ZIP plus an OOXML part marker All of the above, plus relationship analysis, embedded object parts, and a rebuild of the package without its macro storage Yes
Rich text
.rtf
{\rtf header Embedded object parsing and field analysis. Not routed down the macro path, because the format carries no macro project Yes
Portable document
.pdf
%PDF- header Keyword census, trigger correlation, URI, launch-target and embedded-name extraction, over the raw file and its inflated object streams Yes
Notebook
.one
File-data-store GUID Attachment carving, with each attachment typed by its own content Yes
Compiled help
.chm
Container signature Shortcut-control heuristics, extracted command lines, references to signed built-in binaries Conditional
Markup containers
.htm .html .mht .xml
Extension only None. The format reads unclassified; metadata and the general static chain still run over the bytes Yes
Publishing and diagram
.pub .vsd .vsdx
Extension, with the container read where there is one Whatever the underlying container exposes. No analyser is written for these formats themselves Yes

The last column describes the guest, and only the guest: it says whether the file is opened through its shell association, in the application that owns the format. Compiled help is the one conditional entry, because the guest's own document-extension list does not carry it, so it is opened that way only when the sample was typed as a document to begin with.

Typing is done once, and it belongs to the bytes

Sample records here are content addressed and shared by every future scan of the same bytes, so the row is typed by what the file is. The module a submitter happened to pick has no say in it. A label chosen at submission time does not travel to the next analyst who scans those bytes.

An OOXML document is a ZIP, and that makes the automatic archive unpacker a hazard here: taken apart, a macro-enabled package reads as a handful of XML parts nobody submitted, and the macro storage stops being the subject of the scan. The unpacker is therefore forbidden from opening a document, and a test holds the guard in place. The mirror case is handled too, because an encrypted OOXML file is not a ZIP at all but an OLE container holding an encrypted package, so it is recognised by name and container together and stays with the document engine, clear of the binary path.

A document that arrives with no usable extension is stored under the one its content implies, worked out from the container: the header for portable documents, rich text, notebooks and compiled help, the directory entry names for the legacy OLE family, and the part names for OOXML, where the presence of a macro storage is what separates a macro-enabled package from a plain one. The scan keeps the name you submitted. The guest gets a name it can open.

Password-protected archive delivery

The pattern where the password sits in the body of the phishing mail is handled end to end. Supply the password, or tick automatic unpack, and the archive is opened on the analysis host under the same bounded containment as every other parse; the document inside becomes the sample and is what reaches the guest. Without one of those two, an archive is refused outright and the error says why. Quietly reading a container as though it were the document it hides is the failure this rule exists to prevent.

Why is there no image selector on this form?

Because the document has to open in the application that owns its format, and one image carries those applications. A macro is not code this platform runs. It is code the word processor runs. An embedded package is only written out and launched if the object host is there to unpack it; a remote template is only fetched if the application resolves the relationship; a field command only executes because the field engine evaluates it on open. Every technique this module exists to observe needs its interpreter present, which makes the guest image a control variable in the experiment.

So the operating system field on the document form is single choice and pinned to the build carrying the office applications. A different image in the submission is a validation error. The alternative is a run on a machine with nothing installed to open the file, which produces a clean report about nothing. Two more things stand behind that field: a plan-level allowlist of images, and an image record that only advertises office support after the word processor was actually found on that disk. The execution-privilege selector is gone for a related reason. A document is opened at the interactive user's ordinary token, the way it would be by the person who received it, and the run records the token it really got. A privilege choice there would make the run less like the incident it is modelling.

ANALYSIS HOST Typed on its bytes the header routes it, the name does not Stored under the implied extension your own file name is kept on the scan Written into the run overlay offline, with its supporting files GUEST VIRTUAL MACHINE restored from a live memory snapshot, disposable overlay, deleted when the run ends Extension travels with the file no renaming, no forced executable Shell association opens the application the same path a recipient would take The application interprets it macro, embedded object or field command RECORDED FROM OUTSIDE THE GUEST packet capture at the hypervisor link, framebuffer capture, the guest RAM image, the disk overlay read after the guest is gone
One document run, end to end. The staging on the left happens before the machine is powered on, so there is no in-guest download or copy step for a sample to watch; the band across the bottom is recorded by the host, which is why a macro that disables logging inside the guest does not take the recording with it.

Opened the way a recipient opens it

A document is not a program. Hand one to the loader as if it were, and no macro execution follows: Windows declines to start a file that is not a PE, so nothing opens the document and the run finishes clean. A report about nothing having happened is the expensive kind of false negative, because it looks like an answer. So the file keeps the extension its content implies and is opened through its shell association, on an image prepared so the document opens into its full editing surface, since a read-only preview holds the code back, and so nobody has to click a prompt for the sample to reach its own code.

What maldoc analysis reads off the document before it opens

The static read runs on the host while the guest is restoring and arming, so it costs the analyst no wall-clock time. No file you submit is executed there. The document is parsed, and parsing attacker-supplied container formats is itself the exposure, so the whole parse runs in a forked child under a wall clock and an address-space ceiling, and every archive read is budgeted from the container's own directory before a single part is materialised. A part that declares gigabytes does not get to allocate them. When a parse does breach its budget, that is written into the report as a finding about a resource bomb. The alternative, a document that quietly turns out to have no macros in it, is a lie the analyst has no way to catch.

THE STRUCTURE SECTION OF ONE REPORT Document analysis OOXML MACRO PROJECT INDICATOR SENTENCES T1204.002 Opening this document runs code, with no further action. T1059.005 The macro reaches auto-execution and file-write primitives. No execution primitive is present, so the summary does not say it executes anything. RECOVERED MACRO KEYWORDS, TYPED AS THEY WERE RECORDED AutoOpen Document_Open Open ... For Output Environ hxxp://[recovered host] auto-execution trigger suspicious call recovered indicator DISARMED COPY the package rebuilt without its macro storage, removed parts listed by name, stored under its own SHA-256 WHAT THE ANALYST READS FIRST the sentences carry the whole static claim in words; the chips under them are the evidence
How the structure section of a weaponised document reads. The two indicator sentences are the whole static claim in plain words: code runs when the file is opened, and the macro reaches auto-execution and file-write primitives while no execution primitive is present, which is why the summary stops short of saying it executes anything. The keyword chips underneath are the rows an analyst scans first, and each is labelled with the kind of thing it is.

The macro project

Modules in a recovered project are decompressed and kept with their real name and true size, plus a bounded excerpt. Auto-execution triggers are named one by one, each with the procedure that carries it, because AutoOpen, Document_Open and Workbook_Open are different statements about how the file behaves and a single boolean would flatten all three. Together they are what turns the document into a T1204.002 finding: opening it runs code. Keywords are typed as they are recorded, so an auto-execution trigger, a suspicious call and a recovered indicator are three different kinds of row, each labelled with the kind of thing it is.

Primitives are reported as the primitives actually present. Auto-execution, file write and shell or process execution are each tested separately, and the macro text that set each one is quoted alongside it, so the sentence in the report is backed by the line that produced it.

Macro primitive summary one macro-bearing document
A   auto-execution           AutoOpen()
W   file write               Open ... For Output As
X   shell / process exec     not present

summary   the macro combines auto-execution and file write primitives
A macro with no execution primitive is not described as executing anything. The report names the primitives it found, so a reader can tell a document that writes a file from one that starts a process, and the sentence keeps its meaning on the day it does say execution.

Is the macro you can read the one that runs?

A macro project stores two representations of the same code: the compressed source, and the compiled P-code the application executes. They are written together, and nothing keeps them in agreement afterwards. Overwrite the source with something harmless, leave the compiled stream untouched, and a reading of the source describes a benign macro while the application goes on running the original. Malwagon compares the two streams and reports a disagreement as a finding of its own, so the report tells you the readable macro is untrustworthy and declines to repeat what it says.

ONE MACRO MODULE, TWO REPRESENTATIONS Compressed source stream the text a source-level reading parses Compiled P-code stream the form the application actually executes Reads as harmless overwritten by the author Runs the original macro left in place, never recompiled The two representations are compared, and a disagreement is reported as a finding: what you can read is not what will run (T1564).
Why a source-only reading of a macro is not a reading of the document. The disagreement is reported; the compiled stream is not decompiled back to source, so the finding points you at the detonation for what the code actually does.

Containers inside the container

Embedded objects are analysed for both OOXML embeddings and the legacy object pool. Each object's class identifier is resolved against a named table, the original file name an object package carries is recovered, and that name is tested against the 24 extensions that make a dropped package an execution and not an attachment: executables, libraries, installers, shortcut files, script and command types, disc images. A document embedding a portable document is a person attaching a file. A document embedding a shortcut is a delivery mechanism.

Embedded object classes, by what their presence in a document means
Object classWhat it isHow it is weighed
Equation object A legacy equation component, resolved from either of the two class ids that register it Exploit carrier Characteristic of exploit delivery, effectively absent from ordinary authoring, and reported as a structural fact about the file
Object package A generic file wrapper that carries an arbitrary payload and the file name it should be written out as Drops and launches The packaged name is recovered and flagged when it is a runnable type
Script component A scriptlet object that names a script for the object host to fetch and run Exploit carrier Remote script execution reachable from an opened document
HTML document object A markup and script host object embedded inside the document body Exploit carrier Remote markup and script rendered from inside the file
Script engine object An embedded scripting engine instance Exploit carrier Executes script hosted by the object itself
Nested workbook A spreadsheet embedded inside another document Carrier May hold its own macro project, so the nesting is what is reported
Unrecognised class A class identifier that is not in the table and is not the null class Reported by id Named and left unweighted, with the raw identifier printed for you to judge

Relationships are the other half of the container story. OOXML relationship parts are read for attached-template targets and for external object, frame, frameset and link references, and the result is rendered as an external relationship table with the target shown in full. A target on http, https or ftp is written into the scan's IOC table. A UNC target is read differently and deliberately: \\host\share in a template relationship makes the application authenticate outward to a machine the document's author chose, which is a credential exposure that costs the attacker no macro at all.

Field commands are kept apart from one another. Detection is anchored on the field structure itself, so the letters appearing loose somewhere in the file prove nothing, and the automatic and manual forms are reported apart, because one runs a command line the moment the file opens with no macro and no user action while the other waits for someone to update the link. That distinction is the difference between a document that is already running and a document that needs a second mistake.

What happens to a document with no macro project?

Portable documents get a keyword census over the raw file and over its inflated compressed object streams, plus URI extraction, launch-action target extraction, embedded file names, remote go-to and form submission. Script presence and an opening or additional-action trigger are combined into a single stated fact, because it is the pair that means code runs when the file is opened, and two separate counts leave the reader to make that join alone.

The 12 portable-document keywords counted, and what each one carries
KeywordWhat it marksClass
/JSA script stream attached to an objectActive content
/JavaScriptA script entry in the name tree or an actionActive content
/OpenActionAn action performed when the document opensTrigger
/AAAn additional action bound to a page or a field eventTrigger
/LaunchAn action that starts an external program, with its target extractedActive content
/EmbeddedFileA file carried inside the document, with its name extractedActive content
/RichMediaEmbedded media handled by a separate player objectCounted
/AcroFormAn interactive form, which is where field-level actions liveCounted
/JBIG2DecodeA legacy image decoder filterCounted
/URIAn outbound link, extracted and written to the IOC tableCounted
/SubmitFormA form that posts its contents to a remote endpointCounted
/GoToRA jump into a remote documentCounted

Where those keywords are found matters as much as whether they are found. Active content that is invisible in the raw bytes and only appears once the compressed object streams are inflated is reported as hidden, and reported separately from the content itself, with the report saying plainly that hiding corroborates and must not convict. Compressed object streams are also how ordinary authoring tools store objects, so their use is context for a finding and is not a finding by itself.

Notebook files are carved for attachments by their file-data-store marker, and each carved blob is typed by its own content, with the notebook's own claim about it ignored: executable, package, script or command, markup or application file, or plain data. Rich text is parsed for object class names, object sizes, equation objects and embedded executables inside those objects, and it is not sent down the macro path, because the format carries no macro project.

Compiled help is examined for the shortcut control that runs a command when the file opens, for the command line carried in its parameter, and for references to signed built-in binaries. Legacy spreadsheet macro sheets are looked for in modern packages as well as in old binary workbooks, because the modern package is where that technique lives today. And a document that is encrypted is reported as encrypted, as a finding in its own right, because a document nobody can inspect is exactly why the technique is used for delivery.

CODE WITH NO MACRO PROJECT Portable document open action or additional action, and a launch target Rich text embedded object, equation object, packaged executable Notebook carved attachment, typed by its own content Compiled help shortcut control carrying a command line OOXML relationship attached template fetched from a target the author chose The application acts on open no macro project anywhere in the file Reported as its own finding named surface, own technique id STRUCTURE FIRST, THEN THE RUN each surface is read off the file before the guest opens it, and the recording says whether it fired
The half of this module that has nothing to do with macros. Each of these paths reaches code through the application's ordinary handling of the format, which is why a clean macro answer is not by itself a clean answer about the document.

What the document would hand to a shell

Living-off-the-land abuse is matched over the macro's own string literals, joined the way the macro joins them, so a command assembled from concatenated fragments is recovered as one command and an identifier that merely contains a binary's name is not mistaken for a command line. The corpus is 31 signed built-in Windows binaries, each requiring a distinctive abuse argument rather than its bare presence, and each carrying its own ATT&CK technique: certificate and transfer utilities, the library and control-panel loaders, the script hosts, the build and installation tools, the scheduling and service controllers, the help viewer. The same rules run over a compiled help file's extracted command line.

URLs and IPv4 literals are recovered from both the raw macro source and the assembled-literal view, prefix duplicates are collapsed, and private, loopback and link-local space is excluded so a hard-coded internal address does not arrive in your indicator feed as a network target. What survives goes into the scan's IOC table tagged with the layer that found it, and appears in the report as its own kind of keyword row.

The downloader claim is never made on one signal

A document is only described as fetching and executing a remote stage when corroborating evidence stands behind the claim. Taken singly, the things that point at a downloader are things a legitimate business macro does every day, so the claim is made on the corroboration rather than on any one of them, and the report shows the evidence that carried it.

Technique, what is read off the file, and where the finding surfaces
TechniqueRead from the documentATT&CKSurfaces as
Macro project presentDecompressed module source with per-module name and true sizeT1059.005Indicator, named signature, triage tag
Auto-executing macroThe individual trigger procedure names found in the projectT1204.002Indicator, triage tag, narrative row
Legacy spreadsheet macro sheetMacro-sheet parts and their content-type declarations, in modern packages as well as binary workbooksT1059Indicator, named signature
Compiled and source form disagreeComparison of the two stored representations of the same moduleT1564Indicator, named signature
Field command executionField structure, with the automatic and manual forms separatedT1559.002Indicator, named signature
Remote template injectionAttached-template relationship targetsT1221Indicator, named signature, relationship table, IOC
External relationship referenceExternal object, frame, frameset and link targets, including UNCT1221Indicator, named signature, relationship table, IOC
Weaponised compiled helpShortcut control plus the command line in its parameterT1218.001Indicator, named signature
Launch action in a portable documentExtracted launch targetsT1204.002Indicator, named signature
Structure obfuscationActive content present only after object streams are inflatedT1027Indicator, stated separately from the content
Encrypted documentContainer-level encryption of the packageT1027.013Indicator, and a stated reason the file cannot be read
Fetch and execute a remote stageCorroborating evidence from more than one part of the static readingT1204.002 + T1105Indicator, and the strongest static claim the module makes

What the run adds to the reading

Static evidence says what the document is able to do. The detonation says what it did, and the two are reported as different grades of the same claim. The guest is a full Windows virtual machine under a hypervisor, on hardware Malwagon operates, restored from a live memory snapshot of a settled desktop. Nothing is cleaned between runs; the machine is replaced. Its disk is a copy-on-write overlay made for that run alone and destroyed when the run ends, so the document after yours meets the same desktop yours did.

Four recording layers sit outside that machine entirely: packet capture at the hypervisor link, framebuffer capture of the screen as the guest paints it, the guest RAM image read for agentless kernel forensics, and the disk overlay carved host-side once the guest no longer exists. All four are agentless. None of them runs as a process in the guest operating system, so a macro that disables logging or unhooks user-mode instrumentation still leaves the packets, the screen and the memory image intact. Inside the guest, a kernel event trace and the security audit log supply attributed process, file, registry and network activity, and an in-process monitor adds argument-level detail as a second source the report does not rest on alone.

Attribution, and the noise an office application makes

A document run has an attribution problem an executable run does not: the process under observation is a large, chatty application that was already part of the image, and it does an enormous amount of ordinary work simply to open a file. Two things follow from that.

First, the application that opened the document is adopted as the sample's process, and the harness's own launch vector and helper processes are filtered out of the graph. A recipient does not open a document by typing a shell command with the file name as an argument, so leaving that in the tree would mislead the analyst and tell the sample where it is.

Second, part of that ordinary work is condensed out of the behaviour table rather than dropped: what is held back is still counted, and the report states how many rows were held back and why. Autostart locations stay in the table whatever else is condensed, so persistence has nothing to hide behind. Printing every row of it invites an analyst, or a model summarising for one, to narrate persistence that did not happen.

Screen capture is tuned for this module in particular. It starts earlier in the run and reacts to smaller changes on the screen than an executable needs, because a document paints its window within seconds and then sits still, and a cadence built for a long-running process stores an empty desktop and misses the one interesting second. You can also watch the document open live and take the controls, or choose manual mode and open it yourself, on the same run that produces the report.

Everything else that a sample gets, a document gets: behaviour-rule matching over the telemetry, persistence answered from a before-and-after diff of the machine's autostart surfaces, DNS, HTTP and TLS endpoint recovery from the capture, dropped payloads carved and analysed in their own right, an optional memory image with a custom memory rule run against it, and a plain statement of whether the guest ever reached the sample at all.

How a document finding is weighed

The general static chain runs over the same bytes as the document engine and the two views are merged, so a document also receives content typing, cryptographic and fuzzy hashing, entropy, string and obfuscated-string extraction, embedded-secret scanning, signature-rule matching, local antivirus scanning and container carving. Fuzzy hashing is what puts documents into similarity and campaign clustering, which for this class of sample is usually the most useful question you can ask: not what is this file, but what else arrived looking like it. Each part inside the document that is itself a file, the macro storage, an embedded object stream, a carved executable, becomes its own stored artifact with its own hash, rule matches and antivirus verdict.

Alongside the score, the report states the strength of what it has: structural evidence, something the machine watched happen, or agreement across more than one layer. That grade is the line worth reading before the number, because it separates a claim about what the file contains from a claim about what it did. Rules describing a structural defect or a generic technique are barred from naming a malware family, so a malformed but harmless portable document does not arrive attributed to an actor. Where the evidence carries no attribution, the report says so and names the evidence it does have.

Named document signatures, with the severity and technique each carries
SignatureSeverityATT&CK
Document contains VBA macrosMediumT1059.005
Legacy spreadsheet (XLM) macros, legacy macro executionHighT1059
VBA stomping (hidden P-code macro)HighT1564
DDE/DDEAUTO field command executionHighT1559.002
Remote template injectionHighT1221
External document relationship referenceMediumT1221
Weaponised CHM (executes a command on open)HighT1218.001
Launch action in a portable document executes a programHighT1204.002

Triage carries three separate document tags, because they answer three separate questions: does the file contain a macro at all, does that macro run without anyone choosing to run it, and do its primitives read as hostile. A file can be the first without being the second, and the second without being the third, and collapsing them is how a maintenance workbook ends up in the same bucket as a loader.

For OOXML packages the module also produces a disarmed copy: the package is rebuilt without its macro storage parts and without the macro-enabled content-type overrides, the removed parts are recorded by name, and the result is stored as its own artifact with its own SHA-256 and listed among the extracted files.

Leaves the host: nothing
The document itself, its macro source, its embedded objects and every carved part stay on the analysis host. There is no upload path for a sample anywhere in this platform, and no exception for a document that looks harmless.
Leaves the host: derived only
Hashes and derived indicators are what reach reputation services. A recovered URL is an indicator; the file that carried it is not.
Reaches the AI layer
A locally built summary copied through an explicit allowlist: macros present, macro keywords, indicator sentences. The macro source is deliberately excluded, and a test asserts that against the real builder itself, so the guarantee cannot drift away from a description of it.

The same restraint governs the machine-readable surfaces. The API and MCP document fields are the summary only: whether macros are present, a bounded set of macro keywords, and a bounded set of indicator sentences. No macro source, no artifact identifiers, no download links, no bytes. Findings do travel outward in the formats a team already uses, as an ATT&CK Navigator layer, a STIX bundle and a sharing event bundle, all built from derived data.

What this module does not do

An encrypted document is detected, never opened
The password field on the form belongs to an archive. There is no document password input anywhere in the product, so the static layer reports the encryption as the finding and the guest is left in front of a prompt nobody answers.
The disarmed copy has no download route today
It is built, stored, hashed and listed among the extracted files, but the download endpoints serve extracted files, dropped files and unpacked payloads only. Treat it as a record that the rebuild succeeded and as a list of what was removed. It is not yet a file you can hand back to a user.
Disarming covers OOXML only
The portable-document and legacy OLE rebuilds are deferred, and the report names them as deferred, so an empty result cannot read as a clean one. Over the part budget there is no cleaned copy at all.
The macro source is stored but not displayed
It is extracted, bounded, kept as an artifact and deliberately withheld from the AI layer. What the report shows is the keyword rows and the indicator sentences. The code itself stays in the artifact store, and this page is not offering you a macro viewer.
Legacy macro sheets are detected without being reconstructed
The same applies to a compiled-versus-source disagreement: it is reported, and the compiled stream is left compiled. Both findings point you at the detonation for what the code actually does.
Embedded objects are described from the container
Class and packaged file name, with nothing unpacked and nothing executed by this analyser, and the number of objects described is bounded. A recognised exploit-carrier class is a structural fact about what is embedded; only the run can show whether anything fired. Both the OOXML and rich-text object lists currently reach the report as indicator sentences, with no table of class ids, sizes and packaged names.
Portable-document analysis is keyword and structure based
It works over the raw file plus a bounded inflation of its compressed streams. There is no full object-graph parse, no execution or emulation of embedded script, no handling of an encrypted portable document, and the URI, launch-target and embedded-name extraction is pattern based and capped. Streams past the inflation budget are not read.
Compiled help analysis is heuristic
The container itself is not parsed, so its internal files cannot be enumerated and a command carried outside the shapes the heuristics know is missed. That format also depends on the sample being typed as a document: one arriving typed as a generic file is not opened through its association in the guest.
Notebook carving is marker driven
It works to a budget on the number of attachments it will describe, and the report says when that budget was reached. Carved attachments are reported by type and size, and this analyser does not store them as artifacts of their own.
Markup containers get no format-specific analyser
Markup, archived-page and publishing formats are accepted and opened in the guest, but their reported format is unclassified and they receive metadata plus the general chain. There is no smuggling analyser for markup in this module.
A parse that breached its budget leaves a real hole
The resource-bomb finding is recorded and it is the right finding, but the macro-level answer for that document is missing. Read it as absent evidence, never as evidence of absence. The same is true of a rich-text object parse that had to be abandoned.
Nothing interacts with the document's own content
There is no simulated reader: interaction with content the document draws inside its own body is not simulated, and the handling of blocking dialogs is best effort and does not hold on every guest build. Manual mode and the live view are the answer when a document needs a human.
Free and anonymous runs have no egress at all
A remote template fetch, a macro downloader or a callback therefore produces no network evidence on those tiers, and that absence is a property of the plan. Read nothing into it about the sample. Those runs are also capped at 120 seconds, so a document that waits out a long pause can finish the run without reaching its payload unless sleep bypass is enabled and the plan allows a longer run.
One image, one office build
Behaviour that only triggers on a different version, patch level or locale cannot be reproduced here, and this module has no image matrix. Where a build-dependent question is the whole question, that is another module's job.
An archive of several files yields one sample
When an archive holds more than one file, its contents are analysed and the report names what was found. Which member becomes the subject of the detonation is not yours to choose, so submit the document on its own when it is the document you want detonated. A wrong or missing password yields zero-byte stubs, which count as nothing extracted, and the container itself becomes the sample.
Conservative on purpose
A weak-but-real technique standing on its own is not treated as an answer; the module waits for the run or another layer to corroborate it before it says more. That is a deliberate trade against a verdict nobody can act on.

Where this module hands off

Neighbouring modules

A document that drops and launches a payload has told you what to look at next. The dropped file is carved from the guest's own disk overlay after the guest is gone and analysed in its own right by the file module, which is also where a submission refused by this form should go when its header turns out to be an executable. A macro that assembles a command line is often easier to read as a command than as a macro, and the command module deobfuscates one locally before detonating it as a script. Where the interesting question is which office build a document triggers on, a OneShot run puts one sample on several images at once and gives the screen back from each.

The boundary underneath all of it does not move for documents. The sample stays on this analysis host, and what travels outward is hashes and derived indicators. The AI layer is fed through a copy allowlist that excludes the macro source. The whole boundary is written out on the security page, and the retention and deletion side of it on the privacy page.

Sign in

Sign in

The analyst console and your scan history. Private scans and the API come with a paid plan.

or
Continue with Google

New team? Create a free account

Sign up

Create your account

Free tier: 20 scans a month, three sandbox images, reports public. No card required.

12 characters minimum

or
Continue with Google

By creating an account you accept the terms and privacy policy.

Already provisioned? Sign in