← Back to SOC feed Coverage →

Storage Alert Correlation with CommonSecurityLogs and StorageLogs

kql MEDIUM Azure-Sentinel
T1586T1570
CommonSecurityLogSecurityAlert
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-06-03T23:00:00Z · Confidence: medium

Hunt Hypothesis

Adversaries may exfiltrate data by leveraging Azure Storage services while simultaneously establishing persistence through compromised credentials in CommonSecurityLogs. SOC teams should proactively hunt for this behavior to detect potential data exfiltration and credential misuse in their Azure Sentinel environment.

KQL Query

SecurityAlert
| where DisplayName has_any ("Potential malware uploaded to a storage blob container","Storage account identified as source for distribution of malware")
| extend Entities = parse_json(Entities)
| mv-expand Entities
| where Entities['Type'] =~ "ip"
| extend AttackerIP = tostring(Entities['Address']), AttackerCountry = tostring(Entities['Location']['CountryName'])
| join kind=inner (
union
StorageFileLogs,
StorageBlobLogs
//File upload operations
| where StatusText =~ "Success"
| where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
| extend ClientIP = tostring(CallerIpAddress)
) on $left.AttackerIP == $right.ClientIP
| project AlertTimeGenerated = TimeGenerated, AttackerIP, AttackerCountry
| join kind=inner (
CommonSecurityLog
| where DeviceVendor =~ "Fortinet"
| where ApplicationProtocol has_any ("SSL","RDP")
| where LogSeverity has_any ("2","3")
| where isnotempty(SourceIP) and isnotempty(DestinationIP) and SourceIP != "0.0.0.0"
| where DeviceAction !in ("close", "client-rst", "server-rst", "deny") and DestinationPort != 161
| project DeviceProduct,LogSeverity,DestinationPort,DestinationIP,Message,SourceIP,SourcePort,Activity,SentBytes,ReceivedBytes)
 on $left.AttackerIP==$right.DestinationIP
| summarize count() by AlertTimeGenerated,IpAddress=DestinationIP,SentBytes,ReceivedBytes,AttackerCountry

Analytic Rule Definition

id: 7098cae1-c632-4b40-b715-86d6b07720d7
name: Storage Alert Correlation with CommonSecurityLogs and StorageLogs
description: |
  'This query combines different Storage alerts with CommonSecurityLogs and StorageLogs helping analysts  triage and investigate any 
  possible Storage related attacks faster thus reducing Mean Time To Respond'
requiredDataConnectors:
  - connectorId: AzureSecurityCenter
    dataTypes:
      - SecurityAlert (ASC)
  - connectorId: Fortinet
    dataTypes:
      - CommonSecurityLog
tactics:
  - InitialAccess
  - LateralMovement
relevantTechniques:
  - T1586
  - T1570
query: |
  SecurityAlert
  | where DisplayName has_any ("Potential malware uploaded to a storage blob container","Storage account identified as source for distribution of malware")
  | extend Entities = parse_json(Entities)
  | mv-expand Entities
  | where Entities['Type'] =~ "ip"
  | extend AttackerIP = tostring(Entities['Address']), AttackerCountry = tostring(Entities['Location']['CountryName'])
  | join kind=inner (
  union
  StorageFileLogs,
  StorageBlobLogs
  //File upload operations
  | where StatusText =~ "Success"
  | where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
  | extend ClientIP = tostring(CallerIpAddress)
  ) on $left.AttackerIP == $right.ClientIP
  | project AlertTimeGenerated = TimeGenerated, AttackerIP, AttackerCountry
  | join kind=inner (
  CommonSecurityLog
  | where DeviceVendor =~ "Fortinet"
  | where ApplicationProtocol has_any ("SSL","RDP")
  | where LogSeverity has_any ("2","3")
  | where isnotempty(SourceIP) and isnotempty(DestinationIP) and SourceIP != "0.0.0.0"
  | where DeviceAction !in ("close", "client-rst", "server-rst", "deny") and DestinationPort != 161
  | project DeviceProduct,LogSeverity,DestinationPort,DestinationIP,Message,SourceIP,SourcePort,Activity,SentBytes,ReceivedBytes)
   on $left.AttackerIP==$right.DestinationIP
  | summarize count() by AlertTimeGenerated,IpAddress=DestinationIP,SentBytes,ReceivedBytes,AttackerCountry
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IpAddress

Required Data Sources

Sentinel TableNotes
CommonSecurityLogEnsure this data connector is enabled
SecurityAlertEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/MultipleDataSources/StorageAlertCorrelationwithCommonSecurityLogsandStorageLogs.yaml