zmustafa/AzureEntraIDIAMScanner

GitHub: zmustafa/AzureEntraIDIAMScanner

一款只读的 Azure 与 Microsoft Entra ID 身份和访问权限发现扫描器,通过全面盘点各类 RBAC、目录角色、组派生访问等权限分配并生成多格式审计报告,解决云租户权限可见性难题。

Stars: 0 | Forks: 0

# Azure 和 EntraID IAM 扫描器 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/68b6eab854163317.svg)](https://github.com/zmustafa/AzureEntraIDIAMScanner/actions/workflows/ci.yml) [![CodeQL](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/bcc5942606163323.svg)](https://github.com/zmustafa/AzureEntraIDIAMScanner/actions/workflows/codeql.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![PowerShell 5.1+](https://img.shields.io/badge/PowerShell-5.1%2B-5391FE?logo=powershell&logoColor=white)](https://learn.microsoft.com/powershell/) [![Node.js 18+](https://img.shields.io/badge/Node.js-18%2B-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![只读](https://img.shields.io/badge/access-read--only-success)](SECURITY.md) `all-azure-access` 是 Azure 和 EntraID IAM 扫描器的包和扫描命令标识,这是一个可在控制台运行的 Azure 和 Microsoft Entra 访问发现扫描器。它旨在对广泛的访问权限进行盘点,包括 Azure 控制平面、Azure 数据平面角色分配、Entra 目录角色、基于组的访问权限、服务主体所有权、Key Vault 访问策略,以及可选/尽力而为的访问面(如 PIM、计费、预留和经典订阅管理员)。 该扫描器具有高度的容错性:每个访问区域独立收集,失败情况会记录在输出中,并在可能的情况下继续运行。 ## 安全说明 - 该扫描器通过 Azure CLI、Microsoft Graph 和 Azure Resource Manager API 执行只读发现。 - 该扫描器使用您现有的本地 `az login` 会话。它不要求或存储密码、客户端密钥、证书、刷新令牌或私钥。 - 真实的扫描输出可能包含敏感访问数据,包括特权用户、组、服务主体、所有权关系、订阅、资源和角色分配。 - 请勿将真实的扫描输出提交到公共存储库。 - 默认情况下,真实的扫描输出会写入操作系统临时文件夹下的存储库之外,例如 Windows 上的 `%TEMP%\azure-scanners\all-azure-access\\`。 ## 支持策略 此 v1 版本包以 Windows 优先,并使用 Windows PowerShell 进行了测试。PowerShell 7 可能适用于许多路径,但跨平台 Linux/macOS 支持并不是当前的兼容性目标。 ## 主要命令 在此独立文件夹中: ``` npm install powershell -ExecutionPolicy Bypass -File .\run.ps1 -ContinueOnError ``` 一次实际且有边界的验证运行: ``` powershell -ExecutionPolicy Bypass -File .\run.ps1 -LimitResources 25 -SkipReservations -ContinueOnError ``` 针对一个或多个订阅: ``` powershell -ExecutionPolicy Bypass -File .\run.ps1 -SubscriptionIds , -ContinueOnError ``` 选择自定义输出根目录: ``` powershell -ExecutionPolicy Bypass -File .\run.ps1 -OutputRoot D:\AzureScannerOutput -LimitResources 25 -SkipReservations -ContinueOnError ``` 您还可以为 shell 会话设置默认的输出根目录: ``` $env:AZURE_IAM_SCANNER_OUTPUT_ROOT = 'D:\AzureScannerOutput' powershell -ExecutionPolicy Bypass -File .\run.ps1 -LimitResources 25 -SkipReservations -ContinueOnError ``` ## 发现内容 ### Microsoft Entra ID RBAC 通过 Microsoft Graph 角色管理 API 收集 Entra 目录角色分配。 此访问面中包含的角色示例: - 全局管理员 - 特权角色管理员 - 用户管理员 - 应用程序管理员 - 组管理员 - 安全管理员 - Exchange 管理员 - Teams 管理员 - SharePoint 管理员 - Intune 管理员 - 通过 Entra 角色 API 暴露的合规性和安全门户角色 捕获的详细信息包括角色名称、主体 ID/类型、分配状态、目录范围、应用范围(如果存在)、分配 ID 以及源 API 元数据。 ### Azure RBAC 跨可见的 Azure 订阅和范围收集 Azure Resource Manager 角色分配。 支持的范围级别包括: - 租户根范围(尽力而为) - 管理组(尽力而为) - 订阅 - 资源组 - 资源 - 选定的子资源范围,例如存储容器和文件共享 此访问面中包含的 Azure RBAC 角色示例: - 所有者 - 参与者 - 读者 - 用户访问管理员 - 网络参与者 - 虚拟机参与者 - Key Vault 参与者 - 存储账户参与者 - 自定义 Azure 角色 扫描器会保留范围、范围类型、角色定义 ID、分配 ID、分配时间戳、条件、条件版本、继承标志(如果返回)、订阅名称/ID、资源组、资源类型和资源名称。 ### Azure 数据平面 RBAC Azure 数据平面角色通常通过 Azure RBAC 分配,但授予的是对服务内部数据的访问权限,而不仅仅是对 ARM 资源外壳的管理。 扫描器会尽可能将角色定义和观察到的分配分类为控制平面、数据平面或混合类型。 示例: - 存储 Blob 数据读者 - 存储 Blob 数据参与者 - 存储 Blob 数据所有者 - 存储文件数据 SMB 共享读者 - 存储文件数据 SMB 共享参与者 - Key Vault 机密用户 - Key Vault 加密官 - 事件中心数据接收者 - 事件中心数据发送者 - 服务总线数据发送者 - 服务总线数据接收者 ### 存储子范围 扫描器会尝试对常见的存储 RBAC 数据范围进行子范围发现,包括: - blob 容器 - 文件共享 当这些范围可见且当前环境中的 Azure CLI 支持时,将查询子范围的角色分配并将其包含在标准化输出中。 ### 组和嵌套组扩展 对于授予 Entra 组的分配,扫描器会尝试通过 Microsoft Graph 展开可传递的组成员身份。 它会记录: - 被分配的组 - 通过可传递成员身份解析出的有效成员 - 访问路径为 `GroupTransitive` - 可用的组链文本 - 源组 ID/名称 这使得报告能够同时回答以下问题: - 谁被直接分配了权限? - 谁通过组成员身份实际获得了访问权限? 使用此标志可跳过组扩展: ``` -NoGroupExpansion ``` ### 服务主体和应用程序所有权 对于在访问分配中观察到的服务主体,扫描器会尝试通过 Microsoft Graph 检索服务主体所有者。 所有者行作为有效所有权访问发出,因为根据租户策略,所有者可能能够控制凭据、联合凭据或操作身份配置。 输出包括: - 服务主体 ID/名称 - 所有者主体 ID/类型/名称 - 可用的所有者 UPN - 访问路径 `Owner` - 分配类型 `Owner` ### Key Vault 访问策略 扫描器将 Key Vault 旧版访问策略与 Azure RBAC 分开处理。 这很重要,因为旧的 Key Vault 可能仍在使用访问策略而不是 Azure RBAC 角色来授予数据平面权限。 捕获的详细信息包括: - Vault 范围 - 策略对象 ID - 序列化的密钥/机密/证书/存储权限 - 订阅/资源组/Vault 元数据 ### PIM / 符合条件的访问 扫描器会在允许的情况下尝试收集符合条件的分配。 尽力而为的收集器包括: - 通过 Graph 获取的 Entra 目录角色资格 - 通过 ARM 授权 API 获取的 Azure 角色资格 PIM 不被视为单独的权限模型。这些行会被标记为 `Eligible` 等分配状态,以便工作簿可以区分活动访问与符合条件的/JIT 访问。 ### 计费、预留和与成本相关的访问 计费和预留 API 通常需要单独的权限。这些收集器采用尽力而为的原则,记录状态而不是阻塞运行。 尽力而为的访问面包括: - 计费账户 - 计费范围 - 预留订单 - 预留范围 - Azure CLI/API 支持的计费/预留范围内的角色分配 为了控制台的稳定性,可以跳过预留集合的收集: ``` -SkipReservations ``` ### 经典订阅管理员 扫描器会尝试在 Azure CLI 返回经典管理员类型的分配时将其包含在内。 示例: - 账户管理员 - 服务管理员 - 协同管理员 经典管理员行使用 `ClassicAzureAdmin` 访问模型进行标记。 ## 故障处理 扫描器是围绕独立的收集器构建的。如果一个收集器发生故障,会记录该故障并继续扫描。 收集器状态包括: - `Succeeded` - `SucceededWithWarnings` - `Skipped` - `Failed` - `Unauthorized` - `Throttled` - `PartiallyCollected` 退出代码: - `0`:成功完成 - `2`:完成但有警告、部分失败或未授权的可选收集器 - `1`:启动级别的失败,例如缺少 Azure CLI、未登录或输出文件夹失败 错误和警告会写入: ``` output\collectorStatus.csv output\errorsWarnings.csv errors\.json logs\all-azure-access.log ``` ## 输出位置 每次运行都写入以下位置下: ``` %TEMP%\azure-scanners\all-azure-access\\ ``` 运行文件夹包含: ``` output\ logs\ errors\ cache\ raw\ reports\ ``` ## 主要输出文件 ``` output\allAzureAccess.csv output\allAzureAccess.json output\effectiveAccess.csv output\directAssignments.csv output\groupDerivedAccess.csv output\nestedGroupAccess.csv output\servicePrincipalOwners.csv output\principalResolution.csv output\groupExpansion.csv output\roleDefinitions.csv output\scopeInventory.csv output\collectorStatus.csv output\coverageSummary.json output\errorsWarnings.csv output\results.json output\results.zip reports\all-azure-access-report-.xlsx reports\all-azure-access-summary-.json ``` ## 工作簿工作表 生成的工作簿专为审查和透视样式发现而设计。 工作表包括: - 执行摘要 - 收集器状态 - 覆盖范围 - 所有原始访问权限 - 有效访问权限 - 特权访问权限 - 数据平面访问权限 - 服务主体所有者 - 组访问权限 - Entra 角色 - Azure RBAC - 管理组 - 订阅 - 资源组 - 资源 - 存储子范围 - Key Vault 访问权限 - PIM - 计费预留 - 经典管理员 - 角色定义 - 主体目录 - 错误警告 - 源元数据 - 透视表 ## 透视样式摘要 工作簿包含预计算的摘要部分,例如: - 按访问面划分的访问权限 - 按角色划分的访问权限 - 按主体类型划分的访问权限 - 按主体划分的访问权限 - 按订阅划分的访问权限 - 按管理组划分的访问权限 - 按范围类型划分的访问权限 - 按主体划分的特权角色 - 按资源类型划分的数据平面角色 - 按组划分的派生访问权限 - PIM 符合条件 vs 活动状态 - 按收集器划分的故障 - 按类型发现的资源 ## 标准化访问列 主要标准化输出使用宽架构,以便可以在一个工作簿中比较不同的访问模型。 重要列包括: ``` surface accessModel collector assignmentState assignmentType principalId principalType principalDisplayName principalUserPrincipalName principalAppId effectivePrincipalId effectivePrincipalType effectivePrincipalName effectivePrincipalUserPrincipalName accessPath groupChain sourceGroupId sourceGroupName roleName roleDefinitionId roleCategory roleIsPrivileged roleHasDataActions scope scopeType scopeDisplayName tenantId managementGroupId managementGroupName subscriptionId subscriptionName resourceGroup resourceType resourceName childResourceType childResourceName assignmentId assignmentCreatedOn assignmentUpdatedOn condition conditionVersion isInherited sourceApi collectionStatus errorCode errorMessage ``` ## 常用标志 ``` -SubscriptionIds ``` 将扫描限制为特定的订阅。 ``` -ManagementGroupIds ``` 将管理组 RBAC 收集限制为特定的管理组。 ``` -ResourceTypes ``` 将资源盘点限制为特定的 ARM 资源类型。 ``` -LimitResources ``` 在资源级别发现期间限制每个订阅的资源数量。适用于验证运行。 ``` -SkipResourceLevel ``` 跳过资源级别的角色分配检查。 ``` -SkipChildDataScopes ``` 跳过存储子范围(如 blob 容器和文件共享)发现。 ``` -SkipPim ``` 跳过 PIM 资格收集器。 ``` -SkipBilling ``` 跳过计费收集器。 ``` -SkipReservations ``` 跳过预留收集器。除非明确需要预留访问权限,否则建议在快速控制台运行时使用。 ``` -SkipClassicAdmins ``` 跳过经典订阅管理员检查。 ``` -SkipKeyVaultAccessPolicies ``` 跳过旧版 Key Vault 访问策略收集。 ``` -NoGroupExpansion ``` 不将组分配展开为有效的可传递用户/服务主体行。 ``` -FullRoleDefinitionScan ``` 从每个可见的订阅和管理组收集角色定义。如果没有此标志,扫描器会从响应迅速的订阅收集角色定义,并从观察到的分配中推断元数据,以保持控制台运行的速度。 ``` -ContinueOnError ``` 在收集器失败时继续运行。这是广泛的租户发现的预期操作模式。 ``` -FailFast ``` 在第一个非可选收集器失败时停止。 ``` -OutputRoot ``` 将运行输出写入自定义根目录下。如果省略,扫描器将在设置 `AZURE_IAM_SCANNER_OUTPUT_ROOT` 时使用该变量,否则使用操作系统临时文件夹加上 `azure-scanners`。 ## 推荐运行模式 快速验证: ``` powershell -ExecutionPolicy Bypass -File .\run.ps1 -LimitResources 25 -SkipReservations -ContinueOnError ``` 单订阅验证: ``` powershell -ExecutionPolicy Bypass -File .\run.ps1 -SubscriptionIds -LimitResources 10 -SkipReservations -ContinueOnError ``` 更广泛的租户运行: ``` powershell -ExecutionPolicy Bypass -File .\run.ps1 -SkipReservations -ContinueOnError ``` 具有完整角色定义覆盖的深度运行: ``` powershell -ExecutionPolicy Bypass -File .\run.ps1 -FullRoleDefinitionScan -ContinueOnError ``` ## 要求 - Windows PowerShell 5.1 或更高版本;Windows 是受支持的 v1 操作系统 - 可用的 Azure CLI (`az`) - 有效的 `az login` - 足够的 Azure RBAC 权限以列出分配和资源 - 通过已登录的 Azure CLI 会话提供的 Microsoft Graph 权限,用于 Entra 角色、主体、组和所有者查找 - Node.js 18+,用于通过 `report.mjs` 生成 XLSX 工作簿 - 使用 `npm install` 安装本地 Node 依赖项,该命令将从 `package.json` 安装 `exceljs` ## 验证包 从存储库根目录运行内置的包验证: ``` npm run validate ``` 验证脚本会解析 PowerShell 文件,在需要时安装 npm 依赖项,重新生成虚拟示例工作簿,并验证示例摘要是否包含行。 ## 带有虚拟数据的示例工作簿 以下位置提供了一个仅包含虚拟数据的示例工作簿: ``` samples\all-azure-access-sample-ALL-dummy.xlsx ``` 示例工作簿仅根据以下位置的合成输入生成: ``` samples\dummy-input\ ``` 该示例使用虚假 ID、虚假订阅和 `example.invalid` 标识。它不包含真实的租户数据。 要从虚拟输入重新生成示例工作簿: ``` node .\report.mjs ` --run-dir .\samples\dummy-input ` --access-csv .\samples\dummy-input\allAzureAccess.csv ` --effective-csv .\samples\dummy-input\effectiveAccess.csv ` --direct-csv .\samples\dummy-input\directAssignments.csv ` --group-csv .\samples\dummy-input\groupDerivedAccess.csv ` --service-principal-owners-csv .\samples\dummy-input\servicePrincipalOwners.csv ` --collector-status-csv .\samples\dummy-input\collectorStatus.csv ` --scope-inventory-csv .\samples\dummy-input\scopeInventory.csv ` --role-definitions-csv .\samples\dummy-input\roleDefinitions.csv ` --principal-resolution-csv .\samples\dummy-input\principalResolution.csv ` --errors-csv .\samples\dummy-input\errorsWarnings.csv ` --coverage-json .\samples\dummy-input\coverageSummary.json ` --output .\samples\all-azure-access-sample-ALL-dummy.xlsx ` --summary-json .\samples\all-azure-access-sample-ALL-dummy-summary.json ``` ## 当前限制 - 针对特定工作负载的访问模型(例如 Exchange RBAC、SharePoint 项目权限、Teams 成员身份、Int RBAC、Azure DevOps 权限、SQL 数据库权限和 AKS Kubernetes RBAC)在此扫描器中尚未完全实现。它们需要单独的工作负载 API 和数据模型。 - 根据已登录的账户,某些计费、预留、PIM 和管理组 API 可能会返回无数据或未授权响应。 - 在大型租户中,资源级别和子范围扫描可能会很慢。请使用 `-LimitResources`、`-ResourceTypes`、`-SkipResourceLevel` 或 `-SkipChildDataScopes` 进行有针对性的验证。 - 在 Graph 可传递成员身份可用的情况下,将扩展组的有效访问权限。如果 Graph 拒绝读取成员身份,报告中仍会保留直接分配行,并且收集器状态会记录此问题。 - v1 版本以 Windows 优先。跨平台的 PowerShell 支持可能需要额外的测试和微小的进程启动更改。
标签:AI合规, Azure, IPv6, Libemu, Microsoft Entra ID, MITM代理, PowerShell, 权限审计, 身份与访问管理