elastic / elastic/detection-rules
[Rule Tuning] Web Shell Detection: Script Process Child of Common Web Processes (2917d495-59bd-4250-b395-c29409b76086)
- Dominant language
- Python
- Stars
- 2.7k
- Forks
- 696
- Avg merge
- 4d 17h
- Merged PRs (30d)
- 87
Description
## Rule Tuning Analysis
**Rule ID:** `2917d495-59bd-4250-b395-c29409b76086`
**Rule Name:** Web Shell Detection: Script Process Child of Common Web Processes
**Rule Type:** new_terms
---
### Classification
| Metric | Value |
|--------|-------|
| **Category** | NOISY_PERFORMANT |
| **Priority** | MEDIUM |
| **Tuning Score** | 60.89 |
| **Version Status** | ✅ Established (4 release cycles) |
---
### Alert Telemetry
| Metric | Value |
|--------|-------|
| Total Alerts (3d) | 23,275 |
| Unique Clusters | 12 |
| Cluster Coverage | 0.4% |
| Daily Average | 7758 |
| Days Active | 3 |
| Coefficient of Variation | 0.48 (MODERATE) |
---
### Analysis Flags
- 🔴 Noisy on Latest Version: ✅ Yes
- 🔴 Widespread False Positive: ❌ No
- ⚠️ Version Regression: ❌ No
- ⚠️ Stale and Noisy: ❌ No
- ⚠️ Low Version / High Volume: ❌ No
- ℹ️ Low Activity: ❌ No
---
### Recommendation
**Action:** Add bounded `and not (...)` KQL clauses for the observed XMLPDF, EventSoft pcron, and Avanti bulk-load command lines instead of excluding PHP or command shells generically.
**Rationale:** This rule is noisy because it broadly matches `cmd.exe` and other script hosts spawned by `php.exe`/`php-cgi.exe`, while the rule is also configured as `new_terms` on raw `process.command_line`. In the sample alerts, all observed hits are consistent with legitimate web-application automation—PDF generation, PHP cron execution, and SQL bulk import—where temp file names, timestamps, and daily paths make each run look "new." The safest tuning path is to add tightly bounded KQL exclusions for the exact parent/child/command patterns seen in the evidence, not to exclude `php.exe`, `php-cgi.exe`, or `cmd.exe` globally.
#### Query Modifications
**The exclusion block does not cover the specific benign PHP-driven document-processing, cron, and import workflows shown in the samples.** *(Impact: accuracy)*
**Current:**
```sql
host.os.type:windows and event.category:process and event.type:start and process.args : * and process.parent.name:("w3wp.exe" or "httpd.exe" or "nginx.exe" or "php.exe" or "php-cgi.exe" or "tomcat.exe" or "ArcSOC.exe") and ( process.name : ("cmd.exe" or "cscript.exe" or "powershell.exe" or "pwsh.exe" or "powershell_ise.exe" or "wmic.exe" or "wscript.exe") or process.name.caseless : ("cmd.exe" or "cscript.exe" or "powershell.exe" or "pwsh.exe" or "powershell_ise.exe" or "wmic.exe" or "wscript.exe") ) and not ( ...existing exclusions... )
```
**Modify →**
```sql
Add the following inside the existing `not ( ... )` block as additional `or` clauses:
`(process.parent.executable : "C:\\Program Files (x86)\\PHP\\php_7_2\\php-cgi.exe" and process.name : "cmd.exe" and (process.command_line : "*pdftk*fill_form*drop_xfa*need_appearances*flatten*" or process.command_line : "*java -jar E:\\XMLPDF\\resources\\java\\PDFEstampado.jar*")) or
(process.parent.name : "php.exe" and process.name : "cmd.exe" and process.command_line : "*D:\\EventSoft\\apache2\\htdocs\\intra-test\\pcron\\index.php*" and process.command_line : "*--mode=execute*" and process.command_line : "*--cron-id=*" and process.command_line : "*--started-at=*" and process.command_line : "*\\pcron\\cronjobs\\*.log 2>&1*") or
(process.parent.command_line : "*db-load_avanti_daily_file*loadAvantiDb*" and process.name : "cmd.exe" and process.command_line : "*bcp AvantiContinental.dbo.* IN e:\\AvantiDb\\archive\\* -c -S localhost -T -E -h TABLOCK*")`
```
> These clauses are directly derived from Events 1-5 and keep the exclusion narrowly scoped to parent identity plus exact command intent. They reduce false positives without suppressing generic `php.exe`/`php-cgi.exe` shell spawns that are more consistent with web-shell activity.
**`new_terms` on raw `process.command_line` amplifies recurring benign jobs because timestamps, temp files, and dated paths make each execution unique.** *(Impact: both)*
**Current:**
```sql
[rule.new_terms]
field = "new_terms_fields"
value = ["host.id", "process.command_line"]
```
**Modify →**
```sql
Test a safer, more stable `new_terms` key only after the bounded KQL exclusions above are validated, for example:
`value = ["host.id", "process.parent.executable", "process.executable"]`
```
> Events 1-5 all contain highly variable command-line content (`php*.tmp.xfdf`, `tmp*.pdf`, `--started-at=*`, dated archive folders). That means the same benign workflow will repeatedly produce new terms. This change has more detection-gap risk than the query exclusions, so it should be treated as a second-stage tuning option and validated carefully.
#### Exception Recommendations
**Add exception:** `process.command_line` wildcard `"*pdftk*fill_form*drop_xfa*need_appearances*flatten*"` *(Confidence: MEDIUM)*
> Evidence: Event 1 shows `php-cgi.exe` spawning `cmd.exe` to run `pdftk` for form filling under `E:\XMLPDF\storage\app\private\*`, writing temp files under `C:\Windows\Temp\*`. This appears application-document processing rather than web-shell activity. Do not exclude this pattern alone; add it as a bounded query clause: `and not (process.parent.executable : "C:\\Program Files (x86)\\PHP\\php_7_2\\php-cgi.exe" and process.name : "cmd.exe" and process.command_line : "*pdftk*fill_form*drop_xfa*need_appearances*flatten*")`.
**Modify →**
```sql
and process.command_line wildcard "*pdftk*fill_form*drop_xfa*need_appearances*flatten*"
```
**Add exception:** `process.command_line` wildcard `"*java -jar E:\XMLPDF\resources\java\PDFEstampado.jar*"` *(Confidence: MEDIUM)*
> Evidence: Event 2 shows the same `php-cgi.exe` parent and service account launching `cmd.exe /c` to run `PDFEstampado.jar` from `E:\XMLPDF\resources\java\`. The random PDF names in the command line will keep generating new terms. Add only as a bounded exclusion: `and not (process.parent.executable : "C:\\Program Files (x86)\\PHP\\php_7_2\\php-cgi.exe" and process.name : "cmd.exe" and process.command_line : "*java -jar E:\\XMLPDF\\resources\\java\\PDFEstampado.jar*")`.
**Modify →**
```sql
and process.command_line wildcard "*java -jar E:\XMLPDF\resources\java\PDFEstampado.jar*"
```
**Add exception:** `process.command_line` wildcard `"*D:\EventSoft\apache2\htdocs\intra-test\pcron\index.php*--mode=execute*--cron-id=*--started-at=*"` *(Confidence: MEDIUM)*
> Evidence: Events 3 and 4 show repeated `php.exe` -> `cmd.exe` executions of `D:\EventSoft\apache2\htdocs\intra-test\pcron\index.php` with dynamic `--cron-id` and `--started-at` values and log redirection into `...\pcron\cronjobs\*.log`. These are classic scheduled app-job parameters that will always look novel in a `new_terms` rule. Use a compound exclusion only: `and not (process.parent.name : "php.exe" and process.name : "cmd.exe" and process.command_line : "*D:\\EventSoft\\apache2\\htdocs\\intra-test\\pcron\\index.php*" and process.command_line : "*--mode=execute*" and process.command_line : "*--cron-id=*" and process.command_line : "*--started-at=*" and process.command_line : "*\\pcron\\cronjobs\\*.log 2>&1*")`.
**Modify →**
```sql
and process.command_line wildcard "*D:\EventSoft\apache2\htdocs\intra-test\pcron\index.php*--mode=execute*--cron-id=*--started-at=*"
```
**Add exception:** `process.command_line` wildcard `"*bcp AvantiContinental.dbo.* IN e:\AvantiDb\archive\* -c -S localhost -T -E -h TABLOCK*"` *(Confidence: LOW)*
> Evidence: Event 5 shows `php.exe` launching `cmd.exe` to run a local SQL `bcp` import from `e:\AvantiDb\archive\*` as part of `db-load_avanti_daily_file`. This looks like a scheduled data-load workflow, but only one sample was provided, so confidence is lower. If validated, add the exclusion with parent context: `and not (process.parent.command_line : "*db-load_avanti_daily_file*loadAvantiDb*" and process.name : "cmd.exe" and process.command_line : "*bcp AvantiContinental.dbo.* IN e:\\AvantiDb\\archive\\* -c -S localhost -T -E -h TABLOCK*")`.
**Modify →**
```sql
and process.command_line wildcard "*bcp AvantiContinental.dbo.* IN e:\AvantiDb\archive\* -c -S localhost -T -E -h TABLOCK*"
```
#### Field-Level Recommendations
| Field | Value | Alert % | Cluster % | Confidence | Type |
|-------|-------|---------|-----------|------------|------|
| `process.command_line` | `*pdftk*fill_form*drop_xfa*need...` | 0.0% | 8.3% | MEDIUM | EXCEPTION |
| `process.command_line` | `*java -jar E:\XMLPDF\resources...` | 0.0% | 8.3% | MEDIUM | EXCEPTION |
| `process.command_line` | `*D:\EventSoft\apache2\htdocs\i...` | 0.0% | 8.3% | MEDIUM | EXCEPTION |
| `process.command_line` | `*bcp AvantiContinental.dbo.* I...` | 0.0% | 8.3% | LOW | EXCEPTION |
---
*This issue was generated by the GenAI Tradecraft Rule Tuning Advisor.*
*Analysis timestamp: 2026-07-02T07:14:09.214629*
Contributor guide
Assessment
This issue has not been assessed yet.