mrabousakho/KQL-Hunting-Playbook

GitHub: mrabousakho/KQL-Hunting-Playbook

一份基于 KQL 的威胁狩猎剧本库,覆盖多类 ATT&CK 技术与 Azure AD 错误码,解决在云环境中的检测与响应问题。

Stars: 0 | Forks: 0

# KQL-Hunting-Playbook 威胁狩猎的剧本 ## 防御性安全查询库 ### 作者:[Mr. Sakho Aboubacar] | 审核者:Josh Madakor ## 如何使用本剧本 1. 在下表中查找您正在调查的攻击技术 2. 复制查询 3. 将占位符(标记为 `CAPS`)替换为调查特定的值 4. 在 Microsoft Sentinel 或 Microsoft Defender 高级威胁检测中运行 ## 查询索引 | # | 查询标题 | MITRE ID | 表 | 使用时机 | | --- | --- | --- | --- | --- | | 01 | 暴力破解 RDP 检测 | T1110.001 | DeviceLogonEvents | 同一 IP 重复登录失败后成功 | | 02 | MFA 疲劳检测 | T1621 | SigninLogs | 用户报告意外 MFA 推送通知——统计失败后首次成功 | | 03 | 不可能旅行检测 | T1078 | SigninLogs | 检查用户是否从意外国家登录 | | 04 | 会话指纹对比 | T1078 | SigninLogs | 区分合法与攻击会话——识别操作系统/浏览器/国家异常 | | 05 | 条件访问缺口检测 | T1078 | SigninLogs | 识别未应用条件访问策略的登录——防御缺口发现 | | 06 | 外部收件箱转发规则检测 | T1564.008 | CloudAppEvents | 检测将邮件转发至外部地址的规则 | | 07 | 安全关键词删除规则检测 | T1564.008 | CloudAppEvents | 检测删除安全相关邮件的收件箱规则 | | 08 | 完整收件箱规则参数提取 | T1564.008 | CloudAppEvents | 完整分析收件箱规则配置:名称、动作、关键词、转发 | | 09 | BEC 欺诈邮件检测 | T1534 | EmailEvents | 查找来自已妥协账户的邮件——会话劫持与欺诈 | | 10 | 会话跨表关联 | T1078 | CloudAppEvents + SigninLogs | 将登录会话与后续邮箱操作关联 | | 11 | 认证错误码发现 | T1110 | SigninLogs | 发现所有身份验证失败码(无需预先知晓) | | 12 | 数据压缩用于外泄 | T1560 | DeviceProcessEvents | 查找针对敏感目录的压缩命令 | | 13 | rclone 云外泄检测 | T1567.002 | DeviceProcessEvents | 检测使用 rclone 上传数据到云存储 | | 14 | VSS 影子副本滥用(NTDS 提取) | T1003.003 | DeviceProcessEvents | 检测通过卷影副本提取 ntds.dit | | 15 | Impacket 服务检测 | T1543.003 | DeviceEvents | 检测 Impacket 远程执行——随机 8 字符服务名创建 | | 16 | 进程注入检测 | T1055.003 | DeviceEvents | 检测跨进程的 CreateRemoteThread 注入 | | 17 | LSASS 内存转储检测 | T1003.001 | DeviceFileEvents | 检测由可疑进程创建的 .dmp 文件——凭证盗窃 | | 18 | 通过注册表的 UAC 绕过(fodhelper) | T1548.002 | DeviceRegistryEvents | 检测 fodhelper 注册表劫持导致的 UAC 绕过 | | 19 | 通过管理共享的横向移动 | T1021.002 | DeviceProcessEvents | 通过 C$ 管理共享复制文件的横向移动 | | 20 | 探测命令检测 | T1087 | DeviceProcessEvents | 检测 net user、net group、nltest 等侦察命令 | | 21 | 计划任务持久化检测 | T1053.005 | DeviceProcessEvents | 检测用于持久化的 schtasks /create 命令 | | 22 | AnyDesk 静默安装检测 | T1219 | DeviceProcessEvents | 检测远程访问工具的静默安装 | | 23 | 事件日志清除检测 | T1070.001 | DeviceProcessEvents | 检测 wevtutil cl Security/System | | 24 | 防火墙规则添加检测 | T1562.004 | DeviceProcessEvents | 检测 netsh firewall add rule | | 25 | DNS C2 检测 | T1071.004 | DeviceNetworkEvents | 查找来自可疑进程的 C2 域名查询 | ## 查询语句 ### 01 — 暴力破解 RDP 检测 **MITRE:** T1110.001 — 暴力破解:密码猜测 **表:** DeviceLogonEvents **使用时机:** 调查同一 IP 多次登录失败后的一次成功登录 ``` // STEP 1 — Read the timeline DeviceLogonEvents | where DeviceName contains "TARGET_DEVICE" | where ActionType in ("LogonFailed", "LogonSuccess") | where RemoteIP != "" | where not(RemoteIP startswith "10.") | where not(RemoteIP startswith "192.168.") | where not(RemoteIP startswith "172.") | project TimeGenerated, DeviceName, RemoteIP, ActionType, LogonType | sort by TimeGenerated asc // STEP 2 — Confirm the brute force pattern DeviceLogonEvents | where DeviceName contains "TARGET_DEVICE" | where ActionType in ("LogonFailed", "LogonSuccess") | where RemoteIP != "" | where not(RemoteIP startswith "10.") | where not(RemoteIP startswith "192.168.") | summarize FailCount=countif(ActionType == "LogonFailed"), SuccessCount=countif(ActionType == "LogonSuccess") by RemoteIP | where SuccessCount > 0 and FailCount > 0 | sort by FailCount desc ``` ### 02 — MFA 疲劳检测 **MITRE:** T1621 — 多因素身份验证请求生成 **表:** SigninLogs **使用时机:** 用户报告意外 MFA 推送通知——统计失败后首次成功 ``` // Count failed MFA attempts before first success per IP let FirstSuccess = toscalar( SigninLogs | where UserPrincipalName == "USER@DOMAIN.COM" | where ResultType == 0 | summarize min(TimeGenerated) ); SigninLogs | where UserPrincipalName == "USER@DOMAIN.COM" | where ResultType != 0 | where TimeGenerated < FirstSuccess | summarize FailedAttempts=count() by IPAddress | sort by FailedAttempts desc ``` ### 03 — 不可能旅行检测 **MITRE:** T1078 — 有效账户 **表:** SigninLogs **使用时机:** 检查用户是否从意外国家登录 ``` SigninLogs | where ResultType == 0 | extend Country = tostring(parse_json(LocationDetails).countryOrRegion) | extend City = tostring(parse_json(LocationDetails).city) | where Country !in ("GB", "US") // Add expected countries for your org | project TimeGenerated, UserPrincipalName, IPAddress, Country, City, AppDisplayName | sort by TimeGenerated asc ``` ### 04 — 会话指纹对比 **MITRE:** T1078 — 有效账户 **表:** SigninLogs **使用时机:** 区分合法与攻击会话——识别操作系统/浏览器/国家异常 ``` SigninLogs | where UserPrincipalName == "USER@DOMAIN.COM" | where ResultType == 0 | extend OS = tostring(parse_json(DeviceDetail).operatingSystem) | extend Browser = tostring(parse_json(DeviceDetail).browser) | extend Country = tostring(parse_json(LocationDetails).countryOrRegion) | extend City = tostring(parse_json(LocationDetails).city) | summarize Sessions=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by IPAddress, Country, City, OS, Browser | sort by FirstSeen asc ``` ### 05 — 条件访问缺口检测 **MITRE:** T1078 — 有效账户 **表:** SigninLogs **使用时机:** 识别未应用条件访问策略的登录——防御缺口发现 ``` SigninLogs | where ResultType == 0 | where ConditionalAccessStatus == "notApplied" | extend Country = tostring(parse_json(LocationDetails).countryOrRegion) | extend OS = tostring(parse_json(DeviceDetail).operatingSystem) | project TimeGenerated, UserPrincipalName, IPAddress, Country, OS, ConditionalAccessStatus, AppDisplayName | sort by TimeGenerated asc ``` ### 06 — 外部收件箱转发规则检测 **MITRE:** T1564.008 — 隐藏工件:邮件隐藏规则 **表:** CloudAppEvents **使用时机:** 检测将邮件转发至外部地址的规则 ``` CloudAppEvents | where ActionType == "New-InboxRule" | mv-expand Parameters = parse_json(tostring(RawEventData)).Parameters | where tostring(Parameters.Name) == "ForwardTo" | where tostring(Parameters.Value) !endswith "YOURDOMAIN.COM" | project TimeGenerated, AccountDisplayName, IPAddress, ForwardTo = tostring(Parameters.Value) | sort by TimeGenerated asc ``` ### 07 — 安全关键词删除规则检测 **MITRE:** T1564.008 — 隐藏工件:邮件隐藏规则 **表:** CloudAppEvents **使用时机:** 检测删除安全相关邮件的收件箱规则 ``` CloudAppEvents | where ActionType == "New-InboxRule" | mv-expand Parameters = parse_json(tostring(RawEventData)).Parameters | where tostring(Parameters.Name) == "SubjectOrBodyContainsWords" | where tostring(Parameters.Value) has_any ( "security", "phishing", "compromised", "suspicious", "verify", "unusual") | project TimeGenerated, AccountDisplayName, IPAddress, Keywords = tostring(Parameters.Value) | sort by TimeGenerated asc ``` ### 08 — 完整收件箱规则参数提取 **MITRE:** T1564.008 — 隐藏工件:邮件隐藏规则 **表:** CloudAppEvents **使用时机:** 完整分析收件箱规则配置:名称、动作、关键词、转发 ``` CloudAppEvents | where ActionType == "New-InboxRule" | mv-expand Parameters = parse_json(tostring(RawEventData)).Parameters | where tostring(Parameters.Name) in ( "Name", "ForwardTo", "DeleteMessage", "SubjectOrBodyContainsWords", "StopProcessingRules") | summarize RuleConfig=make_bag(pack( tostring(Parameters.Name), tostring(Parameters.Value))) by TimeGenerated, AccountDisplayName, IPAddress | sort by TimeGenerated asc ``` ### 09 — BEC 欺诈邮件检测 **MITRE:** T1534 — 内部鱼叉式钓鱼 **表:** EmailEvents **使用时机:** 查找来自已妥协账户的邮件——会话劫持与欺诈 ``` EmailEvents | where SenderFromAddress == "COMPROMISED@DOMAIN.COM" | project TimeGenerated, SenderFromAddress, RecipientEmailAddress, Subject, EmailDirection, UrlCount, AttachmentCount | sort by TimeGenerated asc ``` ### 10 — 会话跨表关联 **MITRE:** T1078 — 有效账户 **表:** CloudAppEvents + SigninLogs **使用时机:** 将登录会话与后续邮箱操作关联 ``` // Extract session ID from CloudAppEvents CloudAppEvents | where ActionType == "New-InboxRule" | where IPAddress == "ATTACKER_IP" | extend SessionId = tostring(parse_json(tostring(RawEventData)) .AppAccessContext.AADSessionId) | project TimeGenerated, AccountDisplayName, IPAddress, ActionType, SessionId | sort by TimeGenerated asc ``` ### 11 — 认证错误码发现 **MITRE:** T1110 — 暴力破解 **表:** SigninLogs **使用时机:** 发现所有身份验证失败码(无需预先知晓) ``` SigninLogs | where ResultType != 0 | summarize Count=count(), Description=any(ResultDescription), AffectedUsers=make_set(UserPrincipalName), SeenFromIPs=make_set(IPAddress) by ResultType | sort by Count desc ``` ### 12 — 数据压缩用于外泄 **MITRE:** T1560 — 存档收集的数据 **表:** DeviceProcessEvents **使用时机:** 查找针对敏感目录的压缩命令 ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has_any ( "Compress-Archive", "7z", "zip", "rar", "tar") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 13 — rclone 云外泄检测 **MITRE:** T1567.002 — 外泄到云存储 **表:** DeviceProcessEvents **使用时机:** 检测使用 rclone 上传数据到云存储 ``` // Find all rclone executions DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where FileName == "rclone.exe" or ProcessCommandLine has "rclone" | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 14 — VSS 影子副本滥用(NTDS 提取) **MITRE:** T1003.003 — OS 凭据转储:NTDS **表:** DeviceProcessEvents **使用时机:** 检测通过卷影副本提取 ntds.dit ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has_any ( "vssadmin", "ntds.dit", "HarddiskVolumeShadowCopy", "shadow", "ntdsutil") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 15 — Impacket 服务检测 **MITRE:** T1543.003 — 创建或修改系统进程:Windows 服务 **表:** DeviceEvents **使用时机:** 检测 Impacket 远程执行——随机 8 字符服务名创建 ``` DeviceEvents | where DeviceName contains "TARGET_DEVICE" | where ActionType == "ServiceInstalled" | extend ServiceName = tostring(parse_json(AdditionalFields).ServiceName) | where strlen(ServiceName) == 8 | where ServiceName matches regex @"^[A-Za-z]{8}$" | project Timestamp, DeviceName, ServiceName, AdditionalFields | sort by Timestamp asc ``` ### 16 — 进程注入检测 **MITRE:** T1055.003 — 进程注入:线程执行劫持 **表:** DeviceEvents **使用时机:** 检测跨进程的 CreateRemoteThread 注入 ``` DeviceEvents | where DeviceName contains "TARGET_DEVICE" | where ActionType == "CreateRemoteThreadApiCall" | extend SourceProcess = tostring(parse_json(AdditionalFields).SourceProcessName) | extend TargetProcess = tostring(parse_json(AdditionalFields).TargetProcessName) | project Timestamp, DeviceName, SourceProcess, TargetProcess, AdditionalFields | sort by Timestamp asc ``` ### 17 — LSASS 内存转储检测 **MITRE:** T1003.001 — OS 凭据转储:LSASS 内存 **表:** DeviceFileEvents **使用时机:** 检测由可疑进程创建的 .dmp 文件——凭证盗窃 ``` DeviceFileEvents | where DeviceName contains "TARGET_DEVICE" | where FileName endswith ".dmp" | where FolderPath has_any ("Temp", "Public", "AppData") | project Timestamp, DeviceName, InitiatingProcessFileName, FileName, FolderPath, InitiatingProcessCommandLine | sort by Timestamp asc ``` ### 18 — 通过注册表的 UAC 绕过(fodhelper) **MITRE:** T1548.002 — 提升权限控制滥用:绕过 UAC **表:** DeviceRegistryEvents **使用时机:** 检测 fodhelper 注册表劫持导致的 UAC 绕过 ``` DeviceRegistryEvents | where DeviceName contains "TARGET_DEVICE" | where RegistryKey has "ms-settings" | where RegistryValueName in ("", "DelegateExecute") | project Timestamp, DeviceName, InitiatingProcessFileName, RegistryKey, RegistryValueName, RegistryValueData | sort by Timestamp asc ``` ### 19 — 通过管理共享的横向移动 **MITRE:** T1021.002 — 远程服务:SMB/Windows 管理共享 **表:** DeviceProcessEvents **使用时机:** 检测通过 C$ 管理共享复制文件的横向移动 ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has "C$" | where ProcessCommandLine has_any ("copy", "xcopy", "move") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 20 — 探测命令检测 **MITRE:** T1087 — 账户发现 **表:** DeviceProcessEvents **使用时机:** 检测 net user、net group、nltest 等侦察命令 ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has_any ( "net user", "net group", "nltest", "whoami", "ipconfig", "systeminfo", "net localgroup", "quser") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 21 — 计划任务持久化检测 **MITRE:** T1053.005 — 计划任务/作业:计划任务 **表:** DeviceProcessEvents **使用时机:** 检测用于持久化的 schtasks /create 命令 ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has "schtasks" | where ProcessCommandLine has "/create" | extend TaskName = extract(@"/tn\s+""?([^"" ]+)""?", 1, ProcessCommandLine) | project Timestamp, DeviceName, AccountName, TaskName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 22 — AnyDesk 静默安装检测 **MITRE:** T1219 — 远程访问软件 **表:** DeviceProcessEvents **使用时机:** 检测远程访问工具的静默安装 ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has_any ( "anydesk", "teamviewer", "screenconnect", "splashtop", "logmein", "vnc") | where ProcessCommandLine has "--silent" or ProcessCommandLine has "--install" | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 23 — 事件日志清除检测 **MITRE:** T1070.001 — 指标移除:清除 Windows 事件日志 **表:** DeviceProcessEvents **使用时机:** 检测 wevtutil cl Security/System ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has "wevtutil" | where ProcessCommandLine has "cl" | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 24 — 防火墙规则添加检测 **MITRE:** T1562.004 — 削弱防御:禁用或修改系统防火墙 **表:** DeviceProcessEvents **使用时机:** 检测 netsh firewall add rule ``` DeviceProcessEvents | where DeviceName contains "TARGET_DEVICE" | where ProcessCommandLine has "netsh" | where ProcessCommandLine has_any ("firewall", "advfirewall") | where ProcessCommandLine has "add" | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp asc ``` ### 25 — DNS C2 检测 **MITRE:** T1071.004 — 应用层协议:DNS **表:** DeviceNetworkEvents **使用时机:** 查找来自可疑进程的 C2 域名查询 ``` DeviceNetworkEvents | where DeviceName contains "TARGET_DEVICE" | where InitiatingProcessFileName !in ( "svchost.exe", "chrome.exe", "msedge.exe", "firefox.exe", "SearchApp.exe") | where RemotePort == 53 | project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemoteUrl, InitiatingProcessCommandLine | sort by Timestamp asc ``` ## 关键 Azure AD 错误码参考 | 代码 | 含义 | 调查用途 | | --- | --- | --- | | 0 | 成功 | 攻击者已认证 | | 50074 | 需要 MFA — 未完成 | 推送已发送——MFA 疲劳进行中 | | 50140 | 保持登录中断 | 认证进行中 | | 50126 | 用户名或密码无效 | 凭据填充 | | 50089 | 流程令牌过期 | 会话重放尝试 | | 50055 | 密码已过期 | 目标账户 | | 53003 | 被条件访问阻止 | 防御生效 | | 16003 | 目录中无此账户 | 租户错误 | ## 表选择快速参考 | 问题类型 | 表 | 关键字段 | | --- | --- | --- | | 谁登录了?从哪里? | SigninLogs | UserPrincipalName、IPAddress、LocationDetails | | M365 内发生了什么? | CloudAppEvents | AccountDisplayName、ActionType、RawEventData | | 发送了什么邮件? | EmailEvents | SenderFromAddress、RecipientEmailAddress、Subject | | 端点上运行了什么进程? | DeviceProcessEvents | FileName、ProcessCommandLine、AccountName | | 创建了什么文件? | DeviceFileEvents | FileName、FolderPath、InitiatingProcessFileName | | 网络连接如何? | DeviceNetworkEvents | RemoteIP、RemotePort、InitiatingProcessFileName | | 注册表有何变更? | DeviceRegistryEvents | RegistryKey、RegistryValueName、RegistryValueData | | 谁登录了端点? | DeviceLogonEvents | RemoteIP、ActionType、LogonType | ## JSON 字段提取速查表 始终使用以下公式提取嵌套 JSON 字段: ``` | extend NewColumn = tostring(parse_json(FieldName).keyName) ``` 常见提取: ``` // SigninLogs | extend Country = tostring(parse_json(LocationDetails).countryOrRegion) | extend City = tostring(parse_json(LocationDetails).city) | extend OS = tostring(parse_json(DeviceDetail).operatingSystem) | extend Browser = tostring(parse_json(DeviceDetail).browser) // CloudAppEvents | extend SessionId = tostring(parse_json(tostring(RawEventData)).AppAccessContext.AADSessionId) | extend ServiceName = tostring(parse_json(AdditionalFields).ServiceName) ``` ## countif 模式 — 暴力破解签名 ``` | summarize FailCount=countif(ActionType == "LogonFailed"), SuccessCount=countif(ActionType == "LogonSuccess") by RemoteIP | where SuccessCount > 0 and FailCount > 0 | sort by FailCount desc ``` 每当问题提到“重复失败后成功”时使用。 *KQL 狩猎剧本 — 基于真实网络范围调查构建 作者:[Your Name] | 审核者:Josh Madakor 用于防御性安全与作品集*
标签:AMSI绕过, Azure Sentinel, BEC, BurpSuite集成, Cloudflare, KQL, Microsoft Defender, MITRE ATT&CK, 关键词过滤, 勒索软件, 取证调查, 合规监控, 威胁检测, 安全信息与事件管理, 安全运营, 异常检测, 扫描框架, 搜索引擎爬取, 查询索引, 横向移动, 电子邮件安全, 编程规范, 规则检测, 账号安全, 防御安全查询