Detection rules › Kusto
Detect Unsigned executable launch from scheduled task
Persistence via Scheduled Tasks is a well-known technique used by adversaries to make sure their malware programs keep running an the compromised device. With this detection rule, you can search for unknown executables being launched from scheduled tasks. > [!WARNING] > This detection rule is the base for the detection. You will need to add environment specific finetuning in order to limit the BP detections on legitimate processes
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence | |
| Privilege Escalation |
References
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Microsoft Defender for Endpoint | DeviceProcessEvents action any: Process activity |
Rule body
let scheduled_binaries = (
DeviceProcessEvents
| where ActionType !contains "aggregated"
| where Timestamp > ago(1h)
| where InitiatingProcessCommandLine == "svchost.exe -k netsvcs -p -s Schedule"
| distinct SHA1
);
let untrusted_binaries = (
scheduled_binaries
| join kind=leftanti (
DeviceFileCertificateInfo
| where Timestamp > ago(1h)
| summarize max_trusted=max(IsTrusted) by SHA1
| where max_trusted==1
) on SHA1
);
untrusted_binaries
| invoke FileProfile(SHA1,1000)
| where IsCertificateValid != 1 // Exclude signed binaries
| where (isnotempty(GlobalPrevalence) and GlobalPrevalence < 1000)
| join (
DeviceProcessEvents
| where ActionType !contains "aggregated"
| where InitiatingProcessCommandLine == "svchost.exe -k netsvcs -p -s Schedule"
) on SHA1
Stages and Predicates
let scheduled_binaries and let untrusted_binaries are inlined into the numbered stages below.
Stage 1: source
let scheduled_binaries
Stage 2: source
let untrusted_binaries
Stage 3: source
DeviceProcessEvents
Stage 4: where
where not (ActionType contains "aggregated")
Stage 5: where
where Timestamp > ago(3600s)
Stage 6: where
where InitiatingProcessCommandLine =~ "svchost.exe -k netsvcs -p -s Schedule"
Stage 7: distinct
distinct SHA1
Stage 8: join (negated)
join kind=leftanti (DeviceFileCertificateInfo) on SHA1
Stage 9: invoke
invoke
Stage 10: where
where IsCertificateValid != 1
Stage 11: where
where isnotempty(GlobalPrevalence) and GlobalPrevalence < 1000
Stage 12: join
join (DeviceProcessEvents) on SHA1
Stage 13: summarize aggregation inside the join branch
summarize by SHA1
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
ActionType | contains | aggregated | excludes:ActionType field:"ActionType" value:"aggregated" |
max_trusted | eq | 1 | excludes:max_trusted field:"max_trusted" value:"1" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
GlobalPrevalence | is_not_null | field:"GlobalPrevalence" kind:is_not_null | |
GlobalPrevalence | lt |
| field:"GlobalPrevalence" kind:lt value:"1000" |
InitiatingProcessCommandLine | eq |
| field:"ParentCommandLine" kind:eq value:"svchost.exe -k netsvcs -p -s Schedule" |
IsCertificateValid | ne |
| field:"IsCertificateValid" kind:ne value:"1" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
SHA1 | summarize |