Detection rules › Elastic
Linux Hidden Folder or File Execution via Python
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.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | --include-private-keys | excludes:process.args field:"process.args" value:"--include-private-keys" |
process.parent.args | wildcard | /home/*/.ansible/tmp/ansible-tmp-*/ir_scan.sh | excludes:process.parent.args field:"process.parent.args" value:"/home/*/.ansible/tmp/ansible-tmp-*/ir_scan.sh" |
process.args | eq | build | excludes:process.args field:"process.args" value:"build" |
process.args | in | /bin/ukify, /usr/bin/ukify | excludes:process.args field:"process.args" value:"/bin/ukify" field:"process.args" value:"/usr/bin/ukify" |
process.args | wildcard | /tmp/.tmp*/*/run.py | excludes:process.args field:"process.args" value:"/tmp/.tmp*/*/run.py" |
process.parent.executable | wildcard | /home/gitlab-runner/builds/*/bach | excludes:process.parent.executable field:"process.parent.executable" value:"/home/gitlab-runner/builds/*/bach" |
process.command_line | starts_with | python3 /tmp/.tmp | excludes:process.command_line field:"process.command_line" value:"python3 /tmp/.tmp" |
process.parent.executable | wildcard | /home/*/node_modules/@openai/codex/bin/codex-x86_64-unknown-linux-musl | excludes:process.parent.executable field:"process.parent.executable" value:"/home/*/node_modules/@openai/codex/bin/codex-x86_64-unknown-linux-musl" |
process.parent.command_line | eq | runc init | excludes:process.parent.command_line field:"process.parent.command_line" value:"runc init" |
process.parent.executable | eq | ./runc | excludes:process.parent.executable field:"process.parent.executable" value:"./runc" |
process.args | in | /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.py | excludes:process.args |
process.args | wildcard | /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 | excludes:process.args |
process.parent.args | wildcard | /home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py | excludes:process.parent.args field:"process.parent.args" value:"/home/*/git/roche/product-packages/common/hearst/test-submit-enclave-measurements.py" |
process.parent.name | in | arduino-cli, browser_tests, node, python.original, unit_tests | excludes:process.parent.name |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard |