Query Details

HUNT 03 Storage Blob Exfiltration

Query

// Hunt     : Hunt - Storage Blob High-Volume Read by Single IP (Potential Exfiltration)
// Tactics  : Exfiltration
// MITRE    : T1530
// Purpose  : Identify IPs that performed high-volume blob reads (>500 reads/hr or >1 GB/hr). Correlate with SAS token generation (Rule-04) to confirm exfiltration via ephemeral SAS credentials.
//==========================================================================================

StorageBlobLogs
| where TimeGenerated > ago(30d)
| where OperationName == "GetBlob"
| where StatusCode == "200"
| where isnotempty(CallerIpAddress)
| where CallerIpAddress !startswith "168.63."
| summarize
    ReadCount = count(),
    TotalBytesGB = round(sum(ResponseBodySize) / 1073741824.0, 2),
    DistinctBlobs = dcount(ObjectKey),
    StorageAccounts = make_set(AccountName, 5),
    EarliestRead = min(TimeGenerated),
    LatestRead = max(TimeGenerated)
    by CallerIpAddress, bin(TimeGenerated, 1h)
| where ReadCount > 500 or TotalBytesGB > 1.0
| order by TotalBytesGB desc

Explanation

This query is designed to detect potential data exfiltration from storage blobs by identifying IP addresses that perform a high volume of blob reads. Here's a simplified breakdown of what the query does:

  1. Data Source: It analyzes logs from storage blobs over the past 30 days.

  2. Operation Filter: It focuses on successful "GetBlob" operations, which indicate that a blob was read.

  3. IP Address Filtering: It excludes internal Azure IP addresses (those starting with "168.63.") and ensures that the IP address field is not empty.

  4. Data Aggregation: For each IP address, it calculates:

    • The total number of blob reads (ReadCount).
    • The total data volume read in gigabytes (TotalBytesGB).
    • The number of distinct blobs accessed (DistinctBlobs).
    • A list of up to 5 storage accounts accessed (StorageAccounts).
    • The time of the first and last read within the hour (EarliestRead and LatestRead).
  5. High-Volume Detection: It filters for IP addresses that have either read more than 500 blobs or transferred more than 1 GB of data in an hour.

  6. Result Ordering: The results are sorted by the total data volume read in descending order, highlighting the most significant potential exfiltration activities.

The purpose of this query is to identify suspicious activities that might indicate data exfiltration, particularly when correlated with the generation of ephemeral SAS (Shared Access Signature) credentials.

Details

David Alonso profile picture

David Alonso

Released: March 12, 2026

Tables

StorageBlobLogs

Keywords

StorageBlobLogsOperationNameStatusCodeCallerIPAddressResponseBodySizeObjectKeyAccountNameTimeGenerated

Operators

ago()==isnotempty()!startswithsummarizecount()round()sum()dcount()make_set()min()max()bybin()>ororder bydesc

Actions