使用統計資料分析搜尋資料
本頁說明如何使用 YARA-L 2.0,對 UDM 事件執行統計查詢,並將結果分組以供分析。
處理環境中產生的大量 UDM 事件時,瞭解 UDM 搜尋資料的趨勢非常重要。您可以使用統計和匯總函式,從 UDM 記錄中取得可做為行動依據的洞察資料。UDM 搜尋支援 YARA-L 2.0 中的所有匯總函式。
統計查詢的用途
統計查詢適用於下列用途:
追蹤重要指標:您可以評估 UDM 事件和相關聯資產的分布情形和頻率,例如主機與已知惡意 IP 位址通訊。
偵測異常行為:您可以找出可能表示安全事件的活動尖峰,例如非上班時間的網路流量突然激增或登入。
分析一段時間內的趨勢:您可以評估資安態勢變化,評估控管措施的有效性,或找出需要改善之處,例如監控一段時間內安全漏洞數量的變化。
搜尋中的 YARA-L 2.0 查詢結構
您可以使用類似於偵測引擎規則中 YARA-L 結構的語法,將 UDM 搜尋查詢結果分組及排序。詳情請參閱「開始使用:Google SecOps 中的 YARA-L 2.0」。
YARA-L 2.0 查詢結構如下:
篩選陳述式:指定篩選事件的條件。詳情請參閱「篩選遺漏、零和未初始化的值」。
比對 (選用):定義要分組的欄位。詳情請參閱「比對區段語法」。
結果:指定查詢的輸出內容。詳情請參閱「結果區段語法」。
重複資料刪除 (選用):減少重複結果的數量。詳情請參閱「在搜尋和資訊主頁中使用重複資料刪除功能」。
順序:決定查詢結果的順序,可以是
asc(遞增) 或desc(遞減)。如未指定順序 (asc或desc),則預設為asc。上限 (選用):設定查詢傳回的資料列數量上限。
範例:訂購和使用限制
以下範例顯示訂單和限制用量:
metadata.log_type = "OKTA" match: principal.ip Outcome: $user_count_by_ip = count(principal.user.userid) order: $user_count_by_ip desc limit: 20
匯總函式
如果事件包含多個值,您必須使用匯總函式來匯總資料。
搜尋支援下列匯總函式:
array
array 函式會以清單形式傳回所有值。並將清單截斷為最多 25 個隨機元素。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
array(expression) |
STRING |
LIST |
程式碼範例
傳回內含事件類型的陣列。
$event_type = metadata.event_type outcome: $event_type_array = array($event_type)
array_distinct
array_distinct 函式會以清單形式傳回所有相異值。並將清單截斷為最多 25 個隨機元素。系統會在截斷前套用重複資料刪除程序,取得不重複的清單。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
array_distinct(expression) |
STRING |
LIST |
程式碼範例
傳回不同的事件類型
傳回包含不同事件類型的陣列。
$event_type = metadata.event_type outcome: $event_type_array = array_distinct($event_type)從相異陣列中排除預設值
以下範例會篩除缺少安全結果說明的事件。它會使用重複欄位中的 any 關鍵字,在結果匯總期間保留所有陣列索引:
events: $e.security_result[0].description != "" any $e.security_result.description = "" outcome: $security_result_description = array_distinct($e.security_result.description)
avg
avg 函式會傳回數值欄中的平均值。計算時會忽略 NULL 值。這項函式通常會與 match 搭配使用,計算資料中特定群組的平均值。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
avg(numericExpression) |
NUMBER |
NUMBER |
程式碼範例
找出
target.ip不為空白的所有事件。針對所有符合principal.ip的事件,將metadata.event_timestamp.seconds的平均值儲存在名為avg_seconds的變數中。target.ip != "" match: principal.ip outcome: $avg_seconds = avg(metadata.event_timestamp.seconds)
count
count 函式會傳回群組內的資料列數。這項函式通常會與 match 搭配使用,取得資料中特定群組的計數。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
count(expression) |
STRING |
NUMBER |
程式碼範例
傳回一段時間內使用者成功登入的次數。
metadata.event_type = "USER_LOGIN" $security_result = security_result.action $security_result = "ALLOW" $date = timestamp.get_date(metadata.event_timestamp.seconds, "America/Los_Angeles") match: $security_result, $date outcome: $event_count = count(metadata.id)
count_distinct
count_distinct 函式會傳回群組中具有相異值的資料列數。這項函式通常會與 match 搭配使用,取得資料中特定群組的計數。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
count_distinct(expression) |
STRING |
NUMBER |
程式碼範例
傳回不重複使用者登入次數
傳回一段時間內成功登入的不重複使用者人數。
metadata.event_type = "USER_LOGIN" $security_result = security_result.action $security_result = "ALLOW" $date = timestamp.get_date(metadata.event_timestamp.seconds, "America/Los_Angeles") match: $security_result, $date outcome: $event_count = count_distinct(metadata.id)從不重複計數中排除預設值
以下範例會篩除未初始化的使用者 ID,因此
count_distinct不會在總計數中納入預設空白字串:metadata.event_type = "USER_LOGIN" $userid = principal.user.userid $userid != "" match: metadata.event_type outcome: $distinct_users = count_distinct($userid)
earliest
earliest 函式會從一組記錄中傳回最早的時間戳記,解析度為微秒。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
earliest(timestamp) |
TIMESTAMP |
TIMESTAMP |
程式碼範例
針對所有符合
hostname的事件,將最早的metadata.event_timestamp儲存在start變數中。$hostname = principal.hostname match: $hostname outcome: $start = earliest(metadata.event_timestamp)
latest
latest 函式會從一組記錄中傳回最新的時間戳記,解析度為微秒。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
latest(timestamp) |
TIMESTAMP |
TIMESTAMP |
程式碼範例
針對所有符合
hostname的事件,將metadata.event_timestamp的最新值儲存在end變數中。$hostname = principal.hostname match: $hostname outcome: $end = latest(metadata.event_timestamp)
max
max 函式會傳回數值欄中的最大值。這項函式通常會與 match 搭配使用,以取得資料中每個群組的最大值。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
max(numericExpression) |
NUMBER |
NUMBER |
程式碼範例
找出
target.ip不為空白的所有事件。針對所有符合principal.ip的事件,將principal.ip的最大值儲存在名為max_seconds的變數中。metadata.event_timestamp.secondstarget.ip != "" match: principal.ip outcome: $max_seconds = max(metadata.event_timestamp.seconds)
min
min 函式會傳回數值欄中的最小值。這項函式通常會與 match 搭配使用,取得資料中每個群組的最小值。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
min(numericExpression) |
NUMBER |
NUMBER |
程式碼範例
找出
target.ip不為空白的所有事件。針對所有符合principal.ip的事件,將metadata.event_timestamp.seconds的最小值儲存在名為min_seconds的變數中。target.ip != "" match: principal.ip outcome: $min_seconds = min(metadata.event_timestamp.seconds)
stddev
stddev 函式會傳回所有可能值的標準差。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
stddev(numericExpression) |
NUMBER |
NUMBER |
程式碼範例
找出
target.ip不為空白的所有事件。針對所有符合principal.ip的事件,將principal.ip的標準差儲存在名為stddev_seconds的變數中。metadata.event_timestamp.secondstarget.ip != "" match: principal.ip outcome: $stddev_seconds = stddev(metadata.event_timestamp.seconds)
sum
sum 函式會傳回數值欄中的值總和。計算時會忽略 NULL 值。這項函式通常會與 match 搭配使用,計算資料中不同群組的總和。
| 語法 | 參數資料類型 | 傳回類型 |
|---|---|---|
sum(numericExpression) |
NUMBER |
NUMBER |
程式碼範例
找出
target.ip不為空白的所有事件。針對所有符合principal.ip的事件,將network.sent_bytes的總和儲存在名為sent_bytes的變數中。target.ip != "" match: principal.ip outcome: $sent_bytes = sum(network.sent_bytes)
篩選缺少、零和未初始化的值
匯總 Unified Data Model (UDM) 事件資料時,結果可能會包含非預期的空字串、零值或 [Unknown] 項目。這是因為 YARA-L 2.0 會將未初始化的欄位評估為預設零值,而不是 NULL。
舉例來說,未初始化的字串欄位預設為空字串 (""),整數欄位預設為零 (0),列舉欄位則預設為未指定的值 (例如 principal.security_result.action 的 "UNKNOWN_ACTION")。使用零值可避免負向比較篩選器 (例如 $e.principal.hostname != "test_domain") 意外排除缺少主機名稱的事件。
由於匯總函式會將預設零值視為有效資料,因此這項行為會對查詢結果造成下列影響:
- 不重複計數:
count_distinct等函式會將預設零值視為不重複項目。如果部分事件缺少欄位,count_distinct會將預設零值視為額外項目,使總計數增加一。 - 陣列清單:
array和array_distinct等函式會在傳回的清單中加入預設零值。如果結果陣列只包含空字串 ([""]),偵測時間軸會將值顯示為[Unknown]。
如要從匯總中移除預設值,請在查詢的 events 區段中新增篩選條件,排除這些值 (例如 $e.field != ""、$e.field != 0 或 $e.field != "UNKNOWN_ACTION")。
篩選重複欄位時,請在篩選器前面加上 any 關鍵字,例如 any $e.security_result.description != ""。使用 any 會評估整個事件的條件,並在結果彙整資料時保留所有陣列索引。
YARA-L 2.0:搜尋與 UDM 的比較
搜尋功能不支援用於搜尋事件視窗的
over關鍵字。UDM 搜尋查詢不包含
condition和option區段。
如要詳細比較 UDM 搜尋查詢和即時 YARA-L 2.0 偵測規則,請參閱「UDM 搜尋與規則結果比較」。
依時間精細程度分組
您可以在 match 區段中,依指定的時間精細程度將事件欄位和預留位置分組,類似於在 SQL 中將資料欄分組。
語法如下:
語法格式
match: ... [BY|OVER EVERY] [FIRST] [NUMBER] [TIME_GRANULARITY]
如要依時間細微程度分組,可以使用 by 或 over
every 關鍵字。允許的時間精細程度如下:
MINUTE或mHOUR或hDAY或dWEEK或wMONTH或mo
by 和 over every 關鍵字的功能相同。你可以將其中一個疊在另一個上面。
範例:每兩小時將 IP 位址和主機名稱分組
$hostname = principal.hostname match: $hostname, target.ip by 2h範例:依主機名稱分組,並以完整時間粒度顯示
$hostname = principal.hostname match: $hostname by minute範例:依主機名稱和事件發生日期將所有事件分組
$hostname = target.hostname match: $hostname over every day outcome: $events_count = count($hostname)
依時間範圍將資料來源分組
部分資料來源 (例如實體內容) 在時間範圍 (<start_time>, <end_time>) 內有效,而非單一時間戳記。在這些資料來源中依時間精細程度分組時,您可以評估整個時間範圍,或將分組限制為開始時間戳記。
評估整個時間範圍 (預設)
根據預設,如果省略 first 關鍵字,查詢會評估記錄的整個時間範圍。
範例:依實體 IP 位址在完整時間範圍內分組
graph.entity.hostname != "" match: graph.entity.ip by hour outcome: $min_seconds = min(graph.metadata.event_metadata.event_timestamp.seconds)
使用第一個關鍵字評估開始時間戳記
如要將分組限制為僅限記錄的開始時間戳記 (<start_time>),請在 match 陳述式中新增選用的 first 關鍵字。您可以搭配 by 或 over every 使用 first (by first 等同於 over every first)。
舉例來說,假設實體的時間範圍為 1m 到 5m,時間精細程度為 1m。如果使用 first 將結果依主機 (h1、h2) 分組,則傳回的資料欄會是 (h1、1m) 和 (h2、1m),並忽略其餘時間範圍。
範例:僅使用開始時間,依實體 IP 位址分組
graph.entity.hostname != "" match: graph.entity.ip by first hour outcome: $min_seconds = min(graph.metadata.event_metadata.event_timestamp.seconds)
在搜尋中建立及儲存視覺化內容
本節說明 Google SecOps 統合式資料模型 (UDM) 搜尋的資料圖表製作功能。這項功能可讓資安營運中心 (SOC) 分析師從搜尋結果建立視覺化內容,並儲存至資訊主頁,有效偵測、調查及應對威脅。
如要建立視覺化效果,您必須具備 chronicle.nativeDashboards.create 和 chronicle.nativeDashboards.update IAM 權限。
建立及儲存圖表,以便新增至資訊主頁
如要建立及儲存圖表,並新增至資訊主頁,請按照下列步驟操作:
使用
match和outcome區段撰寫 YARA-L 查詢。選取日期範圍,然後按一下「執行搜尋」執行查詢。 在「統計資料」和「視覺化」分頁中查看結果。
在「Visualize」(視覺化) 分頁中,執行下列操作: a. 從「圖表類型」清單中選取圖表類型。 b. 調整「資料設定」下方的設定,即可自訂圖表。
在「Add to dashboard」(新增至資訊主頁) 畫面中,執行下列操作: a. 輸入圖表名稱、說明和時間範圍。 b. 選擇將圖表新增至現有資訊主頁,或建立新的資訊主頁。
按一下「新增至資訊主頁」,將圖表新增至資訊主頁。
限制
統計查詢執行作業有以下限制:
- 查詢無法處理 90 天前的資料 (3 個月的追溯期)。
- 統計查詢最多會傳回 10,000 個結果。
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求解答。