結果部分語法
YARA-L 查詢的 outcome 區段會定義結果變數,指定搜尋和資訊主頁查詢的輸出內容,以及規則觸發時偵測到的其他脈絡和資訊。這些變數可用於各種用途,例如在資訊主頁上顯示相關資料,以及建立風險評分。
定義結果部分
在單一查詢的 outcome 區段中,使用 $ 字元,後面加上變數名稱,即可定義結果變數。您最多可以定義 20 個結果變數。變數名稱本身是任意的,如果是規則,系統會根據每次偵測計算並匯總結果值。
每個結果變數都會使用運算式指派值。
這項規則會搜尋來自新位置的登入失敗事件:
rule failed_logins
{
meta:
author = "Security Team"
description = "Detects multiple failed user logins within 10-minute windows."
severity = "HIGH"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$user = $e.target.user.userid
match:
$user over 10m
outcome:
$failed_login_count = count($e.metadata.id)
$first_fail_time = min($e.metadata.event_timestamp.seconds)
condition:
#e >= 5
}
「outcome」部分會對事件和預留位置變數執行彙整作業:計算登入失敗次數、計算不重複的 IP,以及取得失敗發生時間。
outcome:
$failed_login_count = count($e.metadata.id)
$first_fail_time = min($e.metadata.event_timestamp.seconds)
如果您納入並填入特殊的 $risk_score 結果變數,系統會在查詢產生的快訊「快訊和 IoC」頁面中顯示其值 (整數或浮點數)。
如果查詢的 outcome 區段未包含 $risk_score 變數,系統會設定下列其中一個預設值:
如果查詢設定為產生快訊,則
$risk_score會設為 40。如果查詢未設定為產生快訊,則
$risk_score會設為 15。
$risk_score 的值會儲存在 security_result.risk_score UDM 欄位中。
風險分數結果變數
Google SecOps 風險分析功能會自動將偵測結果和快訊與相關實體建立關聯。risk_score 結果變數用於指派風險量。如果未設定這個值,系統會使用預設的偵測或快訊值。您可以在「設定」中設定預設值。
為確保平台一致性,建議您在為自訂偵測項目指派 risk_score 時,使用下列分數範圍。這項調整有助於標準化警示優先順序和回應工作流程。
| 嚴重程度 | 分數範圍 | 說明 | 範例 |
|---|---|---|---|
| 警示 - 重大 | 90 - 100 | 主動入侵,可能對單一使用者帳戶或端點以外的項目造成影響。需要立即審查。 | 在網域控制站上執行 Mimikatz。 |
| 快訊 - 高 | 80 - 89 | 單一端點或實體遭到入侵。應立即審查。 | 實際運作伺服器呼叫最近已知的 C2。 |
| 警告 - 中 | 50 - 79 | 需要調查的潛在安全性問題。未確認遭到入侵,但可能發生。 | 憑證外洩,但沒有遭到濫用的跡象。 |
| 非警示 - 低於警示門檻下限 | 20 - 49 | 影響較小的安全事件,但如果與其他指標或觀察結果合併,可能會導致更重大的事件。一般來說,不需要審查,可透過複合規則與其他偵測結果合併,建立快訊。 | 內部通訊埠掃描。 |
| 非警示觀察事項 | 1 - 19 | 一般來說,資訊偵測的目的是要建立威脅的情境意識。一般不需要審查;可透過複合規則與其他偵測項目合併,產生快訊。 | 登入事件,沒有濫用跡象。 |
由於 risk_score 是結果變數,因此規則可根據威脅情報或其他並行條件等因素,表達細微差異。
實體風險分數可用於近乎即時地產生風險警報。詳情請參閱「風險分析總覽」。
結果變數資料類型
每個結果變數可以有不同的資料類型,這取決於用於計算結果變數的運算式。Google SecOps 支援下列結果資料類型:
- 整數
- 浮動
- 字串
- 整數清單
- 浮點數清單
- 字串清單
條件式邏輯
您可以使用條件式邏輯計算結果值。條件式 是使用下列語法模式指定:
if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)
您可以將條件運算式解讀為「如果 BOOL_CLAUSE 為 true,則傳回 THEN_CLAUSE,否則傳回 ELSE_CLAUSE」。
BOOL_CLAUSE 的評估結果必須是布林值。BOOL_CLAUSE 運算式的形式與 events 區段中的運算式類似。例如:
含有比較運算子的 UDM 欄位名稱:
if($context.graph.entity.user.title = "Vendor", 100, 0)在
events部分中定義的預留位置變數:if($severity = "HIGH", 100, 0)outcome區段中定義的另一個結果變數:if($risk_score > 20, "HIGH", "LOW")傳回布林值的函式:
if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)在參照清單中查詢:
if($u.principal.hostname in %my_reference_list_name, 100, 0)匯總比較:
if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)
THEN_CLAUSE 和 ELSE_CLAUSE 必須是相同的資料類型。我們支援整數、浮點數和字串。
如果資料類型是整數或浮點數,可以省略 ELSE_CLAUSE。如果省略,ELSE_CLAUSE 會評估為 0。例如:
`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`
如果資料類型是字串,或 THEN_CLAUSE 是預留位置變數或結果變數,您就必須提供 ELSE_CLAUSE。
數學運算
您可以在查詢的 outcome 和 events 區段中使用數學運算,計算整數或浮點資料型別。Google Security Operations 支援加法、減法、乘法、除法和模數,做為運算中的頂層運算子。
以下程式碼片段是 outcome 區段的計算範例:
outcome:
$risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))
只要每個運算元和整個算術運算式都經過適當彙整 (請參閱「彙整」),即可對下列類型的運算元執行數學運算:
- 數值事件欄位
events部分定義的數字預留位置變數- 在
outcome部分中定義的數值結果變數 - 傳回整數或浮點數的函式
- 傳回整數或浮點數的彙整
浮點數不允許使用模數。
結果中的預留位置變數
計算結果變數時,您可以使用查詢事件部分中定義的預留位置變數。在本範例中,假設 $email_sent_bytes 是在規則的事件部分中定義:
範例:沒有賽事專區的單一賽事
// No match section, so this is a single-event query. outcome: // Use placeholder directly as an outcome value. $my_outcome = $email_sent_bytes // Use placeholder in a conditional. $other_outcome = if($file_size > 1024, "SEVERE", "MODERATE") condition: $e
範例:含有相符區段的多事件
match:
// This is a multi event query with a match section.
$hostname over 5m
outcome:
// Use placeholder directly in an aggregation function.
$max_email_size = max($email_sent_bytes)
// Use placeholder in a mathematical computation.
$total_bytes_exfiltrated = sum(
1024
+ $email_sent_bytes
+ $file_event.principal.file.size
)
condition:
$email_event and $file_event結果指派運算式中的結果變數
結果變數可用於衍生其他結果變數,類似於 events 區段中定義的預留位置變數。您可以在指派其他結果變數時,參照結果變數,方法是使用 $ 符記,後面接著變數名稱。必須先定義結果變數,才能在查詢文字中參照這些變數。在指派運算式中使用時,結果變數不得匯總 (請參閱「匯總」)。
在下列範例中,結果變數 $risk_score 的值衍生自結果變數 $event_count:
範例:從另一個結果變數衍生的結果變數
match: // This is a multi event query with a match section. $hostname over 5m outcome: // Aggregates all timestamp on login events in the 5 minute match window. $event_count = count($login.metadata.event_timestamp.seconds) // $event_count cannot be aggregated again. $risk_score = if($event_count > 5, "SEVERE", "MODERATE") // This is the equivalent of the 2 outcomes combined. $risk_score2 = if(count($login.metadata.event_timestamp.seconds) > 5, "SEVERE", "MODERATE") condition: $e
結果變數可用於結果指派右側的任何類型運算式,但下列運算式除外:
- 匯總資料
Arrays.length()個函式呼叫- 使用
any或all修飾符
匯總資料
重複事件欄位為非純量值。也就是說,單一變數會指向多個值。舉例來說,事件欄位變數 $e.target.ip 是重複欄位,可以有零個、一個或多個 IP 值。這是非純量值,而事件欄位變數 $e.principal.hostname 不是重複欄位,只有 1 個值 (即純量值)。
同樣地,在具有比對視窗的查詢的 outcome 區段中使用的非重複事件欄位和重複事件欄位,都是非純量值。
範例:使用相符區段和非重複欄位將事件分組
下列查詢會使用 `match` 區段將事件分組,並在 `outcome` 區段中參照非重複事件欄位:
rule OutcomeAndMatchWindow{
...
match:
$userid over 5m
outcome:
$hostnames = array($e.principal.hostname)
...
}查詢執行的任何 5 分鐘時間範圍,可能包含零個、一個或多個事件。結果部分會處理相符視窗中的所有事件。結果部分中參照的任何事件欄位變數,都可以在比對視窗中,指向每個事件的零個、一個或多個欄位值。舉例來說,如果 5 分鐘的時間範圍內有 5 個 $e 事件,結果部分會顯示五個不同的主機名稱。$e.principal.hostname這個查詢的 outcome 區段會將事件欄位變數 $e.principal.hostname 視為非純量值。
由於結果變數一律必須產生單一純量值,因此結果指派作業所依據的任何非純量值,都必須經過彙整,才能產生單一純量值。在結果部分中,下列為非純量值,必須經過彙整:
- 查詢使用
match區段時的事件欄位 (重複或非重複) - 查詢使用
match區段時的活動預留位置 (重複或非重複) - 查詢未使用
match區段時,重複的事件欄位 - 查詢未使用
match區段時,重複的活動預留位置
在不含 match 區段的查詢中,純量事件欄位、純量事件預留位置和常數可以包裝在匯總函式中。不過在大多數情況下,這些匯總會傳回包裝值,因此沒有必要。例外狀況是 array() 匯總,您可以使用這項匯總,將純量值明確轉換為陣列。
結果變數會視為匯總資料,因此在其他結果指派中參照時,不得重新匯總。
您可以使用下列匯總函式:
| 匯總函式 | 說明 |
|---|---|
max() |
輸出所有可能值的最大值。僅適用於整數和浮點數。 |
min() |
輸出所有可能值的最小值。僅適用於整數和浮點數。 |
sum() |
輸出所有可能值的總和。僅適用於整數和浮點數。 |
count_distinct() |
收集所有可能的值,然後輸出可能值的相異計數。 |
count() |
行為與 `count_distinct()` 類似,但會傳回可能值的非不重複計數。 |
array_distinct() |
收集所有可能的相異值,然後輸出這些值的清單。系統會將不重複值清單截斷為 1,000 個隨機元素。系統會先套用去重複功能,取得不重複的清單,然後再套用截斷功能。 |
array() |
行為與 array_distinct() 類似,但會傳回非不重複的值清單。此外,系統也會將值清單截斷為 1,000 個隨機元素。 |
如果規則包含 condition 區段,且該區段指定必須存在多個事件,則匯總函式就非常重要,因為匯總函式會對產生偵測結果的所有事件執行運算。
範例:多個事件的條件
以下是多個事件的條件範例。如果結果和條件部分包含:
outcome: $asset_id_count = count($event.principal.asset_id) $asset_id_distinct_count = count_distinct($event.principal.asset_id) $asset_id_list = array($event.principal.asset_id) $asset_id_distinct_list = array_distinct($event.principal.asset_id) condition: #event > 1
由於 `condition` 區段需要每個偵測項目有多個 `event`,因此匯總函式會對多個事件執行運算。假設下列事件產生一項偵測結果:
event: // UDM event 1 asset_id="asset-a" event: // UDM event 2 asset_id="asset-b" event: // UDM event 3 asset_id="asset-b"
那麼結果的值會是:
- $asset_id_count = 3
- $asset_id_distinct_count = 2
- $asset_id_list = `["asset-a", "asset-b", "asset-b"]
- $asset_id_distinct_list = `["asset-a", "asset-b"]
限制
outcome區段不得參照events區段或outcome區段中未定義的新預留位置變數。outcome區段無法使用events區段中未定義的事件變數。如果事件欄位所屬的事件變數已在
events區段中定義,則outcome區段可以使用events區段中未使用的事件欄位。「
outcome」部分只能關聯已在「events」部分關聯的事件變數。當不同事件變數的兩個事件欄位相等時,就會發生關聯。
如需 outcome 區段的範例,請參閱「YARA-L 2.0 總覽」。
如要進一步瞭解如何使用 outcome 區段偵測重複項目,請參閱「建立情境感知分析」。
後續步驟
其他資訊
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。