关于 detecting-misconfigured-azure-storage
面向 Azure 管理员和安全审计人员的存储配置审计技能,指导跨订阅检查存储账户及容器。重点检查匿名公开访问、网络限制、加密、访问密钥和诊断日志。
主要功能
- 01跨订阅枚举存储账户
- 02检查 Blob 匿名公开访问
- 03审计网络规则与防火墙
- 04核查加密和密钥管理
- 05检查 SAS、访问密钥与诊断日志
适用场景
- 01审计多个订阅中的存储账户
- 02调查公开 Blob 导致的数据暴露
- 03核查加密、网络访问和日志合规
- 04建立新订阅的存储安全基线
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-misconfigured-azure-storage安装后在 Claude Code 中输入/detecting-misconfigured-azure-storage确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
检测配置错误的 Azure 存储
何时使用
- 在对各订阅中的 Azure 存储账户执行安全审计时
- 在响应 Microsoft Defender for Storage 关于匿名访问或数据外泄的警报时
- 在合规性要求验证加密、网络限制和访问日志记录时
- 在调查通过可公开访问的 blob 容器可能导致的数据暴露时
- 在接入 Azure 订阅并建立存储安全基线时
请勿使用于 Azure SQL 或 Cosmos DB 安全审计(请使用专用的数据库安全工具)、存储操作的实时威胁检测(请使用 Defender for Storage),或在未调整检查项的情况下对 Azure Files 或 Data Lake Gen2 进行特定审计。
先决条件
- 已安装并完成身份验证的 Azure CLI(
az login),并具有 Reader 和 Storage Account Contributor 角色 - 已安装 Az PowerShell 模块以执行高级查询(
Install-Module Az.Storage) - 已启用 Microsoft Defender for Storage 以进行威胁检测
- 可访问 Azure Resource Graph 以执行跨订阅查询
- 使用 ScoutSuite 或 Prowler Azure 提供程序进行自动化评估
工作流
步骤 1:枚举所有存储账户及基本配置
列出各订阅中的所有存储账户并评估其基线安全设置。
# List all storage accounts across all subscriptions
az storage account list \
--query "[].{Name:name, ResourceGroup:resourceGroup, Location:location, Kind:kind, Sku:sku.name, HttpsOnly:enableHttpsTrafficOnly, MinTLS:minimumTlsVersion, PublicAccess:allowBlobPublicAccess}" \
-o table
# Use Resource Graph for cross-subscription enumeration
az graph query -q "
Resources
| where type == 'microsoft.storage/storageaccounts'
| project name, resourceGroup, subscriptionId, location,
properties.allowBlobPublicAccess,
properties.enableHttpsTrafficOnly,
properties.minimumTlsVersion,
properties.networkAcls.defaultAction
" -o table
步骤 2:检测可公开访问的 blob 容器
识别允许匿名公开访问 blob 数据的存储账户和容器。
# Check each storage account for public blob access setting
for account in $(az storage account list --query "[].name" -o tsv); do
public=$(az storage account show --name "$account" --query "allowBlobPublicAccess" -o tsv)
echo "$account: allowBlobPublicAccess=$public"
done
# List containers with public access level set
for account in $(az storage account list --query "[?allowBlobPublicAccess==true].name" -o tsv); do
key=$(az storage account keys list --account-name "$account" --query "[0].value" -o tsv)
echo "=== $account ==="
az storage container list \
--account-name "$account" \
--account-key "$key" \
--query "[?properties.publicAccess!='off' && properties.publicAccess!=null].{Container:name, PublicAccess:properties.publicAccess}" \
-o table 2>/dev/null
done
# Test anonymous access to discovered public containers
curl -s "https://ACCOUNT.blob.core.windows.net/CONTAINER?restype=container&comp=list" | head -50
步骤 3:审计网络访问和防火墙规则
检查可从所有网络访问的存储账户与仅限特定 VNet 或 IP 范围访问的存储账户。
# Find storage accounts with default network action set to Allow (open to all networks)
az storage account list \
--query "[?networkRuleSet.defaultAction=='Allow'].{Name:name, DefaultAction:networkRuleSet.defaultAction, VNetRules:networkRuleSet.virtualNetworkRules}" \
-o table
# Detailed network rule audit
for account in $(az storage account list --query "[].name" -o tsv); do
echo "=== $account ==="
az storage account show --name "$account" \
--query "{DefaultAction:networkRuleSet.defaultAction, IPRules:networkRuleSet.ipRules[*].ipAddressOrRange, VNetRules:networkRuleSet.virtualNetworkRules[*].virtualNetworkResourceId, Bypass:networkRuleSet.bypass}" \
-o json
done
# Find storage accounts with private endpoints
az network private-endpoint list \
--query "[?privateLinkServiceConnections[0].groupIds[0]=='blob'].{Name:name, Storage:privateLinkServiceConnections[0].privateLinkServiceId}" \
-o table
步骤 4:验证加密设置和密钥管理
确保所有存储账户使用静态加密并采用适当的密钥管理(Microsoft 托管密钥或客户托管密钥)。
# Check encryption configuration for all storage accounts
for account in $(az storage account list --query "[].name" -o tsv); do
echo "=== $account ==="
az storage account show --name "$account" \
--query "{Encryption:encryption.services, KeySource:encryption.keySource, KeyVaultUri:encryption.keyVaultProperties.keyVaultUri, InfraEncryption:encryption.requireInfrastructureEncryption}" \
-o json
done
# Find accounts without infrastructure encryption (double encryption)
az storage account list \
--query "[?encryption.requireInfrastructureEncryption!=true].{Name:name, KeySource:encryption.keySource}" \
-o table
# Check for accounts using TLS version below 1.2
az storage account list \
--query "[?minimumTlsVersion!='TLS1_2'].{Name:name, TLS:minimumTlsVersion}" \
-o table
步骤 5:审计共享访问签名和访问密钥
识别权限过宽的 SAS 令牌并检查访问密钥的使用模式。
# Check when storage account keys were last rotated
for account in $(az storage account list --query "[].name" -o tsv); do
echo "=== $account ==="
az storage account keys list \
--account-name "$account" \
--query "[].{KeyName:keyName, CreationTime:creationTime}" \
-o table
done
# Check if storage account allows shared key access (should be disabled for AAD-only)
az storage account list \
--query "[].{Name:name, AllowSharedKeyAccess:allowSharedKeyAccess}" \
-o table
# Review stored access policies on containers (SAS governance)
for account in $(az storage account list --query "[].name" -o tsv); do
key=$(az storage account keys list --account-name "$account" --query "[0].value" -o tsv 2>/dev/null)
for container in $(az storage container list --account-name "$account" --account-key "$key" --query "[].name" -o tsv 2>/dev/null); do
policies=$(az storage container policy list --container-name "$container" --account-name "$account" --account-key "$key" 2>/dev/null)
[ -n "$policies" ] && echo "$account/$container: $policies"
done
done
步骤 6:检查诊断日志记录和监控
验证是否已启用存储分析日志记录和 Azure Monitor 诊断设置。
# Check diagnostic settings for storage accounts
for account in $(az storage account list --query "[].name" -o tsv); do
rg=$(az storage account show --name "$account" --query "resourceGroup" -o tsv)
echo "=== $account ==="
az monitor diagnostic-settings list \
--resource "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$rg/providers/Microsoft.Storage/storageAccounts/$account" \
--query "[].{Name:name, Logs:logs[*].category, Metrics:metrics[*].category}" \
-o json 2>/dev/null || echo " No diagnostic settings configured"
done
# Check blob service logging properties
for account in $(az storage account list --query "[].name" -o tsv); do
key=$(az storage account keys list --account-name "$account" --query "[0].value" -o tsv 2>/dev/null)
az storage logging show \
--account-name "$account" \
--account-key "$key" \
--services b 2>/dev/null
done
关键概念
| 术语 | 定义 |
|---|---|
| Blob 公共访问 | 一种存储账户设置,允许在未经身份验证的情况下匿名读取 blob 容器及其内容 |
| 共享访问签名 | 带有嵌入式身份验证令牌的限时 URI,以特定权限授予对 Azure 存储资源的委派访问 |
| 网络 ACL 默认操作 | 一种存储防火墙设置,决定默认情况下流量是被允许还是被拒绝,并对指定的 IP 和 VNet 例外 |
| 客户托管密钥 | 存储在 Azure Key Vault 中、由客户控制的加密密钥,用于存储加密,而非 Microsoft 托管密钥 |
| 存储访问策略 | 容器上的命名策略,定义 SAS 权限、开始/过期时间,并可独立于单个 SAS 令牌被撤销 |
| Defender for Storage | Microsoft Defender 计划,为异常的存储访问模式、恶意软件上传和数据外泄提供威胁检测 |
工具与系统
- Azure CLI:用于查询存储账户配置、容器和访问策略的主要工具
- Azure Resource Graph:跨订阅查询引擎,可大规模高效枚举存储安全设置
- Microsoft Defender for Storage:威胁检测服务,识别异常访问模式和潜在的数据外泄
- Prowler Azure:开源工具,提供与 CIS Azure Foundations 对齐的自动化存储安全检查
- ScoutSuite:多云审计工具,具有针对 Azure 存储的公共访问、加密和网络检查
常见场景
场景:检测因开发者错误配置而暴露的存储账户
背景:开发者为 Web 应用创建了一个存储账户,并启用了 Blob 公共访问以提供静态文件。他们不小心将 API 密钥和数据库连接字符串存储在了一个可公开访问的容器中。
处理方法:
- 运行
az storage account list,筛选allowBlobPublicAccess=true - 枚举公共访问级别设置为
blob或container的容器 - 列出公共容器的内容,以识别敏感文件
- 检查 Defender for Storage 警报,查找来自异常 IP 的可疑访问
- 立即将存储账户上的
allowBlobPublicAccess设置为false - 轮换在公共容器中发现的所有已暴露凭据
- 启用网络 ACL,限制对应用程序 VNet 的访问
- 为合法的公共内容分发配置 Azure CDN 或 Front Door
陷阱:立即禁用 Blob 公共访问会破坏以公开方式提供内容的应用程序。在禁用公共访问之前,请与开发团队协调并实施 Azure CDN。在密钥轮换之前生成的 SAS 令牌在过期之前仍然有效,除非重新生成底层存储密钥。
输出格式
Azure Storage Security Audit Report
======================================
Subscription: Production (SUB-ID)
Assessment Date: 2026-02-23
Storage Accounts Audited: 24
CRITICAL FINDINGS:
[STOR-001] Public Blob Access Enabled
Account: webapp-static-prod
Container: uploads (PublicAccess: blob)
Risk: Anonymous users can read all blobs in the container
Contents: 1,247 files including .env and config.json
Remediation: Disable allowBlobPublicAccess, use Azure CDN with SAS
[STOR-002] Storage Account Open to All Networks
Account: data-lake-analytics
Default Action: Allow (no network restrictions)
Risk: Accessible from any network including the internet
Remediation: Set default action to Deny, add VNet rules
SUMMARY:
Public blob access enabled: 3 / 24
Open to all networks: 8 / 24
Missing infrastructure encryption: 12 / 24
TLS version below 1.2: 2 / 24
No diagnostic logging: 10 / 24
Shared key access enabled: 18 / 24
Keys not rotated in 90+ days: 14 / 24
评论
支持 Markdown