Adversaries may use Curl to download malicious payloads or establish command and control channels, leveraging this technique to expand their presence within the network. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential lateral movement or data exfiltration activities early.
KQL Query
let known_files = DeviceNetworkEvents
| where TimeGenerated between (ago(7d)..ago(1d))
| where InitiatingProcessFileName has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,InitiatingProcessCommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, InitiatingProcessCommandLine)
| extend remote_file = iif(isnotempty(url), url, ip)
| union (SecurityEvent
| where TimeGenerated between (ago(7d)..ago(1d))
| where EventID == 4688
| where CommandLine has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,CommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, CommandLine)
| extend remote_file = iif(isnotempty(url), url, ip))
| summarize by remote_file;
DeviceNetworkEvents
| where TimeGenerated > ago(1d)
| where InitiatingProcessFileName has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,InitiatingProcessCommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, InitiatingProcessCommandLine)
| extend remote_file = iif(isnotempty(url), url, ip)
| union (SecurityEvent
| where EventID == 4688
| where CommandLine has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,CommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, CommandLine)
| extend remote_file = iif(isnotempty(url), url, ip))
| where remote_file !in (known_files)
id: 96066361-e101-4c8a-ad37-b0f58d75cd2b
name: Download of New File Using Curl
description: |
'Threat actors may use tools such as Curl to download additional files, communicate with C2 infrastructure, or exfiltrate data. This query looks for new files being downloaded using Curl. Curl also has legitimate uses files and hosts should be reviewed to identify potentially malicious activity.
Ref: https://www.microsoft.com/security/blog/2022/07/27/untangling-knotweed-european-private-sector-offensive-actor-using-0-day-exploits/'
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceNetworkEvents
- connectorId: SecurityEvents
dataTypes:
- SecurityEvents
tactics:
- CommandAndControl
relevantTechniques:
- T1071
query: |
let known_files = DeviceNetworkEvents
| where TimeGenerated between (ago(7d)..ago(1d))
| where InitiatingProcessFileName has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,InitiatingProcessCommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, InitiatingProcessCommandLine)
| extend remote_file = iif(isnotempty(url), url, ip)
| union (SecurityEvent
| where TimeGenerated between (ago(7d)..ago(1d))
| where EventID == 4688
| where CommandLine has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,CommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, CommandLine)
| extend remote_file = iif(isnotempty(url), url, ip))
| summarize by remote_file;
DeviceNetworkEvents
| where TimeGenerated > ago(1d)
| where InitiatingProcessFileName has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,InitiatingProcessCommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, InitiatingProcessCommandLine)
| extend remote_file = iif(isnotempty(url), url, ip)
| union (SecurityEvent
| where EventID == 4688
| where CommandLine has "curl"
| extend url = extract("http[s]?:\\/\\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", 0,CommandLine)
| extend ip = extract("(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}[^ ]*", 0, CommandLine)
| extend remote_file = iif(isnotempty(url), url, ip))
| where remote_file !in (known_files)
entityMappings:
- entityType: URL
fieldMappings:
- identifier: Url
columnName: url
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ip
- entityType: File
fieldMappings:
- identifier: Name
| Sentinel Table | Notes |
|---|---|
DeviceNetworkEvents | Ensure this data connector is enabled |
SecurityEvent | Ensure this data connector is enabled |
Scenario: System Update via Curl
Description: A system administrator uses Curl to download a legitimate system update or patch from a trusted repository.
Filter/Exclusion: process.parent_process contains "sudo" or process.parent_process contains "apt" or process.parent_process contains "yum"
Scenario: Scheduled Job File Download
Description: A scheduled job (e.g., using cron or systemd) uses Curl to fetch a configuration file or script from a secure internal server.
Filter/Exclusion: process.parent_process contains "cron" or process.parent_process contains "systemd" or process.parent_process contains "at"
Scenario: API Integration Testing
Description: A developer is testing an API integration using Curl to send or receive data from a known internal service.
Filter/Exclusion: process.parent_process contains "bash" or process.parent_process contains "node" or process.parent_process contains "python"
Scenario: Log File Collection
Description: A log aggregation tool (e.g., logrotate, rsyslog, or fluentd) uses Curl to send log files to a centralized logging server.
Filter/Exclusion: process.name contains "logrotate" or process.name contains "rsyslog" or process.name contains "fluentd"
Scenario: Internal File Sync via Curl
Description: An internal file sync tool (e.g., rsync or scp) uses Curl as part of its workflow to transfer files between servers.
Filter/Exclusion: process.name contains "rsync" or process.name contains "scp" or process.name contains "sync"