Detection rules › Elastic
At Job Creation or Modification via Shell Command
Detects the creation or modification of an At job by a suspicious process. This activity should almost never take place as Apple is slowly deprecating it and atrun execution is disabled by default. If this rule fires it should indicate highly abnormal or malicious activity. Threat actors can abuse the atrun scheduler to persist their binaries on a system.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence |
Rule body
[rule]
description = """
Detects the creation or modification of an At job by a suspicious process. This activity should almost never take place
as Apple is slowly deprecating it and atrun execution is disabled by default. If this rule fires it should indicate
highly abnormal or malicious activity. Threat actors can abuse the atrun scheduler to persist their binaries on a
system.
"""
id = "779f18ce-1457-457c-80e1-3a5d146c2dc0"
license = "Elastic License v2"
name = "At Job Creation or Modification via Shell Command"
os_list = ["macos"]
reference = ["https://theevilbit.github.io/beyond/beyond_0014/"]
version = "1.0.23"
query = '''
sequence by process.entity_id with maxspan=5s
[process where event.type == "start" and (process.name in ("bash", "sh", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh", "fish") or process.name like "tclsh*") and process.args == "-c"]
[file where event.action != "deletion" and
file.path like "/private/var/at/jobs/*" and not
file.path == "/private/var/at/jobs/root"]
'''
min_endpoint_version = "8.11.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 = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[threat.technique.subtechnique]]
id = "T1053.002"
name = "At"
reference = "https://attack.mitre.org/techniques/T1053/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[threat.technique.subtechnique]]
id = "T1053.002"
name = "At"
reference = "https://attack.mitre.org/techniques/T1053/002/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[internal]
min_endpoint_version = "8.11.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5s, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and (process.name in ("bash", "sh", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh", "fish") or process.name like "tclsh*") and process.args == "-c"]
Stage 2: file
[file where event.action != "deletion" and
file.path like "/private/var/at/jobs/*" and not
file.path == "/private/var/at/jobs/root"]
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.path | eq | /private/var/at/jobs/root | excludes:file.path field:"file.path" value:"/private/var/at/jobs/root" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard value:"/private/var/at/jobs/*" |
process.args | eq |
| field:"process.args" kind:eq value:"-c" |
process.name | in |
| field:"process_name" kind:in |
process.name | wildcard |
| field:"process_name" kind:wildcard value:"tclsh*" |