Detection rules › Kusto

Detect executable drops via Azure custom script extension

Author
Robbe Van den Daele
Source
github.com/HybridBrothers/Hunting-Queries-Detection-Rules

This detection rule flags when the Custom Script extension service on a machine is dropping executable files. This might indicate that an actor is trying to drop malware or beacons via a compromised cloud admin account. In the most legitimate cases administrators are pushing only PowerShell or Shell scripts, although these can also contain malicious content. Be aware of this gap in the below detection rule.

MITRE ATT&CK coverage

References

Event coverage

Rule body yaml

// Executable extensions we want to flag (you can also add .ps1 and .sh)
let win_executable_extensions = dynamic([".dll", ".exe", ".msi", ".bat", ".cmd", ".com", ".vbs", ".wsf", ".scr", ".cpl"]);
DeviceFileEvents
| where TimeGenerated > ago(1h)
// Search for file created events by Arc Custom Script Handler
| where ActionType == "FileCreated"
| where InitiatingProcessFileName =~ "customscripthandler.exe"
// Get the file type
| extend FileType = tostring(parse_json(AdditionalFields).FileType)
// Flag on extension or executable file type
| where FileName has_any (win_executable_extensions) or 
    FileType contains "Executable"

Stages and Predicates

Parameters

let win_executable_extensions = dynamic([".dll", ".exe", ".msi", ".bat", ".cmd", ".com", ".vbs", ".wsf", ".scr", ".cpl"]);

Stage 1: source

DeviceFileEvents

Stage 2: where

| where TimeGenerated > ago(1h)

Stage 3: where

| where ActionType == "FileCreated"

Stage 4: where

| where InitiatingProcessFileName =~ "customscripthandler.exe"

Stage 5: extend

| extend FileType = tostring(parse_json(AdditionalFields).FileType)

Stage 6: where

| where FileName has_any (win_executable_extensions) or 
    FileType contains "Executable"

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
ActionTypeeq
  • FileCreated transforms: cased corpus 8 (kusto 8)
FileNamematch
  • .bat corpus 2 (kusto 2)
  • .cmd corpus 2 (kusto 2)
  • .com corpus 2 (kusto 2)
  • .cpl corpus 2 (kusto 2)
  • .dll corpus 2 (kusto 2)
  • .exe corpus 2 (kusto 2)
  • .msi
  • .scr
  • .vbs corpus 2 (kusto 2)
  • .wsf
FileTypecontains
  • Executable
InitiatingProcessFileNameeq
  • customscripthandler.exe corpus 2 (kusto 2)

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
FileTypeextend