Detections/MultipleDataSources/RunCommandUEBABreach.yaml (79 lines of code) (raw):

id: 11bda520-a965-4654-9a45-d09f372f71aa name: Azure VM Run Command operation executed during suspicious login window description: | 'Identifies when the Azure Run Command operation is executed by a UserPrincipalName and IP Address that has resulted in a recent user entity behaviour alert.' severity: High requiredDataConnectors: - connectorId: AzureActivity dataTypes: - AzureActivity - connectorId: BehaviorAnalytics dataTypes: - BehaviorAnalytics queryFrequency: 1d queryPeriod: 2d triggerOperator: gt triggerThreshold: 0 tactics: - LateralMovement - CredentialAccess relevantTechniques: - T1570 - T1212 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_any ("Success", "Succeeded") // Extract data from the Authorization field | 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 // Create a join key using the Caller (UPN) | extend joinkey = tolower(Caller) // Join the Run Command actions to UEBA data | join kind = inner ( BehaviorAnalytics // We are specifically interested in unusual logins | where EventSource == "Azure AD" and ActivityInsights.ActionUncommonlyPerformedByUser == "True" | project UEBAEventTime=TimeGenerated, UEBAActionType=ActionType, UserPrincipalName, UEBASourceIPLocation=SourceIPLocation, UEBAActivityInsights=ActivityInsights, UEBAUsersInsights=UsersInsights | where isnotempty(UserPrincipalName) and isnotempty(UEBASourceIPLocation) | extend joinkey = tolower(UserPrincipalName) ) on joinkey // Create a window around the UEBA event times, check to see if the Run Command action was performed within them | extend UEBAWindowStart = UEBAEventTime - 1h, UEBAWindowEnd = UEBAEventTime + 6h | where StartTime between (UEBAWindowStart .. UEBAWindowEnd) | project StartTime, EndTime, Subscription, VirtualMachineName, Caller, CallerIpAddress, UEBAEventTime, UEBAActionType, UEBASourceIPLocation, UEBAActivityInsights, UEBAUsersInsights | extend AccountName = tostring(split(Caller, "@")[0]), AccountUPNSuffix = tostring(split(Caller, "@")[1]) entityMappings: - entityType: Account fieldMappings: - identifier: FullName columnName: Caller - identifier: Name columnName: AccountName - identifier: UPNSuffix columnName: AccountUPNSuffix - entityType: IP fieldMappings: - identifier: Address columnName: CallerIpAddress version: 1.0.10 kind: Scheduled metadata: source: kind: Community author: name: Microsoft Security Rearch support: tier: Community categories: domains: [ "Security - Others", "Platform" ]