結果區段語法
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 結果變數,其值 (整數或浮點數) 會顯示在「Alerts and IoCs」(快訊和 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 結果變數
根據預設,Google SecOps 會將偵測到的風險分數指派給取樣事件中的所有實體。並將分數指派給規則 match 和 outcome 區段中擷取的所有實體。如要將風險分數指派給特定實體,請一併指定 risk_entity_to_score 結果變數和 risk_score。風險評分支援 user 和 asset 實體。不支援 RESOURCE 或 GROUP 實體類型。
您可以建立多個 risk_entity_to_score 變數,方法是在變數中附加不重複的字串,並將風險評分指派給特定實體。例如:
$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid
這些結果變數會將規則 outcome 部分中指定的 risk_score 指派給 $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://docs.cloud.google.com/chronicle/docs/yara-l/yara-l-2-0-examples#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 支援下列結果資料類型:
- 整數
- floats
- 字串
- 整數清單
- 浮點數清單
- 字串清單
條件式邏輯
您可以使用條件邏輯來計算結果的值。條件式會使用下列語法模式指定:
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區段中定義的數值結果變數 - 傳回整數或浮點數的函式
- 傳回整數或浮點數的匯總
浮點數不允許使用模數。
標準整數常值預設為有正負號的 64 位元整數 (INT64),與無正負號的 64 位元整數 (UINT64) UDM 欄位不相容,例如 network.received_bytes、network.sent_bytes 和 principal.file.size。在算術 (+、-、*) 或模數 (%) 運算中合併這些類型,可能會導致 outcome 區段發生執行階段錯誤。如要解決這個問題,請使用 cast.as_int() 或 cast.as_uint() 比對整數類型。% 運算子必須明確轉換。對於算術運算,您也可以使用浮點常值 (例如 2.0 或 100.0) 或除法強制轉型 (例如 (2/1)),在同一行沒有其他 / 運算子的運算式中,強制整數常數做為浮點數。詳情請參閱「使用無正負號事件欄位進行算術運算」。
結果中的預留位置變數
計算結果變數時,您可以使用在查詢的事件區段中定義的預留位置變數。在這個範例中,假設 $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.0
+ $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() |
收集所有可能的不重複值,然後輸出這些值的清單。系統會先簡化資料,產生不重複的清單,然後再截斷資料。在 Google 搜尋中,清單最多會截斷為 1,000 個隨機元素。在資訊主頁和規則中,清單最多會截斷為 25 個隨機元素。 |
array() |
行為與 array_distinct() 類似,但會傳回非相異值清單。在搜尋中,清單最多會截斷為 1,000 個隨機元素。在資訊主頁和規則中,清單最多會截斷為 25 個隨機元素。 |
如果規則包含 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區段中定義的事件變數。outcome區段可以使用未在events區段中使用的事件欄位,前提是事件欄位所屬的事件變數已在events區段中定義。outcome區段只能關聯已在events區段中關聯的事件變數。當不同事件變數中的兩個事件欄位相等時,就會發生關聯。
如需 outcome 區段的範例,請參閱「YARA-L 2.0 總覽」。
如要瞭解如何使用 outcome 區段刪除重複偵測項目,請參閱「建立內容感知分析」。
後續步驟
其他資訊
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求解答。