Web server worker writes a server-side script into a web root
AN1108 has two halves — an unexpected file appearing in a web directory, and the server worker later spawning a shell — and this rule takes the first. The second is already published in this corpus as the T1505 parent's rule, which matches w3wp.exe, php-cgi.exe, httpd.exe, nginx.exe and sqlservr.exe spawning an interpreter and whose own description says it "sees the payoff and never the plant". This rule is the plant, so the two are complementary rather than duplicates. It requires all three of: a Sysmon EventID 11 file-create whose creating process is a web server worker, a target path inside a web directory, and a server-side script extension. The creator gate is what makes the rule worth running — a release pipeline, an administrator copying files or a package installer writes into the same directories with the same extensions, and none of them is w3wp.exe or php-cgi.exe, whereas an exploited web application writing its own backdoor is the worker process itself, which is the shape ProxyLogon-class web shell drops take. The path list is MITRE's `WebRootPath` knob, populated here with the default IIS layout plus the htdocs/httpdocs/public_html/webapps conventions third-party stacks use; the extension list and the process list are authored, not sourced from MITRE, whose `ParentProcess` knob describes the process-creation leg rather than this one. Three limits are structural, and the first is the one that decides whether this rule ever fires. Sysmon's own sample configurations filter FileCreate hard — the widely used ones include only a handful of extensions and directories — so on a stock deployment this rule returns zero rows not because nothing was dropped but because the event was never generated; the config must include FileCreate for the web roots and script extensions below before the rule means anything, and zero rows reads as quiet when it actually means blind. Second, the rule only sees shells the web server itself wrote: a shell copied in over SMB, unpacked by an installer, or written by an out-of-process ASP.NET Core application (the writer there is dotnet.exe or the application's own binary, neither of which is matched) is invisible here. Third, a JSP shell dropped through a servlet container is written by java.exe rather than by the tomcat9.exe service wrapper, and java.exe is deliberately left out of the creator list because it would match every build, IDE and CI job on the estate — so the Java arm of this technique is uncovered. What is not attempted: the analytic's Security 4624/4648 log source, because a logon record carries no file path and no process lineage and cannot express a web shell at all; MITRE's `PayloadEntropyThreshold` and `TimeWindow` knobs, which are a content measure and a cross-event correlation that lib/sigma models neither of; and the Linux and macOS analytics — AN1109's process leg (apache2 or nginx spawning a shell) is already published as this corpus's T1059.004 rule, its file leg needs auditd watches on the web root that no distribution loads by default, and AN1110's macos/unifiedlog source has no field vocabulary in the brief, in lib/sigma or in Sigma's taxonomy. Vocabulary note: this rule is written in the Sysmon EventID 11 names `Image` and `TargetFilename` that the brief's `file_event` logsource implies. An estate feeding the same category from Security 4663 instead has `ProcessName` and `ObjectName` and needs a field mapping before any of this matches — configuring *Audit Object Access* and a SACL without that mapping buys nothing here. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0394, 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
Sentinel · KQL
Run this as a search.
DeviceFileEvents| where ((InitiatingProcessFolderPath endswith "\\w3wp.exe" or InitiatingProcessFolderPath endswith "\\php-cgi.exe" or InitiatingProcessFolderPath endswith "\\php.exe" or InitiatingProcessFolderPath endswith "\\httpd.exe" or InitiatingProcessFolderPath endswith "\\nginx.exe") and (FolderPath contains "\\inetpub\\" or FolderPath contains "\\wwwroot\\" or FolderPath contains "\\htdocs\\" or FolderPath contains "\\httpdocs\\" or FolderPath contains "\\public_html\\" or FolderPath contains "\\webapps\\" or FolderPath contains "\\www\\") and (FolderPath endswith ".asp" or FolderPath endswith ".aspx" or FolderPath endswith ".ashx" or FolderPath endswith ".asmx" or FolderPath endswith ".asax" or FolderPath endswith ".cshtml" or FolderPath endswith ".vbhtml" or FolderPath endswith ".php" or FolderPath endswith ".php3" or FolderPath endswith ".php4" or FolderPath endswith ".php5" or FolderPath endswith ".php7" or FolderPath endswith ".phtml" or FolderPath endswith ".jsp" or FolderPath endswith ".jspx" or FolderPath endswith ".jspf" or FolderPath endswith ".cfm" or FolderPath endswith ".cfml"))
Splunk · SPL
Run this as a search.
index=* ((Image="*\\w3wp.exe" OR Image="*\\php-cgi.exe" OR Image="*\\php.exe" OR Image="*\\httpd.exe" OR Image="*\\nginx.exe") AND (TargetFilename="*\\inetpub\\*" OR TargetFilename="*\\wwwroot\\*" OR TargetFilename="*\\htdocs\\*" OR TargetFilename="*\\httpdocs\\*" OR TargetFilename="*\\public_html\\*" OR TargetFilename="*\\webapps\\*" OR TargetFilename="*\\www\\*") AND (TargetFilename="*.asp" OR TargetFilename="*.aspx" OR TargetFilename="*.ashx" OR TargetFilename="*.asmx" OR TargetFilename="*.asax" OR TargetFilename="*.cshtml" OR TargetFilename="*.vbhtml" OR TargetFilename="*.php" OR TargetFilename="*.php3" OR TargetFilename="*.php4" OR TargetFilename="*.php5" OR TargetFilename="*.php7" OR TargetFilename="*.phtml" OR TargetFilename="*.jsp" OR TargetFilename="*.jspx" OR TargetFilename="*.jspf" OR TargetFilename="*.cfm" OR TargetFilename="*.cfml"))Elastic · ES|QL
Run this as a search.
FROM logs-*| WHERE ((TO_LOWER(process.executable) LIKE "*\\\\w3wp.exe" OR TO_LOWER(process.executable) LIKE "*\\\\php-cgi.exe" OR TO_LOWER(process.executable) LIKE "*\\\\php.exe" OR TO_LOWER(process.executable) LIKE "*\\\\httpd.exe" OR TO_LOWER(process.executable) LIKE "*\\\\nginx.exe") AND (TO_LOWER(file.path) LIKE "*\\\\inetpub\\\\*" OR TO_LOWER(file.path) LIKE "*\\\\wwwroot\\\\*" OR TO_LOWER(file.path) LIKE "*\\\\htdocs\\\\*" OR TO_LOWER(file.path) LIKE "*\\\\httpdocs\\\\*" OR TO_LOWER(file.path) LIKE "*\\\\public_html\\\\*" OR TO_LOWER(file.path) LIKE "*\\\\webapps\\\\*" OR TO_LOWER(file.path) LIKE "*\\\\www\\\\*") AND (TO_LOWER(file.path) LIKE "*.asp" OR TO_LOWER(file.path) LIKE "*.aspx" OR TO_LOWER(file.path) LIKE "*.ashx" OR TO_LOWER(file.path) LIKE "*.asmx" OR TO_LOWER(file.path) LIKE "*.asax" OR TO_LOWER(file.path) LIKE "*.cshtml" OR TO_LOWER(file.path) LIKE "*.vbhtml" OR TO_LOWER(file.path) LIKE "*.php" OR TO_LOWER(file.path) LIKE "*.php3" OR TO_LOWER(file.path) LIKE "*.php4" OR TO_LOWER(file.path) LIKE "*.php5" OR TO_LOWER(file.path) LIKE "*.php7" OR TO_LOWER(file.path) LIKE "*.phtml" OR TO_LOWER(file.path) LIKE "*.jsp" OR TO_LOWER(file.path) LIKE "*.jspx" OR TO_LOWER(file.path) LIKE "*.jspf" OR TO_LOWER(file.path) LIKE "*.cfm" OR TO_LOWER(file.path) LIKE "*.cfml"))
Wazuh · XML rule
Deploy to your manager — this is a rule, not a search.
<group name="sigma,windows,file_event,"> <!-- Rule ids must be unique on your manager; 100000+ is the user range. --> <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)(\\w3wp\.exe$|\\php-cgi\.exe$|\\php\.exe$|\\httpd\.exe$|\\nginx\.exe$)</field> <field name="TargetFilename" type="pcre2">(?i)(\\inetpub\\|\\wwwroot\\|\\htdocs\\|\\httpdocs\\|\\public_html\\|\\webapps\\|\\www\\)</field> <field name="TargetFilename" type="pcre2">(?i)(\.asp$|\.aspx$|\.ashx$|\.asmx$|\.asax$|\.cshtml$|\.vbhtml$|\.php$|\.php3$|\.php4$|\.php5$|\.php7$|\.phtml$|\.jsp$|\.jspx$|\.jspf$|\.cfm$|\.cfml$)</field> <description>Web server worker writes a server-side script into a web root</description> <mitre> <id>T1505.003</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.