YARA-L 中的單一和多重事件規則
本文顯示以 YARA-L 2.0 編寫的查詢。每個範例都會說明如何在查詢規則語言中建立事件關聯,以找出安全威脅、監控實體行為,以及運用商業邏輯強化偵測結果。
請將這些範例做為 YARA-L 2.0 的建構區塊,包括單一事件偵測、規則運算式比對和網路範圍篩選。這些範例會依功能類別整理,協助您從基本邏輯進展到進階的多事件關聯和複合式偵測。
基礎語法和基本概念
本節的範例說明如何有效關聯 UDM 事件,以及如何在規則語言中建構查詢。
| 主題 | 範例 |
|---|---|
| 單一事件查詢 | 首次使用者登入搜尋; 5 分鐘登入偵測 |
| 查詢和微調 | 排除式程序偵測 |
| 網路範圍和邏輯 | 單一事件比對 (IP 範圍) |
| 查詢中的規則運算式 | 電子郵件篩選; 主機名稱規則運算式; 原始記錄檔搜尋 |
| 具有通用條件的重複欄位 | 驗證可疑的登入 IP |
單一事件查詢
用途:基本偵測特定事件類型 (例如 USER_LOGIN),無須在時間範圍內建立關聯。
主要邏輯:只使用事件和條件部分來找出單一事件。單一事件規則可以是:
- 缺少「
match」部分的規則。 - 規則包含
match區段和condition區段,但只檢查是否存在一個事件 (例如$e、#e > 0、#e >= 1、1 <= #e、0 < #e)。
範例:初始使用者登入搜尋
規則
以下規則範例會搜尋使用者登入 (USER_LOGIN) 事件,並傳回在 Google SecOps 帳戶中儲存的企業資料中,第一個遇到的事件:
rule SingleEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
搜尋
這個未匯總的搜尋範例會直接輸出個別事件。由於這項查詢不需要事件關聯,因此會省略事件變數 (例如 $e1)。
metadata.event_type = "USER_LOGIN"
資訊主頁
由於這項查詢邏輯的重點在於以原始狀態顯示特定不相關的事件,因此不會使用資訊主頁視覺化效果所需的 match 或 outcome 區段。
範例:五分鐘內偵測到登入
規則
以下範例顯示單一事件規則,該規則使用 match 區段,找出在 5 分鐘 (5m) 時間範圍內至少發生一次登入事件的任何使用者。並檢查是否有使用者登入事件。
rule SingleEventRule {
meta:
author = "alice@example.com"
description = "windowed single event example rule"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 5m
condition:
#e > 0
}
搜尋
這個統計搜尋範例會將活動匯總到五分鐘 (5m) 的翻滾視窗,每個視窗的每個使用者會輸出一個資料列。由於查詢著重於每個時間區間的數量計數,因此會省略 event 變數和 condition 區段,因為結果本來就包含一或多個事件。這個版本使用滾動式時間區間,而非跳躍式時間區間,確保結果在平台中正確轉譯。
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
match:
$user by 5m
資訊主頁
以下範例納入 outcome 區段,計算每位使用者的事件總數,有助於將資料繪製為一段時間內的統計值。查詢會使用滾動式時間區間,而非跳躍式時間區間,確保資料點對應至不重疊的離散值區,並提供更清楚的資訊主頁趨勢視覺化效果。
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
match:
$user by 5m
outcome:
$event_count = count(metadata.id)
查詢和調整
應用情境:偵測從非標準目錄啟動的 Windows svchost.exe。
主要邏輯:否定 (not) 搭配規則運算式比對。
範例:以排除項目為準的程序偵測
規則
下列規則會檢查事件資料中的特定模式,並在找到模式時建立偵測結果。這項規則包含用於追蹤事件類型和 metadata.event_type UDM 欄位的變數 $e1。這項規則會使用 e1 檢查規則運算式是否相符。當 $e1 事件發生時,系統會建立偵測結果。規則中包含 not 條件,可排除特定非惡意路徑。您可以新增 not 條件,避免發生誤報。
rule suspicious_unusual_location_svchost_execution
{
meta:
author = "Google Cloud Security"
description = "Windows 'svchost' executed from an unusual location"
yara_version = "YL2.0"
rule_version = "1.0"
events:
$e1.metadata.event_type = "PROCESS_LAUNCH"
re.regex($e1.principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex($e1.principal.process.command_line, `\\Windows\\System32\\`) nocase
condition:
$e1
}
搜尋
這個範例會執行未匯總的搜尋,輸出個別事件。由於這項搜尋不需要跨多個執行個體進行事件關聯,因此不需要 $e1 等事件變數。
metadata.event_type = "PROCESS_LAUNCH"
re.regex(principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex(principal.process.command_line, `\\Windows\\System32\\`) nocase
資訊主頁
這個語法會納入 match 和 outcome 區段,計算一段時間內的事件量。timestamp.get_timestamp() 函式會依天數將結果分組,以視覺化方式呈現趨勢。
metadata.event_type = "PROCESS_LAUNCH"
re.regex(principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex(principal.process.command_line, `\\Windows\\System32\\`) nocase
$date = timestamp.get_timestamp(metadata.event_timestamp.seconds)
match:
$date
outcome:
$event_count = count(metadata.id)
網路範圍和邏輯
用途:根據特定 IP 子網路 (CIDR) 篩選活動,並比對多個可能的主機名稱。
重要概念:
net.ip_in_range_cidr():這個函式會檢查指定 IP 位址是否包含在指定無類別跨網域路由 (CIDR) 子網路中,以進行子網路比對,並檢查字串陣列的 or 運算子。- 邏輯運算子
OR:用於合併多個條件。事件部分中的條件會隱含地與AND結合。OR運算子會檢查多個可能的主機名稱。
範例:單一事件比對 (IP 範圍)
規則
以下範例顯示單一事件規則,用於搜尋兩個特定主機名稱和特定 IP 位址範圍之間的相符項目:
rule OrsAndNetworkRange {
meta:
author = "noone@altostrat.com"
events:
// Checks CIDR ranges.
net.ip_in_range_cidr($e.principal.ip, "203.0.113.0/24")
// Detection when the hostname field matches either value using or.
$e.principal.hostname = /pbateman/ or $e.principal.hostname = /sspade/
condition:
$e
}
搜尋
下列查詢範例會找出特定 IP 位址落在已定義 CIDR 範圍內,且主機名稱符合特定使用者模式的事件:
net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")
principal.hostname = /pbateman/ or principal.hostname = /sspade/
由於這是搜尋查詢,而非偵測規則,因此只要符合篩選條件,系統就會自動傳回整個事件。「match」部分會依據「principal.ip」和「principal.hostname」分組資料。由於未執行任何事件關聯,因此不需要 condition 區段,且會省略事件變數 ($e)。
資訊主頁
下列範例查詢會將不重複的 IP 和主機名稱配對分組,藉此彙整結果:
net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")
principal.hostname = /pbateman/ or principal.hostname = /sspade/
match:
principal.ip, principal.hostname
查詢中的規則運算式
用途:搜尋彈性字串模式 (例如電子郵件中的特定網域),同時忽略大小寫。這項功能最常用於「搜尋」和「規則」。
主要邏輯:使用 /regex/ nocase 進行基本比對,並使用 re.regex() 函式進行複雜的欄位分析。
範例:電子郵件篩選
規則
下列 YARA-L 2.0 規則運算式範例會搜尋從 altostrat.com 網域收到的電子郵件事件。由於 nocase 已新增至 $host 變數 regex 比較和 regex 函式,因此這些比較會忽略大小寫。
rule RegexRuleExample {
meta:
author = "noone@altostrat.com"
events:
$e.principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex($e.network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
condition:
#e > 10
}
搜尋
在搜尋介面中,這項邏輯可用於高保真威脅搜尋和資料探索。分析人員不必等待自動警報,可以手動查詢 UDM,找出符合命名慣例的主機名稱,以及目標電子郵件網域的特定執行個體。這是將這些事件升級為持續偵測規則前,驗證事件量的主要方法。
principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
```
資訊主頁
下列邏輯會將 hostname 和 email 遙測資料匯總到 10 分鐘 (10m) 的值區,藉此找出感興趣的模式。在資訊主頁中使用時,這項邏輯可讓分析師將特定資產 (符合 host) 與 altostrat.com 網域之間的通訊頻率視覺化。這個檢視畫面有助於監控內部資料移動趨勢,並找出重要基礎架構中的熱門通訊者。
principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
```
範例:主機名稱規則運算式
規則
以下範例會找出主體 hostname 識別為網頁 (webserver) 或開發 (devserver) 伺服器的任何記錄活動。這項功能會使用不區分大小寫的規則運算式,確保命名慣例的變化不會導致偵測結果遺漏。
rule WebServerOrDevServerActivity {
meta:
author = "Alex"
description = "Detects events where the principal hostname is 'webserver' or 'devserver', ignoring case."
severity = "Informational"
events:
$e.principal.hostname = /webserver|devserver/ nocase
condition:
$e
}
搜尋
在下列範例中,principal.hostname = /webserver|devserver/ nocase 會比對 "WebServer01"、"devserver-test"、"MyWebServers" 等主機名稱。這是尋找特定事件的常見用途。
// Use /regex/ followed by nocase for a case-insensitive match
principal.hostname = /webserver|devserver/ nocase
資訊主頁
雖然這個具體範例不會顯示在資訊主頁中,但這項規則會主動發出快訊,並持續偵測。與需要手動檢查的資訊主頁不同,這項功能可確保系統自動標記這些伺服器上的每個活動例項,並記錄在偵測引擎中,方便立即搜尋。
範例:搜尋原始記錄
規則
手動搜尋適用於特定時間點的調查,偵測規則則可提供全天候不間斷的遙測監控。您可以將成功的搜尋查詢轉換為 YARA-L 規則,自動執行警報程序。
規則的主要優點:
- 即時快訊:系統會自動標記相符的內容。
- 保留設定:不必再手動重新輸入搜尋字詞。
- 結果動作:直接傳送至偵測檢視畫面,供分析師分類和事件應變。
搜尋
資安分析師經常使用 regex 在 Google SecOps 中搜尋原始、未剖析的記錄。這項動作可彈性比對模式,找出特定構件,即使這些構件並非完全結構化或已編列索引也沒問題。語法使用正斜線:
raw = /host/
這項查詢會傳回任何出現字元序列 "host" 的原始記錄行。相符原始記錄內容的範例可能包括 "hostname": "myhost123"。
資訊主頁
這個特定事件類型沒有專屬的資訊主頁變體。如要大規模查看這些偵測結果,可以採取下列做法:
- 將
metadata.event_type對應至資訊主頁製作工具中的長條圖或圓餅圖。 - 追蹤這些事件在 7 天、30 天或 90 天內的發生頻率,找出使用者行為的異常狀況。
具有通用條件的重複欄位
用途:稽核含有資料清單 (重複欄位) 的事件,確保沒有可信的例外狀況,例如驗證與登入相關聯的每個 IP 位址是否都在已知安全範圍之外。
主要邏輯:使用 all 運算子,根據特定條件評估重複欄位中的每個元素,並說明將重複欄位指派給預留位置變數 (例如 $ip) 時,如何為清單中的每個不重複值建立不同的偵測結果。
範例:驗證可疑登入的 IP 位址
規則
下列規則會搜尋登入事件,其中所有來源 IP 位址在五分鐘的時間範圍內 (5m),都不符合已知安全的 IP 位址。
rule SuspiciousIPLogins {
meta:
author = "alice@example.com"
events:
$e.metadata.event_type = "USER_LOGIN"
// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".
all $e.principal.ip != "100.97.16.0"
// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.
$e.principal.ip = $ip
match:
$ip over 5m
condition:
$e
}
搜尋
metadata.event_type = "USER_LOGIN"
// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".
all principal.ip != "100.97.16.0"
// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.
principal.ip = $ip
match:
$ip over 5m
資訊主頁
metadata.event_type = "USER_LOGIN"
// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".
all principal.ip != "100.97.16.0"
// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.
principal.ip = $ip
match:
$ip over 5m
進階視窗
本節將介紹多級式模式,以及由其他規則的活動觸發的偵測項目。
| 主題 | 範例 |
|---|---|
| 多事件關聯 | 多個城市登入偵測; 快速建立及刪除使用者 |
| 查詢中的滑動時間範圍 | 偵測遺漏的連續事件 |
| 多事件查詢 | 高頻率登入偵測 |
| 含有計算結果的多事件查詢 | 暴力破解後登入成功; 以時間範圍比對主機 |
多事件關聯
本節將提供範例,說明如何追蹤多個事件或時間範圍內的實體 (使用者或主機),以找出行為模式。
用途:偵測不可能的行程,也就是單一使用者在五分鐘內從兩個以上的城市登入。5m
鍵邏輯:使用「match」部分依 $user 和 #city > 1 分組,找出不同的位置值。
範例:偵測到在多個城市登入
規則
以下規則會搜尋在不到 5 分鐘內從兩個以上城市登入企業的使用者,其中 5m 是 $user 變數,$udm 是事件變數,而 $city 和 $user 是預留位置變數:match
rule DifferentCityLogin {
meta:
events:
$udm.metadata.event_type = "USER_LOGIN"
$udm.principal.user.userid = $user
$udm.principal.location.city = $city
match:
$user over 5m
condition:
$udm and #city > 1
}
以下說明這項規則的運作方式:
- 群組事件 (含使用者名稱 (
$user)),並在找到相符項目時傳回該事件 ($user)。 - 時間範圍為五分鐘 (
5m);只有間隔不到 5 分鐘 (5m) 的事件會相互關聯。 - 搜尋事件類型為
USER_LOGIN的事件群組 ($udm)。 - 針對該事件群組,規則會將使用者 ID 稱為
$user,登入城市稱為$city。 - 如果事件群組 (
$udm) 在 5 分鐘 (5m) 時間範圍內,city值的相異數量 (以#city表示) 大於1,則傳回相符項目。
搜尋
下列查詢範例會執行等效的統計搜尋,找出「不可能的行程」模式。這項功能會將 USER_LOGIN 事件依使用者分組,時間範圍為五分鐘 (5m),並篩選結果,只顯示單一身分偵測到多個不同城市的情況。
events:
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
principal.location.city = $city
match:
$user over 5m
condition:
#city > 1
資訊主頁
下列範例查詢會提供類似的資訊主頁視覺化效果,追蹤帳戶遭盜用的可能性。這項規則會匯總五分鐘 (5m) 內每個使用者的 USER_LOGIN 事件,並篩選出與多個不同城市 (#city) 相關聯的單一身分,方便您繪製這些高風險地理位置異常的隨時間變化圖。
events:
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
principal.location.city = $city
match:
$user over 5m
condition:
#city > 1
快速建立及刪除使用者
用途:找出建立的免洗帳戶,並在 4 小時內刪除。
主要邏輯:在共用
$user變數上聯結兩種事件類型 (USER_CREATION和USER_DELETION),並比較時間戳記。
範例:快速建立及刪除使用者
規則
以下規則範例會搜尋在 4 小時內建立並刪除的使用者 (4h),其中 $create 和 $delete 是事件變數,$user 是 match 變數,且沒有預留位置變數:
rule UserCreationThenDeletion {
meta:
events:
$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"
$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"
$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds
match:
$user over 4h
condition:
$create and $delete
}
搜尋
以下範例示範如何使用多事件統計資料搜尋功能,找出帳戶生命週期的快速變化。這項查詢會在四小時內為每位使用者輸出一個資料列,並將身分證明的建立和刪除作業相互關聯。
由於搜尋預設會傳回包含指定事件的任何視窗,因此不需要 condition 區段。
$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"
$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"
$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds
match:
$user over 4h
資訊主頁
以下範例顯示多事件資訊主頁搜尋,旨在繪製帳戶生命週期趨勢隨時間變化的圖表。使用滾動式時間區間 (by 4h) 時,結果會對應至不重疊的離散時間區間,非常適合用於視覺化。
這個變體包含 outcome 區段,可計算每個時間範圍內建立事件的相異計數。與先前的搜尋不同,這個版本不需要傳回特定事件變數,因為重點是匯總統計值,而不是個別記錄行。
$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"
$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"
$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds
match:
$user by 4h
outcome:
$event_count = count_distinct($create.metadata.id)
查詢中的滑動時間範圍
用途:偵測潛在的安全問題,也就是在特定時間範圍內,初始事件 (來自 firewall_1) 後未接續發生預期的後續事件 (來自 firewall_2)。
主要邏輯:
- 樞紐事件:規則以
firewall_1中的事件為中心,並指定為$e1。每次發生$e1事件時,都會做為樞紐。 - 時間範圍:
match區段 ($host over 10m after $e1) 定義 10 分鐘的時間範圍,從每個$e1事件發生後立即開始。每發生新的$e1事件,這個視窗就會滑動。 - 關聯性:系統會依主機名稱 (
$host) 將事件分組。 - 偵測條件 (
$e1和$e2):如果符合下列條件,系統就會針對特定主機觸發偵測:- 有來自
firewall_1($e1) 的事件。 AND,在該特定$e1事件發生後的 10 分鐘內,系統會找到相同主辦人的NO事件 (firewall_2($e2))。
- 有來自
範例:偵測到缺少連續事件
規則
以下範例會找出主要觸發事件發生後,次要事件未發生的情況。這項規則會在 10 分鐘的時間範圍內使用 !$e2 條件,標示缺少的遙測資料,特別是當防火牆記錄出現在某個位置,但未出現在下一個預期躍點時,這表示可能出現可視性缺口或流量下降。
rule MissingSequentialEvent {
meta:
author = "alice@example.com"
events:
$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host
$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host
match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
$host over 10m after $e1
condition:
$e1 and !$e2
}
搜尋
以下範例示範如何使用循序搜尋,找出兩個來源之間遙測資料的缺口。以 $e1 做為樞紐,搜尋會尋找主要防火牆事件,但該事件在 10 分鐘內未在第二個防火牆上觸發相應事件。在調查期間,這是手動搜尋網路流量「黑洞」或記錄失敗的有效方式。
$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host
$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host
match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
$host over 10m after $e1
condition:
$e1 and !$e2
資訊主頁
以下範例提供專為資訊主頁檢視畫面設計的可視度差距分析。彙整次要事件未接續主要事件的執行個體,即可隨時間呈現記錄管道的可靠性。繪製這些「遺失」的事件,有助於找出網路可視性中的持續無效區域,或特定主機名稱的設定問題。
$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host
$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host
match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
$host over 10m after $e1
condition:
$e1 and !$e2
多事件查詢
用途:在特定時間範圍內追蹤單一實體 (例如使用者或主機) 的多個事件,找出高頻率或暴力活動。
主要邏輯:使用
match區段依特定變數將事件分組,並使用condition區段檢查定義時間範圍內的閾值計數 (例如#e >= 10)。
典型的多事件規則包括:
- 用來區分事件的事件變數。
match區段,指定事件的分組時間範圍。condition區段:指定應觸發偵測的條件,並檢查是否存在多個事件。
在搜尋中,如果查詢包含多個事件,即為多事件查詢。對於規則,您可以透過兩種方式定義這項設定:
多個事件:(例如
event1 = successful login, event2 = failed login)。以條件為準的觸發條件:條件會說明只有在多個事件符合條件時才會觸發 (例如
event1 > 10)。這類規則也需要包含outcome區段。
範例:高頻率登入偵測
規則
下列規則會搜尋在 10 分鐘內登入至少 10 次的使用者:
rule MultiEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 10m
condition:
#e >= 10
}
搜尋
下列範例使用多事件統計資料搜尋,找出高頻率的登入活動。如果單一使用者在 10 分鐘 (10m) 內產生 10 個以上的登入事件,系統就會標記該例。
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user by 10m
condition:
#e >= 10
資訊主頁
以下範例使用多事件搜尋功能,監控帳戶是否可能遭到入侵。這項功能會關聯 10 分鐘滑動視窗內的登入嘗試,找出特定使用者和主機多次登入失敗後成功登入的案例,讓您即時查看高風險的驗證模式。
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user by 10m
condition:
#e >= 10
多事件查詢 (含計算結果)
用途:套用條件式邏輯,根據資產嚴重程度或網路流量設定
risk_score。主要邏輯:使用
outcome區段計算變數,並使用條件區段依這些變數篩選。
範例:暴力破解後成功登入
以下範例使用 outcome 區段,計算 match 視窗內的事件。這項查詢產生的輸出內容與標準多事件查詢相同,但會說明如何將計算變數納入偵測邏輯。
規則
rule PossibleBruteForceThenSuccessfulLogin {
meta:
author = "Alex"
description = "Detects multiple failed login attempts followed by a successful login for the same user and host within a 10-minute window."
severity = "High"
tactic = "Credential Access"
events:
// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname
// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname
match:
// This section is key for multi-event rules. It groups events:
// - By the common placeholder variables: $user and $hostname.
// - Within a time window: by 10m.
// The rule will evaluate all events matching $failed or $success that share the same $user and $hostname within any given 10-minute period.
$user, $hostname by 10m
outcome:
// Calculate aggregate values from the events within the match window.
$failed_login_count = count($failed.metadata.id)
$successful_login_count = count($success.metadata.id)
condition:
// The conditions that must be met *within each matched group* ($user, $hostname over 10m).
// - #failed >= 5: There must be 5 or more events matching the $failed criteria.
// - #success >= 1: There must be at least 1 event matching the $success criteria.
#failed >= 5 and #success >= 1
}
搜尋
// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname
// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname
match:
// This section is key for multi-event rules. It groups events:
// - By the common placeholder variables: $user and $hostname.
// - Within a sliding time window: over 10m.
// The rule will evaluate all events matching $failed or $success that share
// the same $user and $hostname within any given 10-minute period.
$user, $hostname over 10m
資訊主頁
// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname
// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname
match:
// This section is key for multi-event rules. It groups events:
// - By the common placeholder variables: $user and $hostname.
// - Within a sliding time window: over 10m.
// The rule will evaluate all events matching $failed or $success that share
// the same $user and $hostname within any given 10-minute period.
$user, $hostname over 10m
範例:時間範圍內的主機比對
規則
下列規則會查看兩個事件,以取得 $hostname 的值。如果 $hostname 的值在 5 分鐘 (5m) 內相符,系統就會套用嚴重程度分數。在 match 區段中加入時間範圍時,規則會檢查指定時間範圍內的資料。
rule OutcomeRuleMultiEvent {
meta:
author = "Google Cloud Security"
events:
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$risk_score =
max(
100
+ if($hostname = "my-hostname", 100, 50)
+ if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}
搜尋
// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname
// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname
match:
// This section is key for multi-event rules. It groups events:
// - By the common placeholder variables: $user and $hostname.
// - Within a sliding time window: over 10m.
// The rule will evaluate all events matching $failed or $success that share
// the same $user and $hostname within any given 10-minute period.
$user, $hostname over 10m
outcome:
// Calculate aggregate values from the events within the match window.
$failed_login_count = count($failed.metadata.id)
$successful_login_count = count($success.metadata.id)
```
資訊主頁
// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname
// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname
match:
// This section is key for multi-event rules. It groups events:
// - By the common placeholder variables: $user and $hostname.
// - Within a sliding time window: over 10m.
// The rule will evaluate all events matching $failed or $success that share
// the same $user and $hostname within any given 10-minute period.
$user, $hostname over 10m
outcome:
// Calculate aggregate values from the events within the match window.
$failed_login_count = count($failed.metadata.id)
$successful_login_count = count($success.metadata.id)
複合偵測項目
複合偵測項目會使用複合規則,進一步提升威脅偵測能力。這些複合規則會使用其他規則的偵測結果做為輸入內容。這樣一來,就能偵測到個別規則可能無法偵測到的複雜威脅。詳情請參閱「複合式偵測總覽」。
| 主題 | 範例 |
|---|---|
| 高風險篩選 | 偵測管理員使用者 |
| 匯總和門檻 | 風險匯總 |
| 策略匯總 | MITRE 戰術匯總 |
| 連續複合偵測 | 暴力破解嘗試後登入成功 |
| 情境感知偵測 | 威脅情報擴充功能 |
| 共同出現偵測 | 提權和外洩同時發生 |
高風險篩選
用途:篩選現有偵測結果,找出高風險屬性,例如涉及管理員帳戶的活動。
主要邏輯:根據現有發現中的結果或中繼資料欄位運作。
高風險篩選複合偵測項目是最簡單的複合偵測項目形式,可對偵測結果中的欄位 (例如結果變數或規則中繼資料) 執行作業。這類規則有助於篩選出可能代表高風險的條件,例如管理員使用者或正式環境。
範例:偵測管理員使用者
規則
下列複合規則會搜尋任何現有偵測結果,其中行為人識別為管理員使用者,並套用標準化風險分數。
rule composite_admin_detection {
meta:
rule_name = "Detection with Admin User"
author = "Google Cloud Security"
description = "Composite rule that looks for any detections where the actor is an admin user"
severity = "Medium"
events:
$rule_name = $d.detection.detection.rule_name
$principal_user = $d.detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase
match:
$principal_user over 1h
outcome:
$risk_score = 75
$upstream_rules = array_distinct($rule_name)
condition:
$d
}
搜尋
下列統計搜尋會找出並匯總高權限帳戶的活動。這項功能旨在顯示所有觸發偵測的專屬規則名稱,包括涉及「管理員」或「根」使用者的規則。
在這項特定查詢中,系統會移除時間範圍,對所選時間範圍內的所有偵測結果執行單一統計分析。此外,由於這是以現有偵測資料為主的非匯總搜尋,因此不需要事件部分、事件變數和條件部分。
$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase
match:
$principal_user
outcome:
$upstream_rules = array_distinct($rule_name)
資訊主頁
這個資訊主頁查詢可讓您以視覺化方式呈現,哪些特定規則最常偵測到與管理員相關的活動。這項功能旨在提供環境中偵測趨勢的概略總覽。
請注意,與先前的範例相比,match 變數和 outcome 匯總的變化。這項查詢會依規則名稱將結果分組,並計算每個規則偵測到的管理員使用者人數。
$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase
match:
$rule_name
outcome:
$admin_detections = count($principal_user)
匯總和門檻
使用案例:找出產生大量快訊或長期累積高風險分數的使用者或主機。
金鑰邏輯:使用 sum() 或 count_distinct() 分析匯總的偵測資料。
匯總複合偵測規則可讓您根據共用屬性 (例如主機名稱或使用者名稱) 將偵測結果分組,並分析匯總資料。常見用途包括:
- 找出產生大量安全性快訊或匯總風險的使用者。
- 彙整相關偵測結果,找出活動模式異常的主機。
範例:風險匯總
規則
這項規則會匯總單一使用者在 48 小時內的風險分數。這項功能會找出累計風險超過特定門檻的使用者。
在這個更新的邏輯中,detection.detection.outcomes 會由地圖欄位變數取代,這些變數會同時儲存 match 和 outcome 變數。此外,由於每項偵測都只包含一個相符變數值,且該值已擷取,因此系統會移除 $principal_users 結果變數。
rule composite_risk_aggregation {
meta:
rule_name = "Risk Aggregation Composite"
author = "Google Cloud Security"
description = "Composite detection that aggregates risk of a user over 48 hours"
severity = "High"
events:
$rule_name = $d.detection.detection.rule_name
$principal_user = $d.detection.detection.outcomes["principal_users"]
$risk = $d.detection.detection.risk_score
match:
$principal_user over 48h
outcome:
$risk_score = 90
$cumulative_risk = sum($risk)
$upstream_rules = array_distinct($rule_name)
condition:
$d and $cumulative_risk > 500
}
搜尋
這項統計搜尋會彙整偵測資料,計算使用者在 48 小時內的總風險。每個視窗會為每個主體使用者輸出一個資料列,提供多種偵測類型的帳戶風險高階檢視畫面。
在這個變體中,不需要事件變數。規則引擎會自動濾除沒有主體使用者的偵測結果,但這項搜尋需要明確的篩選條件 ($principal_user != ""),確保結果只包含已填入的資料。根據預設,查詢只會在特定使用者有一或多項偵測結果時傳回結果。
$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score
match:
$principal_user over 48h
outcome:
$risk_score = 90
$cumulative_risk = sum($risk)
$upstream_rules = array_distinct($rule_name)
condition:
$cumulative_risk > 500
資訊主頁
這個變體專為資訊主頁設計,可繪製一段時間內的使用者風險和偵測活動。這項功能會將資料匯總到個別儲存區,因此非常適合用來呈現趨勢,例如觸發的不重複規則數量,或每位使用者的偵測總數。
在這項查詢中,視窗會從滑動 (跳躍) 時間區間切換為滾動式時間區間 (by 48h)。這可確保資料點對應至不重疊的時間區段,讓時間序列圖表更清楚明瞭。與其他未匯總的搜尋內容一樣,您不需要提供事件變數,且 outcome 區段會展開,顯示規則名稱和偵測 ID 的不重複計數。
$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score
match:
$principal_user by 48h
outcome:
$cumulative_risk = sum($risk)
$rule_count = count_distinct($rule_name)
$detection_count = count_distinct(detection.id)
condition:
$cumulative_risk > 500
策略匯總
用途:找出活動觸發多種不同 MITRE ATT&CK 戰術的偵測結果,這表示攻擊生命週期正在演進 (例如從「初始存取」轉移至「資料外洩」)。
主要邏輯:使用 count_distinct($tactic) 觸發,條件是使用者在 48 小時內,以不同策略達到特定門檻。
範例:MITRE 戰術匯總
規則
rule composite_tactic_aggregation {
meta:
rule_name = "MITRE Tactic Aggregation Composite"
author = "Google Cloud Security"
description = "Composite detection that detects if a user has triggered detections over multiple mitre tactics."
severity = "Medium"
events:
$principal_user = $d.detection.detection.outcomes["principal_users"]
$tactic = $d.detection.detection.outcomes["mitre_tactic"]
$rule_name = $d.detection.detection.rule_name
match:
$principal_user over 48h
outcome:
$mitre_tactics_count = count_distinct($tactic)
$mitre_tactics = array_distinct($tactic)
$calculated_risk = 50 + (15 * $mitre_tactics_count)
$upstream_rules = array_distinct($rule_name)
condition:
$d and $mitre_tactics_count > 1 }
搜尋
以下範例展示專為安全開發人員設計的搜尋變體,這些人員需要關聯現有偵測結果,並套用動態風險權重。這項查詢邏輯會從 detection 資料來源擷取 MITRE ATT&CK 策略和使用者資訊,依據主體使用者將活動分組,並根據觀察到的策略多元性計算自訂風險分數。
detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name
match:
$principal_user
outcome:
$mitre_tactics_count = count_distinct($tactic)
$mitre_tactics = array_distinct($tactic)
$upstream_rules = array_distinct($rule_name)
$calculated_risk = 50 + (15 * $mitre_tactics_count)
$risk_score = if($calculated_risk > 100, 100, $calculated_risk)
資訊主頁
以下範例說明相同偵測分析邏輯的「資訊主頁」變體。在 Google SecOps 資訊主頁中,開發人員可使用這項查詢,關聯不同規則的偵測結果,以視覺化呈現高風險使用者。這項邏輯會擷取主要使用者和 MITRE 戰術、彙整調查結果,並套用設有上限的風險評分,協助您直接在資訊主頁小工具中排定調查工作的優先順序。
detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name
match:
$principal_user
outcome:
$mitre_tactics_count = count_distinct($tactic)
$mitre_tactics = array_distinct($tactic)
$upstream_rules = array_distinct($rule_name)
$calculated_risk = 50 + (15 * $mitre_tactics_count)
$risk_score = if($calculated_risk > 100, 100, $calculated_risk)
```
連續複合偵測
用途:找出作業順序至關重要的重大攻擊模式,例如偵測到帳戶登入成功,但前提是同一 IP 位址必須先發出多個暴力破解嘗試警報。
主要邏輯:透過聯結通用變數 (例如 $bruteforce_ip) 將先前的偵測結果與後續的原始 UDM 事件建立關聯,並使用時間戳記比較,確保事件以正確順序發生。
連續複合式偵測會找出相關事件的模式,偵測順序很重要,例如偵測到暴力登入嘗試,接著登入成功。這些模式可能涉及多項基礎偵測結果,或基礎偵測結果和事件的組合。
範例:暴力破解嘗試後登入成功
規則
下列複合規則會找出相關事件的模式,其中順序很重要。具體來說,系統會尋找 Google Workspace 暴力破解偵測結果,以及 24 小時內來自相同來源 IP 的登入成功事件。
rule composite_bruteforce_login {
meta:
rule_name = "Bruteforce Login Composite"
author = "Google Cloud Security"
description = "Detects when an IP address associated with a Workspace brute force attempt successfully logs in"
severity = "High"
events:
$bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
$bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]
$login_event.metadata.product_name = "login"
$login_event.metadata.product_event_type = "login_success"
$login_event.metadata.vendor_name = "Google Workspace"
$login_ip = $login_event.principal.ip
// Ensure the brute force detection and successful login occurred from the same IP
$login_ip = $bruteforce_ip
$target_account = $login_event.target.user.email_addresses
// Ensure the brute force detection occurred before the successful login
$bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds
match:
$bruteforce_ip over 24h
outcome:
$risk_score = 90
$principal_users = array_distinct($target_account)
condition:
$bruteforce_detection and $login_event
}
搜尋
$bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
$bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]
$login_event.metadata.product_name = "login"
$login_event.metadata.product_event_type = "login_success"
$login_event.metadata.vendor_name = "Google Workspace"
$login_ip = $login_event.principal.ip
// Ensure the brute force detection and successful login occurred from the same IP
$login_ip = $bruteforce_ip
$target_account = $login_event.target.user.email_addresses
// Ensure the brute force detection occurred before the successful login
$bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds
match:
$bruteforce_ip over 24h
outcome:
$principal_users = array_distinct($target_account)
condition:
$bruteforce_detection and $login_event
資訊主頁
資訊主頁著重於將原始事件資料視覺化,而複合式偵測邏輯則會將現有的偵測快訊與後續事件相互關聯。這項多層分析是針對偵測引擎進行最佳化,而非即時資訊主頁小工具。
情境感知偵測
應用情境:使用外部威脅情報擴充現有偵測結果,確認警報是否涉及已知惡意實體,例如檢查安全偵測中標記的 IP 位址是否也列在全域 TOR 退出節點威脅動態饋給中。
主要邏輯:使用複合規則,透過比對 IP 位址等共用屬性,將偵測結果與 GLOBAL_CONTEXT 圖表資料 (例如 Google Cloud Threat Intelligence 資訊動態饋給) 聯結。
情境感知複合式偵測功能會提供更多情境資訊 (例如威脅動態饋給中找到的 IP 位址),讓偵測結果更加豐富。
範例:擴充威脅情報
規則
下列複合規則會自動將 TOR 資訊動態饋給中的額外背景資訊,新增至現有的偵測結果。這項功能會將先前偵測到的 IP 位址與 TOR 結束節點動態饋給相互關聯,以提高發現項目的嚴重程度和風險分數。
rule composite_tor_enrichment {
meta:
rule_name = "Detection with IP from TOR Feed"
author = "Google Cloud Security"
description = "Adds additional context from the TOR intel feed to detections"
severity = "High"
events:
$rule_name = $d.detection.detection.rule_name
$gcti.graph.metadata.entity_type = "IP_ADDRESS"
$gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
$gcti.graph.metadata.source_type = "GLOBAL_CONTEXT"
$gcti.graph.metadata.product_name = "GCTI Feed"
$gcti.graph.metadata.threat.threat_feed_name = "Tor Exit Nodes"
$detection_ip = $d.detection.detection.variables["principal_ips"]
$detection_ip = $gcti.graph.entity.ip
match:
$detection_ip, $rule_name over 1h
outcome:
$risk_score = 80
condition:
$d and $gcti
}
搜尋
``` $rule_name = $d.detection.detection.rule_name
$gcti.graph.metadata.entity_type = "IP_ADDRESS" $gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence" $gcti.graph.metadata.source_type = "GLOBAL_CONTEXT" $gcti.graph.metadata.product_name = "GCTI Feed" $gcti.graph.metadata.threat.threat_feed_name = "Tor Exit Nodes"
$detection_ip = $d.detection.detection.variables["principal_ips"] $detection_ip = $gcti.graph.entity.ip
match: $detection_ip, $rule_name over 1h
condition: $d and $gcti ```
資訊主頁
共同發生偵測
用途:偵測特定時間範圍內,由同一實體觸發的相關策略組合,例如識別在 48 小時內觸發提權偵測和資料外洩偵測的使用者。
主要邏輯:使用某種形式的彙整,透過在 match 區段中加入共用實體變數 (例如 $pe_user),將多種不同的偵測類型相互關聯。
共同發生複合式偵測是一種匯總形式,可偵測相關事件的組合,例如使用者觸發的權限提升和資料外洩偵測組合。
範例:提權和外洩同時發生
規則
下列複合規則會搜尋與同一位使用者在 48 小時內相關聯的特定偵測序列或組合,也就是提權和資料外洩。
rule composite_privesc_exfil_sequential {
meta:
rule_name = "Privilege Escalation and Exfiltration Composite"
author = "Google Cloud Security"
description = "Looks for a detection sequence of privilege escalation followed by exfiltration."
severity = "High"
events:
$privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
$exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"
$privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
$exfil_user = $exfiltration.detection.detection.variables["principal_users"]
$privesc_user = $exfil_user
$privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds
match:
$privesc_user over 48h
outcome:
$risk_score = 75
$privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
$exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)
condition:
$privilege_escalation and $exfiltration
}
搜尋
$privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
$exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"
$privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
$exfil_user = $exfiltration.detection.detection.variables["principal_users"]
$privesc_user = $exfil_user
$privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds
match:
$privesc_user over 48h
outcome:
$privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
$exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)
condition:
$privilege_escalation and $exfiltration
資訊主頁
結果和變數管理
本節將示範如何計算風險,以及如何將資料正規化,供下游使用。
| 主題 | 範例 |
|---|---|
| 結果條件式 | 依計算出的風險分數篩選 |
| 查詢單一事件的結果 | 時間點嚴重程度標記 |
| 網路風險評分 | 網路風險評分規則 |
| 重構多事件邏輯 (重構前) | 結果重構 (重構前) |
| 重構多事件邏輯 (重構後) | 結果重構 (重構後) |
| 函式至預留位置的指派 |
查詢「outcome」專區
您可以在 YARA-L 2.0 規則中新增選用的 outcome 區段,擷取每次偵測的其他資訊。在 condition 部分,您也可以指定結果變數的條件。您可以使用偵測規則的 outcome 區段,設定供下游使用的變數。舉例來說,您可以根據所分析事件的資料設定嚴重程度分數。
如要瞭解詳情,請參考下列資源:
結果條件
用途:根據計算出的風險分數篩選偵測結果,減少干擾,確保只有高信賴度或高嚴重性事件會觸發快訊。這項功能可有效抑制未達特定業務門檻的低風險活動。
主要邏輯:使用條件式數學 (例如根據檔案大小或時間新增風險),在 outcome 區段中定義變數,然後在 condition 區段中參照這些變數,以控管偵測作業。
範例:依計算出的風險分數篩選
規則
在 condition 區段中,您可以使用 outcome 區段中定義的 outcome 變數。以下範例說明如何使用結果條件式,依風險分數篩選,減少偵測結果中的干擾。
rule OutcomeConditionalRule {
meta:
author = "alice@example.com"
description = "Rule that uses outcome conditionals"
events:
$u.metadata.event_type = "FILE_COPY"
$u.principal.file.size = $file_size
$u.principal.hostname = $hostname
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week($u.metadata.collected_timestamp.seconds)
outcome:
$risk_score =
if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices
condition:
$u and $risk_score >= 10
}
搜尋
metadata.event_type = "FILE_COPY"
principal.file.size = $file_size
principal.hostname = $hostname
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.collected_timestamp.seconds)
outcome:
$risk_score =
if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices
資訊主頁
這項查詢會新增 $hostname 結果變數,以便顯示與各個風險分數相關聯的主機。
metadata.event_type = "FILE_COPY"
principal.file.size = $file_size
principal.hostname = $hostname
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.collected_timestamp.seconds)
outcome:
$host = $hostname
$risk_score =
if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices
單一事件查詢 (含結果)
用途:使用即時情境資訊 (例如根據使用者清單或檔案屬性指派嚴重程度標記),豐富時間點偵測結果,無須時間範圍或事件關聯性。
主要邏輯:在缺少 match 區段的規則中使用 outcome 區段。這樣一來,您就能針對符合條件的每個事件擷取中繼資料,並執行條件式邏輯 (例如根據參照清單檢查使用者)。
範例:時間點嚴重程度標記
規則
以下範例說明如何在單一事件規則中使用 outcome 區段,為下游消耗量設定變數,例如根據檔案複製事件中涉及的特定使用者和檔案大小,設定嚴重程度分數。
rule OutcomeRuleSingleEvent {
meta:
author = "alice@example.com"
events:
$u.metadata.event_type = "FILE_COPY"
$u.principal.file.size = $file_size
$u.principal.hostname = $hostname
outcome:
$suspicious_host = $hostname
$admin_severity = if($u.principal.user.userid in %admin_users, "SEVERE", "MODERATE")
$severity_tag = if($file_size > 1024, $admin_severity, "LOW")
condition:
$u
}
搜尋
以下範例會識別檔案建立事件,並使用 outcome 區段,動態為每個結果指派嚴重程度。與多事件規則不同,這項未匯總的搜尋不需要事件變數或 match 區段。而是會個別處理每個記錄檔,並根據檔案大小和使用者權限,以自訂邏輯擴充 1 row per event。
metadata.event_type = "FILE_CREATION"
principal.file.size = $file_size
principal.hostname = $hostname
outcome:
$suspicious_host = $hostname
$admin_severity = if(principal.user.userid in %a1, "SEVERE", "MODERATE")
$severity_tag = if($file_size > 1024, $admin_severity, "LOW")
資訊主頁
由於主要目的是標記及豐富個別事件,因此這個範例不適用於資訊主頁變體。雖然資訊主頁可以匯總這些事件 (例如計算每個嚴重程度標記的事件總數),但這樣做會遮蓋這個未匯總搜尋功能設計要顯示的精細資料列層級詳細資料。
網路型風險評分
用途:計算一組事件的累計網路流量,找出高風險的資料傳輸。這項功能可讓您找出總資料量超過特定限制 (例如 1024 位元組) 的威脅,同時考量相關資產的安全性漏洞嚴重程度。
主要邏輯:在 outcome 區段中使用 sum() 匯總函式,合併 match 期間內所有事件的 sent_bytes 和 received_bytes。對於規則,查詢會使用 if 陳述式,在總和超過定義的門檻時套用較高的風險分數。
範例:以網路為準的風險評分規則
規則
以下範例說明如何使用 outcome 區段,根據網路活動計算動態風險分數。規則會加總事件群組中傳輸的總位元組數,並對超過特定資料門檻 (1024 位元組) 的相符項目套用較高的優先順序,同時考量相關資產的安全性弱點嚴重程度。
rule OutcomeRuleMultiEvent {
meta:
author = "alice@example.com"
events:
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)
$risk_score = if($total_network_bytes > 1024, 100, 50) +
max(
if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}
搜尋
以下範例說明如何建立搜尋變體,將 UDM 網路事件與實體內容圖 (ECG) 中的資產內容建立關聯。這項功能會使用 5 分鐘的 match 視窗,依主機名稱匯總網路流量、根據資料量和安全漏洞嚴重程度計算風險分數,並套用條件式篩選器,從最終結果集中排除特定資產 ID。
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)
$risk_score = if($total_network_bytes > 1024, 100, 50) +
max(
if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
資訊主頁
以下範例說明「資訊主頁」變體,可透過資產安全漏洞資料,擴充即時網路遙測資料。這項查詢會在 5 分鐘的滑動視窗中比對主機名稱,讓開發人員建構資訊主頁小工具,以視覺化方式呈現資產風險等級。系統會根據網路總處理量和資產中發現最嚴重的安全漏洞,動態調整風險分數,優先顯示可能遭入侵的系統。
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)
$risk_score = if($total_network_bytes > 1024, 100, 50) +
max(
if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
重構多事件 outcome 規則 (重構前)
用途:將多事件規則轉換為單一事件規則,提升系統效能並縮短處理延遲時間。如果規則原本只設計了比對部分來啟用結果部分,但實際上不需要跨多個不同事件進行關聯,就非常適合使用這項功能。
主要邏輯:從 outcome 區段移除 match 區段和任何匯總函式 (例如 max()、sum() 或 count())。這項轉換會將規則從依時間分組事件,改為在每個事件抵達時個別評估。
match 區段),以及多重事件規則 (含有 match 區段的規則)。
單一事件規則 (沒有 match 區段的規則) 和多事件規則都可以使用 outcome 區段。如果您先前設計多事件規則只是為了使用結果區段,可以選擇刪除 match 區段來重構這些規則,以提升效能。請注意,由於規則不再有適用於分組的match部分,您可能會收到更多偵測結果。
示例:結果重構 (重構前)
規則
以下範例顯示只使用一個事件變數的多事件結果規則。由於使用 match 區段,規則引擎必須先將事件分組到 5 分鐘的時段,再計算結果,因此會比單一事件評估消耗更多資源。
rule OutcomeMultiEventPreRefactor {
meta:
author = "alice@example.com"
description = "Outcome refactor rule, before the refactor"
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
}
搜尋
等同於統計資料查詢
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
資訊主頁
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
重構多事件 outcome 規則 (重構後)
用途:完成查詢最佳化,提升處理速度。移除分組規定後,查詢會在單一相符事件抵達時立即觸發偵測,大幅提升規則引擎的效率。
主要邏輯:刪除 match 區段,並從 outcome 變數指派中移除 aggregate 函式 (例如 max())。if 陳述式中的邏輯保持不變,但現在會套用至單一事件,而非群組。
您可以刪除 match 區段,重構查詢。注意:您也必須移除 outcome 區段中的匯總,因為查詢現在是單一事件。如要進一步瞭解匯總,請參閱結果匯總。
範例:Outcome refactor (: #outcome-post-refactor)
規則
rule OutcomeSingleEventPostRefactor {
meta:
author = "alice@example.com"
description = "Outcome refactor rule, after the refactor"
events:
$u.udm.principal.hostname = $hostname
// We deleted the match section.
outcome:
// We removed the max() aggregate.
$risk_score = if($hostname = "my-hostname", 100, 50)
condition:
$u
}
搜尋
events:
$u.udm.principal.hostname = $hostname
outcome:
$risk_score = if($hostname = "my-hostname", 100, 50)
資訊主頁
events:
$u.udm.principal.hostname = $hostname
outcome:
$risk_score = if($hostname = "my-hostname", 100, 50)
函式到預留位置的指派
使用案例:正規化資料 (例如標準化電子郵件網域),確認比對部分的群組是否正確。
主要邏輯:將 re.capture() 或 strings.concat() 的結果指派給預留位置變數。
範例:將函式指派給預留位置變數
您可以將預留位置變數指派給函式呼叫的結果,並在規則的其他部分使用預留位置變數,例如 match 區段、outcome 區段或 condition 區段。
規則
rule FunctionToPlaceholderRule {
meta:
author = "alice@example.com"
description = "Rule that uses function to placeholder assignments"
events:
$u.metadata.event_type = "EMAIL_TRANSACTION"
// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture($u.network.email.to , "(.*)@")
// Use function-placeholder assignment to normalize an email:
// address@-> address@company.com
$email_from_normalized = strings.concat(
re.capture($u.network.email.from , "(.*)@"),
"@company.com"
)
// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)
match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m
outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
if($dayofweek = 1 or $dayofweek = 7, 10, 0)
)
condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1
}
搜尋
metadata.event_type = "EMAIL_TRANSACTION"
// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture(network.email.from , "(.*)@")
// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
re.capture(network.email.to , "(.*)@"),
"@company.com"
)
// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.event_timestamp.seconds)
match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m
outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
if($dayofweek = 1 or $dayofweek = 7, 10, 0)
)
condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1
資訊主頁
以下範例展示經過最佳化調整的資訊主頁變體,適合用於時間序列資料視覺化。這項查詢使用一天的滾動式時間區間,而非以分鐘為單位,因此會產生穩定且不重疊的資料點,非常適合繪製長期風險分數圖表。這項邏輯會將電子郵件實體標準化,並對週末交易套用較高的風險權重,提供可長期監控的每日可疑電子郵件活動趨勢。
metadata.event_type = "EMAIL_TRANSACTION"
// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture(network.email.from , "(.*)@")
// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
re.capture(network.email.to , "(.*)@"),
"@company.com"
)
// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.event_timestamp.seconds)
match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m
outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
if($dayofweek = 1 or $dayofweek = 7, 10, 0)
)
condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1
最佳化和篩選
有效最佳化規則需要精確篩選資料,確保偵測引擎只處理有意義的資訊。排除「有雜訊」或不完整的資料,可大幅提升規則效能,並確保產生的快訊可供採取行動。
| 主題 | 範例 |
|---|---|
| 排除零值 | 明確和隱含的零值排除 |
排除零值
用途:明確篩除空白字串、空值或一般預留位置帳戶 (例如「訪客」),確保規則準確度並減少誤判,因為這些帳戶不會提供可執行的安全性資料。
主要邏輯:針對「match」部分使用的變數,運用規則引擎的零值隱含篩選功能,同時針對其他事件欄位使用明確的不等式運算子 (!= ""),確保只有已填入資料的欄位會觸發偵測。
規則引擎會隱含地篩除 match 區段中所有預留位置的零值。使用 allow_zero_values 選項停用。不過,對於其他參照的事件欄位,除非您明確指定這類條件,否則系統不會排除零值。詳情請參閱「比對區段中的零值」。
範例:明確和隱含排除零值
規則
rule ExcludeZeroValues {
meta:
author = "alice@example.com"
events:
$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname
// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"
$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname
// $e2.target.asset_id cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
match:
// $hostname cannot be empty string. The rule behaves as if the
// predicate, `$hostname != ""` was added to the events section, because
// `$hostname` is used in the match section.
$hostname over 1h
condition:
$e1 and $e2
}
搜尋
您必須明確指出 hostname 不得為空字串,因為 match 區段中的預留位置沒有隱含的零值篩選條件。
$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname
// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"
$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname
// $e2.target.asset_id and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""
match:
$hostname over 1h
資訊主頁
您必須明確指出 hostname 不得為空字串,因為 match 區段中的預留位置沒有隱含的零值篩選條件。
$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname
// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"
$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname
// $e2.target.asset_id and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""
match:
$hostname over 1h
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。