Unusual Command Execution via Web Server

This rule leverages the "new_terms" rule type to detect unusual command executions originating from web server processes on Linux systems. Attackers may exploit web servers to maintain persistence on a compromised system, often resulting in atypical command executions. As command execution from web server parent processes is common, the "new_terms" rule type approach helps to identify deviations from normal behavior.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2025/12/02"
  3integration = ["endpoint"]
  4maturity = "production"
  5updated_date = "2026/06/01"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10This rule leverages the "new_terms" rule type to detect unusual command executions originating
 11from web server processes on Linux systems. Attackers may exploit web servers to maintain
 12persistence on a compromised system, often resulting in atypical command executions. As command
 13execution from web server parent processes is common, the "new_terms" rule type approach helps to
 14identify deviations from normal behavior.
 15"""
 16from = "now-9m"
 17index = ["logs-endpoint.events.process*"]
 18language = "kuery"
 19license = "Elastic License v2"
 20name = "Unusual Command Execution via Web Server"
 21note = """## Triage and analysis
 22
 23> **Disclaimer**:
 24> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
 25
 26### Investigating Unusual Command Execution via Web Server
 27
 28This rule detects shells invoked by web server processes on Linux to run one-off commands, surfacing command lines the server has never executed before. Attackers exploit vulnerable apps or dropped webshells to launch bash -c from web roots, e.g., download a payload with wget/curl into /opt or /tmp, chmod +x and execute it, or open a reverse shell (nc -e sh) to implant services or cron-like tasks and persist under the web server account.
 29
 30### Possible investigation steps
 31
 32- Reconstruct the process tree around the event to identify the shell payload and parent service, determine if it chains downloads, reverse shells, or archive extraction, and hash/snapshot any referenced files.
 33- Pivot to web server access and error logs at the timestamp to identify the request path, client IP, user agent, and HTTP verb that triggered execution, noting anomalies like POST uploads, long query strings, or 500s.
 34- List and diff newly created or recently modified files under common web roots and application directories around the event time, looking for webshells, chmod+x artifacts, .php/.jsp backdoors, or systemd/cron writes by the same user.
 35- Correlate with network telemetry to see if the web tier opened outbound connections or listeners (nc, bash -i, curl/wget), and capture any active sockets and destinations for rapid containment.
 36- Validate whether the command matches expected maintenance tasks for the application (e.g., wkhtmltopdf or image processing), and if not, isolate the process and host while scoping for the same pattern across other servers and preserving volatile evidence.
 37
 38### False positive analysis
 39
 40- A legitimate web-admin workflow (plugin/module install, content import, or cache warmup) spawns sh -c from an apache/nginx parent in /var/www to run tar/chmod/chown steps, producing a command line the host has not previously executed under www-data.
 41- A recently deployed application feature performs server-side document or image processing and rotates logs by calling sh -c from a framework parent (flask/rails/php) with a working directory in /opt or /usr/share/nginx, making the specific shell invocation a new term for this server.
 42
 43### Response and remediation
 44
 45- Quarantine the affected web server by removing it from the load balancer, stopping apache/nginx/httpd, and killing the spawned shell (e.g., bash -c) while capturing /proc/<pid>/cmdline and /proc/<pid>/environ, lsof, and active sockets for evidence.
 46- Block outbound egress from the web server account and immediately deny destinations contacted by curl/wget or reverse shells (nc, bash -i to /dev/tcp), and rotate exposed API keys or credentials referenced in the command line.
 47- Eradicate persistence by deleting newly dropped or modified files under /var/www, /usr/share/nginx, /srv/http, /opt, or /home/*/public_html (webshells, .php backdoors), removing downloaded binaries from /tmp or /opt, and cleaning cron/systemd units created by www-data/nginx.
 48- Recover by restoring web content and application code from known-good backups or images, verifying file ownership and permissions, and restarting the service with monitored command allowlists and file integrity checks.
 49- Escalate to full incident response and forensic imaging if any reverse shell artifacts (nc -e sh, bash -i >& /dev/tcp/*), privileged writes (/etc/systemd/system/*.service, /var/spool/cron/*), or sudo execution by the web server user are observed.
 50- Harden by disabling risky exec paths (PHP exec/system/shell_exec and unsafe plugins), enforcing noexec,nodev,nosuid mounts on web roots, applying SELinux/AppArmor confinement to web processes, narrowing outbound egress, and deploying WAF/mod_security rules for upload and RCE vectors.
 51"""
 52risk_score = 47
 53rule_id = "65f28c4d-cfc8-4847-9cca-f2fb1e319151"
 54severity = "medium"
 55tags = [
 56  "Domain: Endpoint",
 57  "Domain: Web",
 58  "OS: Linux",
 59  "Use Case: Threat Detection",
 60  "Tactic: Persistence",
 61  "Data Source: Elastic Defend",
 62  "Resources: Investigation Guide",
 63]
 64timestamp_override = "event.ingested"
 65type = "new_terms"
 66query = '''
 67event.category:process and host.os.type:linux and event.type:start and event.action:exec and (
 68  process.parent.name:(
 69    apache2 or asterisk or caddy or daphne or flask or frankenphp or httpd or httpd.worker or
 70    lswsctrl or mongrel_rails or nginx or php-cgi or php-cgi.cagefs or php-fcgi or starman or
 71    sw-engine-fpm or uvicorn or uwsgi or varnishd or waitress-serve or zabbix_server or *.cgi
 72    or *.fcgi or gunicorn* or php-fpm*
 73  ) or
 74  process.parent.name:ruby* and process.parent.command_line:(*passenger* or *puma* or *rails*) or
 75  process.parent.name:python* and process.parent.command_line:(
 76    *app.py* or *asgi.py* or *django* or *flask* or *hypercorn* or *server.py* or *uvicorn* or *wsgi.py*
 77  ) or
 78  process.parent.name:perl* and process.parent.command_line:*plackup* or
 79  process.parent.name:java and process.parent.args:(
 80    com.atlassian.jira.startup.Launcher or com.caucho.server.resin.Resin or com.google.gerrit.pgm.Daemon or
 81    com.ibm.ws.kernel.boot.cmdline.Bootstrap or com.ibm.ws.runtime.WsServer or
 82    com.sun.enterprise.glassfish.bootstrap.ASMain or io.dropwizard.cli.ServerCommand or
 83    io.helidon.microprofile.server.Main or io.micronaut.runtime.Micronaut or io.quarkus.runner.GeneratedMain or
 84    io.vertx.core.Launcher or org.apache.catalina.startup.Bootstrap or org.eclipse.jetty.start.Main or
 85    org.elasticsearch.bootstrap.Elasticsearch or org.jboss.modules.Main or play.core.server.ProdServerStart or
 86    weblogic.Server or *-Dsolr.solr.home=* or *BitbucketServerLauncher* or *jenkins.war* or *quarkus-run.jar* or
 87    *weblogic-launcher.jar* or -Dcatalina.base=* or -Djboss.home.dir=* or -Djetty.home=* or -Dweblogic.Name=* or
 88    io.helidon.webserver* or org.apereo.cas* or org.keycloak* or org.springframework.boot.loader.*
 89  )
 90) and
 91process.command_line:* and
 92process.name:(bash or busybox or csh or dash or fish or ksh or mksh or sh or tcsh or zsh) and
 93process.args:(-c or -cl or -lc) and
 94not (
 95  process.parent.name:java and not process.parent.executable:/u0*/* or
 96  process.working_directory:(/u0*/*/sysman/emd or /u0*/app/oracle/product/*/db_* or /u0*/app/oracle/product/*/dbhome_* or /var/www/*edoc*) or
 97  process.args:(/usr/bin/rsvg-convert* or /usr/local/bin/wkhtmltopdf*) or
 98  process.command_line:*/opt/sc/bin/showvulns*
 99)
100'''
101
102[[rule.threat]]
103framework = "MITRE ATT&CK"
104
105[[rule.threat.technique]]
106id = "T1505"
107name = "Server Software Component"
108reference = "https://attack.mitre.org/techniques/T1505/"
109
110[[rule.threat.technique.subtechnique]]
111id = "T1505.003"
112name = "Web Shell"
113reference = "https://attack.mitre.org/techniques/T1505/003/"
114
115[rule.threat.tactic]
116id = "TA0003"
117name = "Persistence"
118reference = "https://attack.mitre.org/tactics/TA0003/"
119
120[[rule.threat]]
121framework = "MITRE ATT&CK"
122
123[[rule.threat.technique]]
124id = "T1059"
125name = "Command and Scripting Interpreter"
126reference = "https://attack.mitre.org/techniques/T1059/"
127
128[[rule.threat.technique.subtechnique]]
129id = "T1059.004"
130name = "Unix Shell"
131reference = "https://attack.mitre.org/techniques/T1059/004/"
132
133[rule.threat.tactic]
134id = "TA0002"
135name = "Execution"
136reference = "https://attack.mitre.org/tactics/TA0002/"
137
138[[rule.threat]]
139framework = "MITRE ATT&CK"
140
141[[rule.threat.technique]]
142id = "T1071"
143name = "Application Layer Protocol"
144reference = "https://attack.mitre.org/techniques/T1071/"
145
146[rule.threat.tactic]
147id = "TA0011"
148name = "Command and Control"
149reference = "https://attack.mitre.org/tactics/TA0011/"
150
151[[rule.threat]]
152framework = "MITRE ATT&CK"
153
154[[rule.threat.technique]]
155id = "T1190"
156name = "Exploit Public-Facing Application"
157reference = "https://attack.mitre.org/techniques/T1190/"
158
159[rule.threat.tactic]
160id = "TA0001"
161name = "Initial Access"
162reference = "https://attack.mitre.org/tactics/TA0001/"
163
164[rule.new_terms]
165field = "new_terms_fields"
166value = ["process.command_line", "host.id", "process.parent.executable"]
167
168[[rule.new_terms.history_window_start]]
169field = "history_window_start"
170value = "now-7d"

Triage and analysis

Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

Investigating Unusual Command Execution via Web Server

This rule detects shells invoked by web server processes on Linux to run one-off commands, surfacing command lines the server has never executed before. Attackers exploit vulnerable apps or dropped webshells to launch bash -c from web roots, e.g., download a payload with wget/curl into /opt or /tmp, chmod +x and execute it, or open a reverse shell (nc -e sh) to implant services or cron-like tasks and persist under the web server account.

Possible investigation steps

  • Reconstruct the process tree around the event to identify the shell payload and parent service, determine if it chains downloads, reverse shells, or archive extraction, and hash/snapshot any referenced files.
  • Pivot to web server access and error logs at the timestamp to identify the request path, client IP, user agent, and HTTP verb that triggered execution, noting anomalies like POST uploads, long query strings, or 500s.
  • List and diff newly created or recently modified files under common web roots and application directories around the event time, looking for webshells, chmod+x artifacts, .php/.jsp backdoors, or systemd/cron writes by the same user.
  • Correlate with network telemetry to see if the web tier opened outbound connections or listeners (nc, bash -i, curl/wget), and capture any active sockets and destinations for rapid containment.
  • Validate whether the command matches expected maintenance tasks for the application (e.g., wkhtmltopdf or image processing), and if not, isolate the process and host while scoping for the same pattern across other servers and preserving volatile evidence.

False positive analysis

  • A legitimate web-admin workflow (plugin/module install, content import, or cache warmup) spawns sh -c from an apache/nginx parent in /var/www to run tar/chmod/chown steps, producing a command line the host has not previously executed under www-data.
  • A recently deployed application feature performs server-side document or image processing and rotates logs by calling sh -c from a framework parent (flask/rails/php) with a working directory in /opt or /usr/share/nginx, making the specific shell invocation a new term for this server.

Response and remediation

  • Quarantine the affected web server by removing it from the load balancer, stopping apache/nginx/httpd, and killing the spawned shell (e.g., bash -c) while capturing /proc//cmdline and /proc//environ, lsof, and active sockets for evidence.
  • Block outbound egress from the web server account and immediately deny destinations contacted by curl/wget or reverse shells (nc, bash -i to /dev/tcp), and rotate exposed API keys or credentials referenced in the command line.
  • Eradicate persistence by deleting newly dropped or modified files under /var/www, /usr/share/nginx, /srv/http, /opt, or /home/*/public_html (webshells, .php backdoors), removing downloaded binaries from /tmp or /opt, and cleaning cron/systemd units created by www-data/nginx.
  • Recover by restoring web content and application code from known-good backups or images, verifying file ownership and permissions, and restarting the service with monitored command allowlists and file integrity checks.
  • Escalate to full incident response and forensic imaging if any reverse shell artifacts (nc -e sh, bash -i >& /dev/tcp/), privileged writes (/etc/systemd/system/.service, /var/spool/cron/*), or sudo execution by the web server user are observed.
  • Harden by disabling risky exec paths (PHP exec/system/shell_exec and unsafe plugins), enforcing noexec,nodev,nosuid mounts on web roots, applying SELinux/AppArmor confinement to web processes, narrowing outbound egress, and deploying WAF/mod_security rules for upload and RCE vectors.

Related rules

to-top