elastic / elastic/detection-rules
[New hunt] Rare Child Process of a Web Server Process
- Dominant language
- Python
- Stars
- 2.7k
- Forks
- 696
- Avg merge
- 4d 17h
- Merged PRs (30d)
- 87
Description
## Description
Identifies rare child processes spawned by web server processes on Linux systems: a strong signal of webshell command execution following exploitation of a public-facing application. Unlike a file-creation-based webshell detection, this hunt looks at the *execution* side and scopes explicitly by parent process, surfacing command/process combinations rarely seen fleet-wide (aggregated by child process name, full command line, and parent process name; kept only when seen on ≤3 distinct hosts fleet-wide).
**Behavior-based**, anomaly/rarity-driven rather than a fixed indicator.
**Real testing performed**: stood up a real `nginx` + `php-fpm` stack with a genuine webshell, issued real `GET /shell.php?cmd=id` and `?cmd=whoami` requests. Confirmed the resulting real process chain via kernel-level process auditing: `php-fpm` (the real worker process, confirmed via `/proc//comm`) spawns `sh -c -- id` / `sh -c -- whoami` (this matches how PHP's `system()`/`exec()` actually forks, via `/bin/sh -c`, not a direct child execve of the target binary, which is why the hunt scopes on `process.parent.name` being the web server/PHP handler itself, one level up from the final command). This is real, observed process ancestry, not a hypothesized chain.
## Target Huntset
linux
## Target hunt Type
ES|QL
## Query
```esql
FROM logs-endpoint.events.process-*
| WHERE @timestamp > NOW() - 7 day AND host.os.type == "linux" AND event.type == "start"
AND process.parent.name IN ("nginx", "apache2", "httpd", "php-fpm", "php-cgi", "lsphp", "caddy", "litespeed")
| STATS cc = COUNT(), hosts = COUNT_DISTINCT(agent.id) BY process.name, process.command_line, process.parent.name
| WHERE hosts <= 3
| SORT cc ASC
| LIMIT 100
```
## Related issues or PRs
None yet. Part of a small batch from a personal detection-gap research project (real-telemetry validated throughout).
## References
- https://attack.mitre.org/techniques/T1505/003/
- https://attack.mitre.org/techniques/T1190/
## Redacted Example Data
Real captured process chain (reshaped from real kernel-level process auditing into ECS process-event shape, since Elastic Defend's own eBPF sensor isn't available on the test host's kernel, noted transparently):
```json
{
"event": { "category": ["process"], "type": ["start"] },
"process": {
"name": "sh",
"command_line": "sh -c -- id",
"parent": { "name": "php-fpm" }
},
"host": { "os": { "type": "linux" } }
}
```
```json
{
"event": { "category": ["process"], "type": ["start"] },
"process": {
"name": "sh",
"command_line": "sh -c -- whoami",
"parent": { "name": "php-fpm" }
},
"host": { "os": { "type": "linux" } }
}
```
Known false-positive class (documented in the hunt's own notes): cron- or deploy-tooling-driven child processes that legitimately run from a web server process on a handful of hosts. Verify against known maintenance scripts before escalating.
Contributor guide
Research direction
Start with the ES|QL query in the issue and compare its filters and aggregation with the redacted php-fpm process examples. Done means the Linux hunt identifies rare child processes under the listed web-server parents while accounting for the documented cron or deployment-tooling false-positive class.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elasticsearch, linux
- Domain
- security
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 57/100