关于 azure-kusto-irql
面向安全分析人员的技能,用于在 KQL 上组合 IRQL 管道。它结合统一架构的选择器、提取器和增强器,并要求目标数据库已部署相应 IRQL 函数。
主要功能
- 01组合选择器、提取器和增强器管道
- 02统一不同安全表的架构
- 03支持筛选、汇总和投影
- 04检查 IRQL 函数是否已部署
适用场景
- 01在 KQL 中构建组合式安全调查
- 02为身份验证事件补充员工信息
- 03调查邮件、网络或进程活动
MCP 相关
该技能使用 Kusto MCP 工具执行 IRQL 管道,并检查集群、数据库、表和架构信息。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ azure-skills --skill azure-kusto-irql安装后在 Claude Code 中输入/azure-kusto-irql确认已加载。
附带文件references/EXAMPLES.mdreferences/KUSTO_EXPLORER_LAUNCH.md
详细介绍
IRQL —— 事件响应查询语言
使用选择器、提取器和增强器等构建模块编写 IRQL 函数管道。IRQL 将原始 KQL 安全表封装在能清晰表达意图、可组合的函数之后,使分析师(以及 LLM)无需记忆架构、集群位置或联接键即可开展威胁搜寻。
激活条件
在以下情况下使用此技能:
- 用户明确提到 IRQL、
Get_*、Extract_*或Enrich_*函数 - 用户说“使用 IRQL”或“编写 IRQL 查询”
- 用户请求使用已知 IRQL 选择器构建可组合的威胁搜寻管道
除非用户明确要求使用 IRQL,否则不要在处理一般安全查询(例如“查找登录失败”)时激活此技能。这类查询应交由 azure-kusto 处理。
这不是自然语言转 IRQL 转换器。 此技能用于组合 IRQL 函数管道,也可以处理能直接映射到已知选择器和简单筛选条件的基本自然语言请求。对于一般的自然语言转 KQL 或自然语言转 IRQL 转换,请使用专用的查询生成技能(可单独获取)。
IRQL 函数预检
生成管道之前,请确认目标数据库中是否有 IRQL:
.show functions
| where Name startswith "Get_" or Name startswith "Extract_" or Name startswith "Enrich_"
| project Name
如果未找到 IRQL 函数,请告知用户目标数据库未部署 IRQL,并建议改用 azure-kusto 执行原始 KQL 查询。IRQL 函数是必备条件——此技能不会部署基础 IRQL 选择器。
IRQL 简介
IRQL 是一种基于函数、构建于 KQL 之上的方言。它提供:
- 统一架构——无论底层数据源为何,各类安全表都会映射为一致的列名
- 可组合性——小型函数通过
| invoke链接,从简单步骤构建复杂的威胁搜寻 - 可移植性——同一 IRQL 管道可用于不同的集群/数据库;只需为
Get_*基础函数重新指定目标
IRQL 不是独立语言,而是供你调用的 KQL 函数。任何有效的 KQL 都可以与 IRQL 函数配合使用。
部署 IRQL
IRQL 函数以已存储的 KQL 函数(.create-or-alter function)形式保存。在此技能生成管道之前,必须先将这些函数部署到目标数据库。
公开示例集群(已预部署函数):
- 集群:
https://kc7001.eastus.kusto.windows.net - 数据库:
ValdyTimes、JoJosHospital
要将 IRQL 移植到新的集群/数据库,请创建 Get_* 选择器,将源表映射为统一架构(列名如下),然后部署提取器和增强器。只要输入架构匹配,提取器和增强器就无需修改即可使用。
函数目录
1. 选择器 — Get_*
返回源表的投影视图,并统一架构。默认使用最简形式;需要额外列时使用 _All。
| 函数 | 列 |
|---|---|
Get_Event_Authentication | EnvTime、Hostname、ClientIp、Username、Result |
Get_Event_Authentication_All | + Description、UserAgent、PasswordHash |
Get_Email | EnvTime、EmailSender、EmailRecipient、Subject、Url |
Get_Email_All | + ReplyTo、Verdict |
Get_Employees | Name、ClientIp、Email、Username、Hostname、Role |
Get_Employees_All | + HireDate、UserAgent、Domain |
Get_Event_FileCreation | EnvTime、Hostname、Filename、Path |
Get_Event_FileCreation_All | + Username、Sha256、ProcessName |
Get_Event_NetworkInbound | EnvTime、ClientIp、Url |
Get_Event_NetworkInbound_All | + Method、UserAgent、StatusCode |
Get_Event_NetworkOutbound | EnvTime、ClientIp、Url |
Get_Event_NetworkOutbound_All | + Method、UserAgent |
Get_Dns_All | EnvTime、Domain、ClientIp |
Get_Event_Process | EnvTime、ProcessCommandLine、ProcessName、Hostname、Username |
Get_Event_Process_All | + ParentProcessName、ParentProcessHash、ProcessHash |
Get_SecurityAlerts_All | EnvTime、AlertType、Severity、Description、Indicators |
Get_Network_Connection_All | EnvTime、SourceIp、SourcePort、DestinationIp、DestinationPort、Protocol、Bytes |
2. 提取器 — Extract_*
从现有列派生新列。应在选择器之后调用。
| 函数 | 输入列 | 新增列 |
|---|---|---|
Extract_Email_Sender_Domain(T) | EmailSender | Domain |
Extract_Employee_Firstname(T) | Name | Firstname |
Extract_Event_Network_Domain(T) | Url | DomainName |
3. 丰富器 — Enrich_*
用于左连接的辅助函数,可从相关表中附加上下文信息。
| 函数 | 键列 | 丰富内容 |
|---|---|---|
Enrich_Event_Authentication_Username(T) | Username | 该用户的身份验证事件 |
Enrich_Ip_Employee(T) | ClientIp | 根据 IP 获取员工身份信息 |
Enrich_Username_Employee(T) | Username | 根据用户名获取员工身份信息 |
Enrich_Ip_Domain(T) | ClientIp | 解析到该 IP 的 DNS 域名 |
Enrich_Ip_Event_NetworkOutbound(T) | ClientIp | 该 IP 的出站网络流量 |
Enrich_Ip_Network_Connection(T) | ClientIp | 该 IP 的网络流量 |
4. 外部丰富
| 函数 | 来源 | 要求 |
|---|---|---|
Enrich_Sha256_VirusTotal(T) | VirusTotal 文件报告 | API 密钥 + callout 策略 |
Get_CISA_KEV() / Enrich_CISA_KEV(T) | CISA KEV 目录 | Callout 策略 |
组合规则
Selector -> Extract -> Filter -> Enrich -> Summarize/Project
- 从选择器开始:
Get_Event_Authentication、Get_Email等。 - 提取派生字段:
| invoke Extract_Email_Sender_Domain() - 筛选信号:
| where Result == "Failed Login" - 丰富上下文信息:
| invoke Enrich_Username_Employee() - 汇总 / 投影答案
步骤之间始终使用管道符号(|)。提取器和丰富器使用 | invoke FunctionName()。
查询生成指南
- 除非需要额外列,否则使用最简选择器;需要时再使用
_All - 在丰富器之前链接提取器(提取器新增的列可能会作为丰富器的键)
- 尽可能提前放置
where筛选条件 - 使用
summarize进行聚合,使用project选择最终列 - 以
order by+take结束,以限制输出
示例
更多提示词和完整示例,请参阅 references/EXAMPLES.md。
暴力破解检测
Get_Event_Authentication
| where Result == "Failed Login"
| summarize FailedCount = count() by Username
| where FailedCount > 19
| invoke Enrich_Username_Employee()
| project Username, Name, Role, Email, FailedCount
| order by FailedCount desc
按收件人资历进行钓鱼邮件分流
Get_Email
| invoke Extract_Email_Sender_Domain()
| project EnvTime, EmailSender, Domain, Username = EmailRecipient, Subject, Url
| invoke Enrich_Username_Employee()
| extend Seniority = case(
Role has_any ("CEO", "Chief", "Director", "VP", "President"), 3,
Role has_any ("Manager", "Lead", "Senior"), 2,
1)
| summarize
TotalEmails = count(),
SeniorityScore = sum(Seniority),
Recipients = make_set(Name, 50),
DistinctRecipients = dcount(Username)
by Domain
| where DistinctRecipients >= 2
| order by SeniorityScore desc
| take 20
从指标进行后利用阶段的关联分析
let victims =
Get_Event_FileCreation_All
| where Filename has "<INDICATOR>"
| distinct Hostname;
Get_Event_Process
| where Hostname in (victims)
| where ProcessCommandLine has_any ("rundll32", "regsvr32", "powershell", "systeminfo")
| project EnvTime, Hostname, Username, ProcessName, ProcessCommandLine
| order by EnvTime asc
丰富了身份信息的可疑出站流量
Get_Event_NetworkOutbound
| invoke Extract_Event_Network_Domain()
| where DomainName has_any ("<SUSPICIOUS_DOMAIN_1>", "<SUSPICIOUS_DOMAIN_2>")
| invoke Enrich_Ip_Employee()
| project EnvTime, Name, Role, DomainName, Url, ClientIp
| order by EnvTime desc
外部 IP 身份验证异常
Get_Event_Authentication_All
| where not(ClientIp startswith "10.") and not(ClientIp startswith "192.168.")
| summarize
Attempts = count(),
Failures = countif(Result == "Failed Login"),
Users = make_set(Username)
by ClientIp
| order by Failures desc
| take 20
MCP 工具
| 工具 | 用途 |
|---|---|
kusto_query | 对 Kusto 数据库执行 IRQL 管道 |
kusto_table_schema_get | 查找可用的表和列 |
kusto_cluster_list | 列出可用的 ADX 群集 |
kusto_database_list | 列出群集中的数据库 |
在 Kusto Explorer 中打开查询(仅限 Windows)
可选的便捷功能。 默认工作流是在聊天中输出 KQL,让用户手动将其复制到 Kusto Explorer 或 VS Code Kusto 扩展中。自动启动仅在选择启用时使用。
始终在聊天回复中输出完整的 KQL 查询,并清楚标注步骤 1(连接)和步骤 2(查询):
// Step 1: Connect to your cluster (skip if already connected)
// Example: uncomment to connect to the KC7 training cluster
// #connect cluster('kc7001.eastus.kusto.windows.net').database('ValdyTimes')
// Or replace with your own cluster:
// #connect cluster('<YOUR_CLUSTER>').database('<YOUR_DATABASE>')
// Step 2: Run the query below
<KQL_QUERY>
如果用户要求在 Kusto Explorer 中保存或打开查询,请按照 references/KUSTO_EXPLORER_LAUNCH.md 中的流程操作。关键规则:
- 写入文件或启动可执行文件前,使用
ask_user进行确认 - 在聊天中显示文件内容,以便用户在打开前进行检查
- 切勿使用 Shell 插值或 here-string;通过
Set-Content/Add-Content写入文件 - 切勿将查询编码到浏览器 URL 中
- 在 macOS/Linux 上,保存
.kql文件,并建议使用 VS Code Kusto 扩展或 ADX Web Explorer - 如需将 IRQL 数据进行图形可视化,请参阅
azure-kusto-graph和azure-kusto-irql-graph