結果部分語法

支援的國家/地區:

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 欄位中。

risk_score 結果變數

Google SecOps 風險分析功能會自動將偵測結果和快訊與相關實體建立關聯。risk_score 結果變數用於指派風險量。如果未設定這個值,系統會使用預設的偵測或快訊值。您可以在「設定」中設定預設值。

為確保平台一致性,建議您在為自訂偵測項目指派 risk_score 時,使用下列分數範圍。這項對齊作業有助於標準化警示優先順序和回應工作流程。

嚴重性 分數範圍 說明 範例
通報 - 重大 90 - 100 主動入侵,可能影響單一使用者帳戶或端點以外的項目。需要立即審查。 在網域控制站上執行 Mimikatz。
快訊 - 高 80 - 89 單一端點或實體遭到入侵。應立即審查。 實際運作伺服器呼叫最近已知的 C2。
快訊 - 中 50 - 79 需要調查的潛在安全性問題。未確認遭到入侵,但可能發生。 憑證外洩,但沒有遭到濫用的跡象。
非警示 - 低於警示門檻下限 20 - 49 影響較小的安全事件,但如果與其他指標或觀察結果合併,可能會導致更重大的事件。一般來說,不需要審查,可透過複合規則與其他偵測結果合併,建立快訊。 內部通訊埠掃描。
非警示觀察項目 1 - 19 一般來說,資訊偵測的目的是要建立威脅情境認知。一般不需要審查;可透過複合規則與其他偵測項目合併,產生快訊。 登入事件,沒有濫用跡象。

由於 risk_score 是結果變數,因此規則可根據威脅情報或其他並行條件等因素,表達細微差異。

實體風險分數可用於產生近乎即時的風險警報。 詳情請參閱「風險分析總覽」。

risk_entity_to_score 結果變數

除了 risk_score 結果變數,您也可以指定 risk_entity_to_score 結果變數。這個變數可讓您明確指定規則偵測中的哪些實體應套用該偵測的風險評分。

您可以為變數附加不重複的字串,藉此建立多個 risk_entity_to_score 變數,並將風險分數指派給特定實體。例如:

$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid

這些結果變數會將規則的 risk_score 部分中指定的 outcome 指派給 $e.principal.asset.hostname$e.target.user.userid 實體。

範例:規則偵測到管理員帳戶的登入活動

這項規則會偵測高權限管理員帳戶的登入成功事件。這項功能會使用 risk_entity_to_score 關鍵字,明確指定登入的特定使用者。偵測功能會使用這個變數,確保計算出的風險分數只適用於該使用者,不適用於事件中涉及的其他實體,例如來源 IP 位址。

如要瞭解如何編寫多事件規則,請參閱「多事件規則」。

rule suspicious_admin_privilege_escalation {
 // This rule matches single events. Rules can also match multiple events within
 // the same time window.

 meta:
   // Allows for storage of arbitrary key-value pairs of rule details, such as 
   // who wrote it, what it detects on, and version control.
   // The "author" and "severity" fields are special, since they are used as
   // columns on the rules dashboard. To sort based on these fields on the 
   // dashboard, add them here.
   // Severity value should be "Low", "Medium", or "High"
   author = "analyst123"
   description = "Detects suspicious login to critical admin accounts."
   severity = "HIGH"

 events:
   $e.metadata.event_type = "USER_LOGIN"
   $e.target.user.attribute.roles.name = "ADMIN"
   $e.security_result.summary = "Successful login with high-privilege access"

 outcome:
   // Multi-event rules require an aggregation function
   // For example, risk_score = max(0)
   // See https://cloud.google.com/chronicle/docs/detection/yara-l-2-0-overview#outcome_conditionals_example_rule
   $risk_score = 80
   $risk_entity_to_score = $e.target.user.userid
   $source_ip = array_distinct($e.principal.ip)

 condition:
   $e
}

範例:規則會監控內部網路連線

這項規則會找出內部網路區隔之間的網路連線,藉此檢查是否有橫向移動。這項功能會使用 $risk_entity_to_score prefix,在單一偵測中為多個實體指派風險。發起主機 ($risk_entity_to_score_source_asset) 和目標使用者 ($risk_entity_to_score_targeted_user) 的風險分數都會更新。風險引擎會記錄其他未使用這個特定前置字元的結果變數,但會忽略這些變數 (風險分數維持不變)。

如要瞭解如何編寫多事件規則,請參閱「多事件規則」 和「結果條件式範例規則」。

rule lateral_movement_network_connection {
 // This rule matches single events. You can also match multiple events within
 // the same time window.

 meta:
   // Allows for storage of arbitrary key-value pairs of rule details (for 
   // example, who wrote it, what it detects on, and version control).
   // The "author" and "severity" fields are special, since they are used as
   // columns on the rules dashboard. To sort based on these fields on the 
   // dashboard, add them here. Severity value should be "Low", "Medium" or "High"
   author = "analyst123"
   description = "Detects lateral movement attempts between internal segments."
   severity = "MEDIUM"

 events:
   $e.metadata.event_type = "NETWORK_CONNECTION"
   $e.principal.asset.hostname != ""
   $e.target.user.userid != ""
   // Can also use: $e.target.ip = /10\..*/
   net.ip_in_range_cidr($e.target.ip, "10.0.0.0/8")

 outcome:
   // Multi-event rules require an aggregation function
   // for example, risk_score = max(0)
   // See https://docs.cloud.google.com/chronicle/docs/yara-l/yara-l-2-0-examples#outcome-conditionals-example-rule
   $risk_score = 50
   $risk_entity_to_score_source_asset = $e.principal.asset.hostname
   $risk_entity_to_score_targeted_user = $e.target.user.userid
   $target_ip_info = array_distinct($e.target.ip)

 condition:
   $e
}

結果變數資料類型

每個結果變數可以有不同的資料類型,這取決於用於計算結果變數的運算式。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 專業人員尋求答案。