Back to labs
AdvancedIncident ResponseSeptember 22, 2025
Incident Response Lab: Azure Storage Breach Containment

Incident Response Lab: Azure Storage Breach Containment

Investigate and contain credential abuse against Azure Storage accounts, pivoting from unified audit logs to live containment with Logic Apps and Defender for Cloud.

These home labs are placeholder scenarios while I document the full walkthroughs. The environments, objectives, and tooling reflect my real-world practice runs, and I'm actively expanding the playbooks with screenshots, scripts, and validation data.

4 hours
Azure CLI Β· Kusto Query Language Β· Microsoft Sentinel Β· Logic Apps
Runbook with containment

Incident Response Lab: Azure Storage Breach Containment

You will relive a real-world credential abuse incident I handled in a production Azure tenant. The goal: piece together how a leaked Shared Access Signature led to data exfiltration, then build an automated containment workflow.

🧩 Lab Scenario

  • A developer accidentally published a Storage Account connection string in a public repository.
  • An attacker enumerated containers and exfiltrated sensitive blobs over 30 minutes.
  • Defender for Cloud raised an anomaly but no automated response was configured.

πŸ—ΊοΈ Phase 1 β€” Evidence Collection

  1. Configure Diagnostic Settings in the Storage Account:
    bash
    az monitor diagnostic-settings create \
      --name storage-ir \
      --resource $(az storage account show --name  --query id -o tsv) \
      --logs '[{"category":"StorageRead","enabled":true}]' \
      --metrics '[{"category":"Transaction","enabled":true}]' \
      --workspace 
    
  2. Run the pre-built KQL notebook kql/storage_sas_breach.kql inside Sentinel to load baseline queries.
  3. Export a copy of the unified audit log to your evidence folder (./evidence/raw).

πŸ” Phase 2 β€” Timeline Reconstruction

Use KQL to rebuild the incident. Focus on three attack milestones.

1. Initial Enumeration

kusto
// Enumerate LIST operations per client IP
table("StorageBlobLogs")
| where OperationName == "ListBlob"
| summarize Count = count() by CallerIpAddress, bin(TimeGenerated, 5m)
| order by Count desc

2. Exfiltration Burst

kusto
// Identify high-volume downloads per container
StorageBlobLogs
| where OperationName == "GetBlob"
| summarize Downloads = count(), DataOut = sum(TotalIngress) by ContainerName, bin(TimeGenerated, 5m)
| order by Downloads desc

3. Key Enumeration

kusto
// Track calls to key listing endpoints
AzureActivity
| where OperationNameValue has_any("ListKeys", "ListAccountSas")
| project TimeGenerated, Caller, CallerIpAddress, OperationNameValue

Capture screenshots or export results for the report archive.

πŸ› οΈ Phase 3 β€” Automatic Containment

  1. Deploy the containment Logic App with Bicep:
    bash
    az deployment group create \
      --resource-group  \
      --template-file infra/logicapp-lockkeys.bicep \
      --parameters storageAccountName=
    
  2. Connect Sentinel analytics rule "Storage Account Shared Key Access" to the playbook.
  3. Test by creating a Shared Access Signature; verify the Logic App rotates keys and disables the SAS within 60 seconds.

πŸ›‘οΈ Phase 4 β€” Hardening & Lessons Learned

  • Apply Defender for Storage Prevent policy to block anonymous access.
  • Rotate storage account keys and purge any persisted credentials from configuration files.
  • Enforce Azure AD authentication for applications instead of account keys.
  • Update the Secure Development playbook with pipeline checks for secrets.

πŸ“‘ Deliverables

  • report/timeline.md including the KQL outputs and IoCs.
  • Logic App deployment screenshot + JSON export.
  • Sentinel analytics rule update referencing the containment playbook.
  • Ticket template for production hand-off.

Run this lab whenever new engineers join incident response so they absorb both the investigative process and the automation mindset.

Incident Response Lab: Azure Storage Breach Containment | Your Full Name