← Back to SOC feed Coverage →

Azure Storage File Create and Delete

kql MEDIUM Azure-Sentinel
T1020T1537
backdoorhuntingmicrosoftofficial
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-04-23T09:00:00Z · Confidence: medium

Hunt Hypothesis

Adversaries may upload a file to Azure Storage to exfiltrate data or establish persistence and then delete it to avoid detection. SOC teams should proactively hunt for this behavior to identify potential data exfiltration or covert command and control activities in their Azure Sentinel environment.

KQL Query


let threshold = 5m;
let StorageData =
union
StorageFileLogs,
StorageBlobLogs;
StorageData
| where StatusText =~ "Success"
| where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
| extend Uri = tostring(split(Uri, "?", 0)[0])
| join (
    StorageData
    | where StatusText =~ "Success"
    | where OperationName =~ "DeleteBlob" or OperationName =~ "DeleteFile"
    | extend Uri = tostring(split(Uri, "?", 0)[0])
    | project OperationName, DeletedTime=TimeGenerated, Uri
) on Uri
| project TimeGenerated, DeletedTime, Uri, CallerIpAddress, UserAgentHeader, ResponseMd5, StorageAccount=AccountName
| extend windowEnd = TimeGenerated+threshold 
| where DeletedTime between (TimeGenerated .. windowEnd)

Analytic Rule Definition

id: 276731f6-ae09-4469-9fa0-c0791a5a0d8d
name: Azure Storage File Create and Delete
description: |
  'This hunting query will try to identify instances where a file us uploaded to file storage and then deleted
  within a given threshold. By default the query will find instances where a file is uploaded and deleted within
  5 minutes. This hunting query will help detect automated exfiltration.'
requiredDataConnectors: []
tactics:
  - Exfiltration
relevantTechniques:
  - T1020
  - T1537
tags:
  - Ignite2021
query: |

  let threshold = 5m;
  let StorageData =
  union
  StorageFileLogs,
  StorageBlobLogs;
  StorageData
  | where StatusText =~ "Success"
  | where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
  | extend Uri = tostring(split(Uri, "?", 0)[0])
  | join (
      StorageData
      | where StatusText =~ "Success"
      | where OperationName =~ "DeleteBlob" or OperationName =~ "DeleteFile"
      | extend Uri = tostring(split(Uri, "?", 0)[0])
      | project OperationName, DeletedTime=TimeGenerated, Uri
  ) on Uri
  | project TimeGenerated, DeletedTime, Uri, CallerIpAddress, UserAgentHeader, ResponseMd5, StorageAccount=AccountName
  | extend windowEnd = TimeGenerated+threshold 
  | where DeletedTime between (TimeGenerated .. windowEnd)
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: CallerIpAddress

MITRE ATT&CK Context

References

False Positive Guidance

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