Skip to content

Process-tree detection: w3wp, httpd or java spawning shells

Detect web shell activity from process telemetry: suspicious children of IIS, Apache, nginx/PHP-FPM and Java servers, with Sysmon, Event 4688, auditd, KQL and Sigma examples.

Published on 4 min read

A web shell's file can be obfuscated, renamed and timestomped. Its traffic can be encrypted. But when the operator wants to do something — list users, dump credentials, compress data — the web server process has to start a child process. That parent-child relationship is one of the most robust, family-agnostic web shell detections available.

The pattern

Web server worker processes should run application code, not command interpreters. When they spawn shells and reconnaissance utilities, something is executing commands through the web tier.

PlatformWorker (parent) processSuspicious children
IIS / ASP.NETw3wp.execmd.exe, powershell.exe, pwsh.exe, whoami.exe, net.exe, net1.exe, nltest.exe, ipconfig.exe, systeminfo.exe, certutil.exe, bitsadmin.exe, rundll32.exe, reg.exe, tasklist.exe, quser.exe, wmic.exe
Exchangew3wp.exe (MSExchange* app pools), UMWorkerProcess.exeSame as above; plus unexpected writes to webroots
Apache (prefork / mod_php)httpd, apache2sh, bash, dash, id, uname, whoami, curl, wget, nc, python*, perl
nginx + PHP-FPMphp-fpm* (nginx itself does not execute PHP)Same as above
Tomcat / Javajava (Tomcat, JBoss/WildFly, WebLogic, WebSphere)sh, bash, cmd.exe, powershell.exe
Node.jsnodesh, bash, cmd.exe
Python (gunicorn/uwsgi)gunicorn, uwsgi, python*sh, bash

Reconnaissance commands are the highest-signal children: an operator's first actions on a new shell are nearly always identity and environment discovery (whoami, hostname, ipconfig /all, net group "domain admins" /domain).

Getting the telemetry

Windows

  • Sysmon Event ID 1 (ProcessCreate) records Image, CommandLine, ParentImage, ParentCommandLine, user, hashes and a process GUID linking parent and child.
  • Security Event 4688 (Audit Process Creation) plus the policy Include command line in process creation events provides the same core data without Sysmon.
  • EDR products record full process trees and usually ship built-in web shell analytics.

The IIS app pool name appears in the worker's command line (w3wp.exe -ap "DefaultAppPool" ...), which tells you which site spawned the child.

Linux

  • auditd with an execve rule for the web server's UID captures every program it launches:
# /etc/audit/rules.d/60-web-exec.rules — replace 33 with your web server UID (id -u www-data)
-a always,exit -F arch=b64 -S execve -F uid=33 -k web_exec
-a always,exit -F arch=b32 -S execve -F uid=33 -k web_exec

Review with ausearch -k web_exec -i. Any execve by the web user that is not part of a known allow-list is a lead.

  • eBPF-based sensors (Falco, Tetragon, EDR agents) provide richer, lower-overhead process lineage and are well suited to containers.

Detection queries

Microsoft Defender XDR / Sentinel (KQL)

let webParents = dynamic(["w3wp.exe","httpd.exe","tomcat.exe","tomcat9.exe","java.exe","php-cgi.exe","UMWorkerProcess.exe","node.exe"]);
let suspicious = dynamic(["cmd.exe","powershell.exe","pwsh.exe","whoami.exe","net.exe","net1.exe","nltest.exe",
                          "ipconfig.exe","systeminfo.exe","certutil.exe","bitsadmin.exe","reg.exe","wmic.exe",
                          "tasklist.exe","quser.exe","rundll32.exe","mshta.exe"]);
DeviceProcessEvents
| where Timestamp > ago(14d)
| where InitiatingProcessFileName in~ (webParents)
| where FileName in~ (suspicious)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName,
          InitiatingProcessCommandLine, FileName, ProcessCommandLine
| order by Timestamp desc

Splunk (Sysmon)

index=sysmon EventCode=1
  (ParentImage="*\\w3wp.exe" OR ParentImage="*\\httpd.exe" OR ParentImage="*\\java.exe" OR ParentImage="*\\php-cgi.exe")
  (Image="*\\cmd.exe" OR Image="*\\powershell.exe" OR Image="*\\whoami.exe" OR Image="*\\net.exe" OR Image="*\\nltest.exe")
| table _time host User ParentImage ParentCommandLine Image CommandLine

Sigma (portable)

Sigma rules compile to most SIEM query languages. A compact rule for the Windows case:

title: Web Server Worker Spawning Shell or Recon Utility
id: 5b8f2a61-3c1e-4d7a-9b2e-6f0c1a9d4e21
status: experimental
description: Detects IIS, Tomcat, PHP-CGI or Exchange UM worker processes spawning command interpreters or discovery tools, a common web shell behaviour.
references:
  - https://attack.mitre.org/techniques/T1505/003/
author: WebShells
date: 2026-09-24
tags:
  - attack.persistence
  - attack.t1505.003
logsource:
  category: process_creation
  product: windows
detection:
  parent:
    ParentImage|endswith:
      - '\w3wp.exe'
      - '\httpd.exe'
      - '\tomcat.exe'
      - '\java.exe'
      - '\php-cgi.exe'
      - '\UMWorkerProcess.exe'
  child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\whoami.exe'
      - '\net.exe'
      - '\net1.exe'
      - '\nltest.exe'
      - '\ipconfig.exe'
      - '\systeminfo.exe'
      - '\certutil.exe'
      - '\wmic.exe'
  condition: parent and child
falsepositives:
  - Applications that legitimately invoke system utilities (document converters, backup or reporting jobs)
level: high

The Linux equivalent uses logsource: {category: process_creation, product: linux} with ParentImage|endswith values such as /httpd, /apache2, /php-fpm, /java and Image|endswith values such as /sh, /bash, /id, /whoami, /uname. The public SigmaHQ repository contains maintained rules for both platforms; start there and tune.

Reading the command lines

Children tell you what the operator did. Typical sequences, which map neatly onto ATT&CK:

PhaseTypical command linesATT&CK
Discoverywhoami /all, hostname, ipconfig /all, systeminfo, net user, net group ... /domain, nltest /dclist:T1033, T1082, T1016, T1087
Credential accessDumping LSASS via rundll32 with comsvcs.dll, reg save HKLM\SAM, reading config files for connection stringsT1003
Staging / transfercertutil -urlcache, bitsadmin /transfer, curl, wget, PowerShell download cradlesT1105
CollectionArchivers (7z, rar, tar) creating files in web-accessible foldersT1560, T1074
PersistenceNew local accounts, scheduled tasks, additional web shell filesT1136, T1053, T1505.003

When a command writes an archive into the webroot and the next log entry is a GET for that archive, you have evidence of exfiltration through the web server — correlate with log analysis.

Tuning without blinding yourself

  1. Baseline per application pool / service. Record which child processes and command lines each app legitimately uses (for example a PDF renderer). Allow-list by full command line pattern and parent app pool, not by image name alone.
  2. Never allow-list cmd.exe or sh wholesale. Allow the specific invocation.
  3. Weight recon utilities higher than generic interpreters — whoami from w3wp is rarely benign.
  4. Correlate with file events. A child process shortly after a new executable file appears in the webroot is a near-certain true positive.

Beyond parent-child: other process signals

  • Unusual modules loaded by the worker — unsigned DLLs in w3wp.exe, native IIS modules registered recently (appcmd list modules), unfamiliar Java agents or filters.
  • Network connections from the worker to internal hosts on SMB, RDP, WinRM, LDAP or database ports it does not normally use — a sign of tunnelling through the shell.
  • Worker process identity changes — application pools switched to LocalSystem or new service accounts.
  • Prevention as detection — application control (WDAC/AppLocker on Windows, SELinux/AppArmor confinement on Linux) can block worker processes from launching interpreters; the resulting block events are high-fidelity alerts. See eradication and hardening.

Related guides

Indicators & detection

YARA and Sigma rules for web shell detection

Write, test and tune YARA rules for suspicious server-side scripts and Sigma rules for web shell behaviour in logs and process telemetry — with annotated examples and a false-positive strategy.