elastic / elastic/detection-rules

[New hunt] Rare Child Process of a Web Server Process

Open
#6,597 1 comment 0 reactions 0 assignees View on GitHub
community
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.