审核 Azure Active Directory 配置
使用时机
- 对 Azure 租户的身份配置进行安全评估时
- 合规审计需要审查身份验证策略、MFA 强制实施和角色分配时
- 在合并或收购后接入新 Azure 租户时
- 调查可疑登录活动或受损账户时
- 验证条件访问策略是否充分防御基于身份的攻击时
请勿用于 本地 Active Directory 审计(请使用 PingCastle 或 BloodHound AD)、不含身份上下文的 Azure 资源级 RBAC 审计,以及实时威胁检测(请使用 Microsoft Defender for Identity)。
先决条件
- 目标 Microsoft Entra ID 租户中的全局读取者或安全读取者角色
- 已安装 Microsoft Graph PowerShell SDK(
Install-Module Microsoft.Graph) - 已向目标租户认证 Az CLI(
az login --tenant TENANT_ID) - 配置了 Azure 提供程序的 ScoutSuite,用于自动化评估
- 可访问 Azure AD 审核日志和登录日志(需要 Azure AD Premium P1/P2)
工作流程
步骤 1:枚举租户配置和安全默认值
评估租户的基线身份安全设置,包括安全默认值和旧式身份验证状态。
# 连接到 Microsoft Graph
Connect-MgGraph -Scopes "Directory.Read.All","Policy.Read.All","AuditLog.Read.All"
# 获取租户详细信息
Get-MgOrganization | Select-Object DisplayName, Id, VerifiedDomains
# 检查安全默认值是否启用
Get-MgPolicyIdentitySecurityDefaultEnforcementPolicy | Select-Object IsEnabled
# 列出身份验证方法策略
Get-MgPolicyAuthenticationMethodPolicy | ConvertTo-Json -Depth 5
# 通过条件访问检查旧式身份验证状态
Get-MgIdentityConditionalAccessPolicy | Where-Object {
$_.Conditions.ClientAppTypes -contains "exchangeActiveSync" -or
$_.Conditions.ClientAppTypes -contains "other"
} | Select-Object DisplayName, State
步骤 2:审计特权角色分配
审查目录角色分配,以发现权限过高的用户、永久管理员账户和风险角色配置。
# 列出所有全局管理员分配
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/directoryRoles/filterByIds" \
--body '{"ids":["62e90394-69f5-4237-9190-012177145e10"]}' | \
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/directoryRoles?filter=displayName eq 'Global Administrator'" \
--query "value[0].id" -o tsv
# 使用 Graph API 列出所有特权角色分配
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?\$expand=principal" \
--query "value[*].{Role:roleDefinitionId, Principal:principal.displayName, PrincipalType:[email protected]}" \
-o table
# 检查拥有多个管理员角色的用户
az ad user list --query "[].{UPN:userPrincipalName, DisplayName:displayName}" -o table
# 列出拥有管理员角色分配的服务主体
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?\$filter=principalOrganizationId eq 'TENANT_ID'" \
-o json
步骤 3:审查条件访问策略
审计条件访问策略的覆盖漏洞,特别是有关 MFA 强制实施、设备合规性和基于位置的限制。
# 列出所有条件访问策略
Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State, @{
N='授权控制'; E={$_.GrantControls.BuiltInControls -join ', '}
} | Format-Table -AutoSize
# 识别报告专用模式(未强制实施)的策略
Get-MgIdentityConditionalAccessPolicy | Where-Object {$_.State -eq "enabledForReportingButNotNotEnforced"} |
Select-Object DisplayName
# 检查 MFA 强制实施覆盖范围
Get-MgIdentityConditionalAccessPolicy | Where-Object {
$_.GrantControls.BuiltInControls -contains "mfa"
} | Select-Object DisplayName, State, @{
N='用户'; E={$_.Conditions.Users.IncludeUsers -join ', '}
}
# 查找排除组的策略(潜在绕过)
Get-MgIdentityConditionalAccessPolicy | Where-Object {
$_.Conditions.Users.ExcludeGroups.Count -gt 0
} | Select-Object DisplayName, @{
N='排除组'; E={$_.Conditions.Users.ExcludeGroups -join ', '}
}
步骤 4:识别陈旧账户和来宾用户
查找最近未登录的账户、具有活跃角色分配的禁用账户以及有风险的来宾用户配置。
# 查找 90 天以上未登录的用户
az ad user list --query "[?signInActivity.lastSignInDateTime < '2025-11-25T00:00:00Z'].{UPN:userPrincipalName, 最后登录:signInActivity.lastSignInDateTime, 已启用:accountEnabled}" -o table
# 列出所有来宾用户
az ad user list --filter "userType eq 'Guest'" \
--query "[].{UPN:userPrincipalName, 显示名称:displayName, 创建日期:createdDateTime}" \
-o table
# 查找具有特权角色的来宾用户
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?\$expand=principal" \
--query "value[?principal.userType=='Guest'].{角色:roleDefinitionId,来宾:principal.userPrincipalName}" \
-o table
# 检查 MFA 已禁用的账户
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/reports/authenticationMethods/userRegistrationDetails" \
--query "value[?!isMfaRegistered].{UPN:userPrincipalName,已注册MFA:isMfaRegistered}" \
-o table
步骤 5:分析登录日志中的风险活动
审查登录日志以发现异常身份验证模式、失败的 MFA 挑战和风险登录检测。
# 获取过去 7 天的风险登录
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/auditLogs/signIns?\$filter=riskLevelDuringSignIn ne 'none' and createdDateTime ge 2026-02-16T00:00:00Z" \
--query "value[*].{用户:userPrincipalName,风险级别:riskLevelDuringSignIn,IP:ipAddress,应用:appDisplayName,状态:status.errorCode}" \
-o table
# 获取来自陌生位置的登录
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/auditLogs/signIns?\$filter=riskEventTypes_v2/any(r:r eq 'unfamiliarFeatures')" \
--query "value[*].{用户:userPrincipalName,位置:location.city,IP:ipAddress}" \
-o table
# 检查旧式身份验证登录
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/auditLogs/signIns?\$filter=clientAppUsed ne 'Browser' and clientAppUsed ne 'Mobile Apps and Desktop clients'" \
--query "value[*].{用户:userPrincipalName,客户端应用:clientAppUsed,状态:status.errorCode}" \
-o table
步骤 6:运行 ScoutSuite 自动化评估
执行 ScoutSuite 对 Azure 租户配置进行全面的自动化检查。
# 对 Azure 运行 ScoutSuite
python3 -m ScoutSuite azure --cli \
--report-dir ./scoutsuite-azure-report \
--all-subscriptions
# 查看生成的 HTML 报告
open ./scoutsuite-azure-report/azure-report.html
关键概念
| 术语 | 定义 |
|---|---|
| Microsoft Entra ID | Microsoft 的云身份和访问管理服务,前身为 Azure Active Directory,提供身份验证和授权 |
| 条件访问 | 策略引擎,评估信号(用户、设备、位置、风险)以强制执行 MFA、设备合规性或阻止访问等访问控制 |
| 安全默认值 | Microsoft 的基线身份保护设置,强制实施 MFA 注册、阻止旧式身份验证并保护特权操作 |
| 特权身份管理 | Azure AD Premium P2 功能,通过审批工作流和限时角色激活实现实时特权访问 |
| 旧式身份验证 | 不支持 MFA 的较旧身份验证协议(POP3、IMAP、SMTP、ActiveSync),常被用于凭据攻击 |
| 风险登录 | Microsoft Entra 标识保护检测到的异常登录,包括不可能旅行、陌生位置和恶意软件关联 IP |
工具与系统
- Microsoft Graph API:用于查询 Entra ID 配置、策略、角色和审核日志的主要编程接口
- Microsoft Graph PowerShell SDK:用于 Entra ID 管理和安全审计任务的 PowerShell 模块
- ScoutSuite:多云审计工具,支持 Azure 提供程序,用于 IAM、存储、网络和身份检查
- AzureADRecon:用于全面 Azure AD 侦察和安全评估报告的社区工具
- Microsoft Defender for Identity:用于检测身份威胁和受损凭据的云端安全解决方案
常见场景
场景:收购后 Azure 租户安全评估
上下文:收购公司后,安全团队需要在将其与公司 Entra ID 集成之前评估 Azure 租户身份安全状况。
方法:
- 枚举所有全局管理员,检查管理员角色中是否包含个人账户
- 审查条件访问策略,验证所有用户(不仅是管理员)是否强制实施 MFA
- 识别具有特权访问权限的来宾用户,这可能表明第三方供应商权限过度
- 检查 90 天以上未登录的陈旧账户,这些账户可能成为凭据攻击的目标
- 审查登录日志中的旧式身份验证使用情况,这些验证绕过了 MFA
- 验证安全默认值或等效的条件访问策略是否阻止了旧式身份验证协议
- 在租户集成之前生成风险报告,列出优先修复步骤
陷阱:Azure AD Premium P2 是检测风险登录和 PIM 所必需的。如果被收购的租户使用较低许可证级别,许多标识保护功能将不可用。来自合作伙伴租户的来宾用户可能通过动态组获得隐式访问权,这在标准角色分配查询中不可见。
输出格式
Azure Active Directory 安全审计报告
===============================================
租户: acme-acquired.onmicrosoft.com
租户 ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
审计日期: 2026-02-23
许可证: Azure AD Premium P2
身份配置:
安全默认值: 已禁用(正在使用条件访问)
条件访问策略: 12(8 已强制实施,3 报告专用,1 已禁用)
旧式身份验证已阻止: 部分(仅限管理员)
特权访问:
全局管理员: 8(建议:<= 4)
永久管理员分配: 6(无需 PIM 激活)
具有管理员权限的服务主体: 3
具有特权角色的来宾用户: 2
账户卫生:
用户总数: 1,247
陈旧账户(90 天以上): 89
来宾用户: 234
未注册 MFA 的用户: 156
登录风险:
风险登录(过去 30 天): 34
旧式身份验证登录(过去 7 天): 67
不可能旅行检测: 5
陌生位置登录: 12
关键发现:
1. 8 位全局管理员已永久分配(请使用 PIM)
2. 非管理员用户的旧式身份验证未被阻止
3. 156 个用户未注册 MFA
4. 2 个来宾用户具有特权角色管理员角色