Detection rules › Kusto
Ingress Tool Transfer - Certutil
This detection addresses most of the known ways to utilize this binary for malicious/unintended purposes. It attempts to accommodate for most detection evasion techniques, like commandline obfuscation and binary renaming.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth | T1027 Obfuscated Files or Information, T1140 Deobfuscate/Decode Files or Information, T1564.004 Hide Artifacts: NTFS File Attributes |
| Command & Control | T1105 Ingress Tool Transfer |
Event coverage
| Provider | Event/ActionType | Title |
|---|---|---|
| Sysmon | Event ID 1 | Process creation |
| Security-Auditing | Event ID 4688 | A new process has been created. |
| Defender-DeviceProcessEvents | any | Process activity (any) |
Rule body kusto
id: f0be11a9-ec48-4df6-801d-479556044d4e
name: Ingress Tool Transfer - Certutil
description: |
This detection addresses most of the known ways to utilize this binary for malicious/unintended purposes.
It attempts to accommodate for most detection evasion techniques, like commandline obfuscation and binary renaming.
severity: Low
status: Available
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceProcessEvents
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
- DefenseEvasion
relevantTechniques:
- T1105
- T1564.004
- T1027
- T1140
query: |
// Set the time span for the query.
let Timeframe = 1h;
// Set the HashTimeframe for the hash lookup; longer makes it more accurate, but obviously also more resource-intensive.
let HashTimeframe = 14d;
// Get all known SHA1 hashes for certutil executions or renamed files formerly named certutil.
let CertUtilPESha1=materialize(DeviceProcessEvents | where Timestamp > ago(HashTimeframe)| where FileName has "certutil" | where isnotempty(SHA1) | summarize sha1=make_set(SHA1));
let CertUtilFESha1=materialize(DeviceFileEvents | where Timestamp > ago(HashTimeframe)| where PreviousFileName contains "certutil" or FileName contains "certutil" | where isnotempty(SHA1) | summarize sha1=make_set(SHA1));
DeviceProcessEvents
| where Timestamp >= ago(Timeframe)
// Get all executions by processes with a SHA1 hash that is or was named certutil.
| where SHA1 in (CertUtilPESha1) or SHA1 in (CertUtilFESha1) or FileName =~ "certutil.exe" or ProcessCommandLine has "certutil"
// Create a new field called CleanProcessCommandLine which gets populated with the value of ProcessCommandLine as Windows parses it for execution,
// removing any potential command line obfuscation.
| extend CleanProcessCommandLine=parse_command_line(ProcessCommandLine, "windows")
// Search for de-obfuscated commands used.
// Urlcache is the documented attribute. However, url is also accepted.
// Verifyctl is the documented attribute. However, verify is also accepted.
| where CleanProcessCommandLine has_any ("decode", "encode", "verify","url")
| order by Timestamp
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: DeviceName
- entityType: Account
fieldMappings:
- identifier: Sid
columnName: AccountSid
- identifier: Name
columnName: AccountName
- identifier: NTDomain
columnName: AccountDomain
- entityType: Process
fieldMappings:
- identifier: CommandLine
columnName: ProcessCommandLine
version: 1.0.0
kind: Scheduled
Stages and Predicates
Parameters
let Timeframe = 1h;
let HashTimeframe = 14d;
Let binding: CertUtilPESha1
let CertUtilPESha1 = materialize(DeviceProcessEvents | where Timestamp > ago(HashTimeframe)| where FileName has "certutil" | where isnotempty(SHA1) | summarize sha1=make_set(SHA1));
Derived from HashTimeframe.
Let binding: CertUtilFESha1
let CertUtilFESha1 = materialize(DeviceFileEvents | where Timestamp > ago(HashTimeframe)| where PreviousFileName contains "certutil" or FileName contains "certutil" | where isnotempty(SHA1) | summarize sha1=make_set(SHA1));
Derived from HashTimeframe.
Stage 1: source
DeviceProcessEvents
Stage 2: where
| where Timestamp >= ago(Timeframe)
Stage 3: where
| where SHA1 in (CertUtilPESha1) or SHA1 in (CertUtilFESha1) or FileName =~ "certutil.exe" or ProcessCommandLine has "certutil"
References CertUtilFESha1, CertUtilPESha1 (defined above).
Stage 4: extend
| extend CleanProcessCommandLine=parse_command_line(ProcessCommandLine, "windows")
Stage 5: where
| where CleanProcessCommandLine has_any ("decode", "encode", "verify","url")
Stage 6: sort
| order by Timestamp
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
CleanProcessCommandLine | match |
|
FileName | eq |
|
ProcessCommandLine | match |
|
SHA1 | in |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
CleanProcessCommandLine | extend |