Query Details
let query_frequency = 1h;
let query_lookback = 1h;
let query_lookahead = 6h;
let query_period = query_frequency + max_of(query_lookback, query_lookahead);
AzureActivity
| where TimeGenerated > ago(query_frequency + query_lookback)
| where OperationNameValue =~ "Microsoft.Compute/virtualMachines/runCommand/action"
| summarize
StartTime = arg_min(TimeGenerated, *),
EndTime = max(TimeGenerated),
ActivityStatusValueList = make_list(ActivityStatus)
by CorrelationId
| where ActivityStatusValueList has_any ("Succeeded", "Success")
| extend AuxiliarCaller = tolower(Caller)
| join kind=inner (
BehaviorAnalytics
| where TimeGenerated > ago(query_period)
| where ActivityType in ("LogOn", "FailedLogOn") and ActivityInsights["ActionUncommonlyPerformedByUser"] == "True"
| where isnotempty(UserPrincipalName)
| project
UEBA_TimeGenerated = TimeGenerated,
UEBA_EventSource = EventSource,
UEBA_ActivityType = ActivityType,
UEBA_ActionType = ActionType,
UEBA_SourceIPAddress = SourceIPAddress,
UEBA_SourceIPLocation = SourceIPLocation,
UEBA_SourceDevice = SourceDevice,
UEBA_ActivityInsights = ActivityInsights,
UEBA_UsersInsights = UsersInsights,
AuxiliarCaller = tolower(UserPrincipalName)
) on AuxiliarCaller
// Deduplicate alerts
| where UEBA_TimeGenerated > ago(query_frequency) or StartTime > ago(query_frequency)
| where StartTime between ((UEBA_TimeGenerated - query_lookback) .. (UEBA_TimeGenerated + query_lookahead))
| project
UEBA_TimeGenerated,
StartTime,
EndTime,
Caller,
CallerIpAddress,
OperationName,
OperationNameValue,
ActivityStatusValueList,
SubscriptionId,
ResourceGroup,
Resource,
Authorization,
Properties,
HTTPRequest,
ResourceId,
UEBA_EventSource,
UEBA_ActivityType,
UEBA_ActionType,
UEBA_SourceIPAddress,
UEBA_SourceIPLocation,
UEBA_SourceDevice,
UEBA_ActivityInsights,
UEBA_UsersInsights
This query is designed to analyze Azure activity and behavior analytics data. It is set to run every hour, looking back one hour and ahead six hours.
The query first filters Azure activity data for operations related to running commands on virtual machines. It then groups this data by correlation ID, summarizing the start and end times, and the activity status. It only keeps records where the activity status is either "Succeeded" or "Success".
Next, the query joins this data with behavior analytics data, specifically looking for logon activities and failed logon attempts that are flagged as uncommon for the user. It only includes records where the user principal name is not empty.
The query then deduplicates any alerts and filters the data to only include records where the behavior analytics time generated or the Azure activity start time is within the past hour. It also filters the data to only include records where the Azure activity start time is within one hour before or six hours after the behavior analytics time generated.
Finally, the query projects a number of fields from both the Azure activity and behavior analytics data, including time generated, start and end times, caller information, operation names and values, activity status, subscription ID, resource information, HTTP request, resource ID, event source, activity type, action type, source IP address and location, source device, and activity and user insights.

Jose Sebastián Canós
Released: January 4, 2023
Tables
Keywords
Operators