Query Details

Multiple Unsynchronized Defender For Cloud Alert

Query

// https://learn.microsoft.com/en-us/azure/defender-for-cloud/alerts-reference
let query_frequency = 15m;
let query_wait = 15m;
let query_period = 1d;
AzureActivity
| where ingestion_time() between (ago(query_frequency + query_wait) .. ago(query_wait))
| where ResourceProviderValue =~ "MICROSOFT.SECURITY" and OperationNameValue =~ "Microsoft.Security/locations/alerts/activate/action"
| extend PreferenceInteger = case(
    ResourceProviderValue == "Microsoft.Security", 1,
    ResourceProviderValue == "MICROSOFT.SECURITY", 0,
    -1
    )
| summarize hint.shufflekey=CorrelationId
    PropertiesDynamic = make_bag(pack(ResourceProviderValue, todynamic(Properties))),
    EventDataId = make_bag(pack(ResourceProviderValue, EventDataId)),
    take_any(TenantId, SourceSystem, CategoryValue, SubscriptionId, Type),
    arg_min(PreferenceInteger, Properties_d, EventSubmissionTimestamp),
    arg_max(PreferenceInteger, Level, OperationNameValue, OperationId, ResourceGroup, ResourceProviderValue, ActivityStatusValue, OperationName, ActivityStatus, Category, ResourceId, ResourceProvider, Resource)
    by CorrelationId, TimeGenerated, _ResourceId
| extend Key = tostring(bag_keys(PropertiesDynamic)[0])
| extend AlertTitle = tostring(PropertiesDynamic[Key]["eventName"])
| where not((AlertTitle startswith "Security incident" and AlertTitle has "detected")
    or tostring(todynamic(tostring(PropertiesDynamic[Key]["eventProperties"]))["isincident"]) == "****"
    or isnotempty(todynamic(tostring(PropertiesDynamic[Key]["eventProperties"]))["relatedAlerts"])
    )
| project-away PreferenceInteger*
| join kind=leftanti (
    SecurityAlert
    | where TimeGenerated > ago(query_period)
    | where ProductName == "Azure Security Center"
    | distinct VendorOriginalId
    ) on $left.CorrelationId == $right.VendorOriginalId
| extend
    AlertLink = strcat(
    @"https://portal.azure.com/#blade/Microsoft_Azure_Security_AzureDefenderForData/AlertBlade/alertId/",
    CorrelationId,
    "/subscriptionId/",
    tolower(tostring(PropertiesDynamic[Key]["subscriptionId"])),
    "/resourceGroup/",
    tolower(tostring(PropertiesDynamic[Key]["resourceGroup"])),
    "/referencedFrom/alertDeepLink/location/",
    tostring(split(tostring(PropertiesDynamic[Key]["resource"]), "/")[0])
    ),
    AlertSeverity = tostring(todynamic(tostring(PropertiesDynamic[Key]["eventProperties"]))["severity"])
| project
    TimeGenerated,
    ResourceProviderValue,
    SubscriptionId,
    ResourceGroup,
    OperationNameValue,
    AlertTitle,
    AlertSeverity,
    AlertLink,
    CorrelationId,
    PropertiesDynamic,
    EventDataId,
    _ResourceId

Explanation

This KQL (Kusto Query Language) query is designed to analyze Azure Activity logs to identify specific security-related operations and generate alerts. Here's a simplified explanation of what the query does:

  1. Time Frame Definition: The query looks at Azure Activity logs from a specific time window, defined as 15 minutes ago plus a 15-minute wait period.

  2. Filter for Security Operations: It filters the logs to find operations related to Microsoft Security alerts activation.

  3. Data Transformation:

    • It assigns a preference integer based on the resource provider value.
    • It aggregates data by creating dynamic bags of properties and event data IDs for each correlation ID.
    • It selects specific fields and calculates minimum and maximum values for certain attributes.
  4. Alert Title Extraction: It extracts the alert title from the properties and filters out certain alerts based on specific conditions (e.g., not starting with "Security incident" or having certain properties).

  5. Join with Security Alerts: It performs a left anti-join with the SecurityAlert table to exclude alerts that have already been recorded in the Azure Security Center within the last day.

  6. Alert Link and Severity: It constructs a URL link to the alert in the Azure portal and extracts the alert severity from the properties.

  7. Projection: Finally, it selects and displays specific fields such as the time generated, resource provider, subscription ID, resource group, operation name, alert title, severity, alert link, correlation ID, and dynamic properties.

In essence, this query is used to identify and display new security alerts related to Microsoft Security operations in Azure, providing details and a direct link to the alert in the Azure portal.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: February 26, 2024

Tables

AzureActivitySecurityAlert

Keywords

AzureActivitySecurityAlertAzureSecurityCenterMicrosoftAlertResourceSubscriptionResourceGroupOperationNameEventDataTenantIdSourceSystemCategoryTypeLevelOperationIdActivityStatusResourceIdCorrelationIdTimeGenerated

Operators

letbetweenagowhere=~extendcasesummarizehint.shufflekeymake_bagpacktake_anyarg_minarg_maxbytostringbag_keysstartswithhastodynamicisnotemptyproject-awayjoinkind=leftantidistincton==strcattolowersplitproject

Actions

GitHub