Detection rules › Kusto

ASR Rare and Untrusted Executables

Group by
FileName, SHA1
Author
Cyb3rMonk
Source
github.com/Cyb3r-Monk/Threat-Hunting-and-Detection

Below query shows Untrusted executables that are seen on few devices (LocalPrevalence). It requires the below ASR rule to be configured and Cloud-delivered protection to be enabled.
Block executable files from running unless they meet a prevalence, age, or trusted list criterion
You may need to exclude software development users/machines/folders.

MITRE ATT&CK coverage

TacticTechniques
StealthNo specific technique

References

Event coverage

ProviderEvent/ActionTypeTitle
Defender-DeviceEventsAsrUntrustedExecutableAuditedASR untrusted executable (audited)
Windows-DefenderEvent ID 1121Event ID 1121
Windows-DefenderEvent ID 1122Event ID 1122

Rule body kusto

// Author: Cyb3rMonk(https://twitter.com/Cyb3rMonk, https://mergene.medium.com)
//
// Query parameters:
DeviceEvents
| where Timestamp > ago(30d)
| where ActionType in ("AsrUntrustedExecutableAudited","AsrUntrustedExecutableBlocked")
| summarize arg_min(Timestamp,*), LocalPrevalence = dcount(DeviceId) by SHA1, FileName
| where Timestamp > ago(1d)
| where LocalPrevalence <= 5
// there might be files without signature info, perform leftouter join
| join kind=leftouter (
    DeviceFileCertificateInfo
    | where Timestamp > ago(30d)
    | summarize arg_max(Timestamp,*) by SHA1
    )
    on SHA1
// Get GlobalPrevalence info, etc.
| invoke FileProfile(SHA1, 1000)
// GlobalFirstSeen can be used for filtering the results further
// If you want to list only the files that have invalid signatures uncomment the below line
// there might be files without signature info, don't exclude them
// | where IsTrusted <> 1

Stages and Predicates

Stage 1: source

DeviceEvents

Stage 2: where

| where Timestamp > ago(30d)

Stage 3: where

| where ActionType in ("AsrUntrustedExecutableAudited","AsrUntrustedExecutableBlocked")

Stage 4: summarize

| summarize arg_min(Timestamp,*), LocalPrevalence = dcount(DeviceId) by SHA1, FileName
Threshold
le 5

Stage 5: where

| where Timestamp > ago(1d)

Stage 6: where

| where LocalPrevalence <= 5

Stage 7: join

| join kind=leftouter (
    DeviceFileCertificateInfo
    | where Timestamp > ago(30d)
    | summarize arg_max(Timestamp,*) by SHA1
    )
    on SHA1

Stage 8: invoke

| invoke FileProfile(SHA1, 1000)

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.

FieldKindValues
ActionTypein
  • AsrUntrustedExecutableAudited transforms: cased
  • AsrUntrustedExecutableBlocked transforms: cased
LocalPrevalencele
  • 5 transforms: cased

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.

FieldSource
FileNamesummarize
LocalPrevalencesummarize
SHA1summarize