KQL查詢MS Sentinel 資料
KQL 是一種查詢語言,用於對資料進行分析,以建立分析、workbook,並在 Microsoft Sentinel 中執行搜尋。了解如何使用 KQL 語句處理包含結構化和非結構化字串資料的字段,為提取用於在 Microsoft Sentinel 中建立檢測的資料奠定了基礎。
從非結構化字串欄位中提取資料
安全日誌資料通常包含在非結構化字串欄位中,需要解析(parsing)才能提取資料。有多種方法可以從 KQL 中的字串欄位(string fields)中提取資訊。使用的兩個主要operators是提取和解析。
Extract 從文字字串(text string)中取得regular expression的符合項目。可以選擇將提取的子字串(substring)轉換為指定的類型。
print extract("x=([0-9.]+)", 1, "hello x=45.6|wo") == "45.6"
Arguments
- regex: A regular expression.
- captureGroup:
一個正整型常數,指示要擷取的捕獲群組。 「0」代表整個匹配,「1」代表正規表示式中第一個 ‘(‘parenthesis’)’ 匹配的值,2 或更多代表後續括號。 - text: A string to search.
- typeLiteral:
可選的類型文字(例如,typeof(long))。如果提供,提取的子字串將轉換為此類型。
Returns
如果正規表示式在文字中找到符合項目:與指定的擷取群組 captureGroup 相符的子字串,可以選擇轉換為 typeLiteral。
如果沒有匹配,或者類型轉換失敗:null。
以下範例使用 extract 函數從 SecurityEvent table的帳號欄位(Account field)中提取帳號名稱。
SecurityEvent
| where EventID == 4672 and AccountType == 'User'
| extend Account_Name = extract(@"^(.*\\)?([^@]*)(@.*)?$", 2, tolower(Account))
| summarize LoginCount = count() by Account_Name
| where Account_Name != ""
| where LoginCount < 10
parse
Parse 計算string expression並將其值解析為一個或多個calculated columns。對於解析失敗的字串,計算columns將包含空值。
Syntax
T | parse [kind=regex [flags=regex_flags] |simple|relaxed] Expression with * (StringConstant ColumnName [: ColumnType]) *
Arguments
- T: The input table.
- kind:
— simple(預設):StringConstant 是一個regular string value,並且符合(match)是嚴格。所有字串分隔符號(string delimiters)都應出現在已解析的字串中,並且所有extended columns必須與所需類型相符。
— regex:StringConstant可以是一個regular string value,並且符合(match)是嚴格。所有string delimiters(可以是此模式的正規表示式)應出現在已解析的字串中,並且所有extended columns必須與所需類型相符。
— flags:在正規表示式模式下使用的標誌,如 RE2 標誌中的 U(Ungreedy)、m(多行模式)、s(符合新行 \n)、i(不區分大小寫)。
— relaxed:StringConstant是一個常規字串值,匹配是寬鬆的。所有 string delimiters都應出現在已解析的字串中,但extended columns可能部分符合所需的類型。與所需類型不符的extended columns將取得 null 值。 - Expression: An expression that evaluates to a string.
- ColumnName: The name of a column to assign a value to, extracted from the string expression.
- ColumnType: Optional. The scalar value that indicates the type to convert the value to. The default is the string type.
Returns
Input table根據提供給operator的column list進行擴充。
以下語句示範了parse operator,該operator評估string expression並將其值解析為一個或多個 calculated columns。用於structuring unstructured data。
let Traces = datatable(EventText:string)
[
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=23, lockTime=02/17/2016 08:40:01, releaseTime=02/17/2016 08:40:01, previousLockTime=02/17/2016 08:39:01)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=15, lockTime=02/17/2016 08:40:00, releaseTime=02/17/2016 08:40:00, previousLockTime=02/17/2016 08:39:00)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=20, lockTime=02/17/2016 08:40:01, releaseTime=02/17/2016 08:40:01, previousLockTime=02/17/2016 08:39:01)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=22, lockTime=02/17/2016 08:41:01, releaseTime=02/17/2016 08:41:00, previousLockTime=02/17/2016 08:40:01)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=16, lockTime=02/17/2016 08:41:00, releaseTime=02/17/2016 08:41:00, previousLockTime=02/17/2016 08:40:00)"
];
Traces
| parse EventText with * "resourceName=" resourceName ", totalSlices=" totalSlices:long * "sliceNumber=" sliceNumber:long * "lockTime=" lockTime ", releaseTime=" releaseTime:date "," * "previousLockTime=" previousLockTime:date ")" *
| project resourceName, totalSlices, sliceNumber, lockTime, releaseTime, previousLockTime
Extract data from structured string data
Strings fields也可能包含結構化資料,例如JSON或Key-Value pairs。 KQL 可以存取這些值以進行進一步分析。
在 Log Analytics tables中,有定義為動態的欄位類型。動態欄位包含鍵值對,例如:
{"eventCategory":"Autoscale","eventName":"GetOperationStatusResult","operationId":"xxxxxxxx-6a53-4aed-bab4-575642a10226","eventProperties":"{\"OldInstancesCount\":6,\"NewInstancesCount\":5}","eventDataId":" xxxxxxxx -efe3-43c2-8c86-cd84f70039d3","eventSubmissionTimestamp":"2020-11-30T04:06:17.0503722Z","resource":"ch-appfevmss-pri","resourceGroup":"CH-RETAILRG-PRI","resourceProviderValue":"MICROSOFT.COMPUTE","subscriptionId":" xxxxxxxx -7fde-4caf-8629-41dc15e3b352","activityStatusValue":"Succeeded"}
若要存取動態欄位中的字串,請使用點符號。 SigninLogs table中的 DeviceDetail 欄位的類型為動態。在此範例中,可以使用 DeviceDetail.operatingSystem 欄位名稱存取作業系統。
SigninLogs
| extend OS = DeviceDetail.operatingSystem
下面的查詢範例顯示了 SigninLogs table中動態欄位的使用。
// Example query for SigninLogs showing how to break out packed fields.
SigninLogs
| extend OS = DeviceDetail.operatingSystem, Browser = DeviceDetail.browser
| extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)
| extend Date = startofday(TimeGenerated)
| summarize count() by Date, Identity, UserDisplayName, UserPrincipalName, IPAddress, ResultType, ResultDescription, StatusCode, StatusDetails
| sort by Date
JSON
KQL 提供了操作儲存在字串欄位中的 JSON 的函數。許多日誌是JSON格式,這需要我們知道如何將JSON資料轉換為可查詢的欄位。下面的範例是 JSON 相關函數和operators的清單。
單獨執行每個查詢以查看結果。
SigninLogs
| extend AuthDetails = parse_json(AuthenticationDetails)
| extend AuthMethod = AuthDetails[0].authenticationMethod
| extend AuthResult = AuthDetails[0].["authenticationStepResultDetail"]
| project AuthMethod, AuthResult, AuthDetails
SigninLogs
| mv-expand AuthDetails = parse_json(AuthenticationDetails)
| project AuthDetails
SigninLogs
| mv-apply AuthDetails = parse_json(AuthenticationDetails) on
(where AuthDetails.authenticationMethod == "Password"
整合外部資料
externaldata operator傳回一個table,其架構是在查詢本身中定義的。其資料是從外部儲存專案讀取的,例如 Azure Blob storage中的 blob 或 Azure Data Lake Storage 檔案。
Syntax
externaldata ( ColumnName : ColumnType [, ...] )
[ StorageConnectionString [, ...] ]
[with ( PropertyName = PropertyValue [, ...] )]
Arguments
- ColumnName, ColumnType:
由參數定義table的架構。語法與在.create table 中定義table時所使用的語法相同。 - StorageConnectionString:
描述保存要傳回的資料的儲存工件的Storage connection strings。 - PropertyName, PropertyValue, …:
描述如何解釋從儲存中檢索的資料的更多屬性,如ingestion properties下所列。
現行支援的屬性有:ARGUMENTS
Returns
externaldata operator傳回特定schema的資料表,其中包含從storage connection string指示的指定儲存工件解析的資料。
Users
| where UserID in ((externaldata (UserID:string) [
@"https://storageaccount.blob.core.windows.net/storagecontainer/users.txt"
h@"?...SAS..." // Secret token needed to access the blob
]))
| ...
Create parsers with functions
Parsers是定義具有已解析的非結構化字串欄位(例如 Syslog 資料)的virtual table的函數。
在「Logs」視窗中,建立查詢,選擇「Save」按鈕,輸入名稱,然後從下拉清單中選擇「Save As Function」。在本例中,如果我們將函數命名為“PrivLogins”,我就可以使用名稱 PrivLogins 存取該table。
SecurityEvent
| where EventID == 4672 and AccountType == 'User'
PrivLogins