XSL stylesheet transform executed via msxsl or wmic format switch
AN0581 covers proxy execution of embedded JScript/VBScript through XSL transforms and names two paths: the standalone msxsl.exe utility, and wmic.exe's built-in /format: switch pointed at an .xsl stylesheet — the Squiblytwo variant of the same abuse. msxsl.exe is not shipped with Windows at all, so its mere presence and execution is the whole signal; the selection gates on the binary name alone. wmic.exe does ship with Windows and has a legitimate output-formatting feature built on the same XSL engine, so that selection additionally requires the command line to reference both the /format switch and an .xsl target — narrowing to the abuse pattern rather than every wmic invocation. The brief's second log source, Sysmon EventID 7 module load of jscript.dll, is not used here. It would only strengthen this same detection by confirming the script engine actually loaded — a correlation between a process-creation event and a later module-load event in the same process, which lib/sigma has no join or timeframe to express. Taken alone, an image-load selection on jscript.dll would fire on ordinary Internet Explorer/WSH/HTA activity and add nothing MITRE's `TimeWindow` knob wasn't already describing as needing correlation. MITRE's `CommandLinePattern` knob is populated here only with the literal .xsl extension; an adversary renaming the stylesheet to .jpeg or another extension, as the knob's own description anticipates, defeats this rule entirely, and MITRE's `RemoteXSLDomainWhitelist` knob (filtering known-safe remote XSL URLs) is not implemented — this rule alerts on local and remote XSL targets alike. Prerequisite: this logic depends on Sysmon being deployed with EventID 1 enabled and command-line logging in the config, which is not a Windows default; without Sysmon this returns zero rows, and zero rows here means no sensor rather than no activity. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0205, not hand-written and not tested by its author. Any lab result is on this rule's own page.Full descriptionShow less
The detection
The 4 SIEM queries below are previews produced by Siemphony’s own translator, not pySigma, and none has been executed against a real backend — review before you deploy.
detection.yml
title: XSL stylesheet transform executed via msxsl or wmic format switchid: 159f32b6-fb61-44d1-9597-a39dfeac9cf3status: experimentaldescription: | AN0581 covers proxy execution of embedded JScript/VBScript through XSL transforms and names two paths: the standalone msxsl.exe utility, and wmic.exe's built-in /format: switch pointed at an .xsl stylesheet — the Squiblytwo variant of the same abuse. msxsl.exe is not shipped with Windows at all, so its mere presence and execution is the whole signal; the selection gates on the binary name alone. wmic.exe does ship with Windows and has a legitimate output-formatting feature built on the same XSL engine, so that selection additionally requires the command line to reference both the /format switch and an .xsl target — narrowing to the abuse pattern rather than every wmic invocation. The brief's second log source, Sysmon EventID 7 module load of jscript.dll, is not used here. It would only strengthen this same detection by confirming the script engine actually loaded — a correlation between a process-creation event and a later module-load event in the same process, which lib/sigma has no join or timeframe to express. Taken alone, an image-load selection on jscript.dll would fire on ordinary Internet Explorer/WSH/HTA activity and add nothing MITRE's `TimeWindow` knob wasn't already describing as needing correlation. MITRE's `CommandLinePattern` knob is populated here only with the literal .xsl extension; an adversary renaming the stylesheet to .jpeg or another extension, as the knob's own description anticipates, defeats this rule entirely, and MITRE's `RemoteXSLDomainWhitelist` knob (filtering known-safe remote XSL URLs) is not implemented — this rule alerts on local and remote XSL targets alike. Prerequisite: this logic depends on Sysmon being deployed with EventID 1 enabled and command-line logging in the config, which is not a Windows default; without Sysmon this returns zero rows, and zero rows here means no sensor rather than no activity. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0205, not hand-written and not tested by its author. Any lab result is on this rule's own page.references: - https://attack.mitre.org/techniques/T1220 - https://attack.mitre.org/detectionstrategies/DET0205author: Siemphony pipeline (machine-derived from MITRE ATT&CK v19.2)date: 2026-08-18tags: - attack.defense-evasion - attack.t1220logsource: category: process_creation product: windowsdetection: selection_msxsl: Image|endswith: '\msxsl.exe' selection_wmic_xsl: Image|endswith: '\wmic.exe' CommandLine|contains|all: - 'format' - '.xsl' condition: 1 of selection*falsepositives: - "Administrative or reporting scripts that use wmic's built-in HTML output formatters, such as `wmic process list /format:hform.xsl` or `/format:htable.xsl`, which are the shipped .xsl transforms under `%windir%\\System32\\wbem\\en-us` and are a real, if dated, scripting pattern in some estates." - "Legacy line-of-business software that bundles msxsl.exe as a redistributable to perform XML/XSLT transforms as part of report generation, data export or EDI processing — msxsl.exe was Microsoft's own recommended redistributable for this before .NET's XslCompiledTransform, and some older enterprise installers still carry it."level: mediumSentinel · KQL
Run this as a search.
DeviceProcessEvents| where (FolderPath endswith "\\msxsl.exe" or (FolderPath endswith "\\wmic.exe" and (ProcessCommandLine contains "format" and ProcessCommandLine contains ".xsl")))
Splunk · SPL
Run this as a search.
index=* (Image="*\\msxsl.exe" OR (Image="*\\wmic.exe" AND (CommandLine="*format*" AND CommandLine="*.xsl*")))Elastic · ES|QL
Run this as a search.
FROM logs-*| WHERE (TO_LOWER(process.executable) LIKE "*\\\\msxsl.exe" OR (TO_LOWER(process.executable) LIKE "*\\\\wmic.exe" AND (TO_LOWER(process.command_line) LIKE "*format*" AND TO_LOWER(process.command_line) LIKE "*.xsl*")))
Wazuh · XML rule
Deploy to your manager — this is a rule, not a search.
<group name="sigma,windows,process_creation,"> <!-- Rule ids must be unique on your manager; 100000+ is the user range. --> <!-- 2 rules: the Sigma condition ORs across different fields, which one rule cannot express. Any one matching is a hit. --> <rule id="100000" level="7"> <!-- Set <if_sid> to the decoder/base rule for windows so this only evaluates relevant events. --> <field name="Image" type="pcre2">(?i)\\msxsl\.exe$</field> <description>XSL stylesheet transform executed via msxsl or wmic format switch (1/2)</description> <mitre> <id>T1220</id> </mitre> </rule> <rule id="100001" level="7"> <!-- Set <if_sid> to the decoder/base rule for windows so this only evaluates relevant events. --> <field name="Image" type="pcre2">(?i)\\wmic\.exe$</field> <field name="CommandLine" type="pcre2">(?i)(?=.*(?:format))(?=.*(?:\.xsl)).*</field> <description>XSL stylesheet transform executed via msxsl or wmic format switch (2/2)</description> <mitre> <id>T1220</id> </mitre> </rule></group>
Verdicts · reactions · comments
Community
Verdicts from engineers who actually deployed it, and the conversation around it.
Nobody has run this in a real environment and said what happened.
Verdicts from engineers who deployed it
0 castNo verdicts reported yet. The first one is worth more than the tenth — say what you ran it against.
Log in to report a verdict.
Log in to join the discussion.
No comments yet. Someone who deploys this will have something to say about it.