結果部分語法

支援的國家/地區:

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。

數學運算

您可以在查詢的 outcomeevents 區段中使用數學運算,計算整數或浮點資料型別。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() 個函式呼叫
  • 使用 anyall 修飾符

匯總資料

重複事件欄位為非純量值。也就是說,單一變數會指向多個值。舉例來說,事件欄位變數 $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 專業人員尋求答案。