審計 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) - Azure CLI 已透過
az login --tenant TENANT_ID驗證至目標租用戶 - ScoutSuite 已設定 Azure 提供者以進行自動化評估
- 可存取 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='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 ', '}
}
步驟 4:識別閒置帳戶與來賓使用者
尋找近期未登入的帳戶、具有有效角色指派的停用帳戶,以及風險的來賓使用者組態。
# 尋找 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
步驟 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[*].{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
步驟 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 功能,可啟用即時特殊權限存取,並包含核准工作流程和限時角色啟用 |
| 舊版驗證 | 較舊的驗證通訊協定(POP3、IMAP、SMTP、ActiveSync),不支援 MFA,且常被利用於憑證攻擊 |
| 風險登入 | Microsoft Entra Identity Protection 偵測到的登入異常,包括不可能的路程、不熟悉的位置和與惡意軟體相關的 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 的舊版驗證使用情況
- 驗證安全預設值或等效的 CA 原則是否已封鎖舊版驗證通訊協定
- 在租用戶整合前,製作一份風險報告,並列出優先處理的補救步驟
陷阱:風險登入偵測和 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 個來賓使用者具有特殊權限角色管理員角色