Detection rules › Kusto

Detect process drops via Azure Custom Script Extension performing lateral movement

Group by
InitiatingProcessSHA256, SHA256
Author
Robbe Van den Daele
Source
github.com/HybridBrothers/Hunting-Queries-Detection-Rules

This detection rule spots processes that where dropped via Azure Custom Script Extension on a machine and are now performing lateral movement. A common procedures for attackers when they compromised one machine is to move laterally to other machines via common protocols such as RDP, SSH, VNC, WMI, RPC, etc. It is not very common in an environment that Custom Script Extensions is being used for this.

MITRE ATT&CK coverage

References

Event coverage

Rule body yaml

let process_drop_via_arc = (
    DeviceFileEvents
    | where TimeGenerated > ago(7d)
    // Search for file created events by Arc Custom Script Handler
    | where ActionType == "FileCreated"
    | where InitiatingProcessFileName =~ "customscripthandler.exe"
    | where isnotempty(SHA256)
    | distinct SHA256
);
DeviceNetworkEvents
| where TimeGenerated > ago(1h)
| join kind=inner process_drop_via_arc on $left.InitiatingProcessSHA256 == $right.SHA256
| where RemotePort in ("5985", "5986", "445", "3389", "22", "5900", "135")
| where ActionType in~ ("ConnectionSuccess", "ConnectionAttempt", 
"ConnectionFailed", "ConnectionRequest")

Stages and Predicates

Let binding: process_drop_via_arc

let process_drop_via_arc = (
    DeviceFileEvents
    | where TimeGenerated > ago(7d)
    | where ActionType == "FileCreated"
    | where InitiatingProcessFileName =~ "customscripthandler.exe"
    | where isnotempty(SHA256)
    | distinct SHA256
);

Stage 1: source

DeviceNetworkEvents

Stage 2: where

| where TimeGenerated > ago(1h)

Stage 3: join

| join kind=inner process_drop_via_arc on $left.InitiatingProcessSHA256 == $right.SHA256

Stage 4: where

| where RemotePort in ("5985", "5986", "445", "3389", "22", "5900", "135")

Stage 5: where

| where ActionType in~ ("ConnectionSuccess", "ConnectionAttempt", 
"ConnectionFailed", "ConnectionRequest")

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)
ActionTypein
  • ConnectionAttempt
  • ConnectionFailed
  • ConnectionRequest
  • ConnectionSuccess corpus 9 (kusto 9)
InitiatingProcessFileNameeq
  • customscripthandler.exe corpus 2 (kusto 2)
RemotePortin
  • 135 transforms: cased corpus 5 (elastic 4, sigma 1)
  • 22 transforms: cased
  • 3389 transforms: cased corpus 11 (kusto 4, elastic 3, sigma 2, splunk 2)
  • 445 transforms: cased corpus 8 (elastic 5, splunk 2, sigma 1)
  • 5900 transforms: cased
  • 5985 transforms: cased corpus 3 (sigma 2, chronicle 1)
  • 5986 transforms: cased corpus 3 (sigma 2, chronicle 1)
SHA256is_not_null
  • (no value, null check)