Detection rules › Elastic

Potential Data Exfiltration via Curl

Time window
15s
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Detects the use of curl to upload an archived file to an internet server. Threat actors often will collect data on a system and compress it in an archive file before exfiltrating the file back to their C2 server for review. Many threat actors have been seen utilizing curl to upload this archive file with the collected data to do this. Use of curl in this way while not inherently malicious should be considered highly abnormal and suspicious activity.

MITRE ATT&CK coverage

Telemetry coverage

Rule body

[rule]
description = """
Detects the use of curl to upload an archived file to an internet server. Threat actors often will collect data on a
system and compress it in an archive file before exfiltrating the file back to their C2 server for review. Many threat
actors have been seen utilizing curl to upload this archive file with the collected data to do this. Use of curl in this
way while not inherently malicious should be considered highly abnormal and suspicious activity.
"""
id = "192ec591-1d00-4c16-a717-8a7481038d23"
license = "Elastic License v2"
name = "Potential Data Exfiltration via Curl"
os_list = ["macos"]
reference = [
    "https://everything.curl.dev/usingcurl/uploads",
    "https://objective-see.org/blog/blog_0x71.html#-sentinelsneak",
    "https://objective-see.org/blog/blog_0x66.html",
]
version = "1.0.40"

query = '''
sequence by process.entity_id with maxspan=15s
[process where event.type == "start" and event.action == "exec" and process.name == "curl" and 
 process.args like~ ("-F", "-T", "-d", "--data*") and 
 process.args like~ ("*@*.zip", "*@*.gz", "*@*.tgz", "b64=@*") and 
 process.args like~ "http*" and
 (process.parent.name like~ ("osascript", "python*", "node", "ruby", "bash", "sh", "zsh", "perl") or (process.parent.code_signature.trusted == false or process.parent.code_signature.exists == false)) and
 not process.args like ("Authorization*", "PRIVATE-TOKEN*") and 
 not process.parent.command_line like "/bin/bash --init-file /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.sh" and
 not process.Ext.effective_parent.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                               "/Applications/Support.app/Contents/MacOS/Support")]
[network where event.type == "start" and not destination.domain : ("*.cloud.es.io", "*.elastic-cloud.com")]
'''

min_endpoint_version = "8.16.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 = "T1048"
name = "Exfiltration Over Alternative Protocol"
reference = "https://attack.mitre.org/techniques/T1048/"


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

[internal]
min_endpoint_version = "8.16.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 15s, correlated by process.entity_id.

Stage 1: process

[process where event.type == "start" and event.action == "exec" and process.name == "curl" and 
 process.args like~ ("-F", "-T", "-d", "--data*") and 
 process.args like~ ("*@*.zip", "*@*.gz", "*@*.tgz", "b64=@*") and 
 process.args like~ "http*" and
 (process.parent.name like~ ("osascript", "python*", "node", "ruby", "bash", "sh", "zsh", "perl") or (process.parent.code_signature.trusted == false or process.parent.code_signature.exists == false)) and
 not process.args like ("Authorization*", "PRIVATE-TOKEN*") and 
 not process.parent.command_line like "/bin/bash --init-file /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.sh" and
 not process.Ext.effective_parent.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                               "/Applications/Support.app/Contents/MacOS/Support")]

Stage 2: network

[network where event.type == "start" and not destination.domain : ("*.cloud.es.io", "*.elastic-cloud.com")]

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.Ext.effective_parent.executableeq/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon, /Applications/Support.app/Contents/MacOS/Supportexcludes:process.Ext.effective_parent.executable field:"process.Ext.effective_parent.executable" value:"/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon" field:"process.Ext.effective_parent.executable" value:"/Applications/Support.app/Contents/MacOS/Support"
process.argsstarts_withAuthorization, PRIVATE-TOKENexcludes:process.args field:"process.args" value:"Authorization" field:"process.args" value:"PRIVATE-TOKEN"
process.parent.command_lineeq/bin/bash --init-file /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.shexcludes:process.parent.command_line field:"process.parent.command_line" value:"/bin/bash --init-file /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.sh"
destination.domainends_with.cloud.es.io, .elastic-cloud.comexcludes:destination.domain field:"destination.domain" value:".cloud.es.io" field:"destination.domain" value:".elastic-cloud.com"

Indicators

These rows show field, operator, and value matches.