Detection rules › Elastic

Binary Execution from Unusual Location through Shell Profile

Time window
3s
Sequence by
process.entity_id, process.parent.entity_id
Source
github.com/elastic/protections-artifacts

This rule identifies a process that executes a binary from an unusual location through a shell profile configuration. Threat actors can establish persistence by altering shell profile configurations to execute malicious commands or scripts upon user login. These modifications cause the shell launched during login to execute the malicious payload, resulting in a sequence where an authentication event is followed by the execution of a payload in a suspicious location.

MITRE ATT&CK coverage

Rule body

[rule]
description = """
This rule identifies a process that executes a binary from an unusual location through a shell profile configuration.
Threat actors can establish persistence by altering shell profile configurations to execute malicious commands or
scripts upon user login. These modifications cause the shell launched during login to execute the malicious payload,
resulting in a sequence where an authentication event is followed by the execution of a payload in a suspicious
location.
"""
id = "47903010-d527-4200-b43d-971955a80924"
license = "Elastic License v2"
name = "Binary Execution from Unusual Location through Shell Profile"
os_list = ["linux"]
reference = [
    "https://pberba.github.io/security/2022/02/06/linux-threat-hunting-for-persistence-initialization-scripts-and-shell-configuration/",
    "https://www.elastic.co/security-labs/primer-on-persistence-mechanisms",
]
version = "1.0.9"

query = '''
sequence with maxspan=3s
  [process where event.type == "change" and event.action == "uid_change" and (
     process.name in ("su", "sudo", "sshd", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") or
     process.name like ("python*", "php*", "perl*", "ruby*", "lua*")
   ) and not (
     process.executable like ("/srv/snp/docker/*", "/nix/store/*") or
       process.args in (
         "/usr/lib/ubuntu-advantage/apt_news.py", "/usr/lib/ubuntu-advantage/esm_cache.py", "apt-get", "apt",
         "systemctl"
      ) or
       process.command_line like "su cloudendure -c /usr/bin/nice*"
     )
  ] by process.entity_id
  [process where event.type == "start" and event.action == "exec" and process.executable like (
     "/boot/*", "/dev/shm/*", "/etc/cron.*/*", "/etc/init.d/*", "/etc/update-motd.d/*", "/srv/*", "/tmp/*",
     "/var/tmp/*", "/var/log/*"
   ) and process.args_count == 1 and
   not (
     process.executable like (
       "/run/*/newroot/*", "/srv/snp/docker/*", "/tmp/newroot/*", "/var/tmp/cpuid/cpuid", "/tmp/.mount_*/jetbrains-toolbox",
       "/var/tmp/buildah*/mnt/rootfs/bin/readlink", "/var/tmp/rackware/bin/rwdmi", "/srv/zorg-sync/venv/bin/python",
       "/tmp/makeself.*", "/tmp/selfgz*", "/tmp/tmp.*/rustup-init", "/tmp/go-build*"
     ) or
     process.parent.executable like (
       "/tmp/newroot/*", "/tmp/usr/bin/sudo", "/tmp/usr/sbin/sshd", "/tmp/go-build*", "/snap/btop/*/usr/local/bin/btop",
       "/opt/appimagelauncher.AppDir/usr/lib/*/appimagelauncher/binfmt-bypass", "/tmp/snap.rootfs_*"
     )
   )
  ] by process.parent.entity_id
'''

min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[threat.technique.subtechnique]]
id = "T1546.004"
name = "Unix Shell Configuration Modification"
reference = "https://attack.mitre.org/techniques/T1546/004/"



[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 3s, correlated by process.entity_id, process.parent.entity_id.

Stage 1: process

[process where event.type == "change" and event.action == "uid_change" and (
     process.name in ("su", "sudo", "sshd", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") or
     process.name like ("python*", "php*", "perl*", "ruby*", "lua*")
   ) and not (
     process.executable like ("/srv/snp/docker/*", "/nix/store/*") or
       process.args in (
         "/usr/lib/ubuntu-advantage/apt_news.py", "/usr/lib/ubuntu-advantage/esm_cache.py", "apt-get", "apt",
         "systemctl"
      ) or
       process.command_line like "su cloudendure -c /usr/bin/nice*"
     )
  ] by process.entity_id

Stage 2: process

[process where event.type == "start" and event.action == "exec" and process.executable like (
     "/boot/*", "/dev/shm/*", "/etc/cron.*/*", "/etc/init.d/*", "/etc/update-motd.d/*", "/srv/*", "/tmp/*",
     "/var/tmp/*", "/var/log/*"
   ) and process.args_count == 1 and
   not (
     process.executable like (
       "/run/*/newroot/*", "/srv/snp/docker/*", "/tmp/newroot/*", "/var/tmp/cpuid/cpuid", "/tmp/.mount_*/jetbrains-toolbox",
       "/var/tmp/buildah*/mnt/rootfs/bin/readlink", "/var/tmp/rackware/bin/rwdmi", "/srv/zorg-sync/venv/bin/python",
       "/tmp/makeself.*", "/tmp/selfgz*", "/tmp/tmp.*/rustup-init", "/tmp/go-build*"
     ) or
     process.parent.executable like (
       "/tmp/newroot/*", "/tmp/usr/bin/sudo", "/tmp/usr/sbin/sshd", "/tmp/go-build*", "/snap/btop/*/usr/local/bin/btop",
       "/opt/appimagelauncher.AppDir/usr/lib/*/appimagelauncher/binfmt-bypass", "/tmp/snap.rootfs_*"
     )
   )
  ] by process.parent.entity_id

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsin/usr/lib/ubuntu-advantage/apt_news.py, /usr/lib/ubuntu-advantage/esm_cache.py, apt, apt-get, systemctlexcludes:process.args
process.command_linestarts_withsu cloudendure -c /usr/bin/niceexcludes:process.command_line field:"process.command_line" value:"su cloudendure -c /usr/bin/nice"
process.executablestarts_with/srv/snp/docker/, /nix/store/excludes:process.executable field:"process.executable" value:"/srv/snp/docker/" field:"process.executable" value:"/nix/store/"
process.executablewildcard/run/*/newroot/*, /srv/snp/docker/*, /tmp/newroot/*, /var/tmp/cpuid/cpuid, /tmp/.mount_*/jetbrains-toolbox, /var/tmp/buildah*/mnt/rootfs/bin/readlink, /var/tmp/rackware/bin/rwdmi, /srv/zorg-sync/venv/bin/python, /tmp/makeself.*, /tmp/selfgz*, /tmp/tmp.*/rustup-init, /tmp/go-build*excludes:process.executable
process.parent.executablewildcard/tmp/newroot/*, /tmp/usr/bin/sudo, /tmp/usr/sbin/sshd, /tmp/go-build*, /snap/btop/*/usr/local/bin/btop, /opt/appimagelauncher.AppDir/usr/lib/*/appimagelauncher/binfmt-bypass, /tmp/snap.rootfs_*excludes:process.parent.executable

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec
  • uid_change
field:"EventType" kind:eq
event.typeeq
  • change
  • start
field:"event.type" kind:eq
process.args_counteq
  • 1 transforms: number
field:"process.args_count" kind:eq value:"1"
process.executablewildcard
  • /boot/*
  • /dev/shm/*
  • /etc/cron.*/*
  • /etc/init.d/*
  • /etc/update-motd.d/*
  • /srv/*
  • /tmp/*
  • /var/log/*
  • /var/tmp/*
field:"Image" kind:wildcard
process.namein
  • bash
  • csh
  • dash
  • fish
  • ksh
  • sh
  • sshd
  • su
  • sudo
  • tcsh
  • zsh
field:"process_name" kind:in
process.namewildcard
  • lua*
  • perl*
  • php*
  • python*
  • ruby*
field:"process_name" kind:wildcard