L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Productivité · SKILL.md

detecting-misconfigured-azure-storage

detecting-misconfigured-azure-storage

使用 Azure CLI、PowerShell 和 Microsoft Defender for Storage,检测 Azure 存储账户错误配置,包括可公开访问的 blob 容器、缺失的加密设置、过于宽泛的 SAS 令牌、禁用的日志记录以及网络访问违规。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: detecting-misconfigured-azure-storage description: > 使用 Azure CLI、PowerShell 和 Microsoft Defender for Storage,检测 Azure 存储账户错误配置,包括可公开访问的 blob 容器、缺失的加密设置、过于宽泛的 SAS 令牌、禁用的日志记录以及网络访问违规。 domain: cybersecurity subdomain: cloud-security tags: [cloud-security, azure, storage-security, blob-storage, sas-tokens, data-protection] version: "1.0" author: mahipal license: Apache-2.0

检测 Azure 存储错误配置

适用场景

  • 对订阅中的 Azure 存储账户进行安全审计时
  • 响应 Microsoft Defender for Storage 发出的匿名访问或数据泄露告警时
  • 合规要求需要验证加密、网络限制和访问日志记录时
  • 调查通过可公开访问的 blob 容器造成的潜在数据暴露时
  • 接入 Azure 订阅并建立存储安全基线时

不适用于:Azure SQL 或 Cosmos DB 安全审计(使用专用数据库安全工具)、存储操作的实时威胁检测(使用 Defender for Storage),或在不做相应调整的情况下对 Azure Files 或 Data Lake Gen2 进行专项审计。

前置条件

  • 安装 Azure CLI 并通过 az login 完成认证,具备读者和存储账户贡献者角色
  • 安装 Az PowerShell 模块用于高级查询(Install-Module Az.Storage)
  • 启用 Microsoft Defender for Storage 进行威胁检测
  • 可访问 Azure Resource Graph 以进行跨订阅查询
  • 使用 ScoutSuite 或 Prowler Azure 提供商进行自动化评估

工作流程

步骤 1:枚举所有存储账户及基本配置

列出跨订阅的所有存储账户,评估其基线安全设置。

# 列出所有订阅的存储账户
az storage account list \
  --query "[].{Name:name, ResourceGroup:resourceGroup, Location:location, Kind:kind, Sku:sku.name, HttpsOnly:enableHttpsTrafficOnly, MinTLS:minimumTlsVersion, PublicAccess:allowBlobPublicAccess}" \
  -o table

# 使用 Resource Graph 进行跨订阅枚举
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 数据的存储账户和容器。

# 检查每个存储账户的公开 blob 访问设置
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

# 列出已设置公开访问级别的容器
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

# 测试对已发现公开容器的匿名访问
curl -s "https://ACCOUNT.blob.core.windows.net/CONTAINER?restype=container&comp=list" | head -50

步骤 3:审计网络访问和防火墙规则

检查存储账户是否对所有网络开放,还是限制在特定 VNet 或 IP 范围内。

# 查找默认网络操作设置为 Allow(对所有网络开放)的存储账户
az storage account list \
  --query "[?networkRuleSet.defaultAction=='Allow'].{Name:name, DefaultAction:networkRuleSet.defaultAction, VNetRules:networkRuleSet.virtualNetworkRules}" \
  -o table

# 详细的网络规则审计
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

# 查找具有私有端点的存储账户
az network private-endpoint list \
  --query "[?privateLinkServiceConnections[0].groupIds[0]=='blob'].{Name:name, Storage:privateLinkServiceConnections[0].privateLinkServiceId}" \
  -o table

步骤 4:验证加密设置和密钥管理

确保所有存储账户使用静态加密,并采用适当的密钥管理方式(Microsoft 管理的密钥或客户管理的密钥)。

# 检查所有存储账户的加密配置
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

# 查找未启用基础设施加密(双重加密)的账户
az storage account list \
  --query "[?encryption.requireInfrastructureEncryption!=true].{Name:name, KeySource:encryption.keySource}" \
  -o table

# 检查 TLS 版本低于 1.2 的账户
az storage account list \
  --query "[?minimumTlsVersion!='TLS1_2'].{Name:name, TLS:minimumTlsVersion}" \
  -o table

步骤 5:审计共享访问签名和访问密钥

识别权限过于宽泛的 SAS 令牌,并检查访问密钥使用模式。

# 检查存储账户密钥的上次轮换时间
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

# 检查存储账户是否允许共享密钥访问(应禁用,改用仅 AAD)
az storage account list \
  --query "[].{Name:name, AllowSharedKeyAccess:allowSharedKeyAccess}" \
  -o table

# 审查容器上的存储访问策略(SAS 治理)
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 诊断设置。

# 检查存储账户的诊断设置
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 "  未配置诊断设置"
done

# 检查 blob 服务日志记录属性
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 Public Access)存储账户设置,允许匿名读取 blob 容器及其内容,无需身份验证
共享访问签名(Shared Access Signature)带有嵌入式身份验证令牌的有时限 URI,授予对 Azure 存储资源的委托访问权限和特定权限
网络 ACL 默认操作(Network ACL Default Action)存储防火墙设置,决定是否默认允许或拒绝流量,特定 IP 和 VNet 可设为例外
客户管理的密钥(Customer-Managed Key)存储在 Azure Key Vault 中、由客户控制的加密密钥,用于存储加密而不是使用 Microsoft 管理的密钥
存储访问策略(Stored Access Policy)容器上命名的策略,定义 SAS 权限、起止时间,可独立撤销而不影响单个 SAS 令牌
Defender for StorageMicrosoft Defender 计划,为异常存储访问模式、恶意软件上传和数据泄露提供威胁检测

工具与系统

  • Azure CLI:用于查询存储账户配置、容器和访问策略的主要工具
  • Azure Resource Graph:跨订阅查询引擎,可高效地大规模枚举存储安全设置
  • Microsoft Defender for Storage:威胁检测服务,识别异常访问模式和潜在数据泄露
  • Prowler Azure:开源工具,包含符合 CIS Azure Foundations 标准的自动化存储安全检查
  • ScoutSuite:多云审计工具,包含针对公开访问、加密和网络的 Azure 存储专项检查

常见场景

场景:检测由开发人员错误配置导致的存储账户暴露

场景背景:开发人员为 Web 应用创建存储账户,并启用 blob 公开访问以提供静态文件服务。他们不小心将 API 密钥和数据库连接字符串存储在可公开访问的容器中。

方法:

  1. 运行 az storage account list 过滤 allowBlobPublicAccess=true
  2. 枚举公开访问级别设置为 blob 或 container 的容器
  3. 列出公开容器的内容以识别敏感文件
  4. 检查 Defender for Storage 中来自异常 IP 的异常访问告警
  5. 立即将存储账户上的 allowBlobPublicAccess 设置为 false
  6. 轮换在公开容器中发现的所有已暴露凭据
  7. 启用网络 ACL,将访问限制为应用程序 VNet
  8. 为合法的公开内容分发配置 Azure CDN 或 Front Door

常见陷阱:立即禁用 blob 公开访问会破坏公开提供内容的应用程序。应与开发团队协调,在禁用公开访问前先实施 Azure CDN。密钥轮换前生成的 SAS 令牌在过期前仍然有效,除非重新生成底层存储密钥。

输出格式

Azure 存储安全审计报告
======================================
订阅: 生产环境(SUB-ID)
评估日期: 2026-02-23
已审计存储账户: 24 个

严重发现:
[STOR-001] 已启用公开 Blob 访问
  账户: webapp-static-prod
  容器: uploads(PublicAccess: blob)
  风险: 匿名用户可读取容器中的所有 blob
  内容: 1,247 个文件,包含 .env 和 config.json
  修复建议: 禁用 allowBlobPublicAccess,改用带 SAS 的 Azure CDN

[STOR-002] 存储账户对所有网络开放
  账户: data-lake-analytics
  默认操作: Allow(无网络限制)
  风险: 可从任何网络(包括互联网)访问
  修复建议: 将默认操作设置为 Deny,添加 VNet 规则

摘要:
  已启用公开 blob 访问:      3 / 24
  对所有网络开放:            8 / 24
  缺少基础设施加密:         12 / 24
  TLS 版本低于 1.2:          2 / 24
  未启用诊断日志:           10 / 24
  已启用共享密钥访问:       18 / 24
  密钥未在 90 天内轮换:     14 / 24
Skills enregistrées