MS Sentinel的KQL查詢
KQL 是一種查詢語言,用於對資料進行分析,以在 Microsoft Sentinel 中建立分析、工作簿(workbooks)和執行搜尋。了解基本 KQL 語法結構如何為建立更複雜的語句奠定基礎。
KQL 語法結構
KQL 查詢是處理資料並傳回結果的唯讀請求(read-only request)。該請求以純文字形式表述,使用旨在使語法易於閱讀、編寫和自動化的資料流模型。此查詢使用以類似 SQL 的層次結構組織的架構實體:databases、tables與columns。
此查詢由一系列查詢語句組成。至少一個語句是tabular expression statement,其產生以rows和cloumns的table-like mesh的資料。查詢的tabular expression statements產生查詢結果。
Tabular expression statements的語法具有從一個表格查詢運算子到另一個表格資料流。從資料來源開始,然後流經使用管道 (|) 分隔符號綁定在一起的一組資料轉換運算子。
例如,以下查詢有一個語句,它是一個表格表達式語句。該語句以名為 SecurityEvent 的表格開始。 EventID 欄位的值過濾資料(行),然後透過按帳戶為 count() 建立新欄位來匯總結果。接下來,在準備階段,結果被限制為 10 行。
PS:
了解結果如何流經流水線「也就這個 "|" 符號」至關重要。流水線左側的所有內容都經過處理,然後傳遞到流水線右側。
存取Log Analytics demo環境
Microsoft 提供了一個練習編寫 KQL 語法的環境。唯一的要求是擁有一個登入 Azure 的帳號。我們的 Azure 帳號存取此環境無需付費。可以在Demo環境中執行本文中的KQL語法。
可以在 Logs Demo site上存取該環境。如果看到的訊息是“No results found”,嘗試變更時間範圍。
查詢視窗有三個主要區域:
- The left area is a reference list of the tables in the environment.
- The middle top area is the Query editor.
- The bottom area is the Query Results.
在執行查詢之前,請調整時間範圍以確定資料範圍。若要變更顯示的結果列,請選擇「Cloumns」框,然後選取所需的Columns。
Search operator
Search operator提供multi-table/multi-column的搜尋。儘管Search operator很容易使用,但與 where operator相比,它的效率較低。即使效率如此低下,當我們不確定要過濾哪個table或columns時,我們仍然可以使用Search operator來尋找資料。
第一條語句將在所有table中搜尋「err」。第二條語句將在table SecurityEvent、SecurityAlert 和以 A 開頭的表中搜尋「err」。
分別嘗試每個查詢以查看結果。
search "err"
search in (SecurityEvent,SecurityAlert,A*) "err"
where operator
Where operator將table過濾為滿足predicate的rows subset。分別嘗試每個查詢以查看結果。
SecurityEvent
| where TimeGenerated > ago(2d)
SecurityEvent
| where TimeGenerated > ago(3h) and EventID == "4567"
SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == 4624
| where AccountType =~ "user"
SecurityEvent | where EventID in (4567, 4625)
let statement
Let statement將names綁定到expressions。對於範圍的其餘部分(出現 let 語句的地方),names指的是其bound value。讓語句提高模組化和重用性,因為它們允許我們將潛在複雜的expressions分解為多個部分。每個部分都透過 let 語句綁定到一個name,它們一起組成了整體。 Let 語句允許建立user-defined functions與views。Views是其結果看起來像new table的expressions。
Declare與reuse變數
Let 語句允許建立要在後續語句中使用的變數。在此範例中,建立了 timeOffSet 和 DiscardEventId 並將其用作 SecurityEvent「where」子句的一部分。
let timeOffset = 10d;
let discardEventId = 8846;
SecurityEvent
| where TimeGenerated > ago(timeOffset*2) and TimeGenerated < ago(timeOffset)
| where EventID != discardEventId
ago()是一個函數,它將取得當前日期和時間並減去輸入的值。
Declare dynamic tables or lists
Let 語句允許建立動態tables或清單。
let suspiciousAccounts = datatable(account: string) [
@"\administrator",
@"NT AUTHORITY\SYSTEM"
];
SecurityEvent | where Account in (suspiciousAccounts)
let LowActivityAccounts =
SecurityEvent
| summarize cnt = count() by Account
| where cnt < 100;
LowActivityAccounts | where Account contains "SQL"
extend operator
extend operator將建立經過計算的columns並將new columns附加到結果集。下面的 KQL 範例使用extend operator建立一個new column,StartDir columns是包含substring函數結果的columns。
SecurityEvent
| where ProcessName != "" and Process != ""
| extend StartDir = substring(ProcessName,0, string_size(ProcessName)-string_size(Process))
order by operator
以一個row或多個column對input table的行進行排序。 order by 可以使用任何columns或透過使用逗號分隔符號來使用多個columns。每個row可以升序或降序。columns的預設順序是降序。
SecurityEvent
| where ProcessName != "" and Process != ""
| extend StartDir = substring(ProcessName,0, string_size(ProcessName)-string_size(Process))
| order by StartDir desc, Process asc
project operators
Project operators控制在語句的結果集中要包含、新增、刪除或重新命名哪些column。Project operators有多種類型。下表是變體的清單。
選擇要包含、重新命名或刪除的column,然後插入新的計算column。單獨執行每個查詢以查看結果。
SecurityEvent
| project Computer, Account
SecurityEvent
| where ProcessName != "" and Process != ""
| extend StartDir = substring(ProcessName,0, string_size(ProcessName)-string_size(Process))
| order by StartDir desc, Process asc
| project Process, StartDir
Project-away operator
選擇要從輸出中排除的輸入column。這個例子是根據我們之前的extend and order by operators建構的。project-away除將從結果集中刪除不必要的column。在此範例中,我們將刪除 ProcessName 欄位。
SecurityEvent
| where ProcessName != "" and Process != ""
| extend StartDir = substring(ProcessName,0, string_size(ProcessName)-string_size(Process))
| order by StartDir desc, Process asc
| project-away ProcessName