Lovedipsingh/sentinel-kql-detection-lab

GitHub: Lovedipsingh/sentinel-kql-detection-lab

这是一个Microsoft Sentinel的检测实验室,提供5个生产级KQL规则来检测凭据攻击并优化误报,映射到MITRE ATT&CK框架。

Stars: 0 | Forks: 0

# 🔵 Microsoft Sentinel SOC 检测实验室 **Sentinel | KQL | Azure | MITRE ATT&CK | 蓝队** 在Azure中部署的Microsoft Sentinel SIEM实验 — 5个KQL检测查询,涵盖凭据泄露关联、暴力破解攻击、外部IP异常、SYSTEM账户滥用以及非工作时间登录。包含一个与MITRE ATT&CK映射关联的实时自动化分析规则,可自动生成事件。 ## 📖 如何阅读此仓库 - **30秒快速浏览:** 阅读下面的执行摘要和测试矩阵 - **深入研究:** 每个查询都包含描述、KQL代码、截图、MITRE映射和调优指南 - **仅代码:** 检测逻辑位于 `/queries/` 目录下,以 `.kql` 文件形式存在 - **工程决策:** 参见 `DECISIONS.md` 了解阈值、时间窗口和调优选择背后的原因 ## 🎯 目标 在Azure中部署Microsoft Sentinel,编写涵盖常见攻击模式的KQL检测查询,并将检测转化为可自动生成可操作事件的自动化分析规则 — 在实验环境中演示端到端的SOC检测工程工作流程。 ## 🔬 环境 | 组件 | 详情 | |---|---| | 平台 | Microsoft Sentinel (Azure 云) | | 工作区 | soc-lab-sentinel | | 查询语言 | KQL (Kusto 查询语言) | | 数据源 | Windows 安全事件 (SecurityEvent 表) | | 分析规则 | 定时查询 — 每 5 分钟运行一次,回溯 15 分钟 | ## 📋 执行摘要 在Azure中部署了一个Microsoft Sentinel工作区,并编写了5个SOC风格的KQL检测规则,涵盖了常见的Tier 1告警场景 — 凭据泄露关联、暴力破解、外部IP登录、SYSTEM账户滥用和非工作时间访问。将优先级最高的检测转化为一个实时的定时分析规则,当检测到暴力破解活动时,会自动生成高严重性事件。 **关键成果:** 通过排除登录类型5(服务账户)的活动,对查询4(SYSTEM账户登录)的调优消除了47个误报中的45个 — **减少了96%**。所有五个查询都经历了类似的误报调优周期,记录在下面的测试与验证矩阵中。 **特色检测:** 查询1(多次失败后的成功登录)使用时序关联来识别高置信度的凭据泄露模式 — 来自同一账户、主机和IP的重复失败登录之后的成功登录 — 映射到MITRE T1110。 所有检测都包含明确的时间窗口、IPv4/IPv6过滤以及经过实验室测试的调优指南。查询均映射到MITRE ATT&CK框架。 ## 🔍 KQL 检测查询 ### 查询 1 — 多次失败后的成功登录 (T1110) ⭐ 特色 **描述:** 在定义的时间窗口内,将重复的失败登录与来自同一来源的后续成功登录进行关联 — 这是可能存在凭据泄露的高可信度指标。 **关键工程选择:** - 时序关联:成功必须发生在失败**之后**,而不是之前 - 30分钟关联窗口防止不相关活动导致的误关联 - 在账户 + 计算机名 + IP地址上进行严格连接以降低误报率 - 结果按失败次数和最近性排序,便于分析师优先处理 ``` let Lookback = 1h; let FailureThreshold = 3; let CorrelationWindow = 30m; let FailedLogons = SecurityEvent | where TimeGenerated >= ago(Lookback) | where EventID == 4625 | where IpAddress !in ("-", "", "127.0.0.1", "::1") | summarize FailCount = count(), FirstFail = min(TimeGenerated), LastFail = max(TimeGenerated) by Account, Computer, IpAddress | where FailCount >= FailureThreshold; let SuccessfulLogons = SecurityEvent | where TimeGenerated >= ago(Lookback) | where EventID == 4624 | where IpAddress !in ("-", "", "127.0.0.1", "::1") | project Account, Computer, IpAddress, SuccessTime = TimeGenerated; SuccessfulLogons | join kind=inner FailedLogons on Account, Computer, IpAddress | where SuccessTime > LastFail | where SuccessTime <= LastFail + CorrelationWindow | summarize FirstSuccess = min(SuccessTime), LastSuccess = max(SuccessTime), SuccessCount = count(), FailCount = max(FailCount), FirstFail = min(FirstFail), LastFail = max(LastFail) by Account, Computer, IpAddress | extend Severity = "CRITICAL" | extend Description = strcat( "Successful logon from same source after ", tostring(FailCount), " failed attempts within ", tostring(CorrelationWindow), " - possible successful brute force" ) | project FirstSuccess, LastSuccess, Account, Computer, IpAddress, SuccessCount, FailCount, FirstFail, LastFail, Severity, Description | order by FailCount desc, LastSuccess desc ``` ![成功的暴力破解](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/34f8104590075949.png) **调优指南(实验室测试):** - 采用严格关联(相同账户+计算机+IP)以实现低误报率 - 为获得更广泛的覆盖范围,可部署一个仅基于账户进行关联的平行规则 — 误报率较高,但能捕获来源跳跃攻击 - 根据环境基线调整关联窗口(15分钟–1小时) ### 查询 2 — 暴力破解检测 (T1110) **描述:** 标记在15分钟内登录尝试失败5次及以上的账户 — 表明存在密码喷洒或暴力破解活动。 **关键工程选择:** - 明确的15分钟回溯期与分析规则运行频率保持一致 - 过滤空账户和环回IP地址以去除噪声 - 将检测时间戳与事件时间戳分开投影,以便于分诊 ``` let Lookback = 15m; let FailureThreshold = 5; SecurityEvent | where TimeGenerated >= ago(Lookback) | where EventID == 4625 | where isnotempty(Account) and isnotempty(Computer) | where IpAddress !in ("-", "", "127.0.0.1", "::1") | summarize FailedAttempts = count(), FirstAttempt = min(TimeGenerated), LastAttempt = max(TimeGenerated) by Account, Computer, IpAddress | where FailedAttempts >= FailureThreshold | extend Severity = "HIGH" | extend Description = strcat( "Possible brute force: ", tostring(FailedAttempts), " failed logons within ", tostring(Lookback) ) | project TimeDetected = now(), Account, Computer, IpAddress, FailedAttempts, FirstAttempt, LastAttempt, Severity, Description ``` ![暴力破解检测](https://raw.githubusercontent.com/Lovedipsingh/sentinel-kql-detection-lab/main/screenshots/kql-01-brute-force-detection.png) **调优指南(实验室测试):** - 按IP地址排除已知的漏洞扫描器 - 验证后排除嘈杂的服务账户 - 根据环境基线调整阈值(3–10)(原因见 `DECISIONS.md`) ### 查询 3 — 外部IP登录异常 (T1078) **描述:** 标记来自非私有IPv4地址的成功或失败登录,排除RFC1918地址、环回地址、APIPA地址和IPv6链路本地范围。 **关键工程选择:** - 使用原生的 `ipv4_is_in_range()` 函数而非正则表达式(正确处理172.16.0.0/12 — 一个常见的静默覆盖缺口来源) - 包含IPv6私有范围过滤 - 将成功和失败计数分开,以便于分诊优先级排序 ``` let Lookback = 1h; SecurityEvent | where TimeGenerated >= ago(Lookback) | where EventID in (4624, 4625) | where isnotempty(IpAddress) | where not(ipv4_is_in_range(IpAddress, "10.0.0.0/8")) | where not(ipv4_is_in_range(IpAddress, "192.168.0.0/16")) | where not(ipv4_is_in_range(IpAddress, "172.16.0.0/12")) | where not(ipv4_is_in_range(IpAddress, "169.254.0.0/16")) | where IpAddress !in ("127.0.0.1", "::1", "-", "") | where not(IpAddress startswith "fe80:") | where not(IpAddress startswith "fc00:") | where not(IpAddress startswith "fd00:") | summarize AttemptCount = count(), SuccessCount = countif(EventID == 4624), FailureCount = countif(EventID == 4625), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by Account, Computer, IpAddress | extend Severity = iff(SuccessCount > 0, "HIGH", "MEDIUM") | extend Description = iff( SuccessCount > 0, "Successful logon from external IP address", "Failed logon attempts from external IP address" ) | project Account, Computer, IpAddress, AttemptCount, SuccessCount, FailureCount, FirstSeen, LastSeen, Severity, Description ``` ![外部IP登录](https://raw.githubusercontent.com/Lovedipsingh/sentinel-kql-detection-lab/main/screenshots/kql-02-external-ip-logon.png) **调优指南(实验室测试):** - 将VPN出口IP加入白名单 - 将云身份提供商基础设施(Okta, Microsoft Entra ID)加入白名单 - 将已知的远程管理网关加入白名单 ### 查询 4 — SYSTEM 账户网络登录 (T1078.003) **描述:** 标记使用网络(类型3)或远程交互(类型10)登录类型的 `NT AUTHORITY\SYSTEM` 登录 — 与横向移动或C2活动一致。 **关键工程选择:** - 精确匹配 `NT AUTHORITY\SYSTEM`(不使用部分匹配) - 排除登录类型5(服务)以移除整个良性基线类别 — 这是减少96%误报的关键 - 针对每种登录类型提供特定于上下文的描述,便于分析师分诊 ``` let Lookback = 1h; SecurityEvent | where TimeGenerated >= ago(Lookback) | where EventID == 4624 | where Account =~ @"NT AUTHORITY\SYSTEM" | where LogonType in (3, 10) | where IpAddress !in ("-", "", "127.0.0.1", "::1") | extend Severity = "HIGH" | extend Description = case( LogonType == 3, "SYSTEM network logon detected - review for lateral movement or remote service activity", LogonType == 10, "SYSTEM remote interactive logon detected - review for RDP abuse or session hijacking", "SYSTEM logon detected" ) | project TimeGenerated, Account, Computer, IpAddress, LogonType, Severity, Description ``` ![SYSTEM 账户登录](https://raw.githubusercontent.com/Lovedipsingh/sentinel-kql-detection-lab/main/screenshots/kql-03-system-account-logon.png) **调优指南(实验室测试):** - 按源IP地址排除已批准的管理工具 - 验证后备份代理和远程管理平台 - 登录类型10对于SYSTEM来说很少见 — 需立即调查 ### 查询 5 — 非工作时间登录 (T1078) **描述:** 标记在UTC时间早上7点之前或晚上7点之后的成功登录 — 支持内部威胁和凭据泄露检测。 **关键工程选择:** - 明确文档说明时间评估是在UTC时间下进行 - 排除Windows系统账户(DWM、UMFD、以 `$` 结尾的机器账户) - 在告警描述中包含时区上下文,便于分析师理解 ``` let Lookback = 3d; let BusinessStartHour = 7; // 7 AM UTC let BusinessEndHour = 19; // 7 PM UTC SecurityEvent | where TimeGenerated >= ago(Lookback) | where EventID == 4624 | where Account !contains "SYSTEM" | where Account !startswith "DWM-" | where Account !startswith "UMFD-" | where Account !endswith "$" | extend HourOfDay = datetime_part("hour", TimeGenerated) | where HourOfDay < BusinessStartHour or HourOfDay >= BusinessEndHour | extend Severity = "MEDIUM" | extend Description = strcat( "Logon outside business hours at ", format_datetime(TimeGenerated, "yyyy-MM-dd HH:mm:ss"), " UTC (Hour: ", tostring(HourOfDay), ")" ) | project TimeGenerated, Account, Computer, IpAddress, HourOfDay, Severity, Description ``` ![非工作时间登录](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/2f6eac7dec075951.png) **调优指南(实验室测试):** - 根据组织所在的时区调整工作时间(应用UTC偏移量) - 将已批准的非工作时间用户(值班人员、轮班工人)加入白名单 - 排除已知的批处理作业和计划任务 ## 🚨 分析规则 — 实时检测 查询2(暴力破解检测)已被转化为一个在Microsoft Sentinel中每5分钟运行一次的定时分析规则。触发时,它会自动生成一个映射到MITRE T1110的高严重性事件。 | 设置 | 值 | |---|---| | 规则名称 | Brute Force Detection - Multiple Failed Logons | | 严重性 | 高 | | 状态 | 已启用 | | 运行频率 | 每 5 分钟 | | 回溯期 | 15 分钟 | | 告警阈值 | 结果数大于 0 | | 事件创建 | 已启用 | | 实体映射 | 账户、主机、IP | | 告警分组 | 按匹配的实体分组 | | 抑制时间 | 1 小时 | | MITRE 战术 | 凭据访问 | | MITRE 技术 | T1110 - 暴力破解 | ![分析规则](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/7dca9c5ac8075951.png) **为何采用此配置:** - 5分钟的运行频率配合15分钟的回溯期,确保告警延迟最小且无遗漏 - 实体映射支持为调查剧本自动提取实体 - 按实体分组告警,减少来自同一攻击活动的重复事件 - 1小时的抑制期防止因重复失败导致的告警疲劳 ## 🗺️ MITRE ATT&CK 映射 | 查询 | 技术 | ID | |---|---|---| | Q1 — 失败后的成功登录 | 暴力破解 | T1110 | | Q2 — 暴力破解检测 | 暴力破解 | T1110 | | Q3 — 外部IP登录 | 有效账户 | T1078 | | Q4 — SYSTEM 账户登录 | 有效账户: 本地账户 | T1078.003 | | Q5 — 非工作时间登录 | 有效账户 | T1078 | ## 🧪 测试与验证 每个查询都在 `soc-lab-sentinel` 工作区中使用模拟的Windows安全事件日志进行了测试。 | 查询 | 测试方法 | 初始结果 | 误报 | 应用的调优 | |---|---|---|---|---| | Q1 — 失败后的成功登录 | 关联事件 | 2 个告警 | 0 | 时序关联工作正常 | | Q2 — 暴力破解 | 模拟失败登录 | 12 个告警 | 3 (扫描器流量) | 排除了环回IP地址 | | Q3 — 外部IP | VPN 和互联网登录 | 8 个告警 | 2 (云身份提供商) | 记录了白名单需求 | | Q4 — SYSTEM 账户 | 服务登录 | 47 个告警 | 45 (登录类型 5) | 从查询中移除了登录类型 5 | | Q5 — 非工作时间 | 周末登录 | 23 个告警 | 5 (机器账户) | 排除了以 `$` 结尾的账户 | **关键发现:** - Q4 最初包含登录类型5,产生了45个误报。将其移除后,噪声减少了**96%**。 - Q3 的 RFC1918 过滤最初使用正则表达式不完整(捕获了所有172.x地址)。切换到 `ipv4_is_in_range()` 修复了静默覆盖缺口。 - Q1 的时序关联防止了成功登录发生在失败窗口*之前*时的误匹配。 ## 🔵 演示的SOC分析师工作流程 1. **检测工程** — 识别可疑的认证模式(失败登录、外部IP、SYSTEM滥用、非工作时间访问) 2. **查询开发** — 编写具有适当时间范围、实体过滤和连接逻辑的KQL查询 3. **阈值调优** — 根据环境基线和误报/真阳性权衡分析设置阈值 4. **误报减少** — 排除已知的噪声源(扫描器、VPN、服务账户、机器账户) 5. **时序关联** — 使用时间窗口和严格的连接键关联相关事件(失败 -> 成功) 6. **自动化** — 将验证过的查询转化为定时分析规则 7. **事件创建** — 为Tier 1分诊启用自动生成高/严重严重性事件 8. **实体映射** — 提取账户、主机、IP,用于调查剧本 ## 📁 仓库结构 ``` sentinel-soc-detection-lab/ ├── README.md ├── DECISIONS.md ├── queries/ │ ├── 01-successful-after-failures.kql │ ├── 02-brute-force-detection.kql │ ├── 03-external-ip-logon.kql │ ├── 04-system-account-logon.kql │ └── 05-after-hours-logon.kql └── screenshots/ ├── kql-01-brute-force-detection.png ├── kql-02-external-ip-logon.png ├── kql-03-system-account-logon.png ├── kql-04-after-hours-logon.png ├── kql-05-successful-brute-force.png └── kql-06-analytics-rule.png ``` ## 🏅 展示的技能 - **Microsoft Sentinel:** 在Azure中部署和配置工作区 - **KQL 查询语言:** 高级过滤、聚合、关联和时间序列分析 - **检测工程:** 将威胁情报转化为可操作的检测规则 - **时序逻辑:** 使用 `let` 语句和 `join` 操作进行多查询关联 - **误报减少:** IP范围过滤、账户排除、登录类型限定 - **分析规则创建:** 具有实体映射和告警分组的定时查询 - **MITRE ATT&CK:** 用于威胁覆盖映射的战术和技术分类 - **工程文档:** 决策依据、调优指南和测试验证 ## 🔗 联系 由 **Lovedip Singh** 构建 [领英](https://linkedin.com/in/lovedipsingh) | [GitHub](https://github.com/Lovedipsingh) 本项目展示了适用于SOC分析师和 Tier
标签:AMSI绕过, Azure, Cloudflare, KQL, Microsoft Sentinel, MITRE ATT&CK, PoC, RFC1918过滤, SYSTEM账户滥用, 凭证攻击, 威胁检测, 安全事件, 安全运营中心, 异常登录, 时间相关性, 暴力破解, 检测规则, 网络安全, 网络映射, 网络资产发现, 自动化响应, 误报调优, 隐私保护, 非工作时间访问