Detection rules › Elastic
Shell Command Execution via Kworker
This rule monitors for the execution of shell commands via a kworker parent process. kworker, or kernel worker, processes are part of the kernel's workqueue mechanism. They are responsible for executing work that has been scheduled to be done in kernel space, which might include tasks like handling interrupts, background activities, and other kernel-related tasks. Attackers may attempt to evade detection by masquerading as a kernel worker process.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Rule body
[rule]
description = """
This rule monitors for the execution of shell commands via a kworker parent process. kworker, or kernel worker,
processes are part of the kernel's workqueue mechanism. They are responsible for executing work that has been scheduled
to be done in kernel space, which might include tasks like handling interrupts, background activities, and other
kernel-related tasks. Attackers may attempt to evade detection by masquerading as a kernel worker process.
"""
id = "94943f02-5580-4d1d-a763-09e958bd0f57"
license = "Elastic License v2"
name = "Shell Command Execution via Kworker"
os_list = ["linux"]
version = "1.0.11"
query = '''
process where event.type == "start" and event.action == "exec" and process.parent.name like "kworker*" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.args in (
"bash", "/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash",
"sh", "/bin/sh", "/usr/bin/sh", "/usr/local/bin/sh",
"dash", "/bin/dash", "/usr/bin/dash", "/usr/local/bin/dash",
"tcsh", "/bin/tcsh", "/usr/bin/tcsh", "/usr/local/bin/tcsh",
"csh", "/bin/csh", "/usr/bin/csh", "/usr/local/bin/csh",
"zsh", "/bin/zsh", "/usr/bin/zsh", "/usr/local/bin/zsh",
"ksh", "/bin/ksh", "/usr/bin/ksh", "/usr/local/bin/ksh",
"fish", "/bin/fish", "/usr/bin/fish", "/usr/local/bin/fish"
) and
process.args_count >= 3 and process.command_line like (
"*ip*", "*whoami*", "*id*", "*hostname*", "*touch*", "*curl*", "*wget*", "*chmod*", "*busybox*", "*chattr*", "*echo*",
"*python*", "*php*", "*perl*", "*ruby*", "*lua*", "*openssl*", "*nc*", "*netcat*", "*ncat*"
) and not (
process.command_line == "sh -c /bin/true" or
process.args like ("/sbin/modprobe *", "/usr/sbin/modprobe *")
)
'''
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.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.parent.name like "kworker*" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.args in (
"bash", "/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash",
"sh", "/bin/sh", "/usr/bin/sh", "/usr/local/bin/sh",
"dash", "/bin/dash", "/usr/bin/dash", "/usr/local/bin/dash",
"tcsh", "/bin/tcsh", "/usr/bin/tcsh", "/usr/local/bin/tcsh",
"csh", "/bin/csh", "/usr/bin/csh", "/usr/local/bin/csh",
"zsh", "/bin/zsh", "/usr/bin/zsh", "/usr/local/bin/zsh",
"ksh", "/bin/ksh", "/usr/bin/ksh", "/usr/local/bin/ksh",
"fish", "/bin/fish", "/usr/bin/fish", "/usr/local/bin/fish"
) and
process.args_count >= 3 and process.command_line like (
"*ip*", "*whoami*", "*id*", "*hostname*", "*touch*", "*curl*", "*wget*", "*chmod*", "*busybox*", "*chattr*", "*echo*",
"*python*", "*php*", "*perl*", "*ruby*", "*lua*", "*openssl*", "*nc*", "*netcat*", "*ncat*"
) and not (
process.command_line == "sh -c /bin/true" or
process.args like ("/sbin/modprobe *", "/usr/sbin/modprobe *")
)
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | starts_with | /sbin/modprobe , /usr/sbin/modprobe | excludes:process.args field:"process.args" value:"/sbin/modprobe " field:"process.args" value:"/usr/sbin/modprobe " |
process.command_line | eq | sh -c /bin/true | excludes:process.command_line field:"process.command_line" value:"sh -c /bin/true" |
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 | eq |
| field:"process.args" kind:eq value:"-c" |
process.args | in |
| field:"process.args" kind:in |
process.args_count | ge |
| field:"process.args_count" kind:ge value:"3" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | in |
| field:"process_name" kind:in |
process.parent.name | wildcard |
| field:"parent_process_name" kind:wildcard value:"kworker*" |