YARA-L 2.0 を使用した検索の統計情報と集計

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

このページでは、YARA-L 2.0 を使用して UDM イベントに対して統計クエリを実行し、結果をグループ化して分析する方法について説明します。

環境で生成された大量の UDM イベントを処理する場合は、UDM 検索データの傾向を把握することが重要です。統計関数と集計関数を使用して、UDM ログから実用的な分析情報を取得できます。UDM 検索は、YARA-L 2.0 のすべての集計関数をサポートしています。

統計クエリのユースケース

統計クエリは、次のユースケースで使用できます。

  • 重要な指標を追跡する: UDM イベントと、既知の悪意のある IP アドレスと通信しているホストなどの関連アセットの分布と頻度を測定できます。

  • 異常な動作を検出する: 予期しないネットワーク トラフィックの急増や営業時間外のログインなど、セキュリティ インシデントを示す可能性があるアクティビティの急増を特定できます。

  • 経時的な傾向を分析する: セキュリティ ポスチャーの変化を評価して、制御の有効性を評価したり、改善すべき領域を特定したりできます。たとえば、脆弱性数の経時的な変動をモニタリングします。

検出エンジン ルールで使用される YARA-L 構造と同様の構文を使用して、UDM 検索クエリの結果をグループ化して並べ替えることができます。詳細については、YARA-L 2.0 言語の構文をご覧ください。

YARA-L 2.0 クエリの構造は次のとおりです。

  • フィルタリング ステートメント: イベントをフィルタする条件を指定します。

  • Match(省略可): グループ化するフィールドを定義します。詳細については、一致セクションの構文をご覧ください。

  • 結果: クエリの出力を指定します。詳細については、結果セクションの構文をご覧ください。

  • Order: クエリ結果の順序を asc(昇順)または desc(降順)で決定します。順序(asc または desc)が指定されていない場合、デフォルトは asc になります。

  • Limit(省略可): クエリが返す行の最大数を設定します。

注文と上限の使用例を次に示します。

metadata.log_type = "OKTA"

match:
    principal.ip
Outcome:
    $user_count_by_ip = count(principal.user.userid)

order:
 $user_count_by_ip desc

limit:
    20

集約

UDM 検索では、次の集計関数がサポートされています。

配列

array(expression)

説明

array 関数は、すべての値をリスト形式で返します。リストを最大 25 個のランダムな要素に切り詰めます。

パラメータのデータ型

STRING

戻り値の型

LIST

コードサンプル

イベントタイプを含む配列を返します。

  $event_type = metadata.event_type
  outcome:
    $event_type_array = array($event_type)

array_distinct

array_distinct(expression)

説明

array_distinct 関数は、リスト形式で一意の値をすべて返します。リストを最大 25 個のランダムな要素に切り詰めます。重複除去は、切り捨ての前に適用されます。

パラメータのデータ型

STRING

戻り値の型

LIST

コードサンプル

個別のイベントタイプを含む配列を返します。

  $event_type = metadata.event_type
  outcome:
    $event_type_array = array_distinct($event_type)

avg

avg(numericExpression)

説明

avg 関数は、数値列内の値の平均値を返します。計算時、NULL 値は無視されます。多くの場合、match とともに使用して、データ内の特定のグループ内の平均を計算します。

パラメータのデータ型

NUMBER

戻り値の型

NUMBER

コードサンプル

target.ip が空でないすべてのイベントを検索します。principal.ip で一致するすべてのイベントについて、metadata.event_timestamp.seconds の平均値を avg_seconds という変数に格納します。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $avg_seconds = avg(metadata.event_timestamp.seconds)

count

count(expression)

説明

count 関数は、グループ内の行数を返します。多くの場合、match とともに使用して、データ内の特定のグループのカウントを取得します。

パラメータのデータ型

STRING

戻り値の型

NUMBER

コードサンプル

ユーザーのログイン成功回数の経時変化を返します。

  metadata.event_type = "USER_LOGIN"
  $security_result = security_result.action
  $security_result = "ALLOW"
  $date = timestamp.get_date(metadata.event_timestamp.seconds, "America/Los_Angeles")
  match:
      $security_result, $date
  outcome:
      $event_count = count(metadata.id)

count_distinct

count_distinct(expression)

説明

count_distinct 関数は、グループ内で個別の値を持つ行の数を返します。多くの場合、match とともに使用して、データ内の特定のグループのカウントを取得します。

パラメータのデータ型

STRING

戻り値の型

NUMBER

コードサンプル

成功したユーザー ログインの重複を除いた数を経時的に返します。

  metadata.event_type = "USER_LOGIN"
  $security_result = security_result.action
  $security_result = "ALLOW"
  $date = timestamp.get_date(metadata.event_timestamp.seconds, "America/Los_Angeles")
  match:
      $security_result, $date
  outcome:
      $event_count = count_distinct(metadata.id)

最大

max(numericExpression)

説明

max 関数は、数値列内の値の最大値を返します。多くの場合、match とともに使用して、データ内の各グループの最大値を取得します。

パラメータのデータ型

NUMBER

戻り値の型

NUMBER

コードサンプル

target.ip が空でないすべてのイベントを検索します。principal.ip で一致するすべてのイベントについて、metadata.event_timestamp.seconds の最大値を max_seconds という変数に格納します。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $max_seconds = max(metadata.event_timestamp.seconds)

min(numericExpression)

説明

min 関数は、数値列内の値の最小値を返します。多くの場合、match とともに使用して、データ内の各グループの最小値を取得します。

パラメータのデータ型

NUMBER

戻り値の型

NUMBER

コードサンプル

target.ip が空でないすべてのイベントを検索します。principal.ip で一致するすべてのイベントについて、metadata.event_timestamp.seconds の最小値を min_seconds という変数に格納します。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $min_seconds = min(metadata.event_timestamp.seconds)

sum

sum(numericExpression)

説明

sum 関数は、数値列内の値の合計を返します。計算時には NULL 値は無視されます。多くの場合、match とともに使用して、データ内のさまざまなグループ内の合計を計算します。

パラメータのデータ型

NUMBER

戻り値の型

NUMBER

コードサンプル

target.ip が空でないすべてのイベントを検索します。principal.ip で一致するすべてのイベントについて、network.sent_bytes の合計を sent_bytes という変数に格納します。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $sent_bytes = sum(network.sent_bytes)

stddev

stddev(numericExpression)

説明

stddev 関数は、可能なすべての値の標準偏差を返します。

パラメータのデータ型

NUMBER

戻り値の型

NUMBER

コードサンプル

target.ip が空でないすべてのイベントを検索します。principal.ip で一致するすべてのイベントについて、metadata.event_timestamp.seconds の標準偏差を stddev_seconds という変数に格納します。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $stddev_seconds = stddev(metadata.event_timestamp.seconds)

earliest

earliest(timestamp)

説明

earliest 関数は、マイクロ秒単位の解像度で、一連のレコードから最も古いタイムスタンプを返します。

パラメータのデータ型

TIMESTAMP

戻り値の型

TIMESTAMP

コードサンプル

hostname で一致するすべてのイベントについて、metadata.event_timestamp のうち最も古いものを start 変数に保存します。

  $hostname = principal.hostname
  match:
    $hostname
  outcome:
    $start = earliest(metadata.event_timestamp)

最新

latest(timestamp)

説明

latest 関数は、マイクロ秒単位の解像度で、一連のレコードから最新のタイムスタンプを返します。

パラメータのデータ型

TIMESTAMP

戻り値の型

TIMESTAMP

コードサンプル

hostname で一致するすべてのイベントについて、metadata.event_timestamp の最新の値を end 変数に保存します。

  $hostname = principal.hostname
  match:
    $hostname
  outcome:
    $end = latest(metadata.event_timestamp)

YARA-L 2.0: 検索と UDM の使用

  • イベント ウィンドウ検索に使用される over キーワードは、検索ではサポートされていません。

  • UDM 検索クエリに condition セクションと option セクションが含まれていません。

時間粒度でグループ化する

SQL で列をグループ化するのと同様に、match セクションでイベント フィールドとプレースホルダを特定の時間粒度でグループ化できます。

構文は次のとおりです。

match:
  ... [BY|OVER EVERY] [FIRST] [TIME_GRANULARITY]

時間粒度でグループ化するには、キーワード by または over every を使用します。使用できる時間粒度は次のとおりです。

  • MINUTE または m
  • HOUR または h
  • DAY または d
  • WEEK または w
  • MONTH または mo

by キーワードと over every キーワードは機能的に同等です。どちらか一方を使用できます。

IP アドレスとホスト名を時間ごとにグループ化します。

$hostname = principal.hostname
match:
  $hostname, target.ip by hour

すべてのイベントの数をホスト名とイベントが発生した日でグループ化します。

$hostname = target.hostname
match:
  $hostname over every day
outcome:
  $events_count = count($hostname)

エンティティ コンテキストなどの一部のデータソースは、時間範囲(<start_time><end_time>)で有効であり、単一のタイムスタンプはありません。

first キーワードは省略可能で、単一のタイムスタンプに適用されます。つまり、期間にわたって有効なデータソースの場合、キーワード first は開始時刻(<start_time>)のみを考慮します。

たとえば、時間範囲が(1m, 5m)で、時間粒度が 1m のエンティティについて考えてみましょう。結果がホスト(h1h2)でグループ化されている場合、返される列は(h11m)と(h21m)になり、残りの期間は無視されます。

first キーワードは byover every の両方に追加でき、どちらも同じ動作になります。by first の使用は over every first と同等です。

次に、時間範囲で有効なエンティティ コンテキスト データソースで by 演算子を使用するクエリの例を示します。このクエリでは、first キーワードが省略されているため、時間範囲全体が考慮されます。

graph.entity.hostname != ""
match:
  graph.entity.ip by hour
outcome:
  $min_seconds = min(graph.metadata.event_metadata.event_timestamp.seconds)

検索で可視化を作成して保存する

このセクションでは、Google SecOps 統合データモデル(UDM)検索内のデータ可視化機能の概要について説明します。この機能を使用すると、セキュリティ オペレーション センター(SOC)のアナリストは、検索結果から可視化を作成してダッシュボードに保存することで、脅威を効率的に検出、調査、対応できます。

ビジュアリゼーションを作成してダッシュボードに保存する

ダッシュボードに追加する可視化を作成して保存する手順は次のとおりです。

  1. match セクションと outcome セクションを含む YARA-L クエリを作成します。

  2. 期間を選択し、[検索を実行] をクリックしてクエリを実行します。結果は [統計] タブと [可視化] タブで確認できます。

  3. [可視化] タブで、次の操作を行います。 a. [グラフの種類] リストからグラフの種類を選択します。 b. [データ設定] で設定を調整して、グラフをカスタマイズします。

  4. [ダッシュボードに追加] 画面で、次の操作を行います。 a. [グラフ名]、[説明]、[期間] を入力します。 b. グラフを既存のダッシュボードに追加するか、新しいダッシュボードを作成するかを選択します。

  5. [Add to Dashboard] をクリックして、グラフをダッシュボードに追加します。

さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。