IRQL -- 事件回應查詢語言(Incident Response Query Language)
從選擇器、提取器和擴充器這三種建構區塊組合 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 金鑰 + 回呼原則 |
Get_CISA_KEV() / Enrich_CISA_KEV(T) | CISA KEV 目錄 | 回呼原則 |
組合規則
選擇器 -> 提取 -> 過濾 -> 擴充 -> 彙總/投影
- 以選擇器開始:
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(查詢):
// 步驟 1:連線到您的叢集(如果已連線則跳過)
// 範例:取消註解以連線到 KC7 訓練叢集
// #connect cluster('kc7001.eastus.kusto.windows.net').database('ValdyTimes')
// 或者替換為您自己的叢集:
// #connect cluster('<YOUR_CLUSTER>').database('<YOUR_DATABASE>')
// 步驟 2:執行以下查詢
<KQL_QUERY>
如果使用者要求儲存或在 Kusto Explorer 中開啟,請遵循 references/KUSTO_EXPLORER_LAUNCH.md 中的程序。關鍵規則:
- 在寫入檔案或啟動可執行檔之前,使用
ask_user進行確認 - 在聊天中顯示檔案內容,讓使用者可以在開啟前審閱
- 永遠不要使用 Shell 內插或這裡字串——透過
Set-Content/Add-Content寫入檔案 - 永遠不要將查詢編碼到瀏覽器 URL 中
- 在 macOS/Linux 上,儲存
.kql檔案並建議使用 VS Code Kusto 擴充功能或 ADX Web Explorer - 如需從 IRQL 資料進行圖形視覺化,請參閱
azure-kusto-graph和azure-kusto-irql-graph