Query Details

RULE 04 Storage SAS Token Bulk Generation

Query

// Rule    : Azure - Storage Account SAS Token Bulk Generation
// Severity: Medium
// Tactics : CredentialAccess, Exfiltration
// MITRE   : T1550
// Freq    : PT1H   Period: PT2H
//==========================================================================================

let ExcludedPatterns = dynamic(["backup", "monitor", "storagesync", "azurebackup", "recov"]);
AzureActivity
| where TimeGenerated > ago(2h)
| where OperationNameValue has_any ("LISTACCOUNTSAS/ACTION", "LISTSERVICESAS/ACTION")
| where ActivityStatusValue =~ "Success"
| where not(tolower(Caller) has_any (ExcludedPatterns))
| where isnotempty(CallerIpAddress)
| where CallerIpAddress !startswith "168.63."
| summarize
    SASGenerationCount = count(),
    TargetAccounts = make_set(tostring(split(ResourceId, "/")[8]), 10),
    OperationTypes = make_set(OperationNameValue, 3),
    SourceIPs = make_set(CallerIpAddress, 5),
    CallerIP = any(CallerIpAddress),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by Caller, SubscriptionId, bin(TimeGenerated, 30m)
| where SASGenerationCount >= 3
| join kind=leftouter (
    StorageBlobLogs
    | where TimeGenerated > ago(2h)
    | where OperationName == "GetBlob" and StatusCode == "200"
    | summarize BlobReadCount = count(), TotalBytesRead = sum(ResponseBodySize) by RequesterObjectId
) on $left.Caller == $right.RequesterObjectId
| extend
    AccountName = tostring(split(Caller, "@")[0]),
    AccountUPNSuffix = tostring(split(Caller, "@")[1])

Explanation

This KQL query is designed to detect suspicious activity related to the bulk generation of SAS (Shared Access Signature) tokens in Azure Storage Accounts. Here's a simplified breakdown of what the query does:

  1. Exclusion of Certain Patterns: It defines a list of patterns (e.g., "backup", "monitor") that are considered normal and should be excluded from the analysis.

  2. Filter Azure Activity Logs: It looks at Azure activity logs from the past 2 hours for operations related to listing account or service SAS tokens that were successful.

  3. Exclude Specific Callers: It excludes activities from callers whose identifiers match the excluded patterns and those originating from IP addresses starting with "168.63.".

  4. Summarize Activity: It groups the data by the caller, subscription ID, and 30-minute time bins, summarizing:

    • The count of SAS token generation operations.
    • The target storage accounts involved.
    • The types of operations performed.
    • The source IP addresses.
    • The first and last time the activity was seen.
  5. Filter for Suspicious Activity: It only considers cases where there were 3 or more SAS token generation operations.

  6. Join with Blob Access Logs: It joins this data with storage blob logs to see if there were any successful blob read operations by the same caller within the same timeframe.

  7. Extend with Additional Information: It extracts the account name and domain from the caller's email address for further context.

Overall, this query helps identify potential unauthorized access or data exfiltration attempts by monitoring for unusual patterns in SAS token generation and subsequent blob access activities.

Details

David Alonso profile picture

David Alonso

Released: March 12, 2026

Tables

AzureActivityStorageBlobLogs

Keywords

AzureActivityStorageAccountSASTokenCallerSubscriptionIdStorageBlobLogsOperationNameStatusCodeRequesterObjectIdAccountNameAccountUPNSuffix

Operators

letdynamicAzureActivitywhereagohas_any=~tolowerisnotempty!startswithsummarizecountmake_settostringsplitanyminmaxbybinjoinkind=leftouterStorageBlobLogsextendsum

Actions