YARA-L 2.0 語言語法
本節說明 YARA-L 語法的主要元素。另請參閱 YARA-L 2.0 語言總覽。
規則結構
如果是 YARA-L 2.0,您必須依下列順序指定變數宣告、定義和用法:
- meta
- 直播
- 相符項目 (選填)
- 結果 (選填)
- 條件
- 選項 (選用)
以下範例說明規則的一般結構:
rule <rule Name>
{
meta:
// Stores arbitrary key-value pairs of rule details, such as who wrote
// it, what it detects on, version control, etc.
events:
// Conditions to filter events and the relationship between events.
match:
// Values to return when matches are found.
outcome:
// Additional information extracted from each detection.
condition:
// Condition to check events and the variables used to find matches.
options:
// Options to turn on or off while executing this rule.
}
中繼部分語法
中繼資料部分由多行組成,每行定義一個鍵/值組合。鍵部分必須是不含引號的字串,值部分則必須是含引號的字串:
<key> = "<value>"
以下是有效的 meta
區段行範例:
meta:
author = "Google"
severity = "HIGH"
「Events」區段語法
在 events
區段中,列出述詞來指定下列項目:
- 變數宣告
- 事件變數篩選器
- 事件變數聯結
變數宣告
如要宣告變數,請使用下列語法:
<EVENT_FIELD> = <VAR>
<VAR> = <EVENT_FIELD>
兩者效果相同,如下列範例所示:
$e.source.hostname = $hostname
$userid = $e.principal.user.userid
這項宣告表示這個變數代表事件變數的指定欄位。如果事件欄位是重複欄位,比對變數可以代表陣列中的任何值。您也可以將多個事件欄位指派給單一比對或預留位置變數。這是遞移聯結條件。
例如:
$e1.source.ip = $ip
$e2.target.ip = $ip
等同於:
$e1.source.ip = $ip
$e1.source.ip = $e2.target.ip
使用變數時,必須透過變數宣告來宣告變數。如果使用變數時未進行任何宣告,系統會將其視為編譯錯誤。
事件變數篩選器
對單一事件變數執行的布林運算式會視為篩選器。
事件變數聯結
規則中使用的所有事件變數都必須與其他事件變數合併,方法如下:
直接透過兩個已聯結事件變數的事件欄位進行相等比較,例如:
$e1.field = $e2.field
。運算式不得包含算術。間接透過只涉及事件欄位的遞移聯結 (如需「遞移聯結」的定義,請參閱變數宣告)。運算式不得包含算術。
舉例來說,假設規則中使用了 $e1、$e2 和 $e3,則下列 events
區段有效。
events:
$e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
$e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
// $e1 joins with $e2 via function to event comparison
re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
// $e1 joins with $e2 via an `or` expression
$e1.principal.hostname = $e2.src.hostname
or $e1.principal.hostname = $e2.target.hostname
or $e1.principal.hostname = $e2.principal.hostname
events:
// all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
$e1.src.ip = $ip
$e2.target.ip = $ip
$e3.about.ip = $ip
events:
// $e1 and $e2 are transitively joined via function to event comparison
re.capture($e2.principal.application, ".*") = $app
$e1.principal.hostname = $app
不過,以下是無效的 events
區段範例。
events:
// Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
$e1.principal.port = $e2.src.port + 1
events:
$e1.src.ip = $ip
$e2.target.ip = $ip
$e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
$e1.src.port = $port
// Arithmetic to placeholder comparison is an invalid transitive join condition.
$e2.principal.port + 800 = $port
比對區段語法
在 match
部分,列出群組事件的相符變數,然後檢查相符條件。系統會在每次比對時傳回這些欄位。
- 在
events
區段中,指定每個比對變數代表的內容。 - 在
over
關鍵字後方指定時間長度,用於關聯事件。系統會忽略時間範圍外的事件。 請使用下列語法指定時間長度:
<number><m/h/d>
其中
m/h/d
分別代表分鐘、小時和天數。最短時間為 1 分鐘。
最長可指定 48 小時。
以下是有效的 match
範例:
$var1, $var2 over 5m
當規則找到相符項目時,這項陳述式會傳回 $var1
和 $var2
(定義於 events
區段)。指定的時間為 5 分鐘。如果事件間隔超過 5 分鐘,系統就不會將其關聯,因此規則會忽略這些事件。
以下是有效 match
區段的另一個範例:
$user over 1h
規則找到相符項目時,這項陳述式會傳回 $user
。指定的時間範圍為 1 小時。如果事件間隔超過一小時,系統就不會將其相互關聯。規則不會將其視為偵測結果。
以下是有效 match
區段的另一個範例:
$source_ip, $target_ip, $hostname over 2m
如果規則找到相符項目,這個陳述式會傳回 $source_ip
、$target_ip
和 $hostname
。指定的時間範圍為 2 分鐘。如果事件間隔超過 2 分鐘,系統就不會將這些事件相互關聯。規則不會將其視為偵測結果。
以下範例說明無效的 match
區段:
var1, var2 over 5m // invalid variable name
$user 1h // missing keyword
比對區段中的零值處理方式
規則引擎會隱含地篩除比對區段中所有預留位置的零值 (字串為 ""
、數字為 0
、布林值為 false
,列舉型別則為位置 0 中的值)。以下範例說明如何使用規則篩除零值。
rule ZeroValuePlaceholderExample {
meta:
events:
// Because $host is used in the match section, the rule behaves
// as if the following predicate was added to the events section:
// $host != ""
$host = $e.principal.hostname
// Because $otherPlaceholder was not used in the match section,
// there is no implicit filtering of zero values for $otherPlaceholder.
$otherPlaceholder = $e.principal.ip
match:
$host over 5m
condition:
$e
}
不過,如果將預留位置指派給函式,規則就不會隱含地篩除比對區段中使用的預留位置零值。以下範例說明如何使用規則篩除零值:
rule ZeroValueFunctionPlaceholder {
meta:
events:
// Even though $ph is used in the match section, there is no
// implicit filtering of zero values for $ph, because $ph is assigned to a function.
$ph = re.capture($e.principal.hostname, "some-regex")
match:
$ph over 5m
condition:
$e
}
如要停用零值的隱含篩選,請使用選項部分中的 allow_zero_values
選項。
跳躍式時間區間
根據預設,系統會使用跳躍視窗評估含有相符區段的 YARA-L 2.0 規則。
規則的執行時間範圍會劃分為一組重疊的跳躍視窗,每個視窗的持續時間都由 match
區段指定。然後,系統會在每個躍點視窗中關聯事件。
舉例來說,如果規則在 [1:00, 2:00] 的時間範圍內執行,且 match
區段大於 30m
,則可能產生的一組重疊跳躍視窗為 [1:00, 1:30]、[1:03, 1:33] 和 [1:06, 1:36]。這些時間範圍可用於關聯多個事件。
滑動視窗
使用跳躍視窗無法有效搜尋以特定順序發生的事件 (例如 e1
發生在 e2
之後最多 2 分鐘)。只有在產生的相同跳躍視窗中發生事件 e1
和事件 e2
時,這兩個事件才會相互關聯。
如要更有效率地搜尋這類事件序列,請使用滑動視窗。
如果以指定的樞紐事件變數做為開始或結束時間,系統就會產生 match
區段中指定時間長度的滑動視窗。然後在每個滑動視窗中相互關聯。這樣一來,您就能搜尋以特定順序發生的事件 (例如 e1
在 e2
發生後的 2 分鐘內發生)。如果事件 e1
在事件 e2
發生後的滑動視窗時間長度內發生,則事件 e1
和事件 e2
的發生次數會相互關聯。
在規則的 match
區段中指定滑動視窗,如下所示:
<match-var-1>, <match-var-2>, ... over <duration> before|after <pivot-event-var>
樞紐事件變數是滑動視窗的依據事件變數。如果您使用 before
關鍵字,系統會產生滑動視窗,並以每個樞紐事件的發生時間做為結尾。如果使用 after
關鍵字,系統會從每個樞紐事件開始產生滑動視窗。
以下是有效使用滑動視窗的範例:
$var1, $var2 over 5m after $e1
$user over 1h before $e2
請參閱滑動視窗規則範例。
建議不要對單一事件規則使用滑動視窗,因為滑動視窗的設計目的是偵測多個事件。如果您的規則屬於這類,建議採取下列其中一種解決方法:
- 將規則轉換為使用多個事件變數,並在規則需要多次發生事件時,更新條件部分。
- 視需要考慮新增時間戳記篩選器,而非使用滑動時間範圍。
例如
$permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds
。
- 視需要考慮新增時間戳記篩選器,而非使用滑動時間範圍。
例如
- 取下滑動式視窗。
結果區段語法
在 outcome
區段中,您最多可以定義 20 個結果變數,並任意命名。這些結果會儲存在規則產生的偵測結果中。每次偵測的結果值可能不同。
結果名稱「$risk_score
」是特殊名稱,您可以選擇定義具有這個名稱的結果,如果定義,結果必須是整數或浮點數類型。如果已填寫,risk_score
會顯示在企業洞察檢視畫面中,用於來自規則偵測的快訊。
如果規則的結果部分未包含 $risk_score
變數,系統會設定下列其中一個預設值:
- 如果規則設定為產生快訊,則
$risk_score
會設為 40。 - 如果規則未設定為產生快訊,則
$risk_score
會設為 15。
$risk_score
的值會儲存在 security_result.risk_score
UDM 欄位中。
結果變數資料類型
每個結果變數可以有不同的資料類型,這取決於用於計算結果變數的運算式。我們支援下列結果資料類型:
- 整數
- 浮動
- 字串
- 整數清單
- 浮點數清單
- 字串清單
條件式邏輯
您可以使用條件式邏輯計算結果的值。條件式 是使用下列語法模式指定:
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 rule.
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 rule 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 rule 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 above 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 個值 (即純量值)。
同樣地,在具有比對時間範圍的規則結果部分中,使用的非重複事件欄位和重複事件欄位都是非純量值。舉例來說,下列規則會使用比對區段將事件分組,並在結果區段中參照非重複事件欄位:
rule OutcomeAndMatchWindow{
...
match:
$userid over 5m
outcome:
$hostnames = array($e.principal.hostname)
...
}
規則執行的任何 5 分鐘時間範圍,可能包含零個、一個或多個事件。結果部分會處理相符視窗中的所有事件。在結果部分中參照的任何事件欄位變數,都可以在比對視窗中,指向每個事件的零個、一個或多個欄位值。舉例來說,如果 5 分鐘的時間範圍內有 5 個 $e
事件,結果部分會顯示 5 個不同的主機名稱。$e.principal.hostname
系統會將事件欄位變數
$e.principal.hostname
視為這項規則 outcome
區段中的非純量值。
由於結果變數一律必須產生單一純量值,因此結果指派作業所依據的任何非純量值,都必須經過彙整,才能產生單一純量值。在結果部分中,下列為非純量值,必須經過彙整:
- 規則使用相符區段時的事件欄位 (重複或非重複)
- 規則使用比對區段時的活動預留位置 (重複或非重複)
- 規則未使用比對區段時,重複的事件欄位
- 規則未使用相符區段時,重複的活動預留位置
在不含比對部分的規則中,純量事件欄位、純量事件預留位置和常數可以包裝在彙整函式中。不過在大多數情況下,這些匯總會傳回包裝值,因此沒有必要。例外狀況是 array()
匯總,您可以使用這項匯總將純量值明確轉換為陣列。
結果變數會視為匯總資料,因此在其他結果指派中參照時,不得重新匯總。
您可以使用下列匯總函式:
max()
:輸出所有可能值的最大值。僅適用於整數和浮點數。min()
:輸出所有可能值的最小值。僅適用於整數和浮點數。sum()
:輸出所有可能值的總和。僅適用於整數和浮點數。count_distinct()
:收集所有可能的值,然後輸出可能值的不同計數。count()
:行為與count_distinct()
類似,但會傳回可能值的非相異計數。array_distinct()
:收集所有可能的不重複值,然後輸出這些值的清單。系統會將不重複值清單截斷為 25 個隨機元素。系統會先套用去重複程序,取得不重複的清單,然後再套用截斷程序。array()
:行為與array_distinct()
類似,但會傳回不重複的值清單。此外,也會將值清單截斷為 25 個隨機元素。period_start_for_max()
:列出值達到最大值時的時間範圍開頭。period_start_for_min()
:列出值達到最低點的時間範圍開頭。
如果規則包含 condition
區段,且該區段指定必須存在多個事件,則匯總函式就非常重要,因為匯總函式會對產生偵測結果的所有事件執行運算。
舉例來說,如果 outcome
和 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
由於條件部分需要每個偵測項目有多個 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
」部分關聯的事件變數。當不同事件變數的兩個事件欄位相等時,就會發生關聯。
如需使用結果部分的範例,請參閱「YARA-L 2.0 總覽」。如要瞭解如何使用結果部分偵測及重複資料刪除,請參閱「建立情境感知分析」。
條件區段語法
- 指定在
events
區段中定義的事件和預留位置比對條件。詳情請參閱下一節「事件和預留位置條件」。 - (選用) 使用
and
關鍵字,透過outcome
區段中定義的結果變數指定比對條件。詳情請參閱下節「結果條件」。
計算字元
#
字元是 condition
區段中的特殊字元。如果是在任何事件或預留位置變數名稱之前使用,則代表滿足所有 events
區段條件的不同事件或值數量。
舉例來說,#c > 1
表示變數 c
必須出現超過 1 次。
值字元
$
字元是 condition
區段中的特殊字元。如果這個符號出現在任何結果變數名稱之前,則代表該結果的值。
如果這個字元出現在任何事件或預留位置變數名稱之前 (例如 $event
),則代表 #event > 0
。
活動和預留位置條件
使用 and
或 or
關鍵字,列出事件和預留位置變數的條件述詞。您可以使用 and
連結任意條件組合;
不過,只有在所有條件都參照相同事件變數時,才能使用 or
。
以下是使用 or
的有效範例,在同一事件的兩個預留位置之間:
rule ValidConditionOr {
meta:
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
// Note that all placeholders use the same event variable.
$ph = $e.principal.user.userid // Define a placeholder variable to put in match section.
$ph2 = $e.principal.ip // Define a second placeholder variable to put in condition section.
$ph3 = $e.principal.hostname // Define a third placeholder variable to put in condition section.
match:
$ph over 5m
condition:
$ph2 or $ph3
}
以下是無效範例,說明如何在不同事件的兩個條件之間使用 or
:
rule InvalidConditionOr {
meta:
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
$e2.graph.metadata.entity_type = "FILE"
$e2.graph.entity.hostname = $e.principal.hostname
$ph = $e.principal.user.userid // Define a placeholder variable to put in match section.
match:
$ph over 5m
condition:
$e or $e2 // This line will cause an error because there is an or between events.
}
受限和不受限的條件
下列條件為有界條件。這類規則會強制存在相關聯的事件變數,也就是說,任何偵測結果都必須至少出現一次事件。
$var // equivalent to #var > 0
#var > n // where n >= 0
#var >= m // where m > 0
下列條件是不受限的條件。這類變數可讓相關聯的事件變數不存在,也就是說,偵測結果可能不會顯示任何事件發生次數,且對事件變數中欄位的任何參照都會產生零值。無界限條件可用於偵測一段時間內是否沒有發生事件。舉例來說,如果威脅事件在 10 分鐘內沒有緩解事件,使用無界條件的規則稱為不存在規則。
!$var // equivalent to #var = 0
#var >= 0
#var < n // where n > 0
#var <= m // where m >= 0
不存在的規定
如要編譯不存在的規則,必須符合下列規定:
- 至少一個 UDM 事件必須有界限條件 (也就是至少要有一個 UDM 事件)。
- 如果預留位置有不設限的條件,則必須與至少一個設限的 UDM 事件建立關聯。
- 如果實體具有無界限條件,則必須與至少一個有界限的 UDM 事件建立關聯。
請參考下列規則,其中省略了條件部分:
rule NonexistenceExample {
meta:
events:
$u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
$u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
$e1.graph.metadata.entity_type = "FILE" // $e1 is an Entity.
$e2.graph.metadata.entity_type = "FILE" // $e2 is an Entity.
$user = $u1.principal.user.userid // Match variable is required for Multi-Event Rule.
// Placeholder Associations:
// u1 u2
// | \ /
// port ip
// | \
// e1 e2
$u1.target.port = $port
$e1.graph.entity.port = $port
$u1.principal.ip = $ip
$u2.target.ip = $ip
$e2.graph.entity.ip = $ip
// UDM-Entity Associations:
// u1 - u2
// | \ |
// e1 e2
$u1.metadata.event_type = $u2.metadata.event_type
$e1.graph.entity.hostname = $u1.principal.hostname
$e2.graph.entity.hostname = $u1.target.hostname
$e2.graph.entity.hostname = $u2.principal.hostname
match:
$user over 5m
condition:
<condition_section>
}
以下是 <condition_section>
的有效範例:
$u1 and !$u2 and $e1 and $e2
- 條件部分會顯示所有 UDM 事件和實體。
- 至少有一個 UDM 事件受到限制。
$u1 and !$u2 and $e1 and !$e2
$e2
不受限制,但由於與受限的$u1
相關聯,因此允許使用。如果$e2
未與$u1
建立關聯,則無效。
#port > 50 and #ip = 0
- 條件部分沒有 UDM 事件和實體,但現有的預留位置涵蓋所有 UDM 事件和實體。
$ip
同時指派給$u1
和$u2
,且#ip = 0
是無界限條件。不過,有界條件比無界條件更嚴格。由於$port
已指派給$u1
,且#port > 50
是有界條件,因此$u1
仍是有界條件。
以下是 <condition_section>
的無效範例:
$u1 and $e1
- 「事件」部分中顯示的每個 UDM 事件和實體,都必須出現在「條件」部分中 (或已指派給出現在「條件」部分的預留位置)。
$u1, $u2, $e1, $u2, #port > 50
- 條件分隔符號不得使用半形逗號。
!$u1 and !$u2 and $e1 and $e2
- 違反第一項規定,即至少要繫結一個 UDM 事件。
($u1 or #port < 50) and $u2 and $e1 and $e2
- 無界條件不支援
or
關鍵字。
- 無界條件不支援
($u1 or $u2) and $e1 and $e2
- 不同事件變數之間不支援
or
關鍵字。
- 不同事件變數之間不支援
not $u1 and $u2 and $e1 and $e2
not
關鍵字不適用於事件和預留位置條件。
#port < 50 and #ip = 0
- 現有的預留位置涵蓋所有 UDM 事件和實體,但所有條件都不受限制。也就是說,沒有任何 UDM 事件受到限制,導致規則無法編譯。
結果條件
在此列出結果變數的條件述詞,並以 and
或 or
關鍵字加入,或以 not
關鍵字開頭。
視結果變數類型而定,指定結果條件的方式也不同:
整數:使用
=, >, >=, <, <=, !=
運算子與整數常值比較,例如:$risk_score > 10
float:使用
=, >, >=, <, <=, !=
運算子與浮點常值比較,例如:$risk_score <= 5.5
string:使用
=
或!=
與字串常值比較,例如:$severity = "HIGH"
整數或陣列清單:使用
arrays.contains
函式指定條件,例如:arrays.contains($event_ids, "id_1234")
規則分類
在含有相符區段的規則中指定結果條件,表示該規則會歸類為規則配額的多重事件規則。 如要進一步瞭解單一和多重事件分類,請參閱單一事件規則和多重事件規則。
「選項」專區語法
在「規則」options
部分,您可以指定規則的選項。以下範例說明如何指定選項部分:
rule RuleOptionsExample {
// Other rule sections
options:
allow_zero_values = true
}
您可以使用 key = value
語法指定選項,其中 key
必須是預先定義的選項名稱,而 value
必須是選項的有效值,如下列選項所示:
allow_zero_values
這個選項的有效值為 true
和 false
,可決定是否啟用這個選項。預設值為 false
。如果規則中未指定這個選項,系統會停用此選項。
如要啟用這項設定,請在規則的選項部分新增以下內容:allow_zero_values = true
。這麼做可避免規則隱含地篩除比對區段中使用的預留位置零值,詳情請參閱比對區段中的零值處理方式。
suppression_window
suppression_window
選項可讓你控制規則觸發偵測的頻率。即使規則條件多次符合,系統也不會在指定時間範圍內,針對同一規則產生多個偵測項目。抑制時間區間設定會採用滾動式時間區間方法,在固定大小的非重疊時間區間內抑制重複項目。
您可以選擇提供 suppression_key
,進一步縮小範圍,在抑制時間範圍內抑制哪些規則例項。如未指定,系統會抑制所有規則例項。這個鍵定義為結果變數。
在下列範例中,suppression_window
會設為 5m
,而 suppression_key
會設為 $hostname
變數。規則觸發 $hostname
的偵測項目後,接下來五分鐘內,系統會抑制 $hostname
的任何後續偵測項目。不過,如果規則因主機名稱不同的事件而觸發,系統就會建立偵測結果。
suppression_window
的預設值為 0
,也就是預設停用抑制視窗。這個選項只適用於沒有 match
區段的單一事件規則。
範例:
rule SuppressionWindowExample {
// Other rule sections
outcome:
$suppression_key = $hostname
options:
suppression_window = 5m
}
複合偵測規則
Google SecOps 中的複合式偵測功能會連結多個 YARA-L 規則。本節說明如何建構複合規則。如要瞭解複合偵測項目的總覽,請參閱複合偵測項目總覽。
規則結構
複合偵測規則一律為多重事件規則,並遵循相同的結構和語法。 複合式偵測規則須符合下列規定:
- 複合規則必須使用
match
區段定義偵測觸發條件。 - 如果規則同時使用偵測欄位和 UDM 事件,就必須明確彙整這些資料來源。
如要瞭解規則限制,請參閱「限制」一節。
將偵測結果做為規則的輸入內容
複合規則可以參照任何自訂或精選規則產生的規則偵測結果。Google SecOps 提供兩種方法。
使用結果變數、比對變數或中繼標籤,參照偵測到的內容
如要存取偵測結果中的資料,但不想參照原始 UDM 事件,請使用 outcome
變數、match
變數或 meta
標籤。建議採用這種做法,因為這樣做彈性較大,且與不同規則類型相容性較佳。
舉例來說,如果您要在不同情境中尋找字串,多項規則可以將字串 (例如網址、檔案名稱或登錄機碼) 儲存在通用 outcome
變數中。如要從複合規則存取這個字串,請從 detection
開始,然後使用集合資源中的元素找出相關資訊。
示例: 舉例來說,假設偵測規則產生下列資訊:
- 結果變數:
dest_domain = "cymbal.com"
- UDM 欄位:
target.hostname = "cymbal.com"
在複合規則中,您可以使用下列路徑存取這項資料:
detection.detection.outcomes["dest_domain"]
存取dest_domain
結果變數。detection.collection_elements.references.event.target.hostname
存取target.hostname
UDM 欄位。detection.time_window.start_time.seconds
即可存取偵測時間戳記。
Collection API 和 SecurityResult
API 可存取下列兩項資源:
- 偵測中繼資料和結果值 (
detection.detection
) - 參照規則的基礎 UDM 事件 (
collection_elements
)
使用規則 ID 或規則名稱參照偵測內容
您可以依規則名稱或 ID 參照規則。如果偵測邏輯取決於特定規則,建議採用這種做法。依名稱或 ID 參照相關規則,可減少分析的資料量,進而提升效能並避免逾時。舉例來說,您可以直接從已知的先前偵測結果查詢 target.url
或 principal.ip
等欄位。
依規則 ID 參照規則 (建議):使用
detection.detection.rule_id
欄位依 ID 參照規則。您可以在 Google SecOps 中規則的網址中找到規則 ID。使用者產生的規則 ID 格式為ru_UUID
,而精選偵測項目的 ID 格式為ur_UUID
。例如:detection.detection.rule_id = "ru_e0d3f371-6832-4d20-b0ad-1f4e234acb2b"
依規則名稱參照規則:使用
detection.detection.rule_name
欄位依名稱參照規則。您可以指定確切的規則名稱,或使用規則運算式比對。例如:detection.detection.rule_name = "My Rule Name"
detection.detection.rule_name = "/PartOfName/"
注意:建議使用規則 ID 進行參照,因為 ID 是不重複的,而且不會變更。規則名稱可以修改,但可能會導致複合式偵測中斷。
合併事件和偵測結果
複合規則可以結合不同的資料來源,包括 UDM 事件、實體圖表資料和偵測欄位。須符合下列規範:
- 為每個來源使用不同的變數:為每個資料來源指派專屬事件變數 (例如事件的
$e
、偵測的$d
),其中資料來源包括事件、實體和偵測。 - 根據共用環境加入來源:使用規則條件中的使用者 ID、IP 位址或網域名稱等通用值,連結資料來源。
- 定義比對時間範圍:請務必加入
match
子句,且時間範圍不得超過 48 小時。
例如:
rule CheckCuratedDetection_with_EDR_and_EG {
meta:
author = "noone@cymbal.com"
events:
$d.detection.detection.rule_name = /SCC: Custom Modules: Configurable Bad Domain/
$d.detection.collection_elements.references.event.network.dns.questions.name = $domain
$d.detection.collection_elements.references.event.principal.asset.hostname = $hostname
$e.metadata.log_type = "LIMACHARLIE_EDR"
$e.metadata.product_event_type = "NETWORK_CONNECTIONS"
$domain = re.capture($e.principal.process.command_line, "\\s([a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+)$")
$hostname = re.capture($e.principal.hostname, "([^.]*)")
$prevalence.graph.metadata.entity_type = "DOMAIN_NAME"
$prevalence.graph.metadata.source_type = "DERIVED_CONTEXT"
$prevalence.graph.entity.hostname = $domain
$prevalence.graph.entity.domain.prevalence.day_count = 10
$prevalence.graph.entity.domain.prevalence.rolling_max <= 5
$prevalence.graph.entity.domain.prevalence.rolling_max > 0
match:
$hostname over 1h
outcome:
$risk_score = 80
$CL_target = array($domain)
condition:
$e and $d and $prevalence
}
建立連續複合偵測項目
連續複合式偵測會找出相關事件的模式,偵測順序非常重要,例如偵測到暴力登入嘗試,接著登入成功。這些模式可結合多個基本偵測結果、原始 UDM 事件,或兩者兼具。
如要建立循序複合式偵測,您必須在規則中強制執行該順序。如要強制執行預期順序,請使用下列其中一種方法:
- 滑動視窗:在
match
條件中使用滑動視窗定義偵測順序。 - 時間戳記比較:比較規則邏輯中偵測結果的時間戳記,確認這些結果是否按照所選順序發生。
例如:
events:
$d1.detection.detection.rule_name = "fileEvent_rule"
$userid = $d1.detection.detection.outcomes["user"]
$hostname = $d1.detection.detection.outcomes["hostname"]
$d2.detection.detection.rule_name = "processExecution_rule"
$userid = $d2.detection.detection.outcomes["user"]
$hostname = $d2.detection.detection.outcomes["hostname"]
$d3.detection.detection.rule_name = "networkEvent_rule"
$userid = $d3.detection.detection.outcomes["user"]
$hostname = $d3.detection.detection.outcomes["hostname"]
$d3.detection.collection_elements.references.event.metadata.event_timestamp.seconds > $d2.detection.collection_elements.references.event.metadata.event_timestamp.seconds
match:
$userid over 24h after $d1
布林運算式
布林運算式是布林型別的運算式。
比較
如要將二元運算式做為條件,請使用下列語法:
<EXPR> <OP> <EXPR>
運算式可以是事件欄位、變數、常值或函式運算式。
例如:
$e.source.hostname = "host1234"
$e.source.port < 1024
1024 < $e.source.port
$e1.source.hostname != $e2.target.hostname
$e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
$port >= 25
$host = $e2.target.hostname
"google-test" = strings.concat($e.principal.hostname, "-test")
"email@google.org" = re.replace($e.network.email.from, "com", "org")
如果兩側都是常值,則視為編譯錯誤。
函式
部分函式運算式會傳回布林值,可用做 events
區段中的個別述詞。這類函式包括:
re.regex()
net.ip_in_range_cidr()
例如:
re.regex($e.principal.hostname, `.*\.google\.com`)
net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
參照清單運算式
您可以在「事件」部分使用參照清單。詳情請參閱參考清單一節。
邏輯運算式
您可以在 events
區段中使用邏輯 and
和邏輯 or
運算子,如下列範例所示:
$e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
not $e.metadata.event_type = "NETWORK_DNS"
根據預設,優先順序從高到低依序為 not
、and
、or
。
舉例來說,如果運算式中明確定義了 or
和 and
運算子,「a or b and c」會評估為「a or (b and c)」。
在 events
區段中,如果未明確定義運算子,系統會使用 and
運算子聯結述詞。
如果運算式中隱含 and
運算子,評估順序可能會有所不同。
舉例來說,請看下列比較運算式,其中 or
是明確定義。系統會默示使用 and
運算子。
$e1.field = "bat"
or $e1.field = "baz"
$e2.field = "bar"
這個範例的解讀方式如下:
($e1.field = "bat" or $e1.field = "baz")
and ($e2.field = "bar")
由於 or
是明確定義的,因此系統會先將 or
周圍的述詞分組並評估。最後一個述詞 $e2.field = "bar"
會使用 and
隱含聯結。因此評估順序會有所變更。
列舉型別
您可以在列舉型別中使用運算子。這項功能可套用至規則,簡化及最佳化成效 (使用運算符而非參照清單)。
在下列範例中,「USER_UNCATEGORIZED」和「USER_RESOURCE_DELETION」分別對應 15000 和 15014,因此規則會尋找所有列出的事件:
$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"
活動清單:
- USER_RESOURCE_DELETION
- USER_RESOURCE_UPDATE_CONTENT
- USER_RESOURCE_UPDATE_PERMISSIONS
- USER_STATS
- USER_UNCATEGORIZED
Nocase 修飾符
如果您有字串值或規則運算式之間的比較運算式,可以在運算式結尾附加 nocase,忽略大小寫。
$e.principal.hostname != "http-server" nocase
$e1.principal.hostname = $e2.target.hostname nocase
$e.principal.hostname = /dns-server-[0-9]+/ nocase
re.regex($e.target.hostname, `client-[0-9]+`) nocase
如果欄位類型是列舉值,則無法使用這項功能。下列範例無效,會產生編譯錯誤:
$e.metadata.event_type = "NETWORK_DNS" nocase
$e.network.ip_protocol = "TCP" nocase
重複欄位
在整合式資料模型 (UDM) 中,部分欄位標示為重複,表示這些欄位是值清單或其他類型的訊息。
重複欄位和布林運算式
有 2 種布林運算式可對重複欄位執行動作:
- 已修改
- 未修改
請參考下列事件:
event_original {
principal {
// ip is a repeated field
ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]
hostname: "host"
}
}
已修改的運算式
以下章節說明運算式中 any
和 all
修飾符的用途和使用方式。
不限
如果重複欄位的任何元素符合條件,則整個事件都符合條件。
event_original
滿足any $e.principal.ip = "192.0.2.1"
。event_original
失敗any $e.repeated_field.field_a = "9.9.9.9
。
全部
如果重複欄位的所有元素都符合條件,則事件整體符合條件。
event_original
滿足net.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8")
。event_original
失敗all $e.principal.ip = "192.0.2.2"
。
使用 any
或 all
編寫條件時,請注意以 not
否定條件,可能與使用否定運算子意義不同。
例如:
not all $e.principal.ip = "192.168.12.16"
會檢查是否所有 IP 位址都符合192.168.12.16
,也就是檢查至少有一個 IP 位址不符合192.168.12.16
。all $e.principal.ip != "192.168.12.16"
會檢查所有 IP 位址是否不符合192.168.12.16
,也就是檢查是否有任何 IP 位址符合192.168.12.16
。
限制:
any
和all
運算子僅適用於重複欄位 (不適用於純量欄位)。any
和all
無法用於合併兩個重複欄位。舉例來說,any $e1.principal.ip = $e2.principal.ip
是無效。- 參考清單運算式不支援
any
和all
運算子。
未修改的運算式
如果運算式未經修改,系統會個別處理重複欄位中的每個元素。如果事件的重複欄位包含 n 個元素,系統會將規則套用至 n 個事件副本,每個副本都有重複欄位中的其中一個元素。這些副本是暫時性的,不會儲存。
這項規則會套用至下列副本:
活動副本 | principal.ip | principal.hostname |
---|---|---|
event_copy_1 | 「192.0.2.1」 | 「主機」 |
event_copy_2 | 「192.0.2.2」 | 「主機」 |
event_copy_3 | 「192.0.2.3」 | 「主機」 |
如果任何事件副本符合重複欄位中的所有未修改條件,則該事件整體符合所有條件。也就是說,如果重複欄位有多個條件,事件副本必須符合「所有」條件。下列規則範例會使用上述範例資料集,示範這項行為。
針對 event_original
範例資料集執行下列規則時,系統會傳回一個相符項目,因為 event_copy_1
符合所有事件述詞:
rule repeated_field_1 {
meta:
events:
net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/8") // Checks if IP address matches 192.x.x.x
$e.principal.ip = "192.0.2.1"
condition:
$e
}
針對 event_original
範例資料集執行下列規則時,不會傳回相符項目,因為 $e.principal.ip
中沒有符合「所有」事件述詞的事件副本。
rule repeated_field_2 {
meta:
events:
$e.principal.ip = "192.0.2.1"
$e.principal.ip = "192.0.2.2"
condition:
$e
}
重複欄位中的修改運算式與未修改的運算式相容,因為每個事件副本的元素清單都相同。請參考以下規則:
rule repeated_field_3 {
meta:
events:
any $e.principal.ip = "192.0.2.1"
$e.principal.ip = "192.0.2.3"
condition:
$e
}
這項規則會套用至下列副本:
活動副本 | principal.ip | any $e.principal.ip |
---|---|---|
event_copy_1 | 「192.0.2.1」 | ["192.0.2.1", "192.0.2.2", "192.0.2.3"] |
event_copy_2 | 「192.0.2.2」 | ["192.0.2.1", "192.0.2.2", "192.0.2.3"] |
event_copy_3 | 「192.0.2.3」 | ["192.0.2.1", "192.0.2.2", "192.0.2.3"] |
在本例中,所有副本都符合 any $e.principal.ip = "192.0.2.1"
,但只有 event_copy_3
符合 $e.principal.ip = "192.0.2.3"。因此,整個活動會相符。
這些運算式類型也可以這樣理解:
- 使用
any
或all
的重複欄位運算式會在event_original
的清單上運作。 - 重複欄位中未使用
any
或all
的運算式,會對個別event_copy_n
事件執行運算。
重複欄位和預留位置
重複欄位可搭配預留位置指派作業使用。與重複欄位中未修改的運算式類似,系統會為每個元素建立事件副本。以 event_copy
為例,預留位置會取得 event_copy_n
的重複欄位值,其中 n 是事件副本編號。如果預留位置用於比對區段,可能會導致多個比對結果。
以下範例會產生一個相符項目。$ip
預留位置等於 event_copy_1
的 event_copy_1
,符合規則中的述詞。192.0.2.1
相符項目的事件樣本包含單一元素 event_original
。
// Generates 1 match.
rule repeated_field_placeholder1 {
meta:
events:
$ip = $e.principal.ip
$ip = "192.0.2.1"
$host = $e.principal.hostname
match:
$host over 5m
condition:
$e
}
下列範例會產生三筆相符項目。$ip
預留位置等於不同值,適用於每個不同的 event_copy_n
副本。分組程序是按照 $ip
執行,因為該項目位於比對區段。因此,您會得到三筆相符項目,每筆相符項目的$ip
相符變數值都不同。每個相符項目都有相同的事件樣本:單一元素 event_original
。
// Generates 3 matches.
rule repeated_field_placeholder2 {
meta:
events:
$ip = $e.principal.ip
net.ip_in_range_cidr($ip, "192.0.2.0/8") // Checks if IP matches 192.x.x.x
match:
$ip over 5m
condition:
$e
}
指派給重複欄位的預留位置結果
系統會為每個重複欄位的每個元素指派預留位置,而非整個清單。因此,當這些元素用於結果部分時,系統只會使用滿足先前部分的元素來計算結果。
請參考以下規則:
rule outcome_repeated_field_placeholder {
meta:
events:
$ip = $e.principal.ip
$ip = "192.0.2.1" or $ip = "192.0.2.2"
$host = $e.principal.hostname
match:
$host over 5m
outcome:
$o = array_distinct($ip)
condition:
$e
}
這項規則的執行作業分為 4 個階段。第一階段是複製事件:
活動副本 | $ip | $host | $e |
---|---|---|---|
event_copy_1 | 「192.0.2.1」 | 「主機」 | event_id |
event_copy_2 | 「192.0.2.2」 | 「主機」 | event_id |
event_copy_3 | 「192.0.2.3」 | 「主機」 | event_id |
事件部分隨即會濾除不符合篩選條件的資料列:
活動副本 | $ip | $host | $e |
---|---|---|---|
event_copy_1 | 「192.0.2.1」 | 「主機」 | event_id |
event_copy_2 | 「192.0.2.2」 | 「主機」 | event_id |
event_copy_3
已遭篩除,因為 "192.0.2.3"
不符合 $ip = "192.0.2.1" or $ip = "192.0.2.2"
。
然後,比對部分會依比對變數分組,結果部分則會對每個群組執行匯總:
$host | $o | $e |
---|---|---|
「主機」 | ["192.0.2.1", "192.0.2.2"] | event_id |
$o = array_distinct($ip)
是使用前一階段的 $ip
計算得出,而非事件複製階段。
最後,條件區段會篩選每個群組。由於這項規則只會檢查 $e 是否存在,因此先前資料列會產生單一偵測結果。
$o
未包含 $e.principal.ip
中的所有元素,因為並非所有元素都符合事件部分的所有條件。不過,由於事件範例使用 event_original
,因此 e.principal.ip
的所有元素都會顯示在事件範例中。
陣列索引
您可以對重複欄位執行陣列索引編製作業。如要存取第 n 個重複欄位元素,請使用標準清單語法 (元素以 0 為索引)。超出界限的元素會傳回預設值。
$e.principal.ip[0] = "192.168.12.16"
$e.principal.ip[999] = ""
如果元素少於 1000 個,則評估結果為true
。
限制:
- 索引必須是非負整數常值。舉例來說,
$e.principal.ip[-1]
是無效。 - 如果值為
int
類型 (例如設為int
的預留位置),則不計入。 - 陣列索引無法與
any
或all
合併使用。舉例來說,any $e.intermediary.ip[0]
是無效。 - 陣列索引無法與對應語法合併使用。舉例來說,
$e.additional.fields[0]["key"]
是無效。 - 如果欄位路徑包含多個重複欄位,所有重複欄位都必須使用陣列索引。舉例來說,
$e.intermediary.ip[0]
無效,因為intermediary
和ip
都是重複欄位,但只有ip
有索引。
重複訊息
重複 message
欄位會產生非預期的效果,降低比對成功的可能性。如以下範例所示。
請參考下列事件:
event_repeated_message {
// about is a repeated message field.
about {
// ip is a repeated string field.
ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]
hostname: "alice"
}
about {
hostname: "bob"
}
}
如重複欄位中未修改的運算式所述,系統會為重複欄位的每個元素建立事件的暫時副本。請參考以下規則:
rule repeated_message_1 {
meta:
events:
$e.about.ip = "192.0.2.1"
$e.about.hostname = "bob"
condition:
$e
}
這項規則會套用至下列副本:
活動副本 | about.ip | about.hostname |
---|---|---|
event_copy_1 | 「192.0.2.1」 | "alice" |
event_copy_2 | 「192.0.2.2」 | "alice" |
event_copy_3 | 「192.0.2.3」 | "alice" |
event_copy_4 | "" | "bob" |
由於沒有任何事件副本符合所有運算式,因此事件不符合規則。
重複訊息和陣列索引
如果對重複訊息欄位使用陣列索引,且未修改運算式,也可能發生非預期行為。請參考下列使用陣列索引的規則範例:
rule repeated_message_2 {
meta:
events:
$e.about.ip = "192.0.2.1"
$e.about[1].hostname = "bob"
condition:
$e
}
這項規則會套用至下列副本:
活動副本 | about.ip | about[1].hostname |
---|---|---|
event_copy_1 | 「192.0.2.1」 | "bob" |
event_copy_2 | 「192.0.2.2」 | "bob" |
event_copy_3 | 「192.0.2.3」 | "bob" |
event_copy_4 | "" | "bob" |
由於 event_copy_1
滿足 repeated_message_2
中的所有運算式,因此事件符合規則。
這可能會導致非預期的行為,因為規則 repeated_message_1
缺少陣列索引,因此沒有產生任何相符項目,而規則 repeated_message_2
使用陣列索引,因此產生相符項目。
註解
使用兩個斜線字元 (// comment
) 指定註解,或使用斜線星號字元 (/* comment */
) 設定多行註解,就像在 C 中一樣。
文字
支援非負整數和浮點數、字串、布林值和規則運算式常值。
字串和規則運算式常值
您可以使用下列任一引號字元,在 YARA-L 2.0 中括住字串。不過,引號文字的解讀方式會因使用的引號而異。
雙引號 (「"」):用於一般字串。必須包含逸出字元。
例如:「hello\tworld」—\t 會解讀為 Tab 鍵左引號 (`):用於以常值解讀所有字元。
例如:`hello\tworld` - \t 不會解讀為 Tab 鍵
規則運算式有兩種做法。
如要直接使用規則運算式,而不使用 re.regex()
函式,請使用 /regex/
做為規則運算式常值。
使用 re.regex()
函式時,您也可以將字串常值做為規則運算式常值。請注意,如果是雙引號字串常值,您必須使用反斜線字元逸出反斜線字元,這可能看起來很奇怪。
舉例來說,下列規則運算式的作用相同:
re.regex($e.network.email.from, `.*altostrat\.com`)
re.regex($e.network.email.from, ".*altostrat\\.com")
$e.network.email.from = /.*altostrat\.com/
Google 建議在規則運算式中使用反引號字元表示字串,方便閱讀。
運算子
您可以在 YARA-L 中使用下列運算子:
運算子 | 說明 |
= | equal/declaration |
!= | 不等於 |
< | 小於 |
<= | 小於或等於 |
> | 大於 |
>= | 大於或等於 |
變數
在 YARA-L 2.0 中,所有變數都會以 $<variable name>
表示。
您可以定義下列類型的變數:
事件變數:以標準化形式 (UDM) 或實體事件表示事件群組。在「條件」部分指定事件變數的條件。
events
您可以使用名稱、事件來源和事件欄位來識別事件變數。允許的來源為udm
(適用於標準化事件) 和graph
(適用於實體事件)。如果省略來源,系統會將udm
設為預設來源。事件欄位會以 .<欄位名稱> 鏈結表示 (例如 $e.field1.field2)。事件欄位鏈結一律從頂層來源 (UDM 或實體) 開始。比對變數 - 在
match
區段中宣告。比對變數會成為查詢的分組欄位,因為系統會針對每個不重複的比對變數組合 (以及每個時間範圍) 傳回一列。如果規則找到相符項目,就會傳回相符變數值。在events
區段中,指定每個比對變數代表的內容。預留位置變數:在
events
區段中宣告及定義。預留位置變數與比對變數類似,不過,您可以在condition
區段中使用預留位置變數,指定相符條件。
使用比對變數和預留位置變數,透過遞移聯結條件宣告事件欄位之間的關係 (詳情請參閱「事件區段語法」)。
關鍵字
YARA-L 2.0 中的關鍵字不區分大小寫。例如 and
和 AND
是等效的。變數名稱不得與關鍵字衝突。例如,$AND
或 $outcome
無效。
偵測引擎規則的關鍵字如下:rule
、meta
、match
、over
、events
、condition
、outcome
、options
、and
、or
、not
、nocase
、in
、regex
、cidr
、before
、after
、all
、any
、if
、max
、min
、sum
、array
、array_distinct
、count
、count_distinct
、is
和 null
。
地圖
YARA-L 支援結構和標籤的地圖存取權。
結構和標籤
部分 UDM 欄位會使用「Struct」或「Label」資料類型。
如要在 Struct 和 Label 中搜尋特定鍵/值組合,請使用標準對應語法:
// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"
地圖存取權一律會傳回字串。
支援的案件
以下是支援的關鍵字用途。
活動和結果部分
// Using a Struct field in the events section
events:
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// Using a Label field in the outcome section
outcome:
$value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
將對應值指派給預留位置
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
在聯結條件中使用對應欄位
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]
不支援的案例
地圖不支援下列情況。
將 any
或 all
關鍵字與地圖合併
舉例來說,系統不支援下列項目:
all $e.udm.additional.fields["pod_name"] = "kube-scheduler"
其他類型的值
對應語法只能傳回字串值。如果是 Struct 資料類型,地圖語法只能存取值為字串的鍵。您無法存取值為整數等其他原始型別的鍵。
重複值處理方式
地圖存取權一律會傳回單一值。在罕見的極端情況下,地圖存取權可能參照多個值,地圖存取權會確定傳回第一個值。
這可能發生於下列情況:
標籤含有重複的鍵。
標籤結構代表對應,但不會強制執行鍵的唯一性。 按照慣例,地圖應具有不重複的鍵,因此 Google SecOps 不建議使用重複的鍵填入標籤。
如果對下列資料範例執行規則文字
$e.metadata.ingestion_labels["dupe-key"]
,會傳回第一個可能的值val1
:// Disrecommended usage of label with a duplicate key: event { metadata{ ingestion_labels{ key: "dupe-key" value: "val1" // This is the first possible value for "dupe-key" } ingestion_labels{ key: "dupe-key" value: "val2" } } }
標籤有重複的祖先欄位。
重複欄位可能包含標籤做為子項欄位。頂層重複欄位中的兩個不同項目可能含有索引鍵相同的標籤。如果對下列資料範例執行規則文字
$e.security_result.rule_labels["key"]
,則會傳回第一個可能的值val3
:event { // security_result is a repeated field. security_result { threat_name: "threat1" rule_labels { key: "key" value: "val3" // This is the first possible value for "key" } } security_result { threat_name: "threat2" rule_labels { key: "key" value: "val4" } } }
函式
本節說明可在偵測引擎規則和搜尋中使用的 YARA-L 2.0 函式。
這些函式可用於 YARA-L 規則的下列部分:
events
部分。BOOL_CLAUSE
,即可在結果部分中查看條件。
arrays.concat
arrays.concat(string_array, string_array)
說明
複製原始字串陣列中的元素,然後傳回新的字串陣列。
參數資料類型
ARRAY_STRINGS
、ARRAY_STRINGS
傳回類型
ARRAY_STRINGS
程式碼範例
範例 1
以下範例會串連兩個不同的字串陣列。
arrays.concat(["test1", "test2"], ["test3"]) = ["test1", "test2", "test3"]
範例 2
以下範例會使用空字串串連陣列。
arrays.concat([""], [""]) = ["", ""]
範例 3
以下範例會串連空陣列。
arrays.concat([], []) = []
arrays.join_string
arrays.join_string(array_of_strings, optional_delimiter)
說明
將字串陣列轉換為單一字串,並以選用參數分隔。如未提供分隔符號,系統會使用空字串。
參數資料類型
ARRAY_STRINGS
、STRING
傳回類型
STRING
程式碼範例
以下列舉幾個函式使用範例:
範例 1
這個範例會使用分隔符號,將陣列與非空值元素聯結。
arrays.join_string(["foo", "bar"], ",") = "foo,bar"
範例 2
這個範例會將陣列與空值元素和分隔符號合併。
arrays.join_string(["foo", NULL, "bar"], ",") = "foo,bar"
範例 3
這個範例會將陣列與非空值元素聯結,且不含分隔符號。
arrays.join_string(["foo", "bar"]) = "foobar"
arrays.length
arrays.length(repeatedField)
說明
傳回重複欄位元素的數量。
參數資料類型
LIST
傳回類型
NUMBER
程式碼範例
範例 1
傳回重複欄位元素的數量。
arrays.length($e.principal.ip) = 2
範例 2
如果路徑上有多個重複欄位,則會傳回重複欄位元素的總數。
arrays.length($e.intermediary.ip) = 3
arrays.max
arrays.max(array_of_ints_or_floats)
說明
傳回陣列中的最大元素,如果陣列為空白,則傳回零。
參數資料類型
ARRAY_INTS|ARRAY_FLOATS
傳回類型
FLOAT
程式碼範例
以下列舉幾個函式使用範例:
範例 1
這個範例會傳回整數陣列中較大的元素。
arrays.max([10, 20]) = 20.000000
範例 2
這個範例會傳回浮點數陣列中較大的元素。
arrays.max([10.000000, 20.000000]) = 20.000000
arrays.min
arrays.min(array_of_ints_or_floats[, ignore_zeros=false])
說明
傳回陣列中的最小元素,如果陣列為空,則傳回零。如果將第二個選用引數設為 true,系統會忽略等於零的元素。
參數資料類型
ARRAY_INTS|ARRAY_FLOATS
、BOOL
傳回類型
FLOAT
程式碼範例
以下列舉幾個函式使用範例:
範例 1
這個範例會傳回整數陣列中的最小元素。
arrays.min([10, 20]) = 10.000000
範例 2
這個範例會傳回浮點數陣列中的最小元素。
arrays.min([10.000000, 20.000000]) = 10.000000
範例 3
這個範例會傳回浮點數陣列中的最小元素,同時忽略零。
arrays.min([10.000000, 20.000000, 0.0], true) = 10.000000
arrays.size
arrays.size( array )
說明
傳回陣列的大小。若是空陣列,就會傳回 0。
參數資料類型
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
傳回類型
INT
程式碼範例
範例 1
這個範例使用包含兩個元素的字串陣列。
arrays.size(["test1", "test2"]) = 2
範例 2
這個範例使用包含 3 個元素的 int 陣列。
arrays.size([1, 2, 3]) = 3
範例 3
這個範例使用包含 1 個元素的浮點數陣列
arrays.size([1.200000]) = 1
範例 4
本範例使用空陣列。
arrays.size([]) = 0
arrays.index_to_float
arrays.index_to_float(array, index)
說明
傳回陣列中指定索引位置的元素。該索引處的元素會以浮點數形式傳回。
索引是整數值,代表陣列中元素的位置。 根據預設,陣列的第一個元素索引為 0,最後一個元素的索引為 n-1,其中 n 是陣列的大小。 負數索引可存取陣列元素,相對於陣列結尾。舉例來說,索引 -1 是指陣列中的最後一個元素,索引 -2 則是指陣列中的倒數第二個元素。
參數資料類型
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
、INT
傳回類型
FLOAT
程式碼範例
範例 1
以下範例會從浮點數陣列中擷取索引 1 的元素。
arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 1) // 2.1
範例 2
以下範例會從浮點數陣列中擷取索引為 -1 的元素。
arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 0-1) // 4.6
範例 3
以下範例會擷取索引大於陣列大小的元素。
arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 6) // 0.0
範例 4
以下範例會從空陣列擷取元素。
arrays.index_to_float([], 0) // 0.0
範例 5
以下範例會從字串陣列中擷取索引 1 的元素。
arrays.index_to_float(["1.2", "3.3", "2.4"], 1) // 3.3
範例 6
以下範例會從整數陣列中擷取索引 2 的元素。
arrays.index_to_float([1, 3, 2], 2) // 2.0
arrays.index_to_int
arrays.index_to_int(array_of_inputs, index)
說明
傳回陣列中指定索引的值 (整數)。
索引是整數值,代表陣列中元素的位置。 根據預設,陣列的第一個元素索引為 0,最後一個元素的索引為 n-1,其中 n 是陣列的大小。 負數索引可存取陣列元素,相對於陣列結尾。舉例來說,索引 -1 是指陣列中的最後一個元素,索引 -2 則是指陣列中的倒數第二個元素。
參數資料類型
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
、INT
傳回類型
INT
程式碼範例
範例 1
如果索引處的值為非數字字串,這個函式呼叫會傳回 0。
arrays.index_to_int(["str0", "str1", "str2"], 1) = 0
範例 2
這個函式會傳回索引 -1 的元素。
arrays.index_to_int(["44", "11", "22", "33"], 0-1) = 33
範例 3
若是超出範圍的元素,則傳回 0。
arrays.index_to_int(["44", "11", "22", "33"], 5) = 0
範例 4
這個函式會從索引 1 的浮點數陣列擷取元素。
arrays.index_to_int([1.100000, 1.200000, 1.300000], 1) = 1
範例 5
這個函式會從索引 0 的整數陣列擷取元素。
arrays.index_to_int([1, 2, 3], 0) = 1
arrays.index_to_str
arrays.index_to_str(array, index)
說明
從陣列中傳回指定索引處的元素 (以字串形式)。索引是整數值,代表陣列中元素的位置。 根據預設,陣列的第一個元素索引為 0,最後一個元素的索引為 n-1,其中 n 是陣列的大小。 負數索引可從陣列結尾存取陣列元素。舉例來說,索引 -1 是指陣列中的最後一個元素,索引 -2 則是指陣列中的倒數第二個元素。
參數資料類型
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
、INT
傳回類型
STRING
程式碼範例
範例 1
以下範例會從字串陣列中擷取索引 1 的元素。
arrays.index_to_str(["test1", "test2", "test3", "test4"], 1) // "test2"
範例 2
以下範例會從字串陣列中,擷取索引為 -1 的元素 (陣列的最後一個元素)。
arrays.index_to_str(["test1", "test2", "test3", "test4"], 0-1) // "test4"
範例 3
以下範例會擷取索引大於陣列大小的元素,並傳回空字串。
arrays.index_to_str(["test1", "test2", "test3", "test4"], 6) // ""
範例 4
以下範例會從空陣列擷取元素。
arrays.index_to_str([], 0) // ""
範例 5
以下範例會從浮點數陣列中擷取索引 0 的元素。輸出內容會以字串形式傳回。
arrays.index_to_str([1.200000, 3.300000, 2.400000], 0) // "1.2"
範例 6
以下範例會從整數陣列中擷取索引 2 的元素。輸出內容為字串。
arrays.index_to_str([1, 3, 2], 2) // "2"
cast.as_bool
cast.as_bool(string_or_int)
說明
函式會將 int 或字串值轉換為布林值。如果函式呼叫的值無法轉換,就會傳回 FALSE。只會針對整數 1 和不區分大小寫的字串「true」傳回 TRUE。
參數資料類型
INT|STRING
傳回類型
BOOL
程式碼範例
範例 1
這個範例說明如何轉換非布林值字串
cast.as_bool("123") = false
範例 2
Truthy 整數 (1)
cast.as_bool(1) = true
範例 3
Truthy 字串
cast.as_bool("true") = true
範例 4
大寫的真值字串
cast.as_bool("TRUE") = true
範例 5
負整數
cast.as_bool(0-1) = false
範例 6
False 整數 (0)
cast.as_bool(0) = false
範例 7
空字串
cast.as_bool("") = false
cast.as_float
cast.as_float(string_to_cast)
說明
將數值字串轉換為浮點數。如果函式呼叫的值無法轉換,就會傳回 0。浮點數可維持最多 7 個小數位數的精確度。
參數資料類型
STRING
傳回類型
FLOAT
程式碼範例
範例 1
如果轉換的字串不是數字,則會傳回 0。
cast.as_float("str") = 0.0000000
範例 2
轉換空白字串會傳回 0。
cast.as_float("") = 0.0000000
範例 3
轉換有效的數字字串會傳回浮點值。
cast.as_float("1.012345678") = 1.0123456
cast.as_string
cast.as_string(int_or_bytes_or_bool, optional_default_string)
說明
cast.as_string
函式會將 INT
、BYTES
或 BOOL
值轉換為字串表示法。您可以提供選用的 default_string
引數,處理轉換失敗的情況。如果省略 default_string
引數,或輸入無效的 UTF-8
或 BASE64
位元組序列,函式會傳回空字串。
參數資料類型
INT|BYTES|BOOL
、STRING
傳回類型
STRING
程式碼範例
整數轉換為字串
這個函式會將整數 123
轉換為字串 "123"
。
cast.as_string(123) = "123"
將浮點數轉換為字串
這個函式會將浮點數 2.25
轉換為字串 "2.25"
。
cast.as_string(2.25) = "2.25"
位元組轉字串
這個函式會將原始二進位 b'01
轉換為字串 "\x01"
。
cast.as_string(b'01, "") = "\x01"
布林值轉換為字串
此函式會將布林值 true
轉換為字串 "true"
。
cast.as_string(true, "") = "true"
轉換失敗 (預設為選填字串)
如果提供的值無效,函式預設會使用字串「"casting error"
」。
cast.as_string(9223372036854775808, "casting error") = "casting error"
指紋
hash.fingerprint2011(byteOrString)
說明
這個函式會計算輸入位元組序列或字串的 fingerprint2011
雜湊值。這個函式會傳回 INT
範圍內的無符號 [2, 0xFFFFFFFFFFFFFFFF]
值。
參數資料類型
BTYE
、STRING
傳回類型
INT
程式碼範例
id_fingerprint = hash.fingerprint2011("user123")
群組
group(field1, field2, field3, ...)
說明
將類似類型的欄位歸入預留位置變數。
在 UDM 搜尋中,同組欄位可用於搜尋多個類似類型的欄位。群組功能與分組欄位類似,但可讓您選取要分組的欄位,以觸發偵測。您可以使用群組函式,收集不同名詞類型中特定實體 (例如主機名稱、IP 位址或使用者 ID) 的相關資訊。
程式碼範例
範例 1
將所有 IP 位址歸類在一起,並依掃描時間範圍內最常見的 IP 位址,提供遞減計數。
$ip = group(principal.ip, about.ip, target.ip)
$ip != ""
match:
$ip
outcome:
$count = count_distinct(metadata.id)
order:
$count desc
hash.sha256
hash.sha256(string)
說明
傳回輸入字串的 SHA-256 雜湊值。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
這個範例顯示輸入內容為有效字串時的 SHA-256 雜湊。
hash.sha256("str") = "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a"
範例 2
這個範例顯示輸入空白字串時的 SHA-256 雜湊。
hash.sha256("") = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
math.abs
math.abs(numericExpression)
說明
傳回整數或浮點運算式的絕對值。
參數資料類型
NUMBER
傳回類型
NUMBER
程式碼範例
範例 1
如果事件時間與指定時間 (以 Unix Epoch 的秒數表示) 相差超過 5 分鐘,這個範例就會傳回 True,無論事件發生在指定時間之前或之後。對 math.abs
的呼叫不得依附於多個變數或預留位置。舉例來說,您無法將下列範例中硬式編碼的時間值 1643687343 替換為 $e2.metadata.event_timestamp.seconds
。
300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)
math.ceil
math.ceil(number)
說明
傳回大於或等於指定數字的最小整數 (無條件進位)。如果輸入為空值或太大而無法放入 int64,則會傳回 0。
參數資料類型
FLOAT
傳回類型
INT
程式碼範例
本節提供 math.ceil
的使用範例。
範例 1
這個範例會傳回整數的上限。
math.ceil(2.000000) = 2
範例 2
這個範例會傳回負數的上限。
math.ceil(0-1.200000) = -1
範例 3
這個範例會傳回 0,因為數字太大,無法以 64 位元整數表示。
math.ceil(184467440737095516160.0) = 0
math.floor
math.floor(float_val)
說明
傳回不大於所提供值的最大整數值 (向下捨入)。如果輸入為空值或過大而無法納入 int64,則傳回 0。
參數資料類型
FLOAT
傳回類型
INT
程式碼範例
範例 1
這個範例顯示正數的情況。
math.floor(1.234568) = 1
範例 2
這個範例顯示負數的情況。
math.floor(0-1.234568) = -2
範例 3
這個範例顯示零的情況。
math.floor(0.000000) = 0
math.geo_distance
math.geo_distance(longitude1, latitude1, longitude2, latitude2))
說明
傳回兩個地理位置 (座標) 之間的距離,單位為公尺。如果座標無效,則傳回 -1。
參數資料類型
FLOAT
、FLOAT
、FLOAT
、FLOAT
傳回類型
FLOAT
程式碼範例
範例 1
以下範例會傳回距離,前提是所有參數都是有效的座標:
math.geo_distance(-122.020287, 37.407574, -122.021810, 37.407574) = 134.564318
範例 2
以下範例會在其中一個參數是截斷的座標時傳回距離:
math.geo_distance(-122.000000, 37.407574, -122.021810, 37.407574) = 1926.421905
範例 3
如果其中一個參數是無效的座標,以下範例會傳回 -1
:
math.geo_distance(0-122.897680, 37.407574, 0-122.021810, 97.407574) = -1.000000
範例 4
以下範例會在座標相同時傳回 0
:
math.geo_distance(-122.897680, 37.407574, -122.897680, 37.407574) = 0.000000
math.is_increasing
math.is_increasing(num1, num2, num3)
說明
取用數值清單 (整數或雙精度浮點數),如果值為遞增順序,則傳回 True
,否則傳回 False
。
參數資料類型
INT|FLOAT
、INT|FLOAT
、INT|FLOAT
傳回類型
BOOL
程式碼範例
範例 1
這個範例包含以秒為單位的時間戳記值。
math.is_increasing(1716769112, 1716769113, 1716769114) = true
範例 2
這個範例包含一個負數 double、一個零 INT64 和一個正數 INT64 值。
math.is_increasing(-1.200000, 0, 3) = true
範例 3
這個範例包含一個負數 double、一個零 INT64 和一個負數 INT64 值。
math.is_increasing(0-1.200000, 0, 0-3) = false
範例 4
這個範例包含兩個負數倍精確度值和一個零 INT64 值。
math.is_increasing(0-1.200000, 0-1.50000, 0) = false
範例 5
這個範例包含一個負數雙精度浮點數和兩個相同的值。
math.is_increasing(0-1.200000, 0, 0) = false
math.log
math.log(numericExpression)
說明
傳回整數或浮點運算式的自然對數值。
參數資料類型
NUMBER
傳回類型
NUMBER
程式碼範例
範例 1
math.log($e1.network.sent_bytes) > 20
math.pow
math.pow(base, exponent)
說明
傳回第一個引數的第二個引數次方。如果發生溢位,就會傳回 0。
參數資料類型
底數:INT|FLOAT
指數:INT|FLOAT
傳回類型
FLOAT
程式碼範例
範例 1
這個範例顯示整數案例。
math.pow(2, 2) // 4.00
範例 2
這個範例顯示分數基本情況。
math.pow(2.200000, 3) // 10.648
範例 3
這個範例顯示分數底數和指數的情況。
math.pow(2.200000, 1.200000) // 2.575771
範例 4
這個範例顯示負數次方的情況。
math.pow(3, 0-3) // 0.037037
範例 5
這個範例顯示分數次方的情況。
math.pow(3, 0-1.200000) // 0.267581
範例 6
這個範例顯示負數基本情況。
math.pow(0-3, 0-3) // -0.037037
範例 7
這個範例顯示零基底案例。
math.pow(0, 3) // 0
範例 8
這個範例顯示零次方的案例。
math.pow(9223372036854775807, 0) // 1
範例 9
這個範例顯示大型基本案例。
math.pow(9223372036854775807, 1.200000) // 57262152889751593549824
math.random
math.random()
說明
產生 [0, 1)
範圍內的 DOUBLE 型虛擬隨機值,包含 0 但不含 1。
傳回類型
FLOAT
程式碼範例
以下範例會檢查隨機值是否在 [0, 1)
範圍內。none
if(math.random() >= 0 and math.random() < 1) = true
math.round
math.round(numericExpression, decimalPlaces)
說明
傳回四捨五入至最接近整數或指定小數位數的值。
參數資料類型
NUMBER
傳回類型
NUMBER
程式碼範例
math.round(10.7) // returns 11
math.round(1.2567, 2) // returns 1.25
math.round(0-10.7) // returns -11
math.round(0-1.2) // returns -1
math.round(4) // returns 4, math.round(integer) returns the integer
math.sqrt
math.sqrt(number)
說明
傳回指定數字的平方根。如果數字為負數,則傳回 0。
參數資料類型
INT|FLOAT
傳回類型
FLOAT
程式碼範例
範例 1
這個範例會傳回 int 引數的平方根。
math.sqrt(3) = 1.732051
範例 2
這個範例會傳回負數 int 引數的平方根。
math.sqrt(-3) = 0.000000
範例 3
這個範例會傳回零引數的平方根。
math.sqrt(0) = 0.000000
範例 4
這個範例會傳回浮點引數的平方根。
math.sqrt(9.223372) = 3.037000
範例 5
這個範例會傳回負浮點引數的平方根。
math.sqrt(0-1.200000) = 0.000000
個指標
指標函式可以匯總大量歷來資料。您可以在規則中使用這項功能,方法是在結果部分使用 metrics.functionName()
。
詳情請參閱「YARA-L 指標」。
net.ip_in_range_cidr
net.ip_in_range_cidr(ipAddress, subnetworkRange)
說明
如果指定 IP 位址位於指定子網路內,則傳回 true
。
您可以使用 YARA-L,透過 net.ip_in_range_cidr()
陳述式,在子網路內的所有 IP 位址中搜尋 UDM 事件。支援 IPv4 和 IPv6。
如要搜尋某個 IP 位址範圍,請指定 IP UDM 欄位和 CIDR 範圍。YARA-L 可處理單一和重複的 IP 位址欄位。
如要搜尋特定範圍的 IP 位址,請指定 ip
UDM 欄位和無類別跨網域路由 (CIDR) 範圍。YARA-L 可處理單一和重複的 IP 位址欄位。
參數資料類型
STRING
、STRING
傳回類型
BOOL
程式碼範例
範例 1
IPv4 範例:
net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
範例 2
IPv6 範例:
net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")
如需使用 net.ip_in_range_cidr()
陳述式的規則範例,請參閱「IP 位址範圍內的單一事件」中的規則範例。
re.regex
您可以使用下列任一語法,在 YARA-L 2.0 中定義規則運算式比對:
使用 YARA-L 語法 - 與事件相關。 以下是這類語法的泛型表示法:
$e.field = /regex/
使用 YARA-L 語法 - 做為函式,並採用下列參數:
- 套用規則運算式的欄位。
- 以字串形式指定的規則運算式。
以下是這類語法的泛型表示法:
re.regex($e.field, `regex`)
說明
如果字串包含與所提供規則運算式相符的子字串,這個函式會傳回 true
。不必在規則運算式的開頭或結尾加上 .*
。
附註
- 如要比對確切字串,或只比對前置字元或後置字元,請在規則運算式中加入
^
(開頭) 和$
(結尾) 的錨點字元。 舉例來說,/^full$/
完全符合"full"
,而/full/
可能符合"fullest"
、"lawfull"
和"joyfully"
。 - 如果 UDM 欄位包含換行字元,
regexp
只會比對 UDM 欄位的第一行。如要強制執行完整 UDM 欄位比對,請在規則運算式中加入(?s)
。例如,將/.*allUDM.*/
替換為/(?s).*allUDM.*/
。 - 您可以在字串後使用
nocase
修飾符,表示搜尋時應忽略大小寫。
參數資料類型
STRING
、STRING
參數運算式類型
ANY
、ANY
傳回類型
BOOL
程式碼範例
範例 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")
re.capture
re.capture(stringText, regex)
說明
使用引數中提供的規則運算式模式,從字串擷取資料。
這個函式會採用兩個引數:
stringText
:要搜尋的原始字串。regex
:表示要搜尋模式的規則運算式。
規則運算式可包含 0 或 1 個括號中的擷取群組。如果規則運算式包含 0 個擷取群組,函式會傳回第一個相符的完整子字串。如果規則運算式包含 1 個擷取群組,函式會傳回擷取群組的第一個相符子字串。定義兩個以上的擷取群組會傳回編譯器錯誤。
參數資料類型
STRING
、STRING
傳回類型
STRING
程式碼範例
範例 1
在本範例中,如果 $e.principal.hostname
包含「aaa1bbaa2」,則下列項目為 true,因為函式會傳回第一個例項。這個範例沒有擷取群組。
"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")
範例 2
這個範例會擷取電子郵件中 @ 符號後的所有內容。如果 $e.network.email.from
欄位為 test@google.com
,範例會傳回 google.com
。下列範例包含一個擷取群組。
"google.com" = re.capture($e.network.email.from , "@(.*)")
範例 3
如果規則運算式與文字中的任何子字串都不相符,函式會傳回空字串。您可以排除空字串,省略未發生相符項目的事件,這在使用 re.capture()
搭配不等式時特別重要:
// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")
// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")
re.replace
re.replace(stringText, replaceRegex, replacementText)
說明
執行規則運算式取代作業。
這個函式需要三個引數:
stringText
:原始字串。replaceRegex
:表示要搜尋模式的規則運算式。replacementText
:要插入每個相符項目的文字。
傳回衍生自原始 stringText
的新字串,其中所有符合 replaceRegex
模式的子字串都會替換為 replacementText
中的值。您可以在 replacementText
內使用反斜線逸出數字 (\1
到 \9
),好在 replaceRegex
模式中插入與對應放入括號內群組相符的文字。請使用 \0
來參照完整的相符文字。
函式會取代非重疊相符項目,並優先取代找到的第一個相符項目。舉例來說,re.replace("banana", "ana", "111")
會傳回字串「b111na」。
參數資料類型
STRING
、STRING
、STRING
傳回類型
STRING
程式碼範例
範例 1
這個範例會擷取電子郵件中 @
符號後的所有內容,將 com
取代為 org
,然後傳回結果。請注意巢狀函式的使用方式。
"email@google.org" = re.replace($e.network.email.from, "com", "org")
範例 2
本範例在 replacementText
引數中使用反斜線逸出數字,參照 replaceRegex
模式的相符項目。
"test1.com.google" = re.replace(
$e.principal.hostname, // holds "test1.test2.google.com"
"test2\.([a-z]*)\.([a-z]*)",
"\\2.\\1" // \\1 holds "google", \\2 holds "com"
)
範例 3
處理空字串和 re.replace()
時,請注意下列情況:
使用空字串做為 replaceRegex
:
// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")
如要取代空字串,可以使用 "^$"
做為 replaceRegex
:
// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")
sample_rate
optimization.sample_rate(byteOrString, rateNumerator, rateDenominator)
說明
這個函式會根據確定性取樣策略,判斷是否要納入事件。這個函式會傳回:
- 輸入值的分數,相當於 (
rateNumerator
/rateDenominator
),表示事件應納入樣本。true
false
,表示不應將事件納入樣本。
這項函式適用於只想處理部分事件的優化情境。等同於:
hash.fingerprint2011(byteOrString) % rateDenominator < rateNumerator
參數資料類型
- byteOrString:評估結果為
BYTE
或STRING
的運算式。 - rateNumerator: 'INT'
- rateDenominator: 'INT'
傳回類型
BOOL
程式碼範例
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
$asset_id = $e.principal.asset.asset_id
optimization.sample_rate($e.metadata.id, 1, 5) // Only 1 out of every 5 events
match:
$asset_id over 1h
outcome:
$event_count = count_distinct($e.metadata.id)
// estimate the usage by multiplying by the inverse of the sample rate
$usage_past_hour = sum(5.0 * $e.network.sent_bytes)
condition:
// Requiring a certain number of events after sampling avoids bias (e.g. a
// device with just 1 connection will still show up 20% of the time and
// if we multiply that traffic by 5, we'll get an incorrect estimate)
$e and ($usage_past_hour > 1000000000) and $event_count >= 100
strings.base64_decode
strings.base64_decode(encodedString)
說明
傳回字串,其中包含編碼字串的 Base64 解碼版本。
這個函式會將一個 Base64 編碼的字串做為引數。如果 encodedString
不是有效的 Base64 編碼字串,函式會傳回未變更的 encodedString
。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
"test" = strings.base64_decode($e.principal.domain.name)
strings.coalesce
strings.coalesce(a, b, c, ...)
說明
這個函式可接受無限數量的引數,並傳回第一個未評估為空字串的運算式值 (例如「非零值」)。如果所有引數評估結果都是空字串,函式呼叫會傳回空字串。
引數可以是常值、事件欄位或函式呼叫。所有引數都必須是 STRING
型別。如有任何引數是事件欄位,屬性必須來自同一個事件。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
以下範例包含做為引數的字串變數。當 (1) $e.network.email.from
為 suspicious@gmail.com
或 (2) $e.network.email.from
為空且 $e.network.email.to
為 suspicious@gmail.com
時,條件會評估為 true。
"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
範例 2
下列範例會使用兩個以上的引數呼叫 coalesce
函式。這項條件會比較事件 $e
中的第一個非空值 IP 位址與參照清單 ip_watchlist
中的值。這個呼叫中引數的合併順序,與規則條件中列舉的順序相同:
$e.principal.ip
會最先受到評估。$e.src.ip
。$e.target.ip
。- 如果先前的
ip
欄位未設定,則最後會傳回「No IP」字串做為預設值。
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
範例 3
以下範例嘗試從事件 principal.hostname
和事件 $e2
合併 principal.hostname
。$e1
由於引數是不同的事件變數,因此會傳回編譯器錯誤。
// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)
strings.concat
strings.concat(a, b, c, ...)
說明
傳回無限多個項目的串連結果,每個項目可以是字串、整數或浮點數。
如有任何引數是事件欄位,屬性必須來自同一個事件。
參數資料類型
STRING
、FLOAT
、INT
傳回類型
STRING
程式碼範例
範例 1
下列範例包含字串變數和整數變數做為引數。principal.hostname
和 principal.port
都來自同一個事件 $e
,並會串連在一起,傳回字串。
"google:80" = strings.concat($e.principal.hostname, ":", $e.principal.port)
範例 2
下列範例包含字串變數和字串常值做為引數。
"google-test" = strings.concat($e.principal.hostname, "-test") // Matches the event when $e.principal.hostname = "google"
範例 3
以下範例包含字串變數和浮點文字做為引數。以字串表示時,整數的浮點數會以不含小數點的格式表示 (例如 1.0 會表示為「1」)。此外,如果浮點數的小數位數超過 16 位,系統會將其截斷至第 16 位。
"google2.5" = strings.concat($e.principal.hostname, 2.5)
範例 4
以下範例包含字串變數、字串常值、整數變數和浮點常值做為引數。所有變數都來自同一個事件 $e
,並與常值串連,以傳回字串。
"google-test802.5" = strings.concat($e.principal.hostname, "-test", $e.principal.port, 2.5)
範例 5
以下範例會嘗試將事件 $e1
中的 principal.port 與事件 $e2
中的 principal.hostname
串連。因為引數是不同的事件變數,所以會傳回編譯器錯誤。
// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)
strings.contains
strings.contains( str, substr )
說明
如果指定字串包含指定子字串,則傳回 true。否則會傳回 false。
參數資料類型
STRING
、STRING
傳回類型
BOOL
程式碼範例
範例 1
這個範例會傳回 true,因為字串含有子字串「is」。
strings.contains("thisisastring", "is") = true
範例 2
這個範例會傳回 false,因為字串沒有子字串「that」。
strings.contains("thisisastring", "that") = false
strings.count_substrings
strings.count_substrings(string_to_search_in, substring_to_count)
說明
如果提供字串和子字串,則會傳回 int64,表示字串中不重疊的子字串出現次數。
參數資料類型
STRING
、STRING
傳回類型
INT
程式碼範例
本節包含的範例會計算子字串在指定字串中出現的次數。
範例 1
這個範例使用非空字串和非空單一子字串字元。
strings.count_substrings("this`string`has`four`backticks", "`") = 4
範例 2
本範例使用非空值字串和非空值子字串 (長度超過一個字元)。
strings.count_substrings("str", "str") = 1
範例 3
這個範例使用非空值字串和空白子字串。
strings.count_substrings("str", "") = 0
範例 4
這個範例使用空白字串和長度超過一個字元的非空值子字串。
strings.count_substrings("", "str") = 0
範例 5
這個範例使用空字串和空子字串。
strings.count_substrings("", "") = 0
範例 6
這個範例使用非空值字串和非空值子字串,且子字串長度超過一個字元,出現次數也超過一次。
strings.count_substrings("fooABAbarABAbazABA", "AB") = 3
範例 7
本範例使用非空字串和非空子字串,且子字串長度超過一個字元,出現次數也超過一次。這項功能會醒目顯示重疊子字串出現次數的限制
strings.count_substrings("ABABABA", "ABA") = 2
strings.extract_domain
strings.extract_domain(url_string)
說明
從字串中擷取網域。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
這個範例顯示空白字串
strings.extract_domain("") = ""
範例 2
隨機字串,而非網址
strings.extract_domain("1234") = ""
範例 3
多個反斜線
strings.extract_domain("\\\\") = ""
範例 4
妥善處理非字母字元
strings.extract_domain("http://例子.卷筒纸.中国") = "卷筒纸.中国"
範例 5
處理 URI
strings.extract_domain("mailto:?to=&subject=&body=") = ""
範例 6
實際網址前有多個字元
strings.extract_domain(" \t !$5*^)&dahgsdfs;http://www.google.com") = "google.com"
範例 7
URI 中的特殊字元 #
strings.extract_domain("test#@google.com") = ""
範例 8
網址中的特殊字元 #
strings.extract_domain("https://test#@google.com") = ""
範例 9
正向測試案例
strings.extract_domain("https://google.co.in") = "google.co.in"
strings.extract_hostname
strings.extract_hostname(string)
說明
從字串中擷取主機名稱。這項函式會區分大小寫。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
這個範例會傳回空字串。
strings.extract_hostname("") = ""
範例 2
隨機字串,而非網址
strings.extract_hostname("1234") = "1234"
範例 3
多個反斜線
strings.extract_hostname("\\\\") = ""
範例 4
妥善處理非英文字元
strings.extract_hostname("http://例子.卷筒纸.中国") = "例子.卷筒纸.中国"
範例 5
處理 URI
strings.extract_hostname("mailto:?to=&subject=&body=") = "mailto"
範例 6
實際網址前有多個字元
strings.extract_hostname(" \t !$5*^)&dahgsdfs;http://www.google.com") = "www.google.com"
範例 7
URI 中的特殊字元 #
strings.extract_hostname("test#@google.com") = "test"
範例 8
網址中的特殊字元 #
strings.extract_hostname("https://test#@google.com") = "test"
strings.from_base64
strings.from_base64(base64_encoded_string)
說明
函式會將 Base64 編碼的 STRING
值轉換為原始二進位 BYTES
值。如果函式呼叫的值無法轉換,系統預設會傳回空白的 BYTES
。
參數資料類型
STRING
傳回類型
BYTES
程式碼範例
將 Base64 編碼字串轉換為位元組
這個函式會將 Base64 編碼的字串轉換為原始二進位位元組表示法。
strings.from_base64("AAAAAG+OxVhtAm+d2sVuny/hW4oAAAAAAQAAAM0AAAA=") = b'000000006f8ec5586d026f9ddac56e9f2fe15b8a0000000001000000cd000000
轉換失敗 (預設為空白位元組)
如果提供的值無效,函式預設為空白位元組。
strings.from_base64("invalid-value") = b'
strings.from_hex
strings.from_hex(hex_string)
說明
傳回與指定十六進位字串相關聯的位元組。
參數資料類型
STRING
傳回類型
BYTES
程式碼範例
取得與特定十六進位字串相關聯的位元組。
範例 1
這個範例顯示非十六進位字元的轉換。
strings.from_hex("str") // returns empty bytes
範例 2
這個範例顯示輸入內容為空字串。
strings.from_hex("") // returns empty bytes
範例 3
這個範例顯示十六進位字串轉換。
strings.from_hex("1234") // returns 1234 bytes
範例 4
這個範例顯示非 ASCII 字元的轉換。
strings.from_hex("筒纸.中国") // returns empty bytes
strings.length
strings.length(string_value)
說明
傳回輸入字串中的字元數。
參數資料類型
STRING
傳回類型
INT
程式碼範例
範例 1
以下是字串測試的範例。
strings.length("str") = 3
範例 2
以下是輸入空字串的範例。
strings.length("") = 0
範例 3
以下是含有特殊字元字串的範例。
strings.length("!@#$%^&*()-_") = 12
範例 4
以下是含有空格的字串範例。
strings.length("This is a test string") = 21
strings.ltrim
strings.ltrim(string_to_trim, cutset)
說明
從指定字串中移除前置空格。這個函式會移除該剪除集中的開頭字元。
參數資料類型
STRING
、STRING
傳回類型
STRING
程式碼範例
以下是應用範例。
範例 1
這個範例使用相同的第一個和第二個引數。
strings.ltrim("str", "str") = ""
範例 2
這個範例使用空字串做為第二個引數。
strings.ltrim("str", "") = "str"
範例 3
這個範例使用空字串做為第一個引數,並使用字串做為第二個引數。
strings.ltrim("", "str") = ""
範例 4
這個範例使用含有空格的字串,以及做為第二個引數的字串。
strings.ltrim("a aastraa aa ", " a") = "straa aa "
strings.reverse
strings.reverse(STRING)
說明
傳回與輸入字串相反的字串。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
以下範例會傳遞短字串。
strings.reverse("str") = "rts" // The function returns 'rts'.
範例 2
以下範例會傳遞空字串。
strings.reverse("") = ""
範例 3
以下範例會傳遞迴文。
strings.reverse("tacocat") = "tacocat"
strings.rtrim
strings.rtrim(string_to_trim, cutset)
說明
從指定字串中移除結尾的空白字元。移除該剪除集中的尾隨字元。
參數資料類型
STRING
、STRING
傳回類型
STRING
程式碼範例
以下是應用範例。
範例 1
下列範例會將相同字串做為第一個和第二個引數傳遞。
strings.rtrim("str", "str") = ""
範例 2
以下範例會將空字串做為第二個引數傳遞。
strings.rtrim("str", "") = "str"
範例 3
以下範例會將空字串做為第一個引數,並將非空字串做為第二個引數。
strings.rtrim("", "str") = ""
範例 4
在下列範例中,第一個引數會傳遞含有空白字元的字串,第二個引數則會傳遞非空白字串。
strings.rtrim("a aastraa aa ", " a") = "a aasstr"
strings.to_lower
strings.to_lower(stringText)
說明
這個函式會接收輸入字串,並將所有字元轉換為小寫,然後傳回字串
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
以下範例會傳回 true
。
"test@google.com" = strings.to_lower($e.network.email.to)
strings.to_upper
strings.to_upper(string_val)
說明
傳回所有字母字元都是大寫的原始字串。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
以下範例會以大寫形式傳回提供的引數。
strings.to_upper("example") = "EXAMPLE"
strings.trim
strings.trim(string_to_trim, cutset)
說明
從指定字串中移除前置和後置空格。此外,也會從輸入字串中移除不需要的字元 (由 cutset 引數指定)。
參數資料類型
STRING
、STRING
傳回類型
STRING
程式碼範例
以下是應用範例。
範例 1
在下列範例中,系統會將同一個字串當做輸入字串和 cutset 傳遞,因此會產生空字串。
strings.trim("str", "str") // ""
範例 2
在下列範例中,系統會將空字串當做 cutset 傳遞,因此會產生原始字串 str,因為 cutset 中未指定要移除的字元。
strings.trim("str", "") = "str"
範例 3
在下列範例中,函式會產生空字串,因為輸入字串已為空白,且沒有要移除的字元。
strings.trim("", "str") = ""
範例 4
在下列範例中,函式會產生 str,因為 trim 函式會移除下列項目:
- 「a aastraa aa 」中的尾端空白字元
- cutset 中指定的字元 (空格、a)
strings.trim("a aastraa aa ", " a") = "str"
strings.url_decode
strings.url_decode(url_string)
說明
提供網址字串後,解碼逸出字元並處理已編碼的 UTF-8 字元。如果解碼失敗,則傳回空白字串。
參數資料類型
STRING
傳回類型
STRING
程式碼範例
範例 1
這個範例顯示正向測試案例。
strings.url_decode("three%20nine%20four") = "three nine four"
範例 2
這個範例顯示空字串案例。
strings.url_decode("") // ""
範例 3
這個範例顯示如何處理非字母字元。
strings.url_decode("%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B") // "上海+中國"
範例 4
這個範例顯示網址解碼範例。
strings.url_decode("http://www.google.com%3Fparam1%3D%22+1+%3E+2+%22%26param2%3D2%3B") // 'http://www.google.com?param1="+1+>+2+"¶m2=2;'
timestamp.as_unix_seconds
timestamp.as_unix_seconds(timestamp [, time_zone])
說明
這個函式會傳回整數,代表指定時間戳記字串自 Unix 紀元開始至今經過的秒數。
timestamp
是代表有效紀元時間戳記的字串。格式必須為%F %T
。time_zone
為選用項目,代表時區的字串。如果省略,預設值為GMT
。您可以使用字串常值指定時區。選項如下:- TZ 資料庫名稱,例如
America/Los_Angeles
。詳情請參閱 Wikipedia 的 tz 資料庫時區清單。 - 與世界標準時間的時區偏移量,格式為
(+|-)H[H][:M[M]]
,例如「-08:00」。
- TZ 資料庫名稱,例如
以下是有效的 time_zone
規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:
"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"
參數資料類型
STRING
、STRING
傳回類型
INT
程式碼範例
範例 1
有效的紀元時間戳記
timestamp.as_unix_seconds("2024-02-22 10:43:00") = 1708598580
範例 2
有效的 Unix 時間戳記,時區為 America/New_York
timestamp.as_unix_seconds("2024-02-22 10:43:00", "America/New_York") = 1708616580
timestamp.current_seconds
timestamp.current_seconds()
說明
傳回代表目前時間的整數 (以 Unix 秒數為單位)。這大約等於偵測時間戳記,且以規則的執行時間為準。這個函式是 timestamp.now()
函式的同義詞。
參數資料類型
NONE
傳回類型
INT
程式碼範例
範例 1
以下範例會在憑證過期超過 24 小時時傳回 true
。方法是先減去目前的 Unix 秒數,然後使用大於運算子進行比較,計算出時間差。
86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after
timestamp.get_date
timestamp.get_date(unix_seconds [, time_zone])
說明
這個函式會傳回 YYYY-MM-DD
格式的字串,代表時間戳記所在的日期。
unix_seconds
是代表 Unix 紀元後經過秒數的整數,例如$e.metadata.event_timestamp.seconds
,或是包含該值的預留位置。time_zone
為選用項目,代表 time_zone 的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:- 時區資料庫名稱,例如「America/Los_Angeles」。詳情請參閱這個頁面的「時區資料庫名稱」欄。
- 與世界標準時間的時區偏移量,格式為
(+|-)H[H][:M[M]]
,例如「-08:00」。
以下是有效的時區指定符範例,您可以將這些指定符做為第二個引數傳遞至時間擷取函式:
"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"
參數資料類型
INT
、STRING
傳回類型
STRING
程式碼範例
範例 1
在本範例中,我們省略了 time_zone
引數,因此預設為「GMT」。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_date($ts) = "2024-02-19"
範例 2
這個範例使用字串常值定義 time_zone
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_date($ts, "America/Los_Angeles") = "2024-02-20"
timestamp.get_minute
timestamp.get_minute(unix_seconds [, time_zone])
說明
這個函式會傳回介於 [0, 59]
之間的整數,代表分鐘。
unix_seconds
是代表 Unix 紀元後經過秒數的整數,例如$e.metadata.event_timestamp.seconds
,或是包含該值的預留位置。time_zone
為選用項目,代表時區的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:- 時區資料庫名稱,例如「America/Los_Angeles」。詳情請參閱這個頁面的「時區資料庫名稱」欄。
- 與世界標準時間的時區偏移量,格式為
(+|-)H[H][:M[M]]
,例如「-08:00」。
以下是有效的 time_zone
規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:
"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"
參數資料類型
INT
、STRING
傳回類型
INT
程式碼範例
範例 1
在本範例中,我們省略了 time_zone
引數,因此預設為「GMT」。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_hour($ts) = 15
範例 2
這個範例使用字串常值定義 time_zone
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_hour($ts, "America/Los_Angeles") = 15
timestamp.get_hour
timestamp.get_hour(unix_seconds [, time_zone])
說明
這個函式會傳回 [0, 23]
範圍內的整數,代表小時。
unix_seconds
是代表 Unix 紀元後經過秒數的整數,例如$e.metadata.event_timestamp.seconds
,或是包含該值的預留位置。time_zone
為選用項目,代表時區的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:- 時區資料庫名稱,例如「America/Los_Angeles」。詳情請參閱這個頁面的「時區資料庫名稱」欄。
- 與世界標準時間的時區偏移量,格式為
(+|-)H[H][:M[M]]
,例如「-08:00」。
以下是有效的 time_zone
規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:
"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"
參數資料類型
INT
、STRING
傳回類型
INT
程式碼範例
範例 1
在本範例中,我們省略了 time_zone
引數,因此預設為「GMT」。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_hour($ts) = 15
範例 2
這個範例使用字串常值定義 time_zone
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_hour($ts, "America/Los_Angeles") = 15
timestamp.get_day_of_week
timestamp.get_day_of_week(unix_seconds [, time_zone])
說明
這個函式會傳回 [1, 7]
範圍內的整數,代表星期幾 (以週日做為每週起始日)。例如 1 代表星期日,2 代表星期一。
unix_seconds
是代表 Unix 紀元後經過秒數的整數,例如$e.metadata.event_timestamp.seconds
,或是包含該值的預留位置。time_zone
為選用項目,代表 time_zone 的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:- 時區資料庫名稱,例如「America/Los_Angeles」。詳情請參閱這個頁面的「時區資料庫名稱」欄。
- 與世界標準時間的時區偏移量,格式為
(+|-)H[H][:M[M]]
,例如「-08:00」。
以下是有效的時區指定符範例,您可以將這些指定符做為第二個引數傳遞至時間擷取函式:
"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"
參數資料類型
INT
、STRING
傳回類型
INT
程式碼範例
範例 1
在本範例中,我們省略了 time_zone
引數,因此預設為「GMT」。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_day_of_week($ts) = 6
範例 2
這個範例使用字串常值定義 time_zone
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6
timestamp.get_timestamp
timestamp.get_timestamp(unix_seconds, optional timestamp_format/time_granularity, optional timezone)
說明
這個函式會傳回 YYYY-MM-DD
格式的字串,代表時間戳記所在的日期。
unix_seconds
是代表 Unix 紀元後經過秒數的整數,例如$e.metadata.event_timestamp.seconds
,或是包含該值的預留位置。timestamp_format
為選用項目,是代表時間戳記格式的字串。如未填寫此欄位,則預設值為%F %T
。您可以透過日期時間格式字串或下列任一時間精細度指定格式:SECOND
、MINUTE
、HOUR
、DATE
、WEEK
、MONTH
或YEAR
。如需更多格式設定選項,請參閱日期和時間部分的格式元素time_zone
為選用項目,代表時區的字串。如果省略,預設值為GMT
。您可以使用字串常值指定時區。選項如下:- IANA 時區 (TZ) 資料庫名稱,例如
America/Los_Angeles
。詳情請參閱 Wikipedia 上的 tz 資料庫時區清單。 - 與世界標準時間的時區偏移量,格式為
(+|-)H[H][:M[M]]
,例如「-08:00」。
- IANA 時區 (TZ) 資料庫名稱,例如
以下是有效的 time_zone
規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:
"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"
參數資料類型
INT
、STRING
、STRING
傳回類型
STRING
程式碼範例
範例 1
在本例中,系統省略了 time_zone
引數,因此預設為 GMT
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_timestamp($ts) = "2024-02-22 10:43:51"
範例 2
這個範例使用字串常值定義 time_zone
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_timestamp($ts, "%F %T", "America/Los_Angeles") = "2024-02-22 10:43:51"
範例 3
這個範例使用字串常值定義 timestamp_format
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_timestamp($ts, "%Y-%m", "GMT") = "2024-02"
範例 4
這個範例會將 Unix 時間戳記格式化為字串,精確度為秒。
timestamp.get_timestamp(1708598631, "SECOND", "GMT") = "2024-02-22 10:43:51"
範例 5
這個範例會將 UNIX 時間戳記格式化為字串,精確度為分鐘。
timestamp.get_timestamp(1708598631, "MINUTE", "GMT") = "2024-02-22 10:43"
範例 6
這個範例會將 Unix 時間戳記格式化為字串,精確度為小時。
timestamp.get_timestamp(1708598631, "HOUR", "GMT") = "2024-02-22 10"
範例 7
這個範例會將 Unix 時間戳記格式化為字串,精細程度為天。
timestamp.get_timestamp(1708598631, "DATE", "GMT") = "2024-02-22"
範例 8
這個範例會將 Unix 時間戳記格式化為字串,並以週為單位。
timestamp.get_timestamp(1708598631, "WEEK", "GMT") = "2024-02-18"
範例 9
這個範例會將 UNIX 時間戳記格式化為字串,精確度為月份。
timestamp.get_timestamp(1708598631, "MONTH", "GMT") = "2024-02"
範例 10
這個範例會將 Unix 時間戳記格式化為字串,精確度為年。
timestamp.get_timestamp(1708598631, "YEAR", "GMT") = "2024"
timestamp.get_week
timestamp.get_week(unix_seconds [, time_zone])
說明
這個函式會傳回 [0, 53]
範圍內的整數,代表一年中的週次。一週以星期日開始。一年中第一個星期日之前的日期為第 0 週。
unix_seconds
是代表 Unix 紀元後經過秒數的整數,例如$e.metadata.event_timestamp.seconds
,或是包含該值的預留位置。time_zone
為選用項目,代表時區的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:- 時區資料庫名稱,例如「America/Los_Angeles」。詳情請參閱這個頁面的「時區資料庫名稱」欄。
- 與世界標準時間的時區偏移量,格式為
(+|-)H[H][:M[M]]
,例如「-08:00」。
以下是有效的 time_zone
規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:
"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"
參數資料類型
INT
、STRING
傳回類型
INT
程式碼範例
範例 1
在本範例中,我們省略了 time_zone
引數,因此預設為「GMT」。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_week($ts) = 0
範例 2
這個範例使用字串常值定義 time_zone
。
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_week($ts, "America/Los_Angeles") = 0
timestamp.now
timestamp.now()
說明
傳回從 1970-01-01 00:00:00 UTC 算起的秒數。這也稱為 Unix Epoch 時間。
傳回類型
INT
程式碼範例
範例 1
以下範例會傳回 2024 年 5 月 22 日 18:16:59 執行的程式碼時間戳記。
timestamp.now() = 1716401819 // Unix epoch time in seconds for May 22, 2024 at 18:16:59
window.avg
window.avg(numeric_values [, should_ignore_zero_values])
說明
傳回輸入值的平均值 (可以是整數或浮點數)。將選用的第二個引數設為 true,即可忽略零值。
參數資料類型
INT|FLOAT
傳回類型
FLOAT
程式碼範例
範例 1
這個範例顯示整數平均值。
// This rule sets the outcome $size_mode to the average
// file size in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 2.5 if the event file size values in the match window are 1, 2, 3 and 4
範例 2
這個範例顯示浮點數平均值。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 1.75 if the event file size values in the match window are 1.1 and 2.4
範例 3
負數輸入平均值
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 0.6 if the event file size values in the match window are -1.1, 1.1, 0.0 and 2.4
範例 4
0 returns 0
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 0 if the event file size values in the match window is 0
範例 5
忽略 0 個值
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size, true) // yields 394 if the event file size values in the match window are 0, 0, 0 and 394
window.first
window.first(values_to_sort_by, values_to_return)
說明
這項匯總函式會傳回字串值,該值衍生自相符時間範圍內相關性最低的整數值事件。舉例來說,您可從比對時間範圍內時間戳記最低的事件 (最早的事件) 取得使用者 ID。
參數資料類型
INT
、STRING
傳回類型
STRING
程式碼範例
在比對視窗中,取得與最低相關整數值相關聯的事件所衍生的字串值。
// This rule sets the outcome $first_event to the lowest correlated int value
// in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$first_event = window.first($e.metadata.timestamp.seconds, $e.metadata.event_type) // yields v1 if the events in the match window are 1, 2 and 3 and corresponding values v1, v2, and v3.
window.last
window.last(values_to_sort_by, values_to_return)
說明
這項匯總函式會傳回字串值,該值衍生自相符視窗中相關性最高的整數值事件。舉例來說,您可以在相符時間範圍內,從時間戳記最低 (時間戳記最高) 的事件取得使用者 ID。
參數資料類型
INT
、STRING
傳回類型
STRING
程式碼範例
在比對視窗中,取得與最高相關 int 值衍生自事件的字串值。
// This rule sets the outcome $last_event to the highest correlated int value
// in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$last_event = window.first($e.metadata.timestamp.seconds, $e.metadata.event_type) // yields v3 if the events in the match window are 1, 2 and 3 and corresponding values v1, v2, and v3.
window.median
window.median(numeric_values, should_ignore_zero_values)
說明
傳回輸入值的中位數。如有 2 個中位數,系統會隨機選擇 1 個做為傳回值。
參數資料類型
INT|FLOAT
、BOOL
傳回類型
FLOAT
程式碼範例
範例 1
這個範例會在輸入值不為零時傳回中位數。
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 2 if the file sizes in the match window are [1, 2, 3]
condition:
$e
}
範例 2
如果輸入內容包含不應忽略的零值,這個範例會傳回中位數。
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 1 if the file sizes in the match window are [0,0, 1, 2, 3]
condition:
$e
}
範例 3
這個範例會在輸入內容包含應忽略的零值時,傳回中位數。
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size, true) // returns 2 if the file sizes in the match window are [0,0, 1, 2, 3]
condition:
$e
}
範例 4
如果輸入內容包含應忽略的所有零值,這個範例會傳回中位數。
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 0 if the file sizes in the match window are [0,0]
condition:
$e
}
範例 5
這個範例顯示,如果有多個中位數,系統只會傳回一個中位數。
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 1 if the file sizes in the match window are [1, 2, 3, 4]
condition:
$e
}
window.mode
window.mode(values)
說明
傳回輸入值的眾數。如果有多個可能的模式值,系統只會非決定性地選擇其中一個值做為傳回值。
參數資料類型
INT|FLOAT|STRING
傳回類型
STRING
程式碼範例
範例 1
取得比對視窗中值的模式。
// This rule sets the outcome $size_mode to the most frequently occurring
// file size in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.mode($e.file.size) // yields 1.6 if the event file size values in the match window are 1.6, 2, and 1.6
window.stddev
window.stddev(numeric_values)
說明
傳回相符視窗中輸入值的標準差。
參數資料類型
INT|FLOAT
傳回類型
FLOAT
程式碼範例
範例 1
這個範例會傳回相符視窗中整數的標準差。
// This rule creates a detection when the file size stddev in 5 minutes for a user is over a threshold.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 4.0 if the event file size values in the match window are [10, 14, 18].
condition:
$e and #p1 > 2
範例 2
這個範例會傳回比對視窗中浮點數的標準差。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 4.488686 if the event file size values in the match window are [10.00, 14.80, 18.97].
condition:
$e and #p1 > 2
範例 3
這個範例會傳回含有負數的相符時間範圍內的標準差。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 48.644972 if the event file size values in the match window are [-1, -56, -98].
condition:
$e and #p1 > 2
範例 4
如果比對視窗中的所有值都相同,這個範例會傳回零標準差。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 0.000000 if the event file size values in the match window are [1, 1, 1].
condition:
$e and #p1 > 2
範例 5
這個範例會傳回含有正數和負數的相符視窗標準差。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 1.000000 if the event file size values in the match window are [1, 0, -1].
condition:
$e and #p1 > 10
window.variance
window.variance(values)
說明
這個函式會傳回輸入值的指定變異數。
參數資料類型
INT|FLOAT
傳回類型
FLOAT
程式碼範例
範例 1
這個範例會傳回所有整數的變異數。
// This rule creates a detection when the file size variance in 5 minutes for a user is over a threshold.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 16 if the event file size values in the match window are [10, 14, 18].
condition:
$e and #p1 > 10
範例 2
這個範例會傳回所有浮點數的變異數。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 20.148300 if the event file size values in the match window are [10.00, 14.80, 18.97].
condition:
$e and #p1 > 10
範例 3
這個範例會傳回負數的變異數。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 2366.333333 if the event file size values in the match window are [-1, -56, -98].
condition:
$e and #p1 > 10
範例 4
這個範例會傳回較小的變異數值。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 0.000000 if the event file size values in the match window are [0.000000, 0.000000, 0.000100].
condition:
$e and #p1 > 10
範例 5
這個範例會傳回零變異數。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 0.000000 if the event file size values in the match window are [1, 1, 1].
condition:
$e and #p1 > 10
範例 6
這個範例會傳回正數和負數的變異數。
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 1.000000 if the event file size values in the match window are [1, 0, -1].
condition:
$e and #p1 > 10
bytes.to_base64
bytes.to_base64(bytes, optional_default_string)
說明
函式會將 bytes
值轉換為 base64 encoded string
。如果函式呼叫的值無法轉換,預設會傳回空字串。
參數資料類型
BYTES
、STRING
傳回類型
STRING
程式碼範例
將原始二進位位元組轉換為 Base64 編碼字串
這個函式會將原始二進位位元組轉換為 Base64 編碼字串。
bytes.to_base64(b'000000006f8ec5586d026f9ddac56e9f2fe15b8a0000000001000000cd000000) = "AAAAAG+OxVhtAm+d2sVuny/hW4oAAAAAAQAAAM0AAAA="
轉換失敗 (預設為選填字串)
如果提供的位元組值無效,函式會預設為 "invalid bytes"
。
bytes.to_base64(b'000000006f8ec5586d", "invalid bytes") = "invalid bytes"
函式到預留位置的指派
您可以將函式呼叫的結果指派給 events
區段中的預留位置。例如:
$placeholder = strings.concat($e.principal.hostname, "my-string").
接著,您可以在 match
、condition
和 outcome
區段中使用預留位置變數。
不過,函式指派給預留位置時有兩項限制:
函式中每個預留位置的預留位置指派作業,都必須指派給含有事件欄位的運算式。舉例來說,以下範例皆有效:
$ph1 = $e.principal.hostname $ph2 = $e.src.hostname // Both $ph1 and $ph2 have been assigned to an expression containing an event field. $ph1 = strings.concat($ph2, ".com")
$ph1 = $e.network.email.from $ph2 = strings.concat($e.principal.hostname, "@gmail.com") // Both $ph1 and $ph2 have been assigned to an expression containing an event field. $ph1 = strings.to_lower($ph2)
但下列範例無效:
$ph1 = strings.concat($e.principal.hostname, "foo") $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
函式呼叫應取決於一個且僅一個事件。不過,您可以在函式呼叫引數中使用來自同一事件的多個欄位。 舉例來說,以下是有效值:
$ph = strings.concat($event.principal.hostname, "string2")
$ph = strings.concat($event.principal.hostname, $event.src.hostname)
但下列項目無效:
$ph = strings.concat("string1", "string2")
$ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)
參照清單語法
如要進一步瞭解參考清單行為和參考清單語法,請參閱參考清單頁面。
您可以在 events
或 outcome
區段中使用參照清單。以下是在規則中使用各種參照清單的語法:
// STRING reference list
$e.principal.hostname in %string_reference_list
// REGEX reference list
$e.principal.hostname in regex %regex_reference_list
// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list
您也可以搭配參照清單使用 not
運算子和 nocase
運算子,如下列範例所示:
// Exclude events whose hostnames match substrings in my_regex_list.
not $e.principal.hostname in regex %my_regex_list
// Event hostnames must match at least 1 string in my_string_list (case insensitive).
$e.principal.hostname in %my_string_list nocase
nocase
運算子與 STRING
清單和 REGEX
清單相容。
基於效能考量,Detection Engine 會限制參考清單的使用。
- 規則中的
in
陳述式上限 (無論是否使用特殊運算子):7 - 使用
regex
運算子的in
陳述式數量上限:4 - 使用
cidr
運算子的in
陳述式數量上限:2
型別檢查
在介面中建立規則時,Google SecOps 會對 YARA-L 語法執行型別檢查。顯示的型別檢查錯誤可協助您修訂規則,確保規則能正常運作。
以下是無效述詞的範例:
// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"
// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"
偵測事件取樣
多事件規則的偵測結果包含事件樣本,可提供導致偵測結果的事件相關背景資訊。規則中定義的每個事件變數最多可有 10 個事件樣本。舉例來說,如果規則定義了 2 個事件變數,每次偵測最多可有 20 個事件樣本。這項限制適用於每個事件變數。如果一個事件變數在這個偵測中適用 2 個事件,另一個事件變數適用 15 個事件,則產生的偵測會包含 12 個事件樣本 (2 + 10)。
超過上限的事件樣本不會納入偵測範圍。
如要進一步瞭解導致偵測結果的事件,您可以在結果部分使用匯總,在偵測結果中輸出額外資訊。
如果您在使用者介面中查看偵測結果,可以下載偵測到的所有事件樣本。詳情請參閱「下載活動」。
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。