Audits Microsoft Entra ID (Azure AD) configurations using AzureAD PowerShell, Microsoft Graph API, and ScoutSuite to identify high-risk auth policies, permissive roles, stale accounts, conditional access gaps, and guest risks.
npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
- 对 Azure 租户的身份配置进行安全评估时
Audits Microsoft Entra ID (Azure AD) configurations for risky authentication policies, permissive roles, stale accounts, conditional access gaps, and guest risks using PowerShell, Graph API, ScoutSuite.
Audits Microsoft Entra ID configs for risky auth policies, permissive roles, stale accounts, conditional access gaps, and guest risks using PowerShell, Graph API, and ScoutSuite.
Detects and investigates Azure service principal abuse in Microsoft Entra ID, including privilege escalation, credential addition, role assignments, consent bypass, and enumeration using KQL for Sentinel and SPL for Splunk.
Share bugs, ideas, or general feedback.
不适用于:本地 Active Directory 审计(使用 PingCastle 或 BloodHound AD)、无身份上下文的 Azure 资源级别 RBAC 审计,或实时威胁检测(使用 Microsoft Defender for Identity)。
Install-Module Microsoft.Graph)az login --tenant TENANT_ID)评估租户的基线身份安全设置,包括安全默认设置和旧式身份验证状态。
# 连接 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
审查目录角色分配,识别权限过高的用户、永久管理员账户和高风险角色配置。
# 列出所有全局管理员分配
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:principal.@odata.type}" \
-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
审计条件访问策略的覆盖缺口,尤其是 MFA 强制执行、设备合规性和基于位置的限制。
# 列出所有条件访问策略
Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State, @{
N='GrantControls'; E={$_.GrantControls.BuiltInControls -join ', '}
} | Format-Table -AutoSize
# 识别仅报告模式(未强制执行)的策略
Get-MgIdentityConditionalAccessPolicy | Where-Object {$_.State -eq "enabledForReportingButNotEnforced"} |
Select-Object DisplayName
# 检查 MFA 强制执行覆盖范围
Get-MgIdentityConditionalAccessPolicy | Where-Object {
$_.GrantControls.BuiltInControls -contains "mfa"
} | Select-Object DisplayName, State, @{
N='Users'; E={$_.Conditions.Users.IncludeUsers -join ', '}
}
# 查找排除了组的策略(潜在绕过)
Get-MgIdentityConditionalAccessPolicy | Where-Object {
$_.Conditions.Users.ExcludeGroups.Count -gt 0
} | Select-Object DisplayName, @{
N='ExcludedGroups'; E={$_.Conditions.Users.ExcludeGroups -join ', '}
}
查找长期未登录的账户、拥有活跃角色分配的已禁用账户,以及高风险的来宾用户配置。
# 查找 90 天以上未登录的用户
az ad user list --query "[?signInActivity.lastSignInDateTime < '2025-11-25T00:00:00Z'].{UPN:userPrincipalName, LastSignIn:signInActivity.lastSignInDateTime, Enabled:accountEnabled}" -o table
# 列出所有来宾用户
az ad user list --filter "userType eq 'Guest'" \
--query "[].{UPN:userPrincipalName, DisplayName:displayName, CreatedDate:createdDateTime}" \
-o table
# 查找具有特权角色的来宾用户
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?\$expand=principal" \
--query "value[?principal.userType=='Guest'].{Role:roleDefinitionId,Guest:principal.userPrincipalName}" \
-o table
# 检查未启用 MFA 的账户
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/reports/authenticationMethods/userRegistrationDetails" \
--query "value[?!isMfaRegistered].{UPN:userPrincipalName,MfaRegistered:isMfaRegistered}" \
-o table
审查登录日志,识别异常身份验证模式、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[*].{User:userPrincipalName,Risk:riskLevelDuringSignIn,IP:ipAddress,App:appDisplayName,Status: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[*].{User:userPrincipalName,Location: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[*].{User:userPrincipalName,ClientApp:clientAppUsed,Status:status.errorCode}" \
-o table
执行 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 | 微软的云身份和访问管理服务,原名 Azure Active Directory,提供身份验证和授权 |
| 条件访问(Conditional Access) | 策略引擎,评估信号(用户、设备、位置、风险),强制执行 MFA、设备合规或阻止访问等访问控制 |
| 安全默认设置(Security Defaults) | 微软的基线身份保护设置,强制执行 MFA 注册、阻止旧式身份验证并保护特权操作 |
| 特权身份管理(Privileged Identity Management) | Azure AD Premium P2 功能,通过审批工作流和时限角色激活实现即时特权访问 |
| 旧式身份验证(Legacy Authentication) | 不支持 MFA 的旧版身份验证协议(POP3、IMAP、SMTP、ActiveSync),常被用于凭据攻击 |
| 高风险登录(Risky Sign-In) | Microsoft Entra Identity Protection 检测到的登录异常,包括不可能的旅行、陌生位置和恶意软件关联 IP |
场景背景:收购公司后,安全团队需要在将其与企业 Entra ID 集成之前,评估被收购公司的 Azure 租户身份安全态势。
方法:
常见陷阱:高风险登录检测和 PIM 需要 Azure AD Premium P2。如果被收购租户使用较低许可证层,许多身份保护功能将不可用。来自合作伙伴租户的来宾用户可能通过动态组具有隐式访问权限,这在标准角色分配查询中不可见。
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 个来宾用户拥有特权角色管理员(Privileged Role Administrator)角色