IMPORTANT: This documentation is no longer updated. Refer to Elastic's version policy and the latest documentation.

Unusual Web Server Command Execution

edit

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.

Rule type: new_terms

Rule indices:

  • logs-endpoint.events.process*

Severity: medium

Risk score: 47

Runs every: 5m

Searches indices from: now-9m (Date Math format, see also Additional look-back time)

Maximum alerts per execution: 100

References: None

Tags:

  • Domain: Endpoint
  • Domain: Web
  • OS: Linux
  • Use Case: Threat Detection
  • Tactic: Persistence
  • Data Source: Elastic Defend
  • Resources: Investigation Guide

Version: 1

Rule authors:

  • Elastic

Rule license: Elastic License v2

Investigation guide

edit

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 Web Server Command Execution

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/<pid>/cmdline and /proc/<pid>/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.

Rule query

edit
event.category:process and host.os.type:linux and event.type:start and event.action:exec and (
  process.parent.name:(
    "apache" or "nginx" or "apache2" or "httpd" or "lighttpd" or "caddy" or "mongrel_rails" or "haproxy" or
    "gunicorn" or "uwsgi" or "openresty" or "cherokee" or "h2o" or "resin" or "puma" or "unicorn" or "traefik" or "uvicorn" or
    "tornado" or "hypercorn" or "daphne" or "twistd" or "yaws" or "webfsd" or "httpd.worker" or "flask" or "rails" or "mongrel" or
    php* or ruby* or perl* or python* or "node" or "java"
  ) or
  user.name:("apache" or "www-data" or "httpd" or "nginx" or "lighttpd" or "tomcat" or "tomcat8" or "tomcat9") or
  user.id:("33" or "498" or "48" or "54321")
) and process.working_directory:(
  /var/www/* or
  /usr/share/nginx/* or
  /srv/www/* or
  /srv/http/* or
  */webapps/* or
  /home/*/public_html/* or
  /home/*/www/* or
  /opt/* or
  /u0*/*
) and
process.command_line:* and process.name:(bash or dash or sh or tcsh or csh or zsh or ksh or fish) and process.args:"-c" and
not (
  (process.parent.name:java and not process.parent.executable:/u0*/*) or
  (process.parent.name:python* and process.parent.executable:(/bin/python* or /usr/bin/python* or /usr/local/bin/python* or /tmp/*python* or /opt/oracle.ahf/python/*)) or
  (process.parent.name:ruby* and process.parent.executable:(/bin/ruby* or /usr/bin/ruby* or /usr/local/bin/ruby* or /tmp/*ruby* or /bin/ruby or /usr/bin/ruby or /usr/local/bin/ruby)) or
  (process.parent.name:perl* and process.parent.executable:(/bin/perl* or /usr/bin/perl* or /usr/local/bin/perl* or /tmp/*perl* or /bin/perl or /usr/bin/perl or /usr/local/bin/perl)) or
  (process.parent.name:php* and process.parent.executable:(/bin/php* or /usr/bin/php* or /usr/local/bin/php* or /tmp/*php* or /bin/php or /usr/bin/php or /usr/local/bin/php)) or
  (process.parent.name:node and process.parent.executable:(/home/*/.vscode-server/* or /users/*/.vscode-server/* or /bin/node or /usr/bin/node or /usr/local/bin/node or /opt/plesk/node/*/bin/node)) or
  process.working_directory:(/u0*/*/sysman/emd or /u0*/app/oracle/product/*/dbhome_* or /u0*/app/oracle/product/*/db_* or /var/www/*edoc*) or
  process.parent.executable:/tmp/* or
  process.args:/usr/local/bin/wkhtmltopdf*
)

Framework: MITRE ATT&CKTM