Web Server Spawning Unexpected Shell Processes — Basic Detection
Basic detection of web server RCE exploitation patterns: any application runtime (Node.js, Python, PHP, Ruby, Java) spawning OS shells or recon utilities such as bash, curl, wget, or whoami — the foundational indicator behind CVE-2025-55182 (React2Shell).
EDRrceweb-serverreact2shellcve-2025-55182process-spawnT1190T1059.004
FDR Beginnerby darkreitor 3 min read
Query
// ──────────────────────────────────────────────────────────
// Web Server Anomalous Child Process Detection — Beginner Tier
//
// Simplified detection for the React2Shell (CVE-2025-55182)
// exploitation pattern and similar RCE vulnerabilities:
// any web/app server runtime spawning OS shells or recon tools
//
// Web servers NEVER legitimately spawn bash, sh, id, whoami,
// nc, or wget during normal operation. Any match = investigate.
// ──────────────────────────────────────────────────────────
#event_simpleName=ProcessRollup2
// Not platform-restricted: Node.js runs on Linux AND macOS
// Python, PHP, Ruby web servers appear across all three platforms
// Stage 1: Filter by parent process — known web/app server runtimes
// ParentBaseFileName contains only the binary name, not full path
| ParentBaseFileName=/^(node|python3?|uvicorn|gunicorn|php|php-fpm|apache2|httpd|nginx|ruby|java|catalina\.sh|jetty)$/i
// Stage 2: Filter child process — OS utilities that indicate RCE
// Shells provide interactive access; curl/wget download next-stage payloads
// id/whoami/uname are the first recon commands after gaining shell access
| FileName=/^(bash|sh|dash|zsh|ksh|curl|wget|nc|ncat|python3?|id|whoami|uname|hostname|chmod|perl)$/i
// Raw event output — every event warrants immediate investigation
// CommandLine provides the full argument string for analyst context
| table([@timestamp, ComputerName, event_platform, ParentBaseFileName, FileName, CommandLine])
| sort(@timestamp, order=desc)
| head(500)Explanation
| Pipe | Descripción | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
#event_simpleName=ProcessRollup2 (no platform filter) | Intentionally omits event_platform filter — Node.js (React2Shell target) runs on Linux, macOS, and Windows. Keeping it broad ensures coverage across heterogeneous server fleets. | |||||||||||
| `\ | ParentBaseFileName=/^(node\ | python3?\ | uvicorn\ | gunicorn\ | php\ | apache2\ | ruby\ | java\ | ...)$/i` | The detection pivot: restricts parent to known web application runtimes. ParentBaseFileName contains only the executable name (no path), making it consistent across deployment environments. | ||
| `\ | FileName=/^(bash\ | sh\ | dash\ | zsh\ | curl\ | wget\ | nc\ | id\ | whoami\ | uname\ | ...)$/i` | Filters child process to OS-level utilities with no legitimate place in web server subprocess trees. bash/sh = interactive shell access; id/whoami = post-exploitation recon; curl/wget = payload download. |
| `\ | table([@timestamp, ComputerName, event_platform, ParentBaseFileName, FileName, CommandLine])` | Raw event table — no aggregation. Including event_platform lets analysts quickly distinguish Linux servers from macOS build machines. CommandLine exposes the full argument string for triage. | ||||||||||
| `\ | sort(@timestamp, order=desc) \ | head(500)` | Most recent events first. In an active exploitation scenario (React2Shell), you may see rapid repeated spawns as the attacker stabilizes their foothold — head(500) captures the full burst. |
Adjustable Variables
ParentBaseFileName regex: add rails|puma|unicorn for Ruby on Rails servers, or dotnet for .NET Core web applications. Add ComputerName=<hostname> at the top to scope to a single suspected server during active incident response. Promote to intermediate by adding | groupBy([ComputerName, ParentBaseFileName, FileName], function=count(as=SpawnCount), limit=max) and filtering SpawnCount >= 3 to detect automated post-exploitation tool deployment.