MahdiHedhli/m365-ir-toolkit

GitHub: MahdiHedhli/m365-ir-toolkit

面向无 SIEM 的 Microsoft 365 Business Premium 租户的只读 PowerShell 事件响应工具包,用于在日志过期前收集审计日志、追踪可疑 IP 并构建入侵时间线。

Stars: 0 | Forks: 0

# m365-ir-toolkit 用于 Microsoft 365 / Entra 事件响应的只读 PowerShell 工具 —— 收集日志、追踪 IP,并在**没有 SIEM** 的租户中构建时间线。 ![PowerShell](https://img.shields.io/badge/PowerShell-5.1%2B%20%7C%207-blue) ![License](https://img.shields.io/badge/License-MIT-green) ![Read-only](https://img.shields.io/badge/Operations-read--only-brightgreen) ## 为什么会有这个项目 大多数 Microsoft 365 威胁狩猎资料都假设你可以针对 Microsoft Sentinel 或 Defender XDR Advanced Hunting 编写 KQL。这种假设悄无声息地将庞大的租户群体排除在外:使用 **Microsoft 365 Business Premium** 的中小型企业。在该层级中,你拥有 Entra ID P1 和 Defender for Business —— **完全没有任何 KQL 界面**。门户中没有 Advanced Hunting,没有 Log Analytics 工作区,并且登录/审计日志仅保留约 30 天。 因此,当这些租户中的一个出现账号被盗用时,你无法“运行狩猎”。你必须赶在日志过期之前,直接通过 API 自行提取日志 —— 而且你必须清楚哪份日志中保留着答案。这就是该工具包的用途:通过只读的 PowerShell 收集 Business Premium 租户公开的所有数据(通过 Exchange Online 获取统一审计日志;通过 Microsoft Graph 获取登录和目录日志),在所有数据中追踪可疑 IP,并组装成时间线。 它是查询库的响应式、事件发生时的对应工具 —— 专为没有高级遥测技术栈的租户而构建。 ## 已有 SIEM 或 E5?你应改用 KQL 如果租户拥有 **Microsoft Sentinel** 或 **Defender XDR Advanced Hunting** —— 即 Microsoft 365 E5、E5 Security、Defender Suite 附加组件,或者是独立的 Entra ID P2 搭配 Defender 产品 —— 你就拥有了完善的 KQL 狩猎界面和更长的保留期。请使用配套代码库: ➡️ **[Cloud Threat Hunting Playbook](https://github.com/MahdiHedhli/cloud-threat-hunting-playbook)** — 用于 Entra、Azure 和 Defender XDR 的可复用 KQL 狩猎查询。 适用场景对比: | 租户拥有… | KQL 界面? | 使用 | | --- | --- | --- | | Microsoft Sentinel / Log Analytics | 是 | [Cloud Threat Hunting Playbook](https://github.com/MahdiHedhli/cloud-threat-hunting-playbook) (KQL) | | Defender XDR Advanced Hunting (E5 / E5 Security / Defender Suite) | 是 | [Cloud Threat Hunting Playbook](https://github.com/MahdiHedhli/cloud-threat-hunting-playbook) (KQL) | | **Business Premium / Entra P1,无 SIEM** | **否** | **此代码库** | | Entra Free (基础的 Business Basic/Standard) | 否 | 此代码库 — 但注意日志仅保留 7 天 | 完整的许可证 → 遥测 → 保留期映射表:[docs/telemetry-licensing.md](docs/telemetry-licensing.md)。 ## 包含哪些内容 [`scripts/`](scripts/) 中的三个只读脚本: - **`Trace-CompromiseTimeline.ps1`** — 给定一个可疑 IP 和一个用户,提取所有可访问的日志,并构建一个按时间排序的账号活动时间线。 - **`Find-OrgAccessFromIP.ps1`** — 给定一个或多个 IP,在整个租户中搜索该 IP 集*已访问*与仅*尝试访问*的账号,以评估爆炸半径 / 判断“是否已隔离?”。 - **`Get-AccountIPReport.ps1`** — 给定一个或多个用户,报告触及这些账号的每个 IP,并通过 ASN / 公司 / 地理位置 / 托管标记进行丰富,包含跨账号关联以及可揭示 IP 轮换的 ASN 汇总。 这三个脚本都是**只读**的:它们只进行收集,从不更改租户。 ## 前置条件 ``` Install-Module Microsoft.Graph.Authentication, ExchangeOnlineManagement -Scope CurrentUser ``` 运行这些脚本所需账号的角色: - Entra **Security Reader** 或 **Reports Reader**(登录日志需要 Entra P1,Business Premium 已包含此权限) - Exchange/Purview **View-Only Audit Logs**(用于统一审计日志) 完整的设置、Graph scope 和注意事项:[docs/getting-started.md](docs/getting-started.md)。 ## 分步指南:调查被盗用的账号 这些脚本可串联成一个工作流。将日期设置为涵盖从可疑时期到今天的范围 —— 并且在相信任何空结果之前,请先阅读下方的保留期说明。 **1 — 为已知被盗用的账号构建时间线。** ``` .\scripts\Trace-CompromiseTimeline.ps1 -SuspectIP 185.174.101.58 -UserPrincipalName jdoe@client.com -StartDate '2026-05-01' -EndDate '2026-06-22' ``` 生成 `TIMELINE_full.csv`(所有内容,按时间顺序排列)、`TIMELINE_suspect_IP_only.csv`(仅包含攻击者的操作)、收件箱规则和 MFA 快照,以及原始证据。控制台会标记该 IP 登录过的任何*其他*用户。 **2 — 确定爆炸半径:是否已隔离?** ``` .\scripts\Find-OrgAccessFromIP.ps1 -SuspectIP 185.174.101.58 -StartDate '2026-05-01' -EndDate '2026-06-22' ``` 在整个租户中搜索该 IP,并将每个账号判定为 **ACCESSED**(成功登录或有审计日志活动)或 **attempted**(仅失败)。`ORG_IP_ACCESSED_users.txt` 是你的响应清单。 **3 — 分析 IP 特征并捕捉轮换。** ``` .\scripts\Get-AccountIPReport.ps1 -UserPrincipalName jdoe@client.com,asmith@client.com -StartDate '2026-05-01' -EndDate '2026-06-22' ``` 触及这些账号的每个 IP,都通过 ASN / 公司 / 地理位置以及托管/代理标记进行了丰富。`shared_IP_rollup.csv` 显示了触及**多个**账号的 IP(扩散情况);`account_ASN_rollup.csv` 显示了位于**同一个**托管 AS 中的多个 IP(轮换情况)。 **4 — 基于 AS 进行扩展并重新扫描。** 提取汇总报告中显示的托管 AS 关联 IP,并在整个集合中再次运行全租户扫描: ``` .\scripts\Find-OrgAccessFromIP.ps1 -SuspectIP 185.174.101.58,185.174.101.91,185.174.102.7 -StartDate '2026-05-01' -EndDate '2026-06-22' ``` 这将把“此 *IP* 触及了哪些账号”转换为“此 *攻击者* 触及了哪些账号”。 完整决策树:[docs/account-compromise.md](docs/account-compromise.md)。分步遏制操作手册:[docs/containment-checklist.md](docs/containment-checklist.md)。 ## 保留期陷阱(请阅读此处) 在 Business Premium / Entra P1 级别下,**Entra 登录和审计日志仅保留约 30 天。** 而 **Unified Audit Log** (Exchange/Purview) 保留 **~180 天**,涵盖所有工作负载,并在每条记录中带有客户端 IP。因此,如果泄露发生在一个月或更久以前,登录日志可能**已经消失**,UAL 将是你的主要数据源。该时期的登录结果为空意味着*已过期*,而不是*安全无恙*。正是出于这个原因,每个脚本都依赖 UAL,并在其输出中明确说明了这一点。 ## 在 Business Premium 级别下,你能证明什么以及不能证明什么 两个遥测缺失是由于许可证导致的,而不是 Bug: - **风险评分** (`RiskState`, `RiskLevelDuringSignIn`,风险用户报告) 属于 Entra **P2** / Identity Protection 功能 — 在 P1 中为空。 - **邮件是否实际被读取** (`MailItemsAccessed`) 属于 **E5 / Purview Audit Premium** 功能 — 在 Business Premium 中不可用。 因此,你可以证明某个 IP *确实* 登录了以及它做了*什么*(创建的规则、触及的文件、发送的邮件),但无法证明它打开了每一封邮件。这些数据的缺失绝不能作为什么都没发生的证据。 ## 安全与范围 - **只读。** 这些脚本仅进行收集;不会做出任何更改。遏制措施 —— 吊销会话、重置凭证、移除攻击者的 MFA/规则、Conditional Access —— 刻意*没有*被自动化。请通过你自己的管理员流程执行操作 — 参见 [遏制检查清单](docs/containment-checklist.md)。 - **丰富数据使用第三方。** `Get-AccountIPReport.ps1` 会将观察到的 IP(包括用户自己的 IP)发送到 ip-api.com 以获取 ASN/地理信息。对于隐私敏感或受监管的租户,请使用 `-SkipEnrichment` 参数,或者替换为离线的 GeoIP 数据库。 - **输出包含客户数据。** 生成的 CSV 文件夹默认会被 git 忽略。请保持原始的 `*_RAW.csv` 证据不被修改,并在副本上进行分析。 - **根据你自己的环境进行核实。** Microsoft 会重命名产品并更改保留期;请针对你正在操作的租户确认具体细节。 ## 许可证 MIT — 详见 [LICENSE](LICENSE)。仅供在你获授权调查的租户上进行防御性事件响应时使用。
标签:AI合规, IPv6, Libemu, Microsoft 365, PowerShell, 安全运营, 库, 应急响应, 扫描框架