複合検出ルール
Google SecOps の複合検出では、複数の YARA-L ルールを接続します。このドキュメントでは、複合ルールを作成する方法について説明します。詳細については、複合検出の概要をご覧ください。
ルールの構造を理解する
複合検出ルールは常にマルチイベント ルールであり、単一イベント ルールと同じ構造と構文に従います。
複合ルールには、次の重要なコンポーネントがあります。
eventsセクション: 入力(ルールが分析する特定の検出またはイベント)を定義します。matchセクション: 定義された時間枠で入力を接続する方法を指定します。conditionセクション: 結合されたイベントがアラートをトリガーする条件を満たしているかどうかを判断する最終的なロジックが含まれています。
events セクションで入力を定義する
複合検出ルールを構築する最初の手順は、events セクションでルールの入力を定義することです。複合ルールの入力は、他のクエリで生成された検出を保存するコレクションから取得されます。Google SecOps には、コレクションからデータにアクセスする次の 2 つの方法があります。
変数またはメタラベルを使用して検出コンテンツを参照する
元の UDM イベントを参照せずに検出からデータにアクセスするには、outcome 変数、match 変数、または meta ラベルを使用します。このアプローチは、柔軟性が高く、さまざまなルールタイプ間で互換性が高いため、おすすめです。
たとえば、複数のルールで、さまざまなコンテキストで検索する文字列(URL、ファイル名、レジストリキーなど)を共通の outcome 変数に保存できます。複合ルールからこの文字列にアクセスするには、detection で始まり、コレクション リソースの要素を使用して関連情報を特定します。
例: 検出ルールが次の情報を生成するとします。
結果変数:
dest_domain = "cymbal.com"UDM フィールド:
target.hostname = "cymbal.com"
複合ルールでは、次のパスを使用してこのデータにアクセスできます。
detection.detection.outcomes["dest_domain"]を使用してdest_domain結果変数にアクセスします。target.hostnameUDM フィールドにアクセスするdetection.collection_elements.references.event.target.hostname。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 でルールを参照します。ルール ID は、Google SecOps のルールの URL で確認できます。ユーザーが生成したルールにはru_UUID形式の ID があり、キュレートされた検出にはur_UUID形式の ID があります。次に例を示します。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/"
match セクションで入力を結合する
複合ルールで関連する検出、イベント、エンティティを接続するには、events セクションで定義された変数を使用して match セクションを定義します。これらの変数には、ルールラベル、結果変数、一致変数、検出フィールド、コレクション要素などがあります。
構文については、match セクションの構文をご覧ください。
condition セクションを定義する
match セクションの結果を評価する condition セクションを定義します。条件が true の場合、アラートが生成されます。構文については、条件セクションの構文をご覧ください。
複合ルールに高度な手法を適用する
このセクションでは、複合ルールを構築する際に高度な手法を適用する方法について説明します。
イベントと検出を組み合わせる
複合ルールでは、UDM イベント、エンティティ グラフデータ、検出フィールドなど、複数のデータソースを組み合わせることができます。次のガイドラインが適用されます。
ソースごとに個別の変数を使用する: 各データソース(イベント、エンティティ、検出を含む)に一意のイベント変数(イベントの場合は
$e、検出の場合は$dなど)を割り当てます。共有コンテキストでソースを結合する: ルールの条件で、ユーザー ID、IP アドレス、ドメイン名などの共通の値を使用してデータソースを接続します。
一致ウィンドウを定義する: 48 時間以内の時間枠で
match句を常に含めます。
例: イベントと検出を組み合わせる
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
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。