| ID | Technique | Tactic |
|---|---|---|
| T1190 | Exploit Public-Facing Application | Initial Access |
Detection: Linux Auditd Web or Application Server Spawning a Shell
Description
The following analytic detects instances where Java, web server, or application server processes attempts to spawn a Linux shell, which may indicate exploitation attempts. This detection leverages Endpoint Detection and Response (EDR) telemetry, focusing on process names and parent-child process relationships. This activity may indicate a compromised service leading to unauthorized shell access. If confirmed malicious, attackers could execute commands, escalate privileges, or maintain persistent access.
Search
1`linux_auditd`
2type=SYSCALL
3comm IN (
4 "apache*",
5 "bash",
6 "caddy",
7 "csh",
8 "dash",
9 "eshell",
10 "fish",
11 "httpd",
12 "ion",
13 "java",
14 "ksh",
15 "lighttpd",
16 "nginx",
17 "php*",
18 "rbash",
19 "sh",
20 "tcsh",
21 "tomcat*",
22 "zsh"
23)
24
25
26| eval web_process=if(match(comm, "^(apache.*
27|caddy
28|httpd
29|java
30|lighttpd
31|nginx
32|php.*
33|tomcat.*)$"),exe,null())
34
35| eval shell_process=if(match(comm, "^(sh
36|ksh
37|zsh
38|bash
39|dash
40|rbash
41|fish
42|csh
43|tcsh
44|ion
45|eshell)$"),exe,null())
46
47
48| eval web_process_name=if(match(comm, "^(apache.*
49|caddy
50|httpd
51|java
52|lighttpd
53|nginx
54|php.*
55|tomcat.*)$"),comm,null())
56
57| eval shell_process_name=if(match(comm, "^(sh
58|ksh
59|zsh
60|bash
61|dash
62|rbash
63|fish
64|csh
65|tcsh
66|ion
67|eshell)$"),comm,null())
68
69
70| eval web_pid=if(match(comm, "^(apache.*
71|caddy
72|httpd
73|java
74|lighttpd
75|nginx
76|php.*
77|tomcat.*)$"),pid,null())
78
79| eval shell_ppid=if(match(comm, "^(sh
80|ksh
81|zsh
82|bash
83|dash
84|rbash
85|fish
86|csh
87|tcsh
88|ion
89|eshell)$"),ppid,null())
90
91| eval shell_pid=if(match(comm, "^(sh
92|ksh
93|zsh
94|bash
95|dash
96|rbash
97|fish
98|csh
99|tcsh
100|ion
101|eshell)$"),pid,null())
102
103| eval parent_pid=coalesce(web_pid, shell_ppid)
104
105
106| stats count min(_time) as firstTime last(_time) as lastTime
107 values(web_process_name) as parent_process_name
108 values(web_process) as parent_process
109 values(shell_pid) as pid
110 values(shell_process_name) as process_name
111 values(shell_process) as process
112 by host parent_pid
113
114
115| rename host as dest
116
117
118| where isnotnull(parent_process) AND isnotnull(process)
119
120| `security_content_ctime(firstTime)`
121
122| `security_content_ctime(lastTime)`
123
124| `linux_auditd_web_or_application_server_spawning_a_shell_filter`
Data Source
| Name | Platform | Sourcetype | Source |
|---|---|---|---|
| Linux Auditd Syscall | 'auditd' |
'auditd' |
Macros Used
| Name | Value |
|---|---|
| linux_auditd | sourcetype="auditd" |
| linux_auditd_web_or_application_server_spawning_a_shell_filter | search * |
linux_auditd_web_or_application_server_spawning_a_shell_filter is an empty macro by default. It allows the user to filter out any results (false positives) without editing the SPL.
Annotations
Default Configuration
This detection is configured by default in Splunk Enterprise Security to run with the following settings:
| Setting | Value |
|---|---|
| Disabled | true |
| Cron Schedule | 0 * * * * |
| Earliest Time | -70m@m |
| Latest Time | -10m@m |
| Schedule Window | auto |
| Creates Finding (Notable) | Yes |
| Rule Title | %name% |
| Rule Description | %description% |
| Notable Event Fields | user, dest |
| Creates Intermediate Finding (Risk Event) | No |
Implementation
To implement this detection, the process begins by ingesting auditd data, that consists of SYSCALL, TYPE, EXECVE and
PROCTITLE events, which captures command-line executions and process details on Unix/Linux systems. These logs should
be ingested and processed using Splunk Add-on for Unix and Linux (https://splunkbase.splunk.com/app/833), which is
essential for correctly parsing and categorizing the data. The next step involves normalizing the field names to match
the field names set by the Splunk Common Information Model (CIM) to ensure consistency across different data sources
and enhance the efficiency of data modeling. This approach enables effective monitoring and detection of Linux endpoints
where auditd is deployed. Importantly, auditd must also be configured with syscall rules that target the web server
executable (for example, -a always,exit -F arch=b64 -F exe=/usr/sbin/apache2 -S execve -S execveat -k apache_syscall,
repeated for arch=b32). Web server workers typically run as a service account with auid=unset, so human-session rules
in a base ruleset do not cover them, and without such rules the web server's syscalls will not be captured and this
detection will not fire. Adjust the exe path for your web server (e.g., nginx, httpd, or java).
Known False Positives
Filtering may be required on internal developer build systems or classify assets as web facing and restrict the analytic based on asset type.
Associated Analytic Story
Finding
| Title | Entity Field | Entity Type | Risk Score |
|---|---|---|---|
| A Linux web or application server process [$parent_process_name$] spawned shell [$process_name$] on endpoint [$dest$]. | dest | system | 50 |
Threat Objects
| Field | Type |
|---|---|
| process_name | process_name |
| parent_process_name | parent_process_name |
References
-
https://github.com/0x4D31/honeypot-data/blob/main/reports/php2shell/2026-10-24-confirmed-rce.md
-
https://hunt.io/blog/php2shell-honeypot-shells-root-palo-alto-firewalls
Detection Testing
| Test Type | Status | Dataset | Source | Sourcetype |
|---|---|---|---|---|
| Validation | ✅ Passing | N/A | N/A | N/A |
| Unit | ✅ Passing | Dataset | auditd |
auditd |
| Integration | ✅ Passing | Dataset | auditd |
auditd |
Replay any dataset to Splunk Enterprise by using our replay.py tool or the UI.
Alternatively you can replay a dataset into a Splunk Attack Range
Source: GitHub |
Version: 1