複合検出ルールを作成する

以下でサポートされています。

このドキュメントでは、Google Security Operations プラットフォーム内で複合ルールを作成する方法について技術的なガイダンスを提供します。このプロセスでは、複数の YARA-L 2.0 ルールを接続して複雑な攻撃パターンを特定します。複合検出はマルチイベント ルールとして構造化され、標準の単一イベント ルールと同じ基本的な構文を維持します。詳細については、複合検出の概要をご覧ください。

ルール構造を理解する

複合検出ルールは常にマルチイベント ルールであり、単一イベント ルールと同じ構造と構文に従います。

複合ルールには、次の重要なコンポーネントがあります。

  • events セクション: 入力を定義します。ルールが分析する特定の検出またはイベントです。

  • match セクション: 定義された時間枠で入力を接続する方法を指定します。

  • condition セクション: 結合されたイベントがアラートをトリガーする条件を満たしているかどうかを判断する最終的なロジックが含まれています。

events セクションで入力を定義する

複合検出ルールを作成する最初の手順は、events セクションでルールの入力を定義することです。複合ルールの入力はコレクションから取得されます。コレクションには、他のクエリによって生成された検出が保存されます。 Google SecOps には、コレクションからデータにアクセスする次の 2 つの方法が用意されています。

変数またはメタラベルを使用して検出コンテンツを参照する

元の UDM イベントを参照せずに検出からデータにアクセスするには、outcome 変数、match 変数、meta ラベルを使用します。このアプローチは、柔軟性が高く、さまざまなルールタイプで互換性が高いため、おすすめです。

たとえば、複数のルールで、さまざまなコンテキストで文字列(URL、ファイル名、レジストリ キーなど)を検索する場合、共通の outcome 変数に文字列を保存できます。複合ルールからこの文字列にアクセスするには、開始 with detection し、 Collection リソースの要素を使用して関連情報を特定します。

例: 検出ルールで次の情報が生成されるとします。

  • 結果変数: 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.urlprincipal.ip などのフィールドを直接クエリできます。

  • ルール ID でルールを参照する(推奨): detection.detection.rule_id フィールドを使用して、ID でルールを参照します。ルール ID は、Google SecOps のルールの URL で確認できます。ユーザーが生成したルールの 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/"

match セクションで入力を結合する

複合ルールで関連する検出、イベント、エンティティを接続するには、events セクションで定義された変数を使用して match セクションを定義します。これらの変数には、ルールラベル、結果変数、一致変数、検出フィールド、コレクション要素などがあります。

構文については、 一致セクションの構文をご覧ください。

複合ルール: 時間間隔とホップ ウィンドウ

複合ルールは、単一の時点ではなく、時間間隔に対して検出とイベントを照合します。入力検出の時間枠がホップ ウィンドウと重複する場合(たとえば、アクティビティがその時間ブロック中にアクティブだった場合)、複合ホップ ウィンドウと一致します。

検出が隣接するホップ ウィンドウの境界にまたがる場合、1 つの検出で複数のアラートがトリガーされる可能性があります(パイプラインの遅延により、これらの過去の一致は後で表示されます)。具体的には、入力検出の時間枠(WindowStart から WindowEnd)がホップ ウィンドウと重複する場合、複合ルール ホップ ウィンドウは一致をトリガーします。

次に例を示します。

  1. 複合ルールには、60 分のホップ ウィンドウがあります。ホップ 1(18:58 ~ 19:58)とホップ 2(19:58 ~ 20:58)。
  2. アップストリーム プロデューサーの検出には、19:57:54 ~ 20:56:54(59 分)のウィンドウがあります。
  3. プロデューサー ウィンドウは 19:57:54(ホップ 1 の終了の 6 秒前)に開始し、20:56:54(ホップ 2 の間)に終了したため、両方のホップ ウィンドウと重複します。
  4. これにより、2 つの複合検出(ホップ 1 用とホップ 2 用)がトリガーされ、偽陰性を防ぐことができます。プロデューサー ルールが重複で一致しなかった場合、部分的に重複する検出はホップ 1 またはホップ 2 のいずれにも考慮されず、検出と他のイベントの相関関係が見逃されます。

ホップ ウィンドウの指定方法の詳細と例については、 ホップ ウィンドウをご覧ください。

condition セクションを定義する

condition セクションを定義して、match セクションの結果を評価します。条件が 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 のプロフェッショナルから回答を得ることができます。