Detection rules › Kusto
CertUtil Used for File Download (Living off the Land)
Detects certutil.exe being used to download files from remote URLs via the -urlcache or -verifyctl flags. CertUtil is a signed Windows binary (LOLBin) that attackers abuse to download payloads while bypassing application whitelisting and network controls. Tune AllowlistedDomains to match your PKI/CA infrastructure.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth | |
| Command & Control |
Telemetry coverage
Rule body
id: 4a9d3c2e-7f1b-4e58-9a0c-2d5b8e3f1a7c
name: CertUtil Used for File Download (Living off the Land)
description: |
Detects certutil.exe being used to download files from remote URLs via the
-urlcache or -verifyctl flags. CertUtil is a signed Windows binary (LOLBin)
that attackers abuse to download payloads while bypassing application
whitelisting and network controls.
Tune AllowlistedDomains to match your PKI/CA infrastructure.
severity: High
status: Available
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceProcessEvents
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
- DefenseEvasion
relevantTechniques:
- T1105
- T1218
- T1140
query: |
let Lookback = 1h;
let AllowlistedDomains = dynamic([
"windowsupdate.microsoft.com",
"download.microsoft.com",
"dl.delivery.mp.microsoft.com",
"ctldl.windowsupdate.com"
]);
let MDE_Results =
DeviceProcessEvents
| where Timestamp >= ago(Lookback)
| where FileName =~ "certutil.exe"
| where ProcessCommandLine has_any ("-urlcache", "-verifyctl", "-decode", "-decodehex")
| where ProcessCommandLine has_any ("http://", "https://", "ftp://")
| where not(ProcessCommandLine has_any (AllowlistedDomains))
| extend
AccountName = InitiatingProcessAccountName,
AccountDomain = InitiatingProcessAccountDomain,
HostName = DeviceName,
EventTime = Timestamp
| project EventTime, HostName, AccountName, AccountDomain,
ProcessCommandLine, InitiatingProcessFileName;
let SecEvent_Results =
SecurityEvent
| where TimeGenerated >= ago(Lookback)
| where EventID == 4688
| where NewProcessName endswith "\\certutil.exe"
| where CommandLine has_any ("-urlcache", "-verifyctl", "-decode", "-decodehex")
| where CommandLine has_any ("http://", "https://", "ftp://")
| where not(CommandLine has_any (AllowlistedDomains))
| extend
AccountName = SubjectUserName,
AccountDomain = SubjectDomainName,
HostName = Computer,
EventTime = TimeGenerated,
ProcessCommandLine = CommandLine,
InitiatingProcessFileName = ParentProcessName
| project EventTime, HostName, AccountName, AccountDomain,
ProcessCommandLine, InitiatingProcessFileName;
union MDE_Results, SecEvent_Results
| sort by EventTime desc
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: HostName
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: NTDomain
columnName: AccountDomain
- entityType: Process
fieldMappings:
- identifier: CommandLine
columnName: ProcessCommandLine
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 0: let
let Lookback = 1h;
let AllowlistedDomains = dynamic([
"windowsupdate.microsoft.com",
"download.microsoft.com",
"dl.delivery.mp.microsoft.com",
"ctldl.windowsupdate.com"
]);
let MDE_Results = DeviceProcessEvents <inlined as stages below>;
let SecEvent_Results = SecurityEvent <inlined as stages below>;
Stage 1: source
let MDE_Results
Stage 2: source
let SecEvent_Results
Stage 3: union
union of 2 branches
Stage 4: source
DeviceProcessEvents
Stage 5: where
where Timestamp >= ago(3600s)
Stage 6: where
where FileName =~ "certutil.exe"
Stage 7: where
where (ProcessCommandLine contains "-urlcache" or ProcessCommandLine contains "-verifyctl" or ProcessCommandLine contains "-decode" or ProcessCommandLine contains "-decodehex")
Stage 8: where
where (ProcessCommandLine contains "http://" or ProcessCommandLine contains "https://" or ProcessCommandLine contains "ftp://")
Stage 9: where
where not ((ProcessCommandLine contains "windowsupdate.microsoft.com" or ProcessCommandLine contains "download.microsoft.com" or ProcessCommandLine contains "dl.delivery.mp.microsoft.com" or ProcessCommandLine contains "ctldl.windowsupdate.com"))
Stage 10: extend
extend AccountDomain, AccountName, EventTime, HostName
Stage 11: project
project AccountDomain, AccountName, EventTime, HostName, InitiatingProcessFileName, ProcessCommandLine
Stage 12: source
SecurityEvent
Stage 13: where
where TimeGenerated >= ago(3600s)
Stage 14: where
where EventID == 4688
Stage 15: where
where NewProcessName endswith @"\certutil.exe"
Stage 16: where
where (CommandLine contains "-urlcache" or CommandLine contains "-verifyctl" or CommandLine contains "-decode" or CommandLine contains "-decodehex")
Stage 17: where
where (CommandLine contains "http://" or CommandLine contains "https://" or CommandLine contains "ftp://")
Stage 18: where
where not ((CommandLine contains "windowsupdate.microsoft.com" or CommandLine contains "download.microsoft.com" or CommandLine contains "dl.delivery.mp.microsoft.com" or CommandLine contains "ctldl.windowsupdate.com"))
Stage 19: extend
extend AccountDomain, AccountName, EventTime, HostName, InitiatingProcessFileName, ProcessCommandLine
Stage 20: project
project AccountDomain, AccountName, EventTime, HostName, InitiatingProcessFileName, ProcessCommandLine
Stage 21: sort
sort by EventTime
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
CommandLine | match |
| field:"CommandLine" kind:match |
EventID | eq |
| field:"EventID" kind:eq value:"4688" |
FileName | eq |
| field:"file_name" kind:eq value:"certutil.exe" |
NewProcessName | ends_with |
| field:"Image" kind:ends_with value:"\certutil.exe" |
ProcessCommandLine | match |
| field:"CommandLine" kind:match |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
ProcessCommandLine | match | windowsupdate.microsoft.com, download.microsoft.com, dl.delivery.mp.microsoft.com, ctldl.windowsupdate.com | excludes:ProcessCommandLine |
CommandLine | match | windowsupdate.microsoft.com, download.microsoft.com, dl.delivery.mp.microsoft.com, ctldl.windowsupdate.com | excludes:CommandLine |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountDomain | project |
AccountName | project |
EventTime | project |
HostName | project |
InitiatingProcessFileName | project |
ProcessCommandLine | project |