Suspicious Command Execution via Web Server
Identifies suspicious command executions via a web server, which may suggest a vulnerability and remote shell access. Attackers may exploit a vulnerability in a web application to execute commands via a web server, or place a backdoor file that can be abused to gain code execution as a mechanism for persistence.
Rule type: eql
Rule indices:
- logs-endpoint.events.process*
Rule Severity: medium
Risk Score: 47
Runs every:
Searches indices from: now-9m
Maximum alerts per execution: 100
References:
Tags:
- Domain: Endpoint
- OS: Linux
- Use Case: Threat Detection
- Tactic: Persistence
- Tactic: Initial Access
- Use Case: Vulnerability
- Data Source: Elastic Defend
- Resources: Investigation Guide
Version: 1
Rule authors:
- Elastic
Rule license: Elastic License v2
This rule requires data coming in from Elastic Defend.
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the documentation.
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. Helper guide.
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead. For more details on Elastic Agent configuration settings, refer to the helper guide.
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts. For more details on Elastic Defend refer to the helper guide.
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.
This alert fires when a Linux web server launches a shell to run commands that look like exploitation activity, such as discovery, credential access, payload decoding, or reverse shell setup. That matters because web servers rarely need to spawn shell commands, so this behavior often signals command injection, a dropped web shell, or attacker persistence. A common pattern is an app exploit causing php-fpm or nginx to run sh -c 'id; cat /etc/passwd; curl ... | bash' from /tmp.
- Review the full process ancestry and execution context to determine what application component invoked the shell, which service account ran it, what working directory and environment it used, and whether the command aligns with any documented application behavior.
- Correlate the execution time with web server access, error, and application logs to identify the triggering request, including source IP, requested URI, parameters, headers, authenticated user or session, and any indications of command injection or direct web shell access.
- Inspect recently created or modified files in the web root and writable locations such as upload, cache, temp, and shared-memory directories for dropped scripts, encoded payloads, cron changes, SSH key additions, or other persistence artifacts tied to the command.
- Scope for follow-on activity by pivoting on the source IP, command fragments, spawned children, outbound connections, and similar executions on other web servers to determine whether exploitation was successful, repeated, or part of a broader campaign.
- If the activity is unauthorized or cannot be explained, isolate the host, preserve relevant volatile and disk evidence, rotate secrets accessible to the web service, and remediate the vulnerable application or remove any discovered web shell before restoring service.
- A legitimate web administration or diagnostics function may invoke
sh -cto run commands such asid,whoami,hostname, or read OS metadata for status pages; verify the command matches documented application behavior and correlate it to an authorized request in web or application logs. - A normal application workflow may use the web server to unpack user uploads or stage temporary content under
/tmp,/var/tmp, or/dev/shmduring import, conversion, or update operations; verify the execution aligns with a known user action or scheduled maintenance window and that the created files are expected temporary artifacts owned by the service account.
- Isolate the affected web server from the network or remove it from the load balancer immediately, preserve a forensic snapshot if possible, and block the attacker-controlled IPs, domains, and downloaded payload locations observed in the command chain.
- Hunt for and remove persistence by deleting web shells and dropped scripts in the document root, uploads,
/tmp,/var/tmp, and/dev/shm, and by cleaning unauthorized cron entries, systemd services, startup scripts, SSHauthorized_keys, and any attacker-created local accounts. - Reset trust on the host by rotating application secrets, database passwords, API tokens, cloud credentials, and SSH keys that were present or reachable from the web server, and invalidate active sessions tied to the compromised application.
- Rebuild or reimage the server from a known-good source, patch the exploited web application or server component, restore only validated content and configurations, and verify no unauthorized binaries, modified packages, or backdoored application files remain before returning it to service.
- Escalate to incident response immediately if the shell command opened a reverse shell, downloaded or piped a payload into an interpreter, accessed sensitive files such as
/etc/shadow,.ssh, or cloud credential stores, or if similar activity is found on additional hosts. - Harden the environment by removing unnecessary shell execution from the application, disabling write and execute permissions in web-accessible upload and temp paths, enforcing least privilege for the web service account, enabling WAF or virtual patching for the exploited weakness, and increasing monitoring on web roots and startup locations.
process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
process.parent.name in (
"nginx", "apache2", "httpd", "caddy", "mongrel_rails", "uwsgi", "daphne", "httpd.worker", "flask",
"php-cgi", "php-fcgi", "php-cgi.cagefs", "lswsctrl", "varnishd", "uvicorn", "waitress-serve", "starman",
"frankenphp", "zabbix_server", "asterisk", "sw-engine-fpm"
) or
process.parent.name like ("php-fpm*", "gunicorn*", "*.cgi", "*.fcgi") or
(
process.parent.name like "ruby*" and
process.parent.command_line like~ ("*puma*", "*rails*", "*passenger*")
) or
(
process.parent.name like "python*" and
process.parent.command_line like~ (
"*hypercorn*", "*flask*", "*uvicorn*", "*django*", "*app.py*", "*server.py*", "*wsgi.py*", "*asgi.py*"
)
) or
(process.parent.name like "perl*" and process.parent.command_line like~ "*plackup*") or
(
process.parent.name == "java" and (
process.parent.args like~ (
/* Tomcat */
"org.apache.catalina.startup.Bootstrap", "-Dcatalina.base=*",
/* Jetty */
"org.eclipse.jetty.start.Main", "-Djetty.home=*",
/* WildFly / JBoss */
"org.jboss.modules.Main", "-Djboss.home.dir=*",
/* WebLogic */
"weblogic.Server", "-Dweblogic.Name=*", "*weblogic-launcher.jar*",
/* WebSphere traditional + Liberty */
"com.ibm.ws.runtime.WsServer", "com.ibm.ws.kernel.boot.cmdline.Bootstrap",
/* GlassFish */
"com.sun.enterprise.glassfish.bootstrap.ASMain",
/* Resin */
"com.caucho.server.resin.Resin",
/* Spring Boot */
"org.springframework.boot.loader.*",
/* Quarkus */
"*quarkus-run.jar*", "io.quarkus.runner.GeneratedMain",
/* Micronaut */
"io.micronaut.runtime.Micronaut",
/* Dropwizard */
"io.dropwizard.cli.ServerCommand",
/* Play */
"play.core.server.ProdServerStart",
/* Helidon */
"io.helidon.microprofile.server.Main", "io.helidon.webserver*",
/* Vert.x */
"io.vertx.core.Launcher",
/* Keycloak */
"org.keycloak*",
/* Apereo CAS */
"org.apereo.cas*",
/* Elasticsearch */
"org.elasticsearch.bootstrap.Elasticsearch",
/* Atlassian / Gerrit */
"com.atlassian.jira.startup.Launcher", "*BitbucketServerLauncher*", "com.google.gerrit.pgm.Daemon",
/* Solr */
"*-Dsolr.solr.home=*",
/* Jenkins */
"*jenkins.war*"
) or
?process.working_directory like "/u0?/*"
)
)
) and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "mksh", "busybox") and
process.args in ("-c", "-cl", "-lc") and (
process.command_line like~ (
/* Suspicious Paths */
"* /tmp/* ", "* /var/tmp/* ", "* /dev/shm/*", "* /run/*", "* /var/run/*",
/* Encoding, Decoding & Piping */
"*|sh", "*| sh *", "*| sh ", "*|bash*", "*| bash*", "*|zsh*", "*| zsh*", "*|dash*", "*| dash*",
"*|python*", "*| python*", "*|php*", "*| php*", "*|perl*", "*| perl*", "*|ruby*", "*| ruby*",
"*|node*", "*| node*", "*|lua*", "*| lua*", "*|busybox*", "*| busybox*", "*|*base64 -d*", "*|*base64 --decode*",
"*|*base64 --decode*", "*|*openssl base64 -d*", "*xxd *", "*| openssl*enc * -d *", "*b64decode -r*",
/* Interpreter Execution */
"*python -c*", "*python3 -c*", "*php -r*", "*perl -e*", "*ruby -e*", "*lua -e*", "*node -e *",
/* Reverse Shells */
"*netcat *", "* nc *", "*ncat *", "*/dev/tcp*", "*/dev/udp/*", "*socat *", "*openssl*s_client *", "*stty*raw*-echo*",
"*mkfifo /tmp/*",
/* File Access */
"*>*/etc/cron*", "*crontab*", "*/etc/ssh*", "*/home/*/.ssh/*", "*/root/.ssh*", "*~/.ssh/*", "*/etc/shadow*",
"*/etc/passwd*", "*/etc/master.passwd*",
/* Enumeration & Discovery */
"*/etc/hosts*", "*/etc/resolv.conf*", "*/etc/hostname*", "*/etc/issue*", "*/etc/os-release*", "*lsb_release*",
"*/proc/*/environ*", "*sudo -l*", "*/proc/*/cgroup*", "*dockerenv*", "*/proc/*/mountinfo*", "*printenv*",
"*cat*.env *", "*getcap*", "*capsh*", "*find / *", "*netstat *",
/* AWS Credentials */
"*aws_access_key_id*", "*aws_secret_access_key*", "*aws_session_token*", "*accesskeyid*", "*secretaccesskey*",
"*.aws/credentials*", "*/.aws/config*",
/* Azure Credentials */
"*AZURE_CLIENT_ID*", "*AZURE_TENANT_ID*", "*AZURE_CLIENT_SECRET*", "*AZURE_FEDERATED_TOKEN_FILE*",
"*IDENTITY_ENDPOINT*", "*IDENTITY_HEADER*", "*MSI_ENDPOINT*", "*MSI_SECRET*", "*/.azure/*",
"*/run/secrets/azure/*",
/* GCP Credentials */
"*/.config/gcloud/*", "*application_default_credentials.json*", "*type: service_account*",
"*client_email*", "*private_key_id*", "*/run/secrets/google/*", "*GOOGLE_APPLICATION_CREDENTIALS*",
/* Misc. Cloud */
"*/.docker/config.json*", "*/.npmrc*", "*/secrets/kubernetes.io/serviceaccount/*",
/* Helpers */
"*timeout *sh -c *", "*env *sh *-c*", "*exec -a*",
/* Miscellaneous */
"*chattr *", "*busybox *", "*#!*", "*chmod +x *", "*chmod 777*", "*chpasswd*",
"*<?php*?>*", "*kworker*",
/* Decompression */
"*gzip -*d *", "*bzip2 -*d *", "*xz -*d *", "*tar -*x*",
/* Path Traversal */
"*../../../*etc/*", "*/.../*", "*../../../*home/*/*", "*../../../*root/*",
/* File Upload/Download */
"*pastebin.com*", "*transfer.sh*", "*bashupload.com*",
/* Enumeration & Discovery */
"* id *", "* whoami *", "* hostname *"
) or
/* Keep this to not miss FNs due to spacing */
process.args in ("id", "whoami", "hostname")
) and
not (
(
process.parent.name == "nginx" and
process.args like ("chmod 777 /etc/resty-*", "resty*")
) or
(
process.parent.name == "apache2" and (
process.command_line in (
"sh -c /usr/local/bin/php -r 'echo phpversion();'", "sh -c -- /usr/local/bin/php -r 'echo phpversion();'",
"sh -c /usr/bin/php -r 'echo phpversion();'",
"sh -c /usr/bin/lsb_release -a 2>/dev/null"
) or
process.args like (
"""bash -c "( /home/*/apps/richdocumentscode/collabora/Collabora_Online.AppImage*""",
"chmod 777 /etc/cobra/uploads/mysql*", "stat*"
) or
process.command_line like (
"*/usr/bin/crontab*phpupdatecrontab.txt", "*mysqldump*/var/www/html/*/writable/uploads/backup/mysql*",
"sh -c chmod 777 -R /opt/data/www/php_upload/*/temp"
)
)
) or
(
process.parent.name like "php-fpm*" and (
process.command_line in (
"sh -c /usr/bin/php -r 'echo phpversion();'", "sh -c -- /usr/bin/php -r 'echo phpversion();'",
"sh -c php -r 'print_r(phpversion());'", "sh -c chattr -i -a /usr/local/virtualizor/license2.php",
"sh -c source /etc/os-release 2>/dev/null && echo $ID $ID_LIKE",
"sh -c php -r \"echo date('T');\"",
"sh -c php -r \"echo PHP_VERSION;\""
) or
process.command_line like (
"*var_export*extension_loaded*", "*/tmp/tmp_resize*", "*/v1/objects/hosts/*_Infoterminal*", "*python -m json.tool*",
"sh -c timeout 3600 ssh -o ControlMaster=auto -o ControlPath=/var/www/html/storage/app/ssh/mux/*"
) or
process.args like ("ps*|*grep*", "ffmpeg*")
)
) or
(
process.parent.name == "php-cgi" and (
process.command_line like (
"sh -c nohup php /home/*/public_html/lockindex.php index.php >/dev/null 2>&1 &",
"sh -c nohup php /home/*/public_html/wp-content/* >> /dev/null 2>&1 &",
"sh -c nohup php /home/*/public_html/wp-includes/* >> /dev/null 2>&1 &",
"sh -c nohup php /home/*/public_html/*/wp-content/* >> /dev/null 2>&1 &",
"*-ef|grep*"
) or
process.args like "ps*| grep*"
)
) or
(
process.command_line == "/bin/sh -c echo | openssl s_client -connect localhost:61617 2>/dev/null | openssl x509 -noout -enddate" and
process.parent.name == "gunicorn"
) or
(
process.parent.executable == "/usr/local/bin/gunicorn" and
process.command_line == "/bin/sh -c echo 'Q' | openssl s_client -connect localhost:61617 2>/dev/null | openssl x509 -noout -enddate"
) or
(
process.parent.executable == "/opt/bitnami/apache/bin/httpd" and
process.command_line == "sh -c /opt/bitnami/php/bin/php -r 'echo phpversion();'"
) or
(
process.parent.executable like "/var/lib/containers/storage/overlay/*/merged/usr/local/sbin/php-fpm" and
process.command_line == "sh -c /usr/local/bin/php -r 'echo phpversion();'"
) or
(
process.parent.executable like "/var/lib/docker/overlay2/*/merged/usr/sbin/uwsgi" and
process.command_line == "/bin/sh -c { touch /run/uwsgi-logrotate }"
) or
(process.parent.name like "python*" and process.parent.command_line like "*hive_server.py*") or
(process.parent.name == "sw-engine-fpm" and process.command_line like ("*/opt/psa/admin/bin/*", "*/usr/local/psa/admin/*")) or
(process.parent.name == "httpd" and process.command_line like ("*/datastore/htdocs/control-states/compass*", "*/dev/shm/netmon-log*")) or
(process.parent.name == "asterisk" and process.args like "/bin/chmod 777 */gravacoes/*.WAV") or
(process.parent.name == "nginx" and process.command_line like "sh -c gcc -print-multiarch 2>/dev/null > /tmp/lua_*") or
(process.parent.name == "varnishd" and process.args like "exec gcc*") or
(process.parent.name == "zabbix_server" and process.command_line like "*/usr/sbin/sendmail*") or
(process.parent.executable == "/opt/morpheus/embedded/java/jre/bin/java" and process.command_line like "*morpheus-local*") or
(
process.parent.name == "ruby" and
process.command_line in (
"sh -c echo \"^d\" | openssl s_client -connect 127.0.0.1:443 2>&1",
"sh -c cat /etc/hosts.allow 2>/dev/null"
)
) or
(process.parent.name == "java" and process.args like "chmod 777 *.csv") or
process.command_line == "sh -c node -v || nodejs -v" or
process.working_directory == "/var/lib/puppet/rack/puppetmasterd"
)
Framework: MITRE ATT&CK
Tactic:
- Name: Persistence
- Id: TA0003
- Reference URL: https://attack.mitre.org/tactics/TA0003/
Technique:
- Name: Server Software Component
- Id: T1505
- Reference URL: https://attack.mitre.org/techniques/T1505/
Sub Technique:
- Name: Web Shell
- Id: T1505.003
- Reference URL: https://attack.mitre.org/techniques/T1505/003/
Framework: MITRE ATT&CK
Tactic:
- Name: Initial Access
- Id: TA0001
- Reference URL: https://attack.mitre.org/tactics/TA0001/
Technique:
- Name: Exploit Public-Facing Application
- Id: T1190
- Reference URL: https://attack.mitre.org/techniques/T1190/
Framework: MITRE ATT&CK
Tactic:
- Name: Execution
- Id: TA0002
- Reference URL: https://attack.mitre.org/tactics/TA0002/
Technique:
- Name: Command and Scripting Interpreter
- Id: T1059
- Reference URL: https://attack.mitre.org/techniques/T1059/