Query Details

HUNT 25 Storage Data Protection Changes

Query

// Hunt     : Hunt - Storage Data-Protection Config Changes: Immutability / Legal Hold / Soft-Delete (30d)
// Tactics  : Impact, DefenseEvasion
// MITRE    : T1490 (Inhibit System Recovery), T1562
// Purpose  : Broad companion to RULE-20. Timeline of every change that weakens Azure Storage
//            recovery guardrails — immutability policies, legal holds, blob/container soft-delete,
//            versioning, and account deletion. Use to confirm RULE-20 alerts and to spot slow,
//            piecemeal guardrail erosion that stays under the alert rule's window.
//==========================================================================================

let Window = 30d;
let ProtectionOps = dynamic([
    "IMMUTABILITYPOLICIES/DELETE",
    "IMMUTABILITYPOLICIES/EXTEND/ACTION",
    "IMMUTABILITYPOLICIES/LOCK/ACTION",
    "LEGALHOLDS/CLEAR/ACTION",
    "LEGALHOLDS/SETLEGALHOLD/ACTION",
    "BLOBSERVICES/DEFAULT/DELETE",
    "BLOBSERVICES/DEFAULT/WRITE",
    "STORAGEACCOUNTS/DELETE"
]);
AzureActivity
| where TimeGenerated > ago(Window)
| where ActivityStatusValue =~ "Success"
| where OperationNameValue has_any (ProtectionOps)
| extend StorageAccount = tostring(split(ResourceId, "/")[8])
| extend ChangeKind = case(
    OperationNameValue has "IMMUTABILITYPOLICIES/DELETE",        "Immutability Policy Deleted",
    OperationNameValue has "IMMUTABILITYPOLICIES/EXTEND",        "Immutability Policy Extended/Changed",
    OperationNameValue has "IMMUTABILITYPOLICIES/LOCK",          "Immutability Policy Locked",
    OperationNameValue has "LEGALHOLDS/CLEAR",                   "Legal Hold Cleared",
    OperationNameValue has "LEGALHOLDS/SETLEGALHOLD",            "Legal Hold Set",
    OperationNameValue has "BLOBSERVICES/DEFAULT/DELETE",        "Blob Service Settings Deleted",
    OperationNameValue has "BLOBSERVICES/DEFAULT/WRITE",         "Blob Service Settings Changed (soft-delete/versioning)",
    OperationNameValue has "STORAGEACCOUNTS/DELETE",             "Storage Account Deleted",
    "Other")
| extend WeakensRecovery = ChangeKind in (
    "Immutability Policy Deleted", "Immutability Policy Extended/Changed",
    "Legal Hold Cleared", "Blob Service Settings Deleted",
    "Blob Service Settings Changed (soft-delete/versioning)", "Storage Account Deleted")
| project TimeGenerated, Caller, CallerIpAddress, ChangeKind, WeakensRecovery,
    StorageAccount, ResourceId, ResourceGroup, SubscriptionId
| order by WeakensRecovery desc, TimeGenerated desc

Explanation

This query is designed to track changes in Azure Storage configurations that could potentially weaken data protection and recovery mechanisms. Here's a simple breakdown of what it does:

  1. Time Frame: It looks at activities from the past 30 days.

  2. Operations of Interest: The query focuses on specific operations related to data protection, such as:

    • Deleting or altering immutability policies.
    • Clearing or setting legal holds.
    • Deleting or changing blob service settings (like soft-delete or versioning).
    • Deleting storage accounts.
  3. Data Source: It retrieves data from the AzureActivity log.

  4. Filtering: It filters for successful operations that match any of the specified protection-related operations.

  5. Data Processing:

    • It extracts the storage account name from the resource ID.
    • It categorizes the type of change (e.g., "Immutability Policy Deleted").
    • It identifies if the change potentially weakens recovery capabilities.
  6. Output: The query outputs details such as the time of the change, who made it, their IP address, the type of change, whether it weakens recovery, and relevant resource details.

  7. Sorting: The results are sorted to show changes that weaken recovery first, followed by the most recent changes.

Overall, this query helps in monitoring and identifying changes that could compromise the integrity and recoverability of Azure Storage data, allowing for timely investigation and response.

Details

David Alonso profile picture

David Alonso

Released: July 27, 2026

Tables

AzureActivity

Keywords

AzureActivityStorageAccountResourceIdResourceGroupSubscriptionIdTimeGeneratedCallerCallerIpAddressChangeKindWeakensRecovery

Operators

letdynamicagohas_anytostringsplitcaseinprojectorder bydesc

MITRE Techniques

Actions

GitHub