AnalysisType: rule
Filename: azure_storage_blob_permissions_modified.py
RuleID: "Azure.MonitorActivity.Storage.BlobPermissionsModified"
DisplayName: "Azure Storage Blob Container Permissions Modified"
Enabled: true
LogTypes:
- Azure.MonitorActivity
Severity: Medium
Description: >
Detects when permissions are modified on an Azure Storage blob container. Adversaries may modify
container permissions to enable public access, grant unauthorized access, or prepare for data
exfiltration. Changes to blob permissions can indicate attempts to access sensitive data, establish
persistence through external access, or facilitate ransomware by modifying access controls before
encryption.
Reports:
MITRE ATT&CK:
- TA0010:T1567.002 # Exfiltration: Exfiltration to Cloud Storage
- TA0005:T1222 # Defense Evasion: File and Directory Permissions Modification
Tags:
- Exfiltration
- Exfiltration to Cloud Storage
- Defense Evasion
- File and Directory Permissions Modification
Runbook: |
1. Query Azure Monitor Activity logs for all storage container operations (create, modify, delete) by the callerIpAddress in the 24 hours before and after the alert to identify permission modification patterns
2. Find all blob upload and download operations for the affected storage container in the 6 hours after the permission change to identify potential data exfiltration
3. Check if the callerIpAddress has modified storage container permissions in the past 90 days to determine if this is typical administrative behavior
Reference: https://github.com/elastic/detection-rules/blob/main/rules/integrations/azure/persistence_azure_storage_blob_permissions_modified.toml
SummaryAttributes:
- resourceId
- callerIpAddress
- correlationId
- location
Tests:
- Name: Blob Container Permissions Modified
ExpectedResult: true
Log:
{
"time": "2025-12-22T10:30:00.0000000Z",
"resourceId": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/storage-rg/providers/Microsoft.Storage/storageAccounts/prodstorageacct/blobServices/default/containers/sensitive-data",
"operationName": "MICROSOFT.STORAGE/STORAGEACCOUNTS/BLOBSERVICES/CONTAINERS/WRITE",
"operationVersion": "2021-09-01",
"category": "Administrative",
"resultType": "Success",
"resultSignature": "200",
"callerIpAddress": "1.1.1.1",
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"level": "Informational",
"location": "eastus",
"tenantId": "87654321-4321-4321-4321-111111111111"
}
- Name: Container Permissions Modified Case Insensitive
ExpectedResult: true
Log:
{
"time": "2025-12-22T11:15:00.0000000Z",
"resourceId": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/data-rg/providers/Microsoft.Storage/storageAccounts/datastorage/blobServices/default/containers/public-container",
"operationName": "microsoft.storage/storageaccounts/blobservices/containers/write",
"category": "Administrative",
"resultType": "Succeeded",
"callerIpAddress": "2.2.2.2",
"correlationId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"level": "Information",
"location": "westeurope",
"tenantId": "22222222-2222-2222-2222-222222222222"
}
- Name: Different Operation
ExpectedResult: false
Log:
{
"time": "2025-12-22T13:00:00.0000000Z",
"resourceId": "/subscriptions/44444444-4444-4444-4444-444444444444/resourceGroups/storage-rg/providers/Microsoft.Storage/storageAccounts/mystorage/blobServices/default/containers/my-container",
"operationName": "MICROSOFT.STORAGE/STORAGEACCOUNTS/BLOBSERVICES/CONTAINERS/DELETE",
"category": "Administrative",
"resultType": "Success",
"callerIpAddress": "4.4.4.4",
"correlationId": "d4e5f6a7-b8c9-0123-def0-456789012345",
"tenantId": "44444444-4444-4444-4444-444444444444"
}
# ------ paired body: azure_storage_blob_permissions_modified.py ------
from panther_azureactivity_helpers import (
azure_activity_alert_context,
azure_activity_success,
extract_resource_name_from_id,
)
BLOB_PERMISSIONS_OPERATIONS = [
"MICROSOFT.STORAGE/STORAGEACCOUNTS/BLOBSERVICES/CONTAINERS/WRITE",
]
def rule(event):
return event.get(
"operationName", ""
).upper() in BLOB_PERMISSIONS_OPERATIONS and azure_activity_success(event)
def title(event):
resource_id = event.get("resourceId", "<UNKNOWN_RESOURCE>")
container_name = extract_resource_name_from_id(
resource_id, "containers", default="<UNKNOWN_CONTAINER>"
)
storage_account_name = extract_resource_name_from_id(
resource_id, "storageAccounts", default="<UNKNOWN_STORAGE_ACCOUNT>"
)
return (
f"Azure Storage Blob Container Modified: [{container_name}] " f"in [{storage_account_name}]"
)
def alert_context(event):
context = azure_activity_alert_context(event)
return context