IRQL 图函数 -- 查询结果到可视化
将IRQL图函数家族应用于表格结果。给定一个KQL或IRQL查询以及用户的图描述,生成一个Lift_To_Graph映射,并仅组合所需的存储图函数,以在Kusto Explorer中可视化、折叠、提取或增强图。源查询不需要使用IRQL。
范围与路由
| 请求 | 使用场景 |
|---|---|
| 将提供的KQL/IRQL行转换为带图标装饰的可视化图 | 此技能:Lift_To_Graph + Graph_Render_View |
折叠节点或应用Extract_Node_*、Enrich_Node_*或Enrich_Graph_* | 此技能 |
使用make-graph、graph-match、最短路径、连通分量、图模型或快照 | azure-kusto-graph |
| 从自然语言编写复杂的KQL/IRQL调查 | 先使用Kusto或IRQL查询生成技能,再使用此技能 |
如果请求混合了可视化和原生图分析,请将此技能用于提升/渲染部分,将azure-kusto-graph用于运算符语义。除非用户明确要求使用原生图运算符,否则不要用自建的边优先图替换图提升函数。
输入契约
- 首选输入:一个能生成表格结果的可工作KQL/IRQL查询,加上关于所需节点、边、标签、图标、提取、增强或折叠的自然语言描述。
- 此技能不是自然语言转KQL或NL转IRQL转换器。它将现有查询结果转换为图可视化。对于一般的自然语言转KQL或NL转IRQL转换,请使用专用的查询生成技能(单独提供)。
- 保留所提供查询的检索、连接、过滤和聚合。仅添加图映射所需的投影或合成ID。
- 仅当源请求直接映射到一个已知表或IRQL
Get_*选择器,且具有明确的列和简单过滤条件时,才支持基本的自然语言源请求。需说明假定的源,且不得发明连接、模式或调查逻辑。 - 对于非平凡的查询构建,请先使用单独的Kusto/IRQL查询生成技能,然后将其输出应用于此技能。
- 如果没有可用的查询或输出模式,且源不是简单的,请在生成映射前请求KQL查询或其结果列。
激活触发器
当用户执行以下操作时使用此技能:
- 提供KQL/IRQL结果并请求IRQL图可视化或映射
- 提及
Lift_To_Graph、Graph_Render_View或Graph_Fold_By_Property - 请求在Kusto Explorer中为节点/边映射添加图标装饰
- 希望按共享属性折叠/折叠节点
- 通过
Extract_Node_*、Enrich_Node_*或Enrich_Graph_*请求图提取或增强
不要仅为graph-match、图路径/组件、持久化图或通用的make-graph构建而激活此技能;这些属于azure-kusto-graph。
不是自然语言转KQL/IRQL转换器。 输入通常是一个需要图可视化的可工作KQL或IRQL查询。基本的自然语言源请求仅适用于简单的单表/选择器情况。对于一般的自然语言转KQL或NL转IRQL,请使用专用的查询生成技能(单独提供)。
环境
- 集群:
https://kc7001.eastus.kusto.windows.net - 数据库:
ValdyTimes、JoJosHospital(图函数已预部署) - 渲染:Kusto Explorer桌面应用(make-graph可视化窗口)
- 工具:
kusto_query(通过Azure MCP服务器)
函数预检
Lift_To_Graph和Graph_Render_View是存储函数,不是Kusto内置运算符。在对目标数据库生成或运行提升管道之前,请检查已部署的内容:
.show functions
| where Name in~ ("Lift_To_Graph", "Graph_Render_View", "Graph_Fold_By_Property")
| project Name
Lift_To_Graph和Graph_Render_View是必需的。- 仅当请求折叠时才需要
Graph_Fold_By_Property。 - 在使用任何
Extract_Node_*、Enrich_Node_*或Enrich_Graph_*函数之前先进行检查;如果用户未要求部署且函数不可用,则省略可选增强。 - 如果缺少必需的函数并且您拥有更改数据库的权限,请在部署前征求用户确认。然后使用references/DEPLOY_IRQL_FUNCTIONS.md中的
.create-or-alter function定义。运行相关的.create-or-alter块,然后重新运行预检以确认。 - 如果您没有更改权限,请告知用户哪些函数缺失,并引导他们查看
references/DEPLOY_IRQL_FUNCTIONS.md以手动部署。
IRQL 图函数家族
Lift_To_Graph(T, mappingJson)
将任何表格化的KQL结果转换为统一的节点+边表。
输入:任何表T + 一个JSON映射字符串。
输出:具有EntityType = "node"或"edge"的行,可用于make-graph。
Graph_Render_View(T)
接收Lift_To_Graph输出,拆分节点/边,并调用make-graph以打开Kusto Explorer的图窗口。
Graph_Fold_By_Property(T, NodeType, PropertyName)
将共享某个属性值的给定类型节点折叠为单个节点。自动重新连接边。
图提取和增强函数
这些是额外的存储函数,必须已部署在目标数据库上。它们未包含在references/DEPLOY_IRQL_FUNCTIONS.md中。在将其包含到管道之前,请使用.show functions验证可用性。
| 函数 | 操作 | 关键属性 |
|---|---|---|
Extract_Node_Email_Sender_Domain(T, displayName) | 向节点属性添加Domain | EmailSender |
Extract_Node_Employee_Firstname(T, displayName) | 向节点属性添加Firstname | Name |
Extract_Node_Event_Network_Domain(T, displayName) | 向节点属性添加DomainName | Url |
Enrich_Node_Ip_Employee(T, displayName) | 向IP节点添加员工信息 | ClientIp |
Enrich_Node_Username_Employee(T, displayName) | 向用户节点添加员工信息 | Username |
Enrich_Node_Event_Authentication_Username(T, displayName) | 添加认证上下文 | Username |
Enrich_Node_Ip_Domain(T, displayName) | 添加DNS域 | ClientIp |
Enrich_Node_Ip_Event_NetworkOutbound(T, displayName) | 添加出站事件 | ClientIp |
Enrich_Graph_Ip_Employee(T, mappingJson) | 使用员工节点扩展图 | ClientIp |
Enrich_Graph_Username_Employee(T, mappingJson) | 使用员工节点扩展图 | Username |
Enrich_Graph_Event_Authentication_Username(T, mappingJson) | 使用认证节点扩展 | Username |
映射JSON模式
JSON映射包含两个数组:node_types和edges。
node_types[]
| 字段 | 必需 | 描述 |
|---|---|---|
type | 是 | 节点类型标签(例如"User"、"Host"、"IP") |
id | 是 | 节点ID的前缀;通常与类型相同 |
key | 是 | 列名,其值成为节点的身份 |
props | 是 | 要作为节点属性携带的列数组 |
defaults | 否 | 空/空属性回退值的对象 |
defIcon | 否 | 此节点类型的默认图标URL |
displayName | 否 | 用于显示标签的列(默认为id) |
color | 否 | 用于颜色的列 |
size | 否 | 用于大小的列 |
edges[]
| 字段 | 必需 | 描述 |
|---|---|---|
type | 是 | 边类型标签(例如"AuthenticatesTo"、"SentEmail") |
source | 是 | {"id": "<prefix>", "type": "<NodeType>"} |
target | 是 | {"id": "<prefix>", "type": "<NodeType>"} |
props | 否 | 要作为边属性携带的列数组 |
displayName | 否 | 边标签的列 |
color | 否 | 边颜色的列 |
图标库
使用来自https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/的图标:
- IP:
Public-IP-Addresses-(Classic).svg - 主机/虚拟机:
Virtual-Machine.svg - 用户:
Users.svg - 电子邮件:
Mailbox.svg(或azure-cds/command-1070-Mail.svg) - 进程:
App-Services.svg - 文件:
Storage-Accounts.svg - 警报:
Activity-Log.svg - 域:
DNS-Zones.svg
映射生成规则
根据提供的查询列和用户的图描述,按以下步骤生成映射JSON:
- 识别实体 -> 每个不同的名词成为一个
node_type - 识别关系 -> 每个动词/介词成为一条
edge - 映射到列 -> 使用所提供查询生成的实际列;切勿假设不可用的列
- 设置方向 -> 源是执行者,目标是承受者
- 添加属性 -> 包含与调查相关的列(时间戳、结果、哈希值)
- 分配图标 -> 根据实体类型从上述图标集中选择
列参考(IRQL统一模式)
| 实体 | 关键列 | 可用属性 |
|---|---|---|
| 用户 | Username | Username、Name、Role、Email |
| 主机 | Hostname | Hostname |
| IP | ClientIp | ClientIp |
| 电子邮件消息 | Subject | EnvTime、Subject、Verdict、Url |
| 发件人 | EmailSender | EmailSender、Domain |
| 收件人 | EmailRecipient | EmailRecipient |
| 进程 | ProcessName | EnvTime、ProcessName、ProcessCommandLine、ProcessHash |
| 文件 | Filename | EnvTime、Filename、Path、Sha256 |
| 域 | DomainName | DomainName |
| 认证事件 | (合成ID) | EnvTime、UserAgent、Result、Description |
函数选择
- 从提供的KQL/IRQL表格管道开始。
- 使用
Lift_To_Graph(mapping)创建图实体。 - 仅当请求且与映射键兼容时,添加
Extract_Node_*、Enrich_Node_*或Enrich_Graph_*。 - 仅当请求分组/折叠时添加
Graph_Fold_By_Property()。 - 以
Graph_Render_View()结束可视输出。 - 对所选管道选用的确切存储函数进行预检。
管道模式
// 1. 保留提供的KQL或IRQL查询
<input query>
// 2. 提升为图
| invoke Lift_To_Graph(<mapping_json>)
// 3. 可选:提取或增强图实体
| invoke <Extract_Node_* | Enrich_Node_* | Enrich_Graph_*>()
// 4. 可选:按请求折叠节点
| invoke Graph_Fold_By_Property("<NodeType>", "<PropertyName>")
// 5. 渲染
| invoke Graph_Render_View()
示例
更多提示和完整示例,请参见references/EXAMPLES.md。
认证图:IP -> AuthEvent -> User -> Host
输入查询:Get_Event_Authentication_All | where Result == "Failed Login" | take 200
图请求:“显示IP、认证事件、用户和主机;按结果折叠事件。”
let auth_mapping = '{"node_types":[{"type":"SrcIp","id":"SrcIp","key":"ClientIp","props":["ClientIp"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Public-IP-Addresses-(Classic).svg"},{"type":"Host","id":"Host","key":"Hostname","props":["Hostname"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Virtual-Machine.svg"},{"type":"User","id":"User","key":"Username","props":["Username"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Users.svg"},{"type":"AuthEvent","id":"AuthEvent","key":"AuthEventId","props":["AuthEventId","EnvTime","UserAgent","Result","Description"],"defaults":{"Result":"unknown"},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Activity-Log.svg"}],"edges":[{"type":"RequestsAuth","source":{"id":"SrcIp","type":"SrcIp"},"target":{"id":"AuthEvent","type":"AuthEvent"},"props":["EnvTime"]},{"type":"TargetsUser","source":{"id":"AuthEvent","type":"AuthEvent"},"target":{"id":"User","type":"User"},"props":["EnvTime"]},{"type":"AgainstHost","source":{"id":"AuthEvent","type":"AuthEvent"},"target":{"id":"Host","type":"Host"},"props":["EnvTime"]}]}';
Get_Event_Authentication_All
| extend AuthEventId = strcat(Username, "_", Hostname, "_", EnvTime)
| where Result == "Failed Login"
| take 200
| invoke Lift_To_Graph(auth_mapping)
| invoke Graph_Fold_By_Property("AuthEvent", "Result")
| invoke Graph_Render_View()
电子邮件图:发件人 -> 消息 -> 收件人
输入查询:Get_Email_All | take 400
图请求:“可视化发件人到消息到收件人的流程,并按判定折叠消息。”
let mail_mapping = '{"node_types":[{"type":"EmailMessage","id":"Message","key":"Subject","props":["EnvTime","Subject","Verdict"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Media-File.svg"},{"type":"Sender","id":"Email","key":"EmailSender","props":["EmailSender"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-cds/command-1070-Mail.svg"},{"type":"Recipient","id":"Email","key":"EmailRecipient","props":["EmailRecipient"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-cds/command-1070-Mail.svg"}],"edges":[{"type":"SentBy","source":{"id":"Message","type":"EmailMessage"},"target":{"id":"Email","type":"Sender"},"props":["EnvTime","Verdict"]},{"type":"DeliveredTo","source":{"id":"Message","type":"EmailMessage"},"target":{"id":"Email","type":"Recipient"},"props":["EnvTime","Verdict"]}]}';
Get_Email_All
| take 400
| invoke Lift_To_Graph(mail_mapping)
| invoke Graph_Fold_By_Property("EmailMessage", "Verdict")
| invoke Graph_Render_View()
可疑域调查(端到端)
基本源请求:“使用这些可疑域的出站网络事件,并以员工姓名增强的IP到域连接图。”
这是有限的回退:一个已知的选择器、一个提取器和一个直接过滤器。
let suspicious_domain_mapping = '{"node_types":[{"type":"IP","id":"IP","key":"ClientIp","props":["ClientIp"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Public-IP-Addresses-(Classic).svg"},{"type":"Domain","id":"Domain","key":"DomainName","props":["DomainName"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/DNS-Zones.svg"}],"edges":[{"type":"RequestsDomain","source":{"id":"IP","type":"IP"},"target":{"id":"Domain","type":"Domain"},"props":["EnvTime"]}]}';
Get_Event_Network_Outbound_All
| where DomainName in ("suspicious.xyz", "malware.example.com")
| take 100
| invoke Lift_To_Graph(suspicious_domain_mapping)
| invoke Enrich_Graph_Ip_Employee('{"ip_to_label":"ClientIp","employee_to_label":"Name"}')
| invoke Graph_Render_View()