Detection rules › Elastic

Linux Hidden Folder or File Execution via Python

Source
github.com/elastic/protections-artifacts

Detects possible Python-based malware that stages their files in a hidden directory or file. This rule looks for Python executions where the process arguments include references to hidden folders or files in the suspicious directories.

MITRE ATT&CK coverage

Rule body

[rule]
description = """
Detects possible Python-based malware that stages their files in a hidden directory or file. This rule looks for Python
executions where the process arguments include references to hidden folders or files in the suspicious directories.
"""
id = "b25ec4e7-34f1-40c2-b683-bbf1dcdd84e5"
license = "Elastic License v2"
name = "Linux Hidden Folder or File Execution via Python"
os_list = ["linux"]
reference = ["https://github.com/rapid7/metasploit-framework"]
version = "1.0.18"

query = '''
process where event.type == "start" and event.action == "exec" and
process.executable like~ ("/bin/python*", "/usr/bin/python*", "/usr/local/bin/python*") and
process.args : "python*" and process.args : ("/tmp/.*", "/var/tmp/.*", "/dev/shm/.*") and
not (
  process.parent.name in ("browser_tests", "unit_tests", "arduino-cli", "node", "python.original") or
  process.args like (
    "/tmp/.build/*", "/tmp/.sentrycli*", "/var/tmp/.mount_GIMP*", "/tmp/.mount_GIMP*", "/tmp/*/ansible-tmp-*/AnsiballZ*.py",
    "/tmp/selfgz*.py", "/home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py",
    "/tmp/.ctx-mode-*", "/tmp/.tmp*/drivers/fake.*/run.py"
  ) or
  process.args in (
    "/opt/sev-snp-measure/measure.py", "/tmp/.__preview_vite_base_fixer.py", "/tmp/.soc_models_helper.py",
    "/opt/fortanix/enclave-os/blobs/kernel_enabled_gpu/bzImage"
  ) or
  process.parent.args like "/home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py" or
  (
    process.parent.executable like "/home/*/node_modules/@openai/codex/bin/codex-x86_64-unknown-linux-musl" and
    process.command_line like "python3 /tmp/.tmp*"
  ) or
  (process.args in ("/usr/bin/ukify", "/bin/ukify") and process.args == "build") or 
  (process.args == "--include-private-keys" and process.parent.args like "/home/*/.ansible/tmp/ansible-tmp-*/ir_scan.sh") or
  (process.parent.executable == "./runc" and process.parent.command_line == "runc init") or
  (process.parent.executable like "/home/gitlab-runner/builds/*/bach" and process.args like "/tmp/.tmp*/*/run.py")
)
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"

[[threat.technique.subtechnique]]
id = "T1059.006"
name = "Python"
reference = "https://attack.mitre.org/techniques/T1059/006/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and
process.executable like~ ("/bin/python*", "/usr/bin/python*", "/usr/local/bin/python*") and
process.args : "python*" and process.args : ("/tmp/.*", "/var/tmp/.*", "/dev/shm/.*") and
not (
  process.parent.name in ("browser_tests", "unit_tests", "arduino-cli", "node", "python.original") or
  process.args like (
    "/tmp/.build/*", "/tmp/.sentrycli*", "/var/tmp/.mount_GIMP*", "/tmp/.mount_GIMP*", "/tmp/*/ansible-tmp-*/AnsiballZ*.py",
    "/tmp/selfgz*.py", "/home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py",
    "/tmp/.ctx-mode-*", "/tmp/.tmp*/drivers/fake.*/run.py"
  ) or
  process.args in (
    "/opt/sev-snp-measure/measure.py", "/tmp/.__preview_vite_base_fixer.py", "/tmp/.soc_models_helper.py",
    "/opt/fortanix/enclave-os/blobs/kernel_enabled_gpu/bzImage"
  ) or
  process.parent.args like "/home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py" or
  (
    process.parent.executable like "/home/*/node_modules/@openai/codex/bin/codex-x86_64-unknown-linux-musl" and
    process.command_line like "python3 /tmp/.tmp*"
  ) or
  (process.args in ("/usr/bin/ukify", "/bin/ukify") and process.args == "build") or 
  (process.args == "--include-private-keys" and process.parent.args like "/home/*/.ansible/tmp/ansible-tmp-*/ir_scan.sh") or
  (process.parent.executable == "./runc" and process.parent.command_line == "runc init") or
  (process.parent.executable like "/home/gitlab-runner/builds/*/bach" and process.args like "/tmp/.tmp*/*/run.py")
)

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq--include-private-keysexcludes:process.args field:"process.args" value:"--include-private-keys"
process.parent.argswildcard/home/*/.ansible/tmp/ansible-tmp-*/ir_scan.shexcludes:process.parent.args field:"process.parent.args" value:"/home/*/.ansible/tmp/ansible-tmp-*/ir_scan.sh"
process.argseqbuildexcludes:process.args field:"process.args" value:"build"
process.argsin/bin/ukify, /usr/bin/ukifyexcludes:process.args field:"process.args" value:"/bin/ukify" field:"process.args" value:"/usr/bin/ukify"
process.argswildcard/tmp/.tmp*/*/run.pyexcludes:process.args field:"process.args" value:"/tmp/.tmp*/*/run.py"
process.parent.executablewildcard/home/gitlab-runner/builds/*/bachexcludes:process.parent.executable field:"process.parent.executable" value:"/home/gitlab-runner/builds/*/bach"
process.command_linestarts_withpython3 /tmp/.tmpexcludes:process.command_line field:"process.command_line" value:"python3 /tmp/.tmp"
process.parent.executablewildcard/home/*/node_modules/@openai/codex/bin/codex-x86_64-unknown-linux-muslexcludes:process.parent.executable field:"process.parent.executable" value:"/home/*/node_modules/@openai/codex/bin/codex-x86_64-unknown-linux-musl"
process.parent.command_lineeqrunc initexcludes:process.parent.command_line field:"process.parent.command_line" value:"runc init"
process.parent.executableeq./runcexcludes:process.parent.executable field:"process.parent.executable" value:"./runc"
process.argsin/opt/fortanix/enclave-os/blobs/kernel_enabled_gpu/bzImage, /opt/sev-snp-measure/measure.py, /tmp/.__preview_vite_base_fixer.py, /tmp/.soc_models_helper.pyexcludes:process.args
process.argswildcard/tmp/.build/*, /tmp/.sentrycli*, /var/tmp/.mount_GIMP*, /tmp/.mount_GIMP*, /tmp/*/ansible-tmp-*/AnsiballZ*.py, /tmp/selfgz*.py, /home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py, /tmp/.ctx-mode-*, /tmp/.tmp*/drivers/fake.*/run.pyexcludes:process.args
process.parent.argswildcard/home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.pyexcludes:process.parent.args field:"process.parent.args" value:"/home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py"
process.parent.nameinarduino-cli, browser_tests, node, python.original, unit_testsexcludes:process.parent.name

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argswildcard
  • /dev/shm/.*
  • /tmp/.*
  • /var/tmp/.*
  • python*
field:"process.args" kind:wildcard
process.executablewildcard
  • /bin/python*
  • /usr/bin/python*
  • /usr/local/bin/python*
field:"Image" kind:wildcard