← Rule library
critical SPL Windows / Linux
Web Server Process Spawning a Shell
The post-exploitation tell. A web server should never parent a shell; when it does, the exploit already worked and you are looking at what came next.
Rule source
# Web Server Spawning a Shell Process
# T1190 - Exploit Public-Facing Application
# The post-exploitation tell. A web server process should never be the parent
# of a shell; when it is, the exploit already succeeded.
index=sysmon EventCode=1
| search parent_process_name IN (
"w3wp.exe", "httpd", "httpd.exe", "nginx", "java", "tomcat*",
"php-fpm", "node")
| search process_name IN (
"cmd.exe", "powershell.exe", "pwsh.exe", "sh", "bash", "dash",
"whoami.exe", "whoami", "net.exe", "curl", "wget", "certutil.exe")
| eval risk=case(
process_name IN ("powershell.exe", "pwsh.exe", "certutil.exe"), "high",
process_name IN ("whoami", "whoami.exe"), "high",
true(), "medium")
| stats
count as executions,
values(process_name) as children,
values(CommandLine) as command_lines,
min(_time) as first_seen
by Computer, parent_process_name, user, risk
| convert ctime(first_seen)
| sort - executions Required telemetry
Sysmon - Event ID 1, auditd execve on Linux
Confirm this source is arriving before you judge the rule. A detection built on telemetry you do not collect looks identical to one that simply never fires.
Known false positives
- Application health checks that shell out - allowlist the exact command line
- CI agents running on the same host as a web server, which they should not be
Validation
Deployed a test webshell on a lab IIS and Tomcat host, confirmed both fire
Re-run quarterly. Rules decay because the environment moves underneath them - agent upgrades, schema changes and config edits all break detections silently.