purpleshellsecurity/azure-principal-activity-analyzer

GitHub: purpleshellsecurity/azure-principal-activity-analyzer

基于 Azure Logic App 与 Azure OpenAI 的自动化取证分诊工具,对用户或服务主体跨登录、审计和活动日志进行画像并生成结构化的 AI 分析报告。

Stars: 0 | Forks: 0

# 主体活动分析器 (Logic App) 这是一个 Azure Logic App (Consumption),给定一个**用户**或**应用程序(服务主体 (service principal))**,它会从 Log Analytics 工作区的三张表中提取其近期活动,并将证据发送到 **Azure OpenAI** 以生成分析师风格的报告。 | 关注点 | 选择 | |---|---| | 触发器 | HTTP 请求(按需) | | 数据源 | Log Analytics 工作区(REST 查询 API) | | 表 | `SigninLogs` + `AADNonInteractiveUserSignInLogs`(用户) · `AADServicePrincipalSignInLogs`(应用) · `AuditLogs` · `AzureActivity` | | 认证 | 系统分配的托管标识(无需密钥,无需 API 连接) | | RBAC | 在代码中创建 — 工作区 + OpenAI 角色分配(跨资源组安全) | | 输出 | 经过 schema 验证的 JSON 分析(Structured Outputs) + 原始证据 | ## 工作原理 ![主体活动分析器架构](https://static.pigsec.cn/wp-content/uploads/repos/cas/95/951c4795de7625146863db31af000b37762dc192e762325b5445e174fefef24d.svg) ## 前置条件 1. 一个已经在收集以下数据的 **Log Analytics 工作区**: - `SigninLogs`, `AADServicePrincipalSignInLogs`, `AuditLogs` → Entra ID **Diagnostic settings** → 将这些类别发送到该工作区。 - `AzureActivity` → 订阅 **Activity log** → 导出 / 诊断设置到该工作区。 2. 一个 **Azure OpenAI** 资源,且具有支持 **Structured Outputs** 的聊天部署 — `gpt-4o`(版本 `2024-08-06` 或更高)、`gpt-4o-mini`、`gpt-4.1` 或 `gpt-5`。工作流 调用 api-version `2024-10-21`(Structured Outputs 要求 `2024-08-01-preview` 或更高版本)。 3. 执行部署的标识需要在工作区和 OpenAI 的资源组上拥有 **Owner** 或 **User Access Administrator** 权限(模板会创建角色分配)。 ## 部署 — 简便方式(推荐) 运行交互式脚本并回答提示。它会在需要时为您登录,创建 资源组,部署所有内容,并在最后打印触发器 URL: ``` ./scripts/deploy.ps1 ``` 您也可以预先传入任何答案(其余部分将通过提示输入): ``` ./scripts/deploy.ps1 -ResourceGroup rg-secops -WorkspaceName my-law -OpenAiName my-aoai ``` 要求:**PowerShell 7+** 和 **Azure CLI** (`az`)。 ## 部署 — 手动方式(替代方案) 使用您现有工作区和 OpenAI 账户的**名称和资源组**编辑 `infra/main.bicepparam` (工作区 GUID 和 OpenAI endpoint 会自动派生): ``` RG=rg-secops az group create -n $RG -l eastus # RG for the Logic App, if needed az deployment group create \ -g $RG \ -f infra/main.bicep \ -p infra/main.bicepparam ``` 任一路径都会创建 Logic App **以及**两个角色分配 (在工作区上的 `Log Analytics Reader`,在 OpenAI 上的 `Cognitive Services OpenAI User`), 即使这些资源位于同一订阅内的其他资源组中。 ## 运行分析 — 简便方式(推荐) 使用配套脚本。它会为您找到触发器 URL(无需复制机密),询问要分析的内容, 调用它,并打印出可读的报告: ``` ./scripts/invoke.ps1 # fully interactive ./scripts/invoke.ps1 -TargetType user -Identifier jdoe@contoso.com # a user ./scripts/invoke.ps1 -TargetType application -Identifier # a service principal ./scripts/invoke.ps1 -TargetType user -Identifier jdoe@contoso.com -LookbackDays 7 -Raw # custom window + full JSON ``` 如果您部署到了非默认的资源组 / 名称,请传入 `-ResourceGroup` 和 `-LogicAppName`。 ## 运行分析 — 手动方式(替代方案) ``` CALLBACK=$(az rest --method post \ --uri "https://management.azure.com$(az resource show -g $RG -n la-principal-activity-analyzer \ --resource-type Microsoft.Logic/workflows --query id -o tsv)/triggers/manual/listCallbackUrl?api-version=2019-05-01" \ --query value -o tsv) curl -s -X POST "$CALLBACK" \ -H "Content-Type: application/json" \ -d '{ "targetType": "user", "identifier": "jdoe@contoso.com" }' # 应用示例 curl -s -X POST "$CALLBACK" \ -H "Content-Type: application/json" \ -d '{ "targetType": "application", "identifier": "" }' ``` ### 请求 schema | 字段 | 必填 | 说明 | |---|---|---| | `targetType` | 是 | `"user"` 或 `"application"` | | `identifier` | 是 | 用户:UPN 或对象 ID。应用:应用(客户端)ID、SP 对象 ID 或 SP 显示名称。 | | `lookbackDays` | 否 | 默认为 30。 | ### 响应结构 `analysis` 对象是通过 OpenAI **Structured Outputs** 生成的,因此保证 匹配此 schema(下游无需进行解析猜测): ``` { "targetType": "user", "identifier": "jdoe@contoso.com", "lookbackDays": 30, "analysis": { "reasoning": "…", // model's chain-of-thought (generated first) "summary": "…", "notableFindings": [ { "title": "…", "detail": "…", "severity": "High", "evidence": "…" } ], "riskRating": "Medium", // Low | Medium | High "riskJustification": "…", "recommendedActions": [ "…" ], "dataGaps": "…" }, "evidence": { /* raw Log Analytics tables for audit */ } } ``` 有关完整的真实示例(一次 90 天的运行),请参阅 [**docs/sample-response.md**](docs/sample-response.md) — 包括请求、控制台报告以及完整的 JSON 响应。 ## 注意事项与说明 - **表可用性**:如果未收集某个诊断类别,该查询 将从 Log Analytics API 返回错误,并且运行会在该步骤失败。在依赖它之前,请确认 上述三个类别正在传输数据。 - **覆盖范围**:每种日志类型都是一个整洁的联合查询,返回聚合摘要(按 维度的计数),包含高基数切片的汇总行,外加有限数量的 敏感/失败原始事件样本 — 在不导出原始行的情况下实现对时间窗口的全面覆盖。 - **输入处理**:在将 `identifier` 放入 KQL 之前,会去除其引号字符(基本的注入防护)。 - **Prompt 注入强化**:日志字段(显示名称、应用名称、user agents、审计 原因)是攻击者可控的。根据 OpenAI 针对不可信数据的 Model Spec 指南, 查询结果在传递给模型时会包装在 `` XML 标签中,并且 系统提示会指示模型严格将该内容视为数据 — 绝不能视为 指令 — 并将任何嵌入的类似指令的文本标记为可疑发现。 - **Structured Outputs**:AI 调用设置了 `response_format: json_schema` 且带有 `strict: true`, 因此响应始终符合 `HTTP_AI` 操作中的 schema。根据 Azure 的 schema 规则,每个属性都会在 `required` 中列出,并且每个对象都设置了 `additionalProperties:false`。 如果您编辑了 schema,请保持这些规则,否则 API 将返回 400。 - **替换 AI 后端**:要使用非 Azure-OpenAI 模型,请更改 `infra/workflow.json` 中 `HTTP_AI` 操作的 URI/headers/body 及其 `authentication` 块。
标签:AI, AI合规, Azure, Libemu, 自动化代码审查, 自动化分析, 跨站脚本, 运维工具