70 строки
3.8 KiB
YAML
70 строки
3.8 KiB
YAML
|
id: 55fbc363-6cc9-4201-bd68-d980b612082b
|
||
|
name: Azure VM Run Command linked with MDE
|
||
|
description: |
|
||
|
'Identifies any Azure VM Run Command operations and links these operations with
|
||
|
MDE host logging. Linking these two data sources provides hunting opportunities.
|
||
|
Logging from AzureActivity provides the IP address and UPN of the account that
|
||
|
invoked the command. Joining this with logging from MDE provides insights into
|
||
|
what cmdlets were loaded by the command.'
|
||
|
requiredDataConnectors:
|
||
|
- connectorId: AzureActivity
|
||
|
dataTypes:
|
||
|
- AzureActivity
|
||
|
- connectorId: MicrosoftThreatProtection
|
||
|
dataTypes:
|
||
|
- DeviceFileEvents
|
||
|
- DeviceEvents
|
||
|
tactics:
|
||
|
- LateralMovement
|
||
|
- CredentialAccess
|
||
|
relevantTechniques:
|
||
|
- T1570
|
||
|
- T1078.004
|
||
|
query: |
|
||
|
AzureActivity
|
||
|
// Isolate run command actions
|
||
|
| where OperationNameValue == "Microsoft.Compute/virtualMachines/runCommand/action"
|
||
|
// Confirm that the operation impacted a virtual machine
|
||
|
| where Authorization has "virtualMachines"
|
||
|
// Each runcommand operation consists of three events when successful, Started, Accepted (or Rejected), Successful (or Failed).
|
||
|
| summarize StartTime=min(TimeGenerated), EndTime=max(TimeGenerated), max(CallerIpAddress), make_list(ActivityStatusValue) by CorrelationId, Authorization, Caller
|
||
|
// Limit to Run Command executions that Succeeded
|
||
|
| where list_ActivityStatusValue has "Succeeded"
|
||
|
// Extract data from the Authorization field, allowing us to later extract the Caller (UPN) and CallerIpAddress
|
||
|
| extend Authorization_d = parse_json(Authorization)
|
||
|
| extend Scope = Authorization_d.scope
|
||
|
| extend Scope_s = split(Scope, "/")
|
||
|
| extend Subscription = tostring(Scope_s[2])
|
||
|
| extend VirtualMachineName = tostring(Scope_s[-1])
|
||
|
| project StartTime, EndTime, Subscription, VirtualMachineName, CorrelationId, Caller, CallerIpAddress=max_CallerIpAddress
|
||
|
| join kind=leftouter (
|
||
|
DeviceFileEvents
|
||
|
| where InitiatingProcessFileName == "RunCommandExtension.exe"
|
||
|
| extend VirtualMachineName = tostring(split(DeviceName, ".")[0])
|
||
|
| project VirtualMachineName, PowershellFileCreatedTimestamp=TimeGenerated, FileName, FileSize, InitiatingProcessAccountName, InitiatingProcessAccountDomain, InitiatingProcessFolderPath, InitiatingProcessId
|
||
|
) on VirtualMachineName
|
||
|
// We need to filter by time sadly, this is the only way to link events
|
||
|
| where PowershellFileCreatedTimestamp between (StartTime .. EndTime)
|
||
|
| project StartTime, EndTime, PowershellFileCreatedTimestamp, VirtualMachineName, Caller, CallerIpAddress, FileName, FileSize, InitiatingProcessId, InitiatingProcessAccountDomain, InitiatingProcessFolderPath
|
||
|
| join kind=inner(
|
||
|
DeviceEvents
|
||
|
| extend VirtualMachineName = tostring(split(DeviceName, ".")[0])
|
||
|
| where InitiatingProcessCommandLine has "-File"
|
||
|
| extend PowershellFileName = extract(@"\-File\s(script[0-9]{1,9}\.ps1)", 1, InitiatingProcessCommandLine)
|
||
|
| extend PSCommand = tostring(parse_json(AdditionalFields).Command)
|
||
|
| order by TimeGenerated asc
|
||
|
| where PSCommand != PowershellFileName
|
||
|
| summarize PowershellExecStart=min(TimeGenerated), PowershellExecEnd=max(TimeGenerated), make_list(PSCommand) by PowershellFileName, InitiatingProcessCommandLine
|
||
|
) on $left.FileName == $right.PowershellFileName
|
||
|
| project StartTime, EndTime, PowershellFileCreatedTimestamp, PowershellExecStart, PowershellExecEnd, PowershellFileName, PowershellScriptCommands=list_PSCommand, Caller, CallerIpAddress, InitiatingProcessCommandLine, PowershellFileSize=FileSize, VirtualMachineName
|
||
|
| order by StartTime asc
|
||
|
| extend ScriptFingerprintHash = hash_sha256(tostring(PowershellScriptCommands))
|
||
|
entityMappings:
|
||
|
- entityType: Account
|
||
|
fieldMappings:
|
||
|
- identifier: FullName
|
||
|
columnName: AccountCustomEntity
|
||
|
- entityType: IP
|
||
|
fieldMappings:
|
||
|
- identifier: Address
|
||
|
columnName: IPCustomEntity
|