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, 关键词过滤, 勒索软件, 取证调查, 合规监控, 威胁检测, 安全信息与事件管理, 安全运营, 异常检测, 扫描框架, 搜索引擎爬取, 查询索引, 横向移动, 电子邮件安全, 编程规范, 规则检测, 账号安全, 防御安全查询