Detection rules › Elastic
Suspicious Curl File Download and Execution
Detects when Curl downloads a file to a suspicious directory and that file is immediately executed via the same effective parent process. This behavior is often used by threat actors to download and execute additional payloads or tooling on a target system. While the use of Curl is not inherently malicious, the combination of downloading to temporary or shared directories followed by immediate execution is indicative of potentially malicious activity.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry coverage
Rule body
[rule]
description = """
Detects when Curl downloads a file to a suspicious directory and that file is immediately executed via the same
effective parent process. This behavior is often used by threat actors to download and execute additional payloads or
tooling on a target system. While the use of Curl is not inherently malicious, the combination of downloading to
temporary or shared directories followed by immediate execution is indicative of potentially malicious activity.
"""
id = "ce1df6f8-9ddc-492d-8de3-7c663856c9ca"
license = "Elastic License v2"
name = "Suspicious Curl File Download and Execution"
os_list = ["macos"]
version = "1.0.7"
query = '''
sequence with maxspan=15s
[file where event.action == "modification" and process.name in ("curl", "nscurl") and file.path like ("/Users/Shared/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*", "/private/var/tmp/*") and
not Effective_process.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
"/usr/local/jamf/bin/jamf") and
not file.extension == "pkg"] as event0
[process where event.type == "start" and event.action == "exec" and process.name in ("bash", "sh", "zsh") and stringcontains~(event0.file.name, process.command_line)]
'''
min_endpoint_version = "8.16.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "Effective_process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.16.0"
Stages and Predicates
Stage 1: file
[file where event.action == "modification" and process.name in ("curl", "nscurl") and file.path like ("/Users/Shared/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*", "/private/var/tmp/*") and
not Effective_process.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
"/usr/local/jamf/bin/jamf") and
not file.extension == "pkg"] as event0
Stage 2: process
[process where event.type == "start" and event.action == "exec" and process.name in ("bash", "sh", "zsh") and stringcontains~(event0.file.name, process.command_line)]
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
Effective_process.executable | eq | /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon, /usr/local/jamf/bin/jamf | excludes:Effective_process.executable field:"Effective_process.executable" value:"/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon" field:"Effective_process.executable" value:"/usr/local/jamf/bin/jamf" |
file.extension | eq | pkg | excludes:file.extension field:"file.extension" value:"pkg" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
event0.file.name | contains |
| field:"event0.file.name" kind:contains value:"process.command_line" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.name | in |
| field:"process_name" kind:in |