YARA-L 2.0 言語の構文

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

このセクションでは、YARA-L 構文の主な要素について説明します。YARA-L 2.0 言語の概要もご覧ください。

ルールの構造

YARA-L 2.0 では、変数の宣言、定義、用途を次の順序で指定する必要があります。

  1. メタ
  2. events
  3. 一致(省略可)
  4. outcome(省略可)
  5. condition
  6. options(省略可能)

次の図は、ルールの一般的な構造を示しています。

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.
}

メタセクションの構文

Meta セクションは複数の行で構成され、各行は Key-Value ペアを定義します。キー部分は引用符で囲まない文字列に、値の部分は引用符で囲まれた文字列にする必要があります。

<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

この宣言は、この変数がイベント変数に指定されたフィールドを表すことを示します。イベント フィールドが繰り返しフィールドの場合、一致変数は配列内の任意の値を表すことができます。 1 つの一致変数またはプレースホルダ変数に複数のイベント フィールドを割り当てることもできます。これは推移的な結合条件です。

たとえば、次のようになります。

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

これは次と同等です。

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

変数を使用する場合、変数宣言でその変数を宣言する必要があります。変数が宣言なしで使用されていると、コンパイル エラーとみなされます。

イベント変数のフィルタ

単一のイベント変数に対して動作するブール式は、フィルタと見なされます。

イベント変数の結合

ルールで使用されるすべてのイベント変数は、次のいずれかの方法で他のすべてのイベント変数と結合する必要があります。

  • 2 つの結合されたイベント変数のイベント フィールドを直接比較する(例: $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 using function to event comparison
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
  // $e1 joins with $e2 using 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 using the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  // $e1 and $e2 are transitively joined using 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 分です。

  • 指定できる最大時間は 14 日です。

有効な match の例を次に示します。

$var1, $var2 over 5m

このステートメントは、ルールが一致した場合に $var1$var2events セクションで定義)を返します。指定する時間は 5 分です。間隔が 5 分を超えるイベントは相関されないため、ルールで無視されます。

有効な match セクションの別の例を示します。

$user over 1h

次のステートメントは、ルールが一致した場合に $user を返します。指定する期間は 1 時間です。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] に対して実行されるルールで、30mmatch セクションがある場合、次のような重複するホップ ウィンドウのセットが発生する可能性があります。[1:00, 1:30]、[1:03, 1:33]、[1:06, 1:36] などです。これらのウィンドウは、複数のイベントを関連付けるために使用されます。

スライディング ウィンドウ

ホップ ウィンドウを使用すると、特定の順序で発生するイベントを検索することはできません(たとえば、e1e2 から 2 分後までに発生します)。イベント e1 の発生とイベント e2 の発生は、生成された同じホップ ウィンドウに含まれる場合にのみ関係があります。

このようなイベント シーケンスを検索するより効果的な方法は、スライディング ウィンドウを使用することです。指定されたピボット イベント変数の開始時または終了時に、match セクションで指定された期間のスライディング ウィンドウが生成されます。次に、各スライディング ウィンドウ内でイベントが相互に関連付けられます。これにより、特定の順序で発生するイベントを検索できます(たとえば、e1e2 から 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 は特殊です。オプションでこの名前を使用して結果を定義できます。定義する場合は、整数型または浮動型にする必要があります。入力すると、ルール検出から発生したアラートの Enterprise Insights ビューrisk_score が表示されます。

ルールの結果セクションに $risk_score 変数を含めない場合、次のいずれかのデフォルト値が設定されます。

  • ルールがアラートを生成するように構成されている場合、$risk_score は 40 に設定されます。
  • アラートを生成するようにルールが構成されていない場合、$risk_score は 15 に設定されます。

$risk_score の値は security_result.risk_score UDM フィールドに保存されます。

複合検出のターゲット リスクスコアリングでは、オプションの結果変数 $risk_entity_to_score を定義できます。この変数を使用すると、ルールで結果内で定義された特定のエンティティにリスクスコアを選択的に適用できます。この結果変数は、文字列または文字列のリストとして定義できます。

ルールの結果セクションに $risk_entity_to_score 変数を含めない場合は、リスクスコアの計算例で、リスクスコアの割り当て方法の詳細を確認してください。

たとえば、$risk_entity_to_score は次のように使用できます。 none events: $bad_host = $e.principal.hostname outcome: $risk_entity_to_score = $bad_host // only this entity will get a risk score $risk_score = 60

結果変数のデータ型

結果変数はそれぞれ異なるデータ型を持つことができます。データ型は、計算に使用される式によって決まります。次の結果データ型がサポートされています。

  • 整数
  • 浮動小数点数
  • 文字列
  • 整数のリスト
  • 浮動小数点数のリスト
  • 文字列のリスト

条件付きロジック

条件付きロジックを使用して、結果の値を計算できます。条件は、次の構文パターンを使用して指定します。

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 two preceding outcomes combined.
  $risk_score2 = if(count($login.metadata.event_timestamp.seconds) > 5, "SEVERE", "MODERATE")

condition:
  $e

結果変数は、次の式を除き、結果割り当ての右辺の任意のタイプの式で使用できます。

  • 集約
  • Arrays.length() 関数の呼び出し
  • any 修飾子または all 修飾子を使用する

集約

繰り返しイベント フィールドはスカラー以外の値です。つまり、1 つの変数が複数の値を指します。たとえば、イベント フィールド変数 $e.target.ip は繰り返しフィールドであり、0 個、1 個、または複数の IP 値を持つことができます。これはスカラー以外の値です。一方、イベント フィールド変数 $e.principal.hostname は繰り返しフィールドではなく、値は 1 つ(スカラー値)のみです。

同様に、一致ウィンドウのあるルールの結果セクションで使用される繰り返しなしのイベント フィールドと繰り返しありのイベント フィールドは、どちらもスカラー値ではありません。たとえば、次のルールは、一致セクションを使用してイベントをグループ化し、結果セクションで繰り返し以外のイベント フィールドを参照します。

rule OutcomeAndMatchWindow{
  ...
  match:
    $userid over 5m
  outcome:
    $hostnames = array($e.principal.hostname)
  ...
}

ルールが実行される 5 分間のウィンドウには、イベントが 1 つも含まれない場合もあれば、1 つまたは複数のイベントが含まれる場合もあります。結果セクションは、一致ウィンドウ内のすべてのイベントに対して作用します。結果セクション内で参照されるイベント フィールド変数は、一致ウィンドウ内の各イベントのフィールドの 0 個、1 個、または複数の値を指すことができます。たとえば、5 分間の時間枠に 5 つの $e イベントが含まれている場合、結果セクションの $e.principal.hostname は 5 つの異なるホスト名を指します。このルールの outcome セクションでは、イベント フィールド変数 $e.principal.hostname は非スカラー値として扱われます。

結果変数では常に単一のスカラー値が生成される必要があるため、結果の割り当てが依存するスカラー値以外の値はすべて、集約して単一のスカラー値を生成する必要があります。結果セクションでは、次の値はスカラー値ではないため、集約する必要があります。

  • ルールが一致セクションを使用する場合のイベント フィールド(繰り返しまたは非繰り返し)
  • ルールで一致セクションを使用する場合のイベント プレースホルダ(繰り返しまたは非繰り返し)
  • ルールが一致セクションを使用しない場合の繰り返しイベント フィールド
  • ルールで一致セクションを使用していない場合、イベント プレースホルダが繰り返される

スカラー イベント フィールド、スカラー イベント プレースホルダ、定数は、一致セクションを含まないルールの集約関数でラップできます。ただし、ほとんどの場合、これらの集計ではラップされた値が返されるため、不要です。例外は array() 集約です。これを使用すると、スカラー値を配列に明示的に変換できます。

結果変数は集計のように扱われます。別の結果割り当てで参照する場合は、再集約しないでください。

次の集約関数を使用できます。

  • max(): 可能性のあるすべての値の最大値を出力します。整数と浮動小数点数でのみ機能します。
  • min(): 可能性のあるすべての値の最小値を出力します。整数と浮動小数点数でのみ機能します。
  • sum(): 可能性のあるすべての値の和を出力します。整数と浮動小数点数でのみ機能します。
  • count_distinct(): 可能性のあるすべての値を収集し、可能性のある値の一意の値の数を出力します。
  • count(): count_distinct() のように動作しますが、可能性のある値の一意でない値の数を返します。
  • array_distinct(): 可能性のあるすべての一意の値を収集し、これらの値のリストを出力します。Distinct 値のリストを 1,000 個のランダムな要素に切り詰めます。重複除去によって一意のリストを取得してから、切り捨てが適用されます。
  • array(): array_distinct() のように動作しますが、一意でない値のリストを返します。また、値のリストを 1,000 個のランダムな要素に切り詰めます。
  • 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 が必要であるため、集約関数は複数のイベントで動作します。次のイベントで 1 つの検出が生成されたとします。

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 セクションですでに関連付けられているイベント変数のみを関連付けることができます。相関関係は、異なるイベント変数の 2 つのイベント フィールドが等しい場合に発生します。

YARA-L 2.0 の概要の結果セクションを使用して例を確認できます。 結果セクションの検出の重複除去の詳細については、コンテキスト アウェア分析の作成をご覧ください。

条件セクションの構文

  • events セクションで定義されているイベントとプレースホルダに一致する条件を指定します。詳しくは、次のセクションのイベントとプレースホルダの条件をご覧ください。
  • (省略可)and キーワードを使用して、outcome セクションで定義された結果変数を使用して一致条件を指定します。詳細については、次の結果の条件のセクションをご覧ください。

カウント文字

# 文字は condition セクションの特殊文字です。イベント名またはプレースホルダ変数名の前で使用する場合は、すべての events セクション条件を満たす固有のイベントまたは値の数を表します。

たとえば、#c > 1 は、変数 c が 1 回以上発生する必要があることを意味します。

値文字

$ 文字は condition セクションの特殊文字です。結果変数名の前で使用する場合は、その結果の値を表します。

イベント名またはプレースホルダ変数名($event など)の前で使用する場合は、#event > 0 を表します。

イベントとプレースホルダの条件

イベントとプレースホルダ変数の条件述語を一覧表示します。

これらの述語は、キーワード and または or を使用して結合できます。

  • 条件の間に and キーワードを使用します。

  • キーワード or は、ルールに単一のイベント変数のみが含まれている場合にのみ使用します。

同じイベントの 2 つのプレースホルダ間で 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
}

異なるイベントの 2 つの条件間で 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.
}

制限付き条件と制限なし条件

次の条件は制限付き条件です。関連付けられたイベント変数を強制的に存在するようにします。つまり、検出によりイベントが少なくとも 1 回出現する必要があります。

  • $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

不在の場合の要件

不在ルールをコンパイルするには、次の要件を満たす必要があります。

  1. 少なくとも 1 つの UDM イベントに制限付き条件が必要です(つまり、少なくとも 1 つの UDM イベントが存在する必要があります)。
  2. プレースホルダに制限なし条件が設定されている場合は、少なくとも 1 つの制限付き UDM イベントに関連付ける必要があります。
  3. エンティティに制限なし条件がある場合は、少なくとも 1 つの制限付き 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 イベントとエンティティが条件セクションに含まれる。
    • 少なくとも 1 つの 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
    • 少なくとも 1 つの 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

  • 浮動小数点数: 演算子 =, >, >=, <, <=, != を使用して浮動小数点リテラルと比較します。次に例を示します。

    $risk_score <= 5.5

  • 文字列: = または != の文字列リテラルと比較します。次に例を示します。

    $severity = "HIGH"

  • 整数のリストまたは配列: arrays.contains 関数を使用して条件を指定します。例:

    arrays.contains($event_ids, "id_1234")

ルール分類

一致セクションのあるルールで結果条件を指定すると、そのルールがルール割り当てのマルチイベントルールとして分類されます。 単一イベントとマルチイベントの分類について詳しくは、単一イベントルールマルチイベントルールをご覧ください。

options セクションの構文

options セクションでは、ルールのオプションを指定できます。オプション セクションを指定する例を次に示します。

rule RuleOptionsExample {
  // Other rule sections

  options:
    allow_zero_values = true
}

オプションは key = value 構文を使用して指定できます。ここで、key は事前定義されたオプション名、value はオプションの有効な値です。次のオプションで指定されているとおりです。

allow_zero_values

このオプションの有効な値は truefalse です。このオプションが有効かどうかを決定します。デフォルト値は false です。ルールで指定されていない場合、このオプションは無効になります。

この設定を有効にするには、ルールのオプション セクションに allow_zero_values = true を追加します。そうすることで、一致セクションでのゼロ値の処理で説明したように、一致セクションで使用されているプレースホルダのゼロ値がルールによって暗黙的に除外されるのを防ぐことができます。

suppression_window

suppression_window オプションを使用すると、ルールが検出をトリガーする頻度を制御できます。これにより、ルールの条件が複数回満たされた場合でも、同じルールが指定された時間枠内で複数の検出を生成することを防ぎます。抑制ウィンドウ処理では、タンブリング ウィンドウ アプローチが使用されます。このアプローチでは、固定サイズの重複しないウィンドウで重複が抑制されます。

必要に応じて suppression_key を指定して、抑制ウィンドウ内で抑制されるルールのインスタンスをさらに絞り込むことができます。指定しない場合は、ルールのすべてのインスタンスが抑制されます。このキーは結果変数として定義されます。

次の例では、suppression_window5m に設定され、suppression_key$hostname 変数に設定されます。ルールによって $hostname の検出がトリガーされると、その後 5 分間は $hostname の検出が抑制されます。ただし、ルールが別のホスト名を持つイベントでトリガーされた場合は、検出が作成されます。

suppression_window のデフォルト値は 0 です。つまり、抑制ウィンドウはデフォルトで無効になっています。このオプションは、match セクションのない単一イベント ルールでのみ機能します。

例:

rule SuppressionWindowExample {
  // Other rule sections

  outcome:
    $suppression_key = $hostname

  options:
    suppression_window = 5m
}

複合検出ルール

Google SecOps の複合検出では、複数の YARA-L ルールを接続します。このセクションでは、複合ルールを作成する方法について説明します。複合検出の概要については、複合検出の概要をご覧ください。

ルールの構造を理解する

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

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

  1. events ブロック: 入力を定義します。ルールが分析する特定の検出またはイベント。

  2. match ブロック: 定義された時間枠で入力を接続する方法を指定します。

  3. 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 の結果変数にアクセスします。

  • 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 で確認できます。ユーザーが生成したルールには 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 アドレス、ドメイン名などの共通の値を使用してデータソースを接続します。

  • 照合期間を定義する: 14 日以内の期間を指定した 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

リスクスコア

risk_score は、検出の潜在的な重大度または影響を表す 0 ~ 100 の整数です。スコアが高いほど、検出が true であると仮定した場合に、より重大な結果であることを示します。

プラットフォーム全体で一貫性を確保するため、カスタム検出に risk_score を割り当てる際は、次のスコア範囲を使用することをおすすめします。この調整により、アラートの優先順位付けと対応ワークフローを標準化できます。

重大度 スコアの範囲 説明
アラート - 重大 90 - 100 単一のユーザー アカウントやエンドポイントを超えて影響を及ぼす可能性のある、アクティブな侵害。早急な審査が必要です。 ドメイン コントローラで Mimikatz が実行されました。
アラート - 高 80 - 89 単一のエンドポイントまたはエンティティの侵害が進行中である。すぐに審査を受ける必要があります。 本番環境のサーバーが最近確認された既知の C2 に呼び出しを行っている。
アラート - 中 50 - 79 調査が必要なセキュリティ上の問題の可能性がある。セキュリティ侵害は確認されていませんが、エスカレーションは可能です。 認証情報が漏洩しましたが、不正使用の兆候はありません。
アラートなし - 低 20 ~ 49 他の指標や観測と組み合わせると、より重大なインシデントにつながる可能性のある影響の少ないセキュリティ イベント。通常、レビューは必要ありません。複合ルールを使用して他の検出と組み合わせてアラートを作成できます。 内部ポート スキャン。
アラート以外のモニタリング 1 ~ 19 一般に、脅威の状況認識を構築することを目的とした情報ベースの検出。通常はレビューを必要としません。複合ルールを使用して他の検出と組み合わせてアラートを生成できます。 ログイン イベント。不正使用の兆候はありません。

ブール式

ブール値式はブール型の式です。

比較

条件として使用するバイナリ式には、次の構文を使用します。

  • <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")

リファレンス リスト式

イベント セクションでは、リファレンス リストを使用できます。詳細については、リファレンス リストをご覧ください。

論理式

論理 and と論理 or の演算子は、次の例に示すように events セクションで使用できます。

  • $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"

デフォルトでは、優先度の高い順に notandor となります。

たとえば、演算子 orand が式で明示的に定義されている場合、「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 種類があります。

  1. 変更あり
  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_originalany $e.principal.ip = "192.0.2.1" を満たします。
  • event_originalany $e.repeated_field.field_a = "9.9.9.9 に失敗します。
すべて

繰り返しフィールドのすべての要素が条件を満たす場合は、イベント全体が条件を満たしています。

  • event_originalnet.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8") を満たします。
  • event_originalall $e.principal.ip = "192.0.2.2" に失敗します。

any または all を使用して条件を記述する場合、not で条件を否定するときには、否定演算子を使用する場合と意味が異なる可能性があります。

次に例を示します。

  • not all $e.principal.ip = "192.168.12.16" は、一部の IP アドレスが 192.168.12.16 と一致していないかどうかをチェックします。つまり、このルールでは、少なくとも 1 つの IP アドレスが 192.168.12.16 と一致しないことが確認されます。
  • all $e.principal.ip != "192.168.12.16" は、すべての IP アドレスが 192.168.12.16 と一致していないかどうかをチェックします。つまり、このルールでは、192.168.12.16 に一致する IP アドレスがないことが確認されます。

制約:

  • any 演算子と all 演算子は、繰り返しフィールドとのみ互換性があります(スカラー フィールドとは互換性がありません)。
  • anyall を使用して 2 つの繰り返しフィールドを結合することはできません。たとえば、any $e1.principal.ip = $e2.principal.ip は無効です。
  • 参照リストの式では、any 演算子と all 演算子はサポートされていません。

変更されていない式

変更されていない式では、繰り返しフィールドの各要素が個別に処理されます。イベントの繰り返しフィールドに n 個の要素が含まれている場合、ルールはベントの n 個のコピーに適用されます。ここで、各コピーには繰り返しフィールドのいずれかの要素が含まれます。これらのコピーは一時的なもので、保存されません。

このルールは次のコピーに適用されます。

イベント コピー principal.ip principal.hostname
event_copy_1 "192.0.2.1" "host"
event_copy_2 "192.0.2.2" "host"
event_copy_3 "192.0.2.3" "host"

いずれかのイベントコピーが繰り返しフィールドの変更されていない条件をすべて満たす場合は、イベント全体がすべての条件を満たします。つまり、繰り返しフィールドに複数の条件がある場合、イベントコピーはそれらすべてを満たす必要があります。次のルールの例では、上記のデータセットの例を使用してこの動作を示します。

次のルールは、event_original データセットの例に対して実行すると、1 つの一致を返します。これは、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 はイベントのコピー番号です。プレースホルダが match セクションで使用されている場合、複数の一致が発生する可能性があります。

次の例では、1 つの一致が生成されます。$ip プレースホルダは event_copy_1192.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
}

次の例では、3 つの一致が生成されます。$ip プレースホルダは、event_copy_n のコピーごとに異なる値になります。$ip は一致セクションにあるため、グループ化は $ip で行われます。したがって、3 つの一致結果が得られ、それぞれの一致結果の $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
}

繰り返しフィールドに割り当てられたプレースホルダを使用する結果

プレースホルダは、リスト全体ではなく、各繰り返しフィールドの各要素に割り当てられます。したがって、outcome セクションで使用されている場合は、前のセクション条件を満たす要素のみを使用して結果が計算されます。

次のルールを検討します。

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" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id
event_copy_3 "192.0.2.3" "host" event_id

events セクションでは、フィルタに一致しない行が除外されます。

イベント コピー $ip $host $e
event_copy_1 "192.0.2.1" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id

"192.0.2.3"$ip = "192.0.2.1" or $ip = "192.0.2.2" を満たしていないため、event_copy_3 は除外されます。

match セクションは、一致変数ごとにグループ化し、outcome セクションでは各グループに対して集計を行います。

$host $o $e
"host" ["192.0.2.1", "192.0.2.2"] event_id

$o = array_distinct($ip) は、イベントのコピーステージではなく、前のステージの $ip を使用して計算されます。

最後に、condition セクションで各グループをフィルタします。このルールは $e の存在を確認するだけなので、前の行では 1 つの検出が生成されます。

$o には $e.principal.ip のすべての要素が格納されていません。すべての要素が events セクションのすべての条件を満たすわけではないためです。ただし、イベント サンプルでは event_original が使用されるため、e.principal.ip のすべての要素がイベント サンプルに表示されます。

配列のインデックス登録

繰り返しフィールドに対して配列インデックスを作成できます。n 番目の繰り返しフィールド要素にアクセスするには、標準のリスト構文を使用します(要素は 0 から始まるインデックスです)。範囲外の要素はデフォルト値を返します。

  • $e.principal.ip[0] = "192.168.12.16"
  • $e.principal.ip[999] = "" 要素数が 1,000 個未満の場合は、true と評価されます。

制約:

  • インデックスは、負の値ではない整数値のリテラルでなければなりません。たとえば、$e.principal.ip[-1] は無効です。
  • int 型の値(int に設定されたプレースホルダなど)はカウントされません。
  • 配列インデックスを anyall と組み合わせることはできません。たとえば、any $e.intermediary.ip[0] は無効です。
  • 配列インデックスをマップ構文と組み合わせることはできません。たとえば、$e.additional.fields[0]["key"] は無効です。
  • フィールド パスに複数の繰り返しフィールドが含まれている場合、すべての繰り返しフィールドで配列インデックスを使用する必要があります。たとえば、$e.intermediary.ip[0] は無効です。intermediaryip は両方とも繰り返しフィールドですが、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_1repeated_message_2 のすべての式を満たしているため、イベントはルールに一致します。

ルール repeated_message_1 には配列インデックスがなく、一致が生成されませんでしたが、ルール repeated_message_2 では配列インデックスが使用され、一致が生成されたため、予期しない動作が発生する可能性があります。

コメント

C の場合と同様、コメントは 2 つのスラッシュ文字(// comment)により指定します。コメントが複数行にわたる場合は、スラッシュ アスタリスク(/* comment */)を使用してコメントアウトします。

リテラル

負でない整数と浮動小数点数、文字列、ブール値、正規表現のリテラルがサポートされています。

文字列リテラルと正規表現リテラル

YARA-L 2.0 で文字列を囲むには、次のいずれかの引用符を使用します。ただし、引用符で囲まれたテキストは、使用する引用符に応じて解釈が異なります。

  1. 二重引用符(")- 通常の文字列に使用します。エスケープ文字を含める必要があります。
    たとえば、「hello\tworld」の場合、\t はタブとして解釈されます。

  2. バッククォート(`)- すべての文字を文字どおりに解釈するために使用します。
    たとえば、「hello\tworld」の場合、\t はタブとして解釈されません。

正規表現には 2 つのオプションがあります。

re.regex() 関数を使用せずに正規表現を直接使用する場合は、正規表現リテラルに /regex/ を使用します。

re.regex() 関数を使用する場合は、文字列リテラルを正規表現リテラルとして使用することもできます。二重引用符文字列リテラルの場合は、バックスラッシュ文字でバックスラッシュ文字をエスケープする必要があります。これは、ややスマートではない処理の仕方です。

たとえば、次の 2 つの式は等価です。

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

読みやすくするために、正規表現の文字列にはバッククォート文字を使用することをおすすめします。

演算子

YARA-L では次の演算子を使用できます。

オペレーター 説明
= 等しい / 宣言
!= 等しくない
< 未満
<= 以下
> 次より大きい
>= 以上

変数

YARA-L 2.0 では、すべての変数が $<variable name> として表されます。

次のタイプの変数を定義できます。

  • イベント変数 — イベントのグループを正規化された形式(UDM)またはエンティティ イベントで表します。events セクションで、イベント変数の条件を指定します。名前、イベントソース、イベント フィールドを使用して、イベント変数を指定します。許可されるソースは、udm(正規化されたイベントの場合)と graph(エンティティ イベントの場合)です。ソースを省略すると、udm がデフォルトのソースとして設定されます。イベント フィールドは、.<field name> のチェーンで表されます(例: $e.field1.field2)。イベント フィールド チェーンは常に最上位のソース(UDM またはエンティティ)から始まります。

  • 一致変数 - match セクションで宣言します。一致変数は、一意の変数セットのセット(および期間)ごとに 1 行が返されるため、クエリのグループ フィールドになります。ルールが一致を見つけると、一致変数の値が返されます。各一致変数が表す内容を events セクションで指定します。

  • プレースホルダ変数 - events セクションで宣言および定義します。プレースホルダ変数は、match 変数に似ています。ただし、condition セクションでプレースホルダ変数を使用して、一致条件を指定できます。

推移結合条件を使用して、イベント フィールド間の関係を宣言するために、一致変数とプレースホルダ変数を使用します(詳細については、events セクションの構文をご覧ください)。

キーワード

YARA-L 2.0 のキーワードでは大文字と小文字が区別されません。たとえば、andAND は同等です。変数名はキーワードと競合しないようにする必要があります。たとえば、$AND$outcome は無効です。

検出エンジンルールのキーワードは次のとおりです。rulemetamatchovereventsconditionoutcomeoptionsandornotnocaseinregexcidrbeforeafterallanyifmaxminsumarrayarray_distinctcountcount_distinctisnull

マップ

YARA-L は、構造体とラベルのマップ アクセスをサポートしています。

構造体とラベル

一部の UDM フィールドは、構造体ラベルデータ型を使用します。

Struct と Label の両方で特定の Key-Value ペアを検索するには、標準のマップ構文を使用します。

// 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"
        }
      }
    }
    
  • ラベルに祖先の繰り返しフィールドがあります。

    繰り返しフィールドには、子フィールドとしてラベルが含まれることがあります。トップレベルの繰り返しフィールドの 2 つの異なるエントリに、同じキーを持つラベルが含まれている可能性があります。次のデータ例で実行すると、ルールテキスト $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"
        }
      }
    }
    

マップで結果変数にアクセスする

このセクションでは、文字列としてではなく、元のデータ型(整数、ブール値、これらの型のリストなど)としてマップ内の結果変数にアクセスする方法について説明します。この機能を使用すると、ルールロジックの柔軟性と精度を高めることができます。

結果データは、次の 2 つのフィールドで確認できます。

  • 結果の値は、variables フィールドで元の型を保持します。

  • outcomes フィールドには、下位互換性のために string バージョンが保存されます。

これらの結果値には、variables マップを使用してアクセスし、特定の型を取得したり、配列インデックスを使用してシーケンス内の要素にアクセスしたりできます。シーケンス内の特定のアイテムにインデックスでアクセスするか、シーケンス全体を選択して各値を個別に評価できます。

構文:

$d.detection.detection.variables[OUTCOME_NAME].TYPE_SUFFIX

シーケンスの構文:

$d.detection.detection.variables[OUTCOME_NAME].SEQUENCE_TYPE_SUFFIX.TYPE_VALS_SUFFIX

例:

  • 文字列の結果にアクセスする:

    $my_string_outcome = $d.detection.detection.variables["outcome_ip"].string_val
    

    この例では、文字列値を直接取得します(たとえば、outcome_ip が単一の文字列の場合、"1.1.1.1")。

  • 整数結果にアクセスする:

    $my_int_outcome = $d.detection.detection.variables["outcome_port"].int64_value
    

    この例では、整数値(30 など)を取得します。

  • 整数のリスト(Int64Sequence)にアクセスする:

    $my_int_list = $d.detection.detection.variables["outcome_ports"].int64_seq.int64_vals
    

    この例では、整数の完全なリストを取得し、繰り返しフィールド([2, 3, 4] など)のようにネスト解除します。

  • 整数のリストから特定の要素にアクセスする:

    $first_int = $d.detection.detection.variables["outcome_ports"].int64_seq.int64_vals[0]
    

    この例では、リストから最初の整数(2 など)を取得します。

  • 文字列のリスト(StringSequence)にアクセスする:

    $my_string_list = $d.detection.detection.variables["outcome_ips"].string_seq.string_vals
    

    この例では、文字列の完全なリストを取得し、繰り返しフィールド(["1.1.1.1", "2.2.2.2"] など)のようにネスト解除します。

  • 文字列のリストから特定の要素にアクセスする:

    $first_ip = $d.detection.detection.variables["outcome_ips"].string_seq.string_vals[0]
    

    この例では、リストから最初の IP アドレス("1.1.1.1" など)を取得します。

variables で使用可能な型接尾辞

サポートされている接尾辞の一覧については、FindingVariable をご覧ください。

関数

このセクションでは、検出エンジンのルールと検索で使用できる YARA-L 2.0 関数について説明します。

これらの関数は、YARA-L ルールの次の部分で使用できます。

arrays.concat

以下でサポートされています。
arrays.concat(string_array, string_array)

説明

元の文字列配列から要素をコピーして、新しい文字列配列を返します。

パラメータのデータ型

ARRAY_STRINGSARRAY_STRINGS

戻り値の型

ARRAY_STRINGS

コードサンプル

例 1

次の例では、2 つの異なる文字列配列を連結しています。

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_STRINGSSTRING

戻り値の型

STRING

コードサンプル

関数の使用例をいくつかご紹介します。

例 1

この例では、非 null 要素を含む配列と区切り文字を結合します。

arrays.join_string(["foo", "bar"], ",") = "foo,bar"
例 2

この例では、null 要素と区切り文字を含む配列を結合します。

arrays.join_string(["foo", NULL, "bar"], ",") = "foo,bar"
例 3

この例では、null 以外の要素を含む配列を区切り文字なしで結合します。

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)

説明

配列内の最大の要素を返します。配列が空の場合は 0 を返します。

パラメータのデータ型

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])

説明

配列内の最小要素を返します。配列が空の場合は 0 を返します。2 番目の省略可能な引数が true に設定されている場合、ゼロに等しい要素は無視されます。

パラメータのデータ型

ARRAY_INTS|ARRAY_FLOATSBOOL

戻り値の型

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

この例では、2 つの要素を含む文字列配列を使用します。

arrays.size(["test1", "test2"]) = 2
例 2

この例では、3 つの要素を含む整数配列を使用します。

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)

説明

配列の指定されたインデックスにある要素を返します。そのインデックスの要素が float として返されます。

インデックスは、配列内の要素の位置を表す整数値です。デフォルトでは、配列の最初の要素のインデックスは 0、最後の要素のインデックスは n-1 です。ここで、n は配列のサイズです。負のインデックスを使用すると、配列の末尾を基準にして配列要素にアクセスできます。たとえば、インデックス -1 は配列の最後の要素を参照し、インデックス -2 は配列の最後から 2 番目の要素を参照します。

パラメータのデータ型

ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATSINT

戻り値の型

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 は配列の最後から 2 番目の要素を参照します。

パラメータのデータ型

ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATSINT

戻り値の型

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 の float 配列から要素を取得します。

arrays.index_to_int([1.100000, 1.200000, 1.300000], 1) = 1
例 5

この関数は、インデックス 0 の int 配列から要素を取得します。

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 は配列の最後から 2 番目の要素を参照します。

パラメータのデータ型

ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATSINT

戻り値の型

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 または文字列値を bool 値に変換します。キャストできない値を含む関数呼び出しは FALSE を返します。整数 1 と大文字と小文字を区別しない文字列「true」の場合にのみ TRUE を返します。

パラメータのデータ型

INT|STRING

戻り値の型

BOOL

コードサンプル

例 1

この例では、ブール値以外の文字列をキャストする方法を示します。

cast.as_bool("123") = false
例 2

真の整数(1)

cast.as_bool(1) = true
例 3

真の文字列

cast.as_bool("true") = true
例 4

大文字の真の文字列

cast.as_bool("TRUE") = true
例 5

負の整数

cast.as_bool(0-1) = false
例 6

偽の整数(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 関数は、INTBYTES、または BOOL の値を文字列形式に変換します。キャストが失敗した場合を処理するために、必要に応じて default_string 引数を指定できます。default_string 引数を省略した場合、または入力が無効な UTF-8 バイト シーケンスまたは BASE64 バイト シーケンスの場合、関数は空の文字列を返します。

パラメータのデータ型

INT|BYTES|BOOLSTRING

戻り値の型

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 ハッシュを計算します。この関数は、範囲 [2, 0xFFFFFFFFFFFFFFFF] の符号なし INT 値を返します。

パラメータのデータ型

BTYESTRING

戻り値の型

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 エポックからの秒数)から 5 分以上経過した場合に True を返します。math.abs の呼び出しは、複数の変数やプレースホルダに依存できません。たとえば、次の例のハードコードされた時間値 1643687343 を $e2.metadata.event_timestamp.seconds に置き換えることはできません。

300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)

math.ceil

以下でサポートされています。
math.ceil(number)

説明

指定された数値以上の最小の整数を返します(切り上げ)。入力が null の場合、または int64 に収まらないほど大きい場合は 0 を返します。

パラメータのデータ型

FLOAT

戻り値の型

INT

コードサンプル

このセクションでは、math.ceil の使用例を示します。

例 1

この例では、整数の天井関数を返します。

math.ceil(2.000000) = 2
例 2

この例では、負の数の ceil を返します。

math.ceil(0-1.200000) = -1
例 3

この例では、64 ビット整数には大きすぎる数値の天井関数として 0 が返されます。

math.ceil(184467440737095516160.0) = 0

math.floor

以下でサポートされています。
math.floor(float_val)

説明

指定された値以下の最大の整数値を返します(切り捨て)。入力が null であるか、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))

説明

2 つの地理的位置(座標)間の距離をメートル単位で返します。座標が無効な場合は -1 を返します。

パラメータのデータ型

FLOATFLOATFLOATFLOAT

戻り値の型

FLOAT

コードサンプル

例 1

次の例では、すべてのパラメータが有効な座標である場合に距離を返します。

math.geo_distance(-122.020287, 37.407574, -122.021810, 37.407574) = 134.564318
例 2

次の例では、パラメータの 1 つが切り捨てられた座標の場合に距離を返します。

math.geo_distance(-122.000000, 37.407574, -122.021810, 37.407574) = 1926.421905
例 3

次の例では、パラメータの 1 つが無効な座標である場合に -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

この例では、1 つの負の double 値、1 つのゼロ INT64 値、1 つの正の INT64 値が含まれています。

math.is_increasing(-1.200000, 0, 3) = true
例 3

この例では、1 つの負の double 値、1 つのゼロ INT64 値、1 つの負の INT64 値が含まれています。

math.is_increasing(0-1.200000, 0, 0-3) = false
例 4

この例では、2 つの負の double 値と 1 つのゼロ INT64 値が含まれています。

math.is_increasing(0-1.200000, 0-1.50000, 0) = false
例 5

この例には、1 つの負の double 値と 2 つの同じ値が含まれています。

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)

説明

最初の引数を 2 番目の引数のべき乗で累乗した値を返します。オーバーフローの場合は 0 を返します。

パラメータのデータ型

base: INT|FLOAT exponent: 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

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

指標関数は、大量の履歴データを集計できます。結果セクションで 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 アドレス フィールドの両方を処理できます。

パラメータのデータ型

STRINGSTRING

戻り値の型

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 構文の使用 - イベントに関連します。この構文の一般的な表現は次のとおりです。

    $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 修飾子を使用すると、検索で大文字小文字の区別が無視されるよう指定できます。

パラメータのデータ型

STRINGSTRING

パラメータ式のタイプ

ANYANY

戻り値の型

BOOL

コードサンプル

例 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")

re.capture

以下でサポートされています。
re.capture(stringText, regex)

説明

引数で指定された正規表現パターンを使用して、文字列からデータをキャプチャ(抽出)します。

この関数は次の 2 つの引数を取ります。

  • stringText: 検索する元の文字列。
  • regex: 検索するパターンを示す正規表現。

正規表現では、0 または 1 つのキャプチャ グループをかっこで囲むことができます。正規表現にキャプチャ グループがない場合、この関数は最初に一致した部分文字列を返します。正規表現に 1 つのキャプチャ グループが含まれている場合、キャプチャ グループの最初の一致部分文字列が返されます。2 つ以上のキャプチャ グループを定義すると、コンパイラ エラーが返されます。

パラメータのデータ型

STRINGSTRING

戻り値の型

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 が返されます。次の例では、1 つのキャプチャ グループが含まれています。

"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)

説明

正規表現の置き換えを行います。

この関数は次の 3 つの引数を取ります。

  • stringText: 元の文字列。
  • replaceRegex: 検索するパターンを示す正規表現。
  • replacementText: 各一致に挿入するテキスト。

元の文字列 stringText から派生した新しい文字列を返します。ここでは、replaceRegex のパターンに一致するすべての部分文字列が、replacementText に置き換えられます。replacementText 内でバックスラッシュでエスケープされた数字(\1\9)を使用して、対応する括弧で囲まれたグループと一致するテキストを replaceRegex パターン内に挿入できます。一致するテキスト全体を参照するには、\0 を使用します。

この関数は、重複しない一致を置き換えるもので、最初に見つかったものを優先的に置き換えます。たとえば、re.replace("banana", "ana", "111") は文字列「b111na」を返します。

パラメータのデータ型

STRING, STRING, STRING

戻り値の型

STRING

コードサンプル

例 1

この例では、メール内の @ 記号の後のすべての部分をキャプチャし、comorg に置き換えて結果を返します。ネストされた関数が使用されることに注意してください。

"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")

サンプルレート

以下でサポートされています。
optimization.sample_rate(byteOrString, rateNumerator, rateDenominator)

説明

この関数は、あるイベントを含めるかどうかを、決定論的なサンプリングの方法に基づいて判断します。次の結果を返します。

  • true: 入力値の割合(rateNumerator / rateDenominator に相当)。イベントをサンプルに含める必要があることを示します。
  • 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 でエンコードされた 1 つの文字列を引数として受け取ります。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.fromsuspicious@gmail.com であるか、(2)$e.network.email.from が空かつ$e.network.email.tosuspicious@gmail.com の場合、条件は true と評価されます。

"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
例 2

次の例では、2 つ以上の引数を使用して coalesce 関数を呼び出します。この条件は、イベント $e の最初の null 以外の IP アドレスを、リファレンス リスト ip_watchlist の値と比較します。この呼び出しで引数が結合される順序は、ルール条件で引数が列挙されている順序と同じです。

  1. $e.principal.ip が最初に評価されます。
  2. $e.src.ip が評価されます。
  3. $e.target.ip が評価されます。
  4. 最後に、以前の ip フィールドが設定されていない場合、文字列「No IP」がデフォルト値として返されます。
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
例 3

次の例では、イベント $e1 とイベント $e2principal.hostname を結合しようとしています。引数が異なるイベント変数であるため、コンパイラ エラーが返されます。

// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)

strings.concat

以下でサポートされています。
strings.concat(a, b, c, ...)

説明

無制限の数のアイテムを連結した値を返します。各アイテムは、文字列、整数、または浮動小数点数です。

引数がイベント フィールドの場合、属性は同じイベントからのものである必要があります。

パラメータのデータ型

STRINGFLOATINT

戻り値の型

STRING

コードサンプル

例 1

次の例には、引数として文字列変数と整数変数が含まれています。principal.hostnameprincipal.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」と表されます)。また、10 進 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 とイベント $e2principal.hostname を連結しようとしています。引数が異なるイベント変数であるため、コンパイラ エラーが返されます。

// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

strings.contains

以下でサポートされています。
strings.contains( str, substr )

説明

指定された文字列に指定された部分文字列が含まれている場合に true を返します。それ以外の場合は false を返します。

パラメータのデータ型

STRINGSTRING

戻り値の型

BOOL

コードサンプル

例 1

この例では、文字列に部分文字列「is」が含まれているため、true が返されます。

strings.contains("thisisastring", "is") = true
例 2

この例では、文字列に部分文字列「that」が含まれていないため、false が返されます。

strings.contains("thisisastring", "that") = false

strings.count_substrings

以下でサポートされています。
strings.count_substrings(string_to_search_in, substring_to_count)

説明

文字列と部分文字列を指定すると、文字列内で重複しない部分文字列の出現回数の int64 を返します。

パラメータのデータ型

STRINGSTRING

戻り値の型

INT

コードサンプル

このセクションでは、特定の文字列に部分文字列が出現する回数を計算する例を示します。

例 1

この例では、null 以外の文字列と、null 以外の単一の部分文字列文字を使用しています。

strings.count_substrings("this`string`has`four`backticks", "`") = 4
例 2

この例では、null 以外の文字列と、1 文字以上の null 以外の部分文字列を使用しています。

strings.count_substrings("str", "str") = 1
例 3

この例では、null 以外の文字列と空の部分文字列を使用しています。

strings.count_substrings("str", "") = 0
例 4

この例では、空の文字列と、1 文字以上の null 以外の部分文字列を使用しています。

strings.count_substrings("", "str") = 0
例 5

この例では、空の文字列と空の部分文字列を使用しています。

strings.count_substrings("", "") = 0
例 6

この例では、null 以外の文字列と、複数文字で複数回出現する null 以外の部分文字列を使用しています。

strings.count_substrings("fooABAbarABAbazABA", "AB") = 3
例 7

この例では、null 以外の文字列と、複数文字で複数回出現する null 以外の部分文字列を使用しています。重複する部分文字列の出現に関する制限がハイライト表示されます。

strings.count_substrings("ABABABA", "ABA") = 2

strings.extract_domain

以下でサポートされています。
strings.extract_domain(url_string)

説明

文字列からドメインを抽出します。

パラメータのデータ型

STRING

戻り値の型

STRING

コードサンプル

例 1

この例では、空の文字列

strings.extract_domain("") = ""
例 2

ランダムな文字列(URL ではない)

strings.extract_domain("1234") = ""
例 3

複数のバックスラッシュ

strings.extract_domain("\\\\") = ""
例 4

アルファベット以外の文字が適切に処理される

strings.extract_domain("http://例子.卷筒纸.中国") = "卷筒纸.中国"
例 5

URI の処理

strings.extract_domain("mailto:?to=&subject=&body=") = ""
例 6

実際の URL の前に複数の文字がある

strings.extract_domain("     \t   !$5*^)&dahgsdfs;http://www.google.com") = "google.com"
例 7

URI 内の特殊文字 #

strings.extract_domain("test#@google.com") = ""
例 8

URL 内の特殊文字 #

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

ランダムな文字列(URL ではない)

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

実際の URL の前に複数の文字がある

strings.extract_hostname("     \t   !$5*^)&dahgsdfs;http://www.google.com") = "www.google.com"
例 7

URI 内の特殊文字 #

strings.extract_hostname("test#@google.com") = "test"
例 8

URL 内の特殊文字 #

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
Failed Conversion(デフォルトは空のバイト)

指定された値が無効な場合、関数はデフォルトで空のバイトを返します。

strings.from_base64("invalid-value") = b'

strings.from_hex

以下でサポートされています。
strings.from_hex(hex_string)

説明

指定された 16 進文字列に関連付けられたバイト列を返します。

パラメータのデータ型

STRING

戻り値の型

BYTES

コードサンプル

指定された 16 進文字列に関連付けられたバイト列を取得します。

例 1

この例では、16 進数以外の文字の変換を示します。

strings.from_hex("str") // returns empty bytes
例 2

この例では、空の文字列を含む入力を示します。

strings.from_hex("") // returns empty bytes
例 3

この例では、16 進文字列の変換を示します。

strings.from_hex("1234") // returns 1234 bytes
例 4

この例では、ASCII 以外の文字の変換を示します。

strings.from_hex("筒纸.中国") // returns empty bytes

strings.ltrim

以下でサポートされています。
strings.ltrim(string_to_trim, cutset)

説明

指定された文字列の先頭の空白を削除します。この関数は、そのカットセットにある先頭の文字を削除します。

パラメータのデータ型

STRINGSTRING

戻り値の型

STRING

コードサンプル

ユースケースの例を次に示します。

例 1

この例では、同じ第 1 引数と第 2 引数を使用しています。

strings.ltrim("str", "str") = ""
例 2

この例では、2 番目の引数として空の文字列を使用しています。

strings.ltrim("str", "") = "str"
例 3

この例では、最初の引数として空の文字列を使用し、2 番目の引数として文字列を使用しています。

strings.ltrim("", "str") = ""
例 4

この例では、空白を含む文字列と、2 番目の引数として文字列を使用しています。

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)

説明

指定された文字列の末尾の空白文字を削除します。そのカットセットに含まれる末尾の文字を削除します。

パラメータのデータ型

STRINGSTRING

戻り値の型

STRING

コードサンプル

ユースケースの例を次に示します。

例 1

次の例では、同じ文字列を最初の引数と 2 番目の引数として渡します。

strings.rtrim("str", "str") = ""
例 2

次の例では、2 番目の引数として空の文字列を渡しています。

strings.rtrim("str", "") = "str"
例 3

次の例では、最初の引数として空の文字列を渡し、2 番目の引数として空でない文字列を渡します。

strings.rtrim("", "str") = ""
例 4

次の例では、空白文字を含む文字列を最初の引数として渡し、空でない文字列を 2 番目の引数として渡しています。

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 引数で指定)を削除します。

パラメータのデータ型

STRINGSTRING

戻り値の型

STRING

コードサンプル

ユースケースの例を次に示します。

例 1

次の例では、同じ文字列が入力文字列とカットセットとして渡されるため、空の文字列が返されます。

strings.trim("str", "str") // ""
例 2

次の例では、カットセットとして空の文字列が渡されます。カットセットで削除する文字が指定されていないため、元の文字列 str が返されます。

strings.trim("str", "") = "str"
例 3

次の例では、入力文字列がすでに空で、削除する文字がないため、関数は空の文字列を返します。

strings.trim("", "str") = ""
例 4

次の例では、trim 関数が次のものを削除するため、関数は str を返します。

  • 「a aastraa aa 」の末尾に空白文字が含まれている
  • カットセットで指定された文字(スペース、a)
strings.trim("a aastraa aa ", " a") = "str"

strings.url_decode

以下でサポートされています。
strings.url_decode(url_string)

説明

URL 文字列が指定されたら、エスケープ文字をデコードし、エンコードされた 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

この例では、URL デコードのサンプルを示します。

strings.url_decode("http://www.google.com%3Fparam1%3D%22+1+%3E+2+%22%26param2%3D2%3B") // 'http://www.google.com?param1="+1+>+2+"&param2=2;'

timestamp.as_unix_seconds

以下でサポートされています。
timestamp.as_unix_seconds(timestamp [, time_zone])

説明

この関数は、指定されたタイムスタンプ文字列の Unix エポックからの経過秒数を表す整数を返します。

  • timestamp は、有効なエポック タイムスタンプを表す文字列です。形式は %F %T にする必要があります。
  • time_zone は省略可能で、タイムゾーンを表す文字列です。省略した場合、デフォルトは GMT です。文字列リテラルを使用してタイムゾーンを指定できます。以下のオプションがあります。

以下に、有効な time_zone 指定子の例を示します。これらは、時間抽出関数に 2 番目の引数として渡すことができます。

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

パラメータのデータ型

STRINGSTRING

戻り値の型

INT

コードサンプル

例 1

有効なエポック タイムスタンプ

timestamp.as_unix_seconds("2024-02-22 10:43:00") = 1708598580
例 2

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 は、$e.metadata.event_timestamp.seconds などの Unix エポックからの経過秒数を表す整数か、その値を含むプレースホルダです。
  • time_zone は省略可能で、time_zone を表す文字列です。省略した場合、デフォルトは「GMT」です。文字列リテラルを使用してタイムゾーンを指定できます。次のオプションがあります。
    • TZ データベース名(「America/Los_Angeles」など)。詳しくは、このページの「TZ データベース名」列をご覧ください。
    • (+|-)H[H][:M[M]] 形式の UTC からのタイムゾーン オフセット(例: 「-08:00」)。

以下に、有効な time_zone 指定子の例を示します。これらは、時間抽出関数に 2 番目の引数として渡すことができます。

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

パラメータのデータ型

INTSTRING

戻り値の型

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 は、$e.metadata.event_timestamp.seconds などの Unix エポックからの経過秒数を表す整数か、その値を含むプレースホルダです。
  • time_zone は省略可能で、タイムゾーンを表す文字列です。省略した場合、デフォルトは「GMT」です。文字列リテラルを使用してタイムゾーンを指定できます。次のオプションがあります。
    • TZ データベース名(「America/Los_Angeles」など)。詳しくは、このページの「TZ データベース名」列をご覧ください。
    • (+|-)H[H][:M[M]] 形式の UTC からのタイムゾーン オフセット(例: 「-08:00」)。

以下に、有効な time_zone 指定子の例を示します。これらは、時間抽出関数に 2 番目の引数として渡すことができます。

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

パラメータのデータ型

INTSTRING

戻り値の型

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 は、$e.metadata.event_timestamp.seconds などの Unix エポックからの経過秒数を表す整数か、その値を含むプレースホルダです。
  • time_zone は省略可能で、タイムゾーンを表す文字列です。省略した場合、デフォルトは「GMT」です。文字列リテラルを使用してタイムゾーンを指定できます。次のオプションがあります。
    • TZ データベース名(「America/Los_Angeles」など)。詳しくは、このページの「TZ データベース名」列をご覧ください。
    • (+|-)H[H][:M[M]] 形式の UTC からのタイムゾーン オフセット(例: 「-08:00」)。

以下に、有効な time_zone 指定子の例を示します。これらは、時間抽出関数に 2 番目の引数として渡すことができます。

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

パラメータのデータ型

INTSTRING

戻り値の型

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 は、$e.metadata.event_timestamp.seconds などの Unix エポックからの経過秒数を表す整数か、その値を含むプレースホルダです。
  • time_zone は省略可能で、time_zone を表す文字列です。省略した場合、デフォルトは「GMT」です。文字列リテラルを使用してタイムゾーンを指定できます。次のオプションがあります。
    • TZ データベース名(「America/Los_Angeles」など)。詳しくは、このページの「TZ データベース名」列をご覧ください。
    • (+|-)H[H][:M[M]] 形式の UTC からのタイムゾーン オフセット(例: 「-08:00」)。

以下に、有効な time_zone 指定子の例を示します。これらは、時間抽出関数に 2 番目の引数として渡すことができます。

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

パラメータのデータ型

INTSTRING

戻り値の型

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 は、$e.metadata.event_timestamp.seconds などの Unix エポックからの経過秒数を表す整数か、その値を含むプレースホルダです。
  • timestamp_format は省略可能で、タイムスタンプの形式を表す文字列です。省略した場合、デフォルトは %F %T です。形式は、日時形式文字列または次の時間粒度のいずれかを使用して指定できます。SECONDMINUTEHOURDATEWEEKMONTHYEAR。その他の形式設定オプションについては、日付と時刻の部分の形式設定要素をご覧ください。
  • time_zone は省略可能で、タイムゾーンを表す文字列です。省略した場合、デフォルトは GMT です。文字列リテラルを使用してタイムゾーンを指定できます。以下のオプションがあります。

以下に、有効な time_zone 指定子の例を示します。これらは、時間抽出関数に 2 番目の引数として渡すことができます。

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

パラメータのデータ型

INTSTRINGSTRING

戻り値の型

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])

説明

この関数は、1 年の中の週を表す [0, 53] の範囲の整数を返します。週は日曜日から始まります。年の最初の日曜日より前の日付は 0 週目です。

  • unix_seconds は、$e.metadata.event_timestamp.seconds などの Unix エポックからの経過秒数を表す整数か、その値を含むプレースホルダです。
  • time_zone は省略可能で、タイムゾーンを表す文字列です。省略した場合、デフォルトは「GMT」です。文字列リテラルを使用してタイムゾーンを指定できます。次のオプションがあります。
    • TZ データベース名(「America/Los_Angeles」など)。詳しくは、このページの「TZ データベース名」列をご覧ください。
    • (+|-)H[H][:M[M]] 形式の UTC からのタイムゾーン オフセット(例: 「-08:00」)。

以下に、有効な time_zone 指定子の例を示します。これらは、時間抽出関数に 2 番目の引数として渡すことができます。

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

パラメータのデータ型

INTSTRING

戻り値の型

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 エポック時間とも呼ばれます。

戻り値の型

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])

説明

入力値(整数または浮動小数点数)の平均値を返します。省略可能な 2 番目の引数を 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 は 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 を取得するといったユースケースがあります。

パラメータのデータ型

INTSTRING

戻り値の型

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 を取得するといったユースケースがあります。

パラメータのデータ型

INTSTRING

戻り値の型

STRING

コードサンプル

一致ウィンドウ内で相関関係が最も高い整数値を持つイベントから派生した文字列値を取得します。

// 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|FLOATBOOL

戻り値の型

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

この例では、中央値が複数ある場合、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 1 if the file sizes in the match window are [1, 2, 3, 4]
  condition:
      $e
}

window.mode

以下でサポートされています。
window.mode(values)

説明

入力値の最頻値を返します。モード値の候補が複数ある場合、そのうちの 1 つの値が非決定論的に選択され、戻り値として返されます。

パラメータのデータ型

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 に変換します。キャストできない値を含む関数呼び出しは、デフォルトで空の文字列を返します。

パラメータのデータ型

BYTESSTRING

戻り値の型

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").

その後、matchconditionoutcome セクションでプレースホルダ変数を使用できます。 ただし、関数からプレースホルダへの割り当てには次の 2 つの制限があります。

  1. 関数からプレースホルダへの割り当てのすべてのプレースホルダは、イベント フィールドを含む式に割り当てる必要があります。たとえば、次の例は有効です。

    $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.
    
  2. 関数呼び出しは、いずれか 1 つのイベントに依存する必要があります。ただし、同じイベントからの複数のフィールドが関数呼び出し引数で使用される場合があります。 たとえば、以下は有効です。

    $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

// regular expression 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 個のイベント サンプルを含めることができます。この上限は、各イベント変数に個別に適用されます。1 つのイベント変数にこの検出で適用されるイベントが 2 つあり、もう 1 つのイベント変数に適用されるイベントが 15 個ある場合、検出結果には 12 個のイベント サンプル(2 + 10)が含まれます。

上限を超えるイベント サンプルは検出から除外されます。

検出の原因となったイベントの詳細情報を取得する場合は、結果セクションで集計を使用して、検出で追加情報を出力できます。

UI で検出を表示している場合は、検出のすべてのイベント サンプルをダウンロードできます。詳しくは、イベントをダウンロードするをご覧ください。

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