YARA-L 2.0 言語の構文
このセクションでは、YARA-L 構文の主な要素について説明します。YARA-L 2.0 言語の概要もご覧ください。
ルールの構造
YARA-L 2.0 では、変数の宣言、定義、用途を次の順序で指定する必要があります。
- meta
- events
- 一致(省略可)
- outcome(省略可)
- condition
- 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 via function to event comparison
re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
// $e1 joins with $e2 via 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 via the placeholder variable $ip
$e1.src.ip = $ip
$e2.target.ip = $ip
$e3.about.ip = $ip
events:
// $e1 and $e2 are transitively joined via 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 分です。
指定できる最大時間は 48 時間です。
有効な match
の例を次に示します。
$var1, $var2 over 5m
このステートメントは、ルールが一致した場合に $var1
と $var2
(events
セクションで定義)を返します。指定する時間は 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] に対して実行されるルールで、30m
に match
セクションがある場合、次のような重複するホップ ウィンドウのセットが発生する可能性があります。[1:00, 1:30]、[1:03, 1:33]、[1:06, 1:36] などです。これらのウィンドウは、複数のイベントを関連付けるために使用されます。
スライディング ウィンドウ
ホップ ウィンドウを使用すると、特定の順序で発生するイベントを検索することはできません(たとえば、e1
は e2
から 2 分後までに発生します)。イベント e1
の発生とイベント e2
の発生は、生成された同じホップ ウィンドウに含まれる場合にのみ相関します。
このようなイベント シーケンスを検索するより効果的な方法は、スライディング ウィンドウを使用することです。スライディング ウィンドウを使用すると、指定されたピボット イベント変数の開始時または終了時に、match
セクションで指定された期間のスライディング ウィンドウが生成されます。次に、各スライディング ウィンドウ内でイベントが相互に関連付けられます。これにより、特定の順序で発生するイベントを検索できます(たとえば、e1
は e2
から 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 フィールドに格納されます。
結果変数のデータ型
各結果変数には異なるデータ型を指定できます。データ型は、計算に使用される式によって決まります。次の成果データ型がサポートされています。
- 整数
- 浮動小数点数
- 文字列
- 整数のリスト
- 浮動小数点数のリスト
- 文字列のリスト
条件付きロジック
条件付きロジックを使用して、結果の値を計算できます。条件は、次の構文パターンを使用して指定します。
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 2 outcomes above 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 分間のウィンドウには、イベントが 0 個、1 個、または複数含まれる場合があります。[結果] セクションは、一致ウィンドウ内のすべてのイベントに対して動作します。結果セクション内で参照されるイベント フィールド変数は、一致期間内の各イベントのフィールドの値を 0、1、または複数参照できます。上記のルールでは、5 分間のウィンドウに 5 つの $e
イベントが含まれている場合、結果セクションの $e.principal.hostname
は 5 つの異なるホスト名を参照します。したがって、イベント フィールド変数 $e.principal.hostname
は、このルールの結果セクションでスカラー以外の値になります。
結果変数は常に単一のスカラー値を返す必要があるため、結果の割り当てが依存するスカラー以外の値は、単一のスカラー値を返すように集計する必要があります。結果セクションでは、次の値はスカラー値ではなく、集計する必要があります。
- ルールで一致セクションを使用する場合のイベント フィールド(繰り返しまたは非繰り返し)
- ルールで一致セクションを使用する場合のイベント プレースホルダ(繰り返しまたは非繰り返し)
- ルールで一致セクションを使用していない場合にイベント フィールドが繰り返される
- ルールで一致セクションを使用していない場合にイベント プレースホルダが繰り返される
スカラー イベント フィールド、スカラー イベント プレースホルダ、定数は、一致セクションを使用しないルールの集計でラップできます。ただし、ほとんどの集計ではラップされた値が返されるため、不要です。例外は、スカラー値を配列に変換するために使用できる array()
集計です。
結果変数は集計値として扱われます。別の結果割り当てで参照する場合は、再集計しないでください。
次の集計関数を使用できます。
max()
: 可能性のあるすべての値の最大値を出力します。整数と浮動小数点数でのみ機能します。min()
: 可能性のあるすべての値の最小値を出力します。整数と浮動小数点数でのみ機能します。sum()
: 可能性のあるすべての値の和を出力します。整数と浮動小数点数でのみ機能します。count_distinct()
: 可能性のあるすべての値を収集し、可能性のある値の一意の値の数を出力します。count()
:count_distinct()
のように動作しますが、可能性のある値の一意でない値の数を返します。array_distinct()
: 可能性のあるすべての一意の値を収集し、これらの値のリストを返します。Distinct 値のリストを 25 個のランダムな要素に切り詰めます。一意のリストを得るための重複除去が最初に適用され、次に切り捨てが適用されます。array()
:array_distinct()
のように動作しますが、一意でない値のリストを返します。また、値のリストを 25 個のランダムな要素に切り詰めます。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
が複数回出現する必要があることを意味します。
値文字
$
文字は condition
セクションの特殊文字です。結果変数名の前で使用する場合、その結果の値を表します。
イベント名またはプレースホルダ変数名($event
など)の前に使用する場合、#event > 0
を表します。
イベントとプレースホルダの条件
イベントとプレースホルダ変数の条件述語を一覧表示します。キーワード and
または or
と結合します。キーワード and
は任意の条件間で使用できますが、キーワード or
は、ルールにイベント変数が 1 つしかない場合にのみ使用できます。
同じイベントの 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 つの UDM イベントに境界条件が設定されていること(つまり、少なくとも 1 つの UDM イベントが存在すること)。
- プレースホルダに無制限の条件が設定されている場合は、少なくとも 1 つの制限付き UDM イベントに関連付ける必要があります。
- エンティティに無制限の条件がある場合は、少なくとも 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
このオプションの有効な値は true
と false
です。このオプションが有効かどうかを決定します。デフォルト値は false
です。このオプションは、ルールで指定されていない場合、無効になります。
この設定を有効にするには、ルールのオプション セクションに allow_zero_values = true
を追加します。これにより、一致セクションでのゼロ値の処理で説明されているように、一致セクションで使用されているプレースホルダのゼロ値がルールによって暗黙的に除外されなくなります。
Boolean Expressions
ブール値式はブール型の式です。
比較
条件として使用するバイナリ式には、次の構文を使用します。
<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"
デフォルトでは、優先度の高い順に not
、and
、or
となります。
たとえば、演算子 or
と and
が式で明示的に定義されている場合、「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 を追加することで大文字と小文字の区別を無視できます。
$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 種類があります。
- 変更
- 未変更
次のイベントについて考えてみましょう。
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_original
はany $e.principal.ip = "192.0.2.1"
を満たします。event_original
はany $e.repeated_field.field_a = "9.9.9.9
に失敗します。
すべて
繰り返しフィールドのすべての要素が条件を満たす場合は、イベント全体が条件を満たしています。
event_original
はnet.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8")
を満たします。event_original
はall $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
演算子は、繰り返しフィールドとのみ互換性があります(スカラー フィールドとは互換性がありません)。any
とall
を使用して 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_1
の 192.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
に対して行われます。したがって、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
に設定されたプレースホルダなど)はカウントされません。- 配列インデックスは
any
またはall
と組み合わせることはできません。たとえば、any $e.intermediary.ip[0]
は無効です。 - 配列インデックスは、マップ構文と組み合わせることはできません。たとえば、
$e.additional.fields[0]["key"]
は無効です。 - フィールドパスに複数の繰り返しフィールドが含まれている場合は、すべての繰り返しフィールドで配列インデックスを使用する必要があります。たとえば、
$e.intermediary.ip[0]
は無効です。intermediary
とip
は両方とも繰り返しフィールドですが、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_1
は repeated_message_2
のすべての式を満たしているため、イベントはルールに一致します。
これにより、ルール repeated_message_1
には配列インデックスがないため一致が生成されず、ルール repeated_message_2
には配列インデックスが使用され一致が生成されるため、予期しない動作が発生する可能性があります。
コメント
C の場合と同様、コメントは 2 つのスラッシュ文字(// comment
)により指定します。コメントが複数行にわたる場合は、スラッシュ アスタリスク(/* comment */
)を使用してコメントアウトします。
リテラル
負でない整数と浮動小数点数、文字列、ブール値、正規表現のリテラルがサポートされています。
文字列リテラルと正規表現リテラル
YARA-L 2.0 で文字列を囲むには、次のいずれかの引用符を使用します。ただし、引用符で囲まれたテキストは、使用する引用符に応じて解釈が異なります。
二重引用符(")- 通常の文字列に使用します。エスケープ文字を含める必要があります。
たとえば、「hello\tworld」の場合、\t はタブとして解釈されます。バッククォート(`)- すべての文字を文字どおりに解釈するために使用します。
たとえば、「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 のキーワードでは大文字と小文字が区別されません。たとえば、and
と AND
は同等です。変数名はキーワードと競合しないようにする必要があります。たとえば、$AND
や $outcome
は無効です。
検出エンジンルールのキーワードは次のとおりです。rule
、meta
、match
、over
、events
、condition
、outcome
、options
、and
、or
、not
、nocase
、in
、regex
、cidr
、before
、after
、all
、any
、if
、max
、min
、sum
、array
、array_distinct
、count
、count_distinct
、is
、null
。
マップ
YARA-L は、構造体とラベルのマップアクセスをサポートしています。
構造体とラベル
一部の UDM フィールドは、構造体かラベルデータ型を使用します。
構造体とラベルの両方で特定の 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"
その他の種類の値
マップ構文で返せるのは文字列値のみです。構造体データ型の場合、マップ構文は値が文字列のキーにのみアクセスできます。値が整数などの他のプリミティブ型であるキーにアクセスすることはできません。
重複値の処理
マップアクセスは常に単一の値を返します。マップアクセスが複数の値を参照する可能性のあるまれなエッジケースでは、マップアクセスは最初の値を確定的に返します。
これは、次のいずれかの場合で発生する可能性があります。
ラベルに重複するキーがある。
ラベル構造はマップを表しますが、キーの一意性は強制されません。慣例として、マップには一意のキーが必要です。そのため、Google Security Operations では、重複するキーでラベルにデータを入力することはおすすめしません。
次のデータ例で実行すると、ルールテキスト
$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" } } }
関数
このセクションでは、検出エンジンのルールと検索で使用できる YARA-L 2.0 関数について説明します。
これらの関数は、YARA-L ルールの次の部分で使用できます。
events
セクション- 結果セクションの条件付き
BOOL_CLAUSE
。
arrays.concat
arrays.concat(string_array, string_array)
説明
元の文字列配列から要素をコピーして、新しい文字列配列を返します。
パラメータのデータ型
ARRAY_STRINGS
、ARRAY_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_STRINGS
、STRING
戻り値の型
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])
説明
配列内の最小要素を返します。配列が空の場合はゼロを返します。省略可能な 2 番目の引数を true に設定すると、ゼロに等しい要素は無視されます。
パラメータのデータ型
ARRAY_INTS|ARRAY_FLOATS
、BOOL
戻り値の型
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 つの要素を含む int 配列を使用します。
arrays.size([1, 2, 3]) = 3
例 3
この例では、1 つの要素を含む浮動小数点配列を使用します。
arrays.size([1.200000]) = 1
例 4
この例では空の配列を使用しています。
arrays.size([]) = 0
arrays.index_to_int
arrays.index_to_int(array_of_inputs, index)
説明
配列の指定されたインデックスの値を整数として返します。インデックスが負数の場合、値は配列の最後から取得されます。
パラメータのデータ型
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
、INT
戻り値の型
INT
コードサンプル
例 1
この関数呼び出しは、インデックスの値が数値以外の文字列の場合、0 を返します。
arrays.index_to_int(["str0", "str1", "str2"], 1) = 0
例 2
この関数は、インデックス -1 の要素を返します。
arrays.index_to_int(["44", "11", "22", "33"], -1) = 33
例 3
境界外の要素の場合は 0 を返します。
arrays.index_to_int(["44", "11", "22", "33"], 5) = 0
例 4
この関数は、浮動小数点配列のインデックス 2 にある要素を取得します。
arrays.index_to_int([1.100000, 1.200000, 1.300000], 1) = 1
例 5
この関数は、int 配列のインデックス 0 にある要素を取得します。
arrays.index_to_int([1, 2, 3], 2) = 1
cast.as_bool
cast.as_bool(string_or_int)
説明
関数は、整数値または文字列値をブール値に変換します。キャストできない値を含む関数呼び出しは 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(-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
フィンガープリント
hash.fingerprint2011(byteOrString)
説明
この関数は、入力バイト シーケンスまたは文字列の fingerprint2011
ハッシュを計算します。この関数は、[2, 0xFFFFFFFFFFFFFFFF]
の範囲内の符号なし INT
値を返します。
パラメータのデータ型
BTYE
、STRING
戻り値の型
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
この例では、負の値の天井を返します。
math.ceil(-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(-1.234568) = -2
例 3
この例では、ゼロの場合を示します。
math.floor(0.000000) = 0
math.geo_distance
math.geo_distance(longitude1, latitude1, longitude2, latitude2))
説明
2 つの位置情報(座標)間の距離を返します。地理座標が無効な場合は -1 を返します。
パラメータのデータ型
FLOAT
、FLOAT
、FLOAT
、FLOAT
戻り値の型
FLOAT
コードサンプル
例 1
この例では、すべてのパラメータが有効な座標の場合に距離を返します。
math.geo_distance(-122.020287, 37.407574, -122.021810, 37.407574) = 134.564318
例 2
この例では、パラメータのいずれかが切り捨てられた座標の場合に距離を返します。
math.geo_distance(-122.000000, 37.407574, -122.021810, 37.407574) = 1926.421905
例 3
この例では、パラメータのいずれかが無効な座標の場合、-1 を返します。
math.geo_distance(-122.897680, 37.407574, -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
この例には、負の double 値 1 つ、ゼロの INT64 値 1 つ、正の INT64 値 1 つが含まれています。
math.is_increasing(-1.200000, 0, 3) = true
例 3
この例には、負の double 値 1 つ、ゼロの INT64 値 1 つ、負の INT64 値 1 つが含まれています。
math.is_increasing(-1.200000, 0, -3) = false
例 4
この例には、2 つの負の double 値と 1 つのゼロ INT64 値が含まれています。
math.is_increasing(-1.200000, -1.50000, 0) = false
例 5
この例には、1 つの負の double 値と 2 つの同じ値が含まれています。
math.is_increasing(-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 を返します。
パラメータのデータ型
基数: INT|FLOAT
指数: 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, -3) // 0.037037
例 5
この例では、小数指数のケースを示します。
math.pow(3, -1.200000) // 0.267581
例 6
この例では、負ベースのケースを示します。
math.pow(-3, -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(-10.7) // returns -11
math.round(-1.2) // returns -1
math.round(4) // returns 4, math.round(integer) returns the integer
指標
指標関数を使用すると、大量の過去データを集計できます。これは、結果セクションで 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 アドレス フィールドの両方を処理できます。
パラメータのデータ型
STRING
、STRING
戻り値の型
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
修飾子を使用すると、検索で大文字小文字の区別が無視されるよう指定できます。
パラメータのデータ型
STRING
、STRING
パラメータ式の型
ANY
、ANY
戻り値の型
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 つ以上のキャプチャ グループを定義すると、コンパイラ エラーが返されます。
パラメータのデータ型
STRING
、STRING
戻り値の型
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
この例では、メール内の @
記号の後のすべての部分をキャプチャし、com
を org
に置き換えて結果を返します。ネストされた関数が使用されることに注意してください。
"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")
sample_rate
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.from
が suspicious@gmail.com
であるか、(2)$e.network.email.from
が空かつ$e.network.email.to
が suspicious@gmail.com
の場合、条件は true と評価されます。
"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
例 2
次の例では、2 つを超える引数を使用して coalesce
関数を呼び出します。この条件は、イベント $e
の最初の null 以外の IP アドレスを、リファレンス リスト ip_watchlist
の値と比較します。この呼び出しで引数が結合される順序は、ルール条件で引数が列挙されている順序と同じです。
$e.principal.ip
が最初に評価されます。$e.src.ip
が評価されます。$e.target.ip
が評価されます。- 最後に、以前の
ip
フィールドが設定されていない場合、文字列「No IP」がデフォルト値として返されます。
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
例 3
次の例では、イベント $e1
とイベント $e2
の principal.hostname
を結合しようとしています。引数が異なるイベント変数であるため、コンパイラ エラーが返されます。
// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)
strings.concat
strings.concat(a, b, c, ...)
説明
無制限の数のアイテムを連結した値を返します。各アイテムは、文字列、整数、または浮動小数点数です。
引数がイベント フィールドの場合、属性は同じイベントからのものである必要があります。
パラメータのデータ型
STRING
、FLOAT
、INT
戻り値の型
STRING
コードサンプル
例 1
次の例には、引数として文字列変数と整数変数が含まれています。principal.hostname
と principal.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 とイベント $e2
の principal.hostname
を連結しようとしています。引数が異なるイベント変数であるため、コンパイラ エラーが返されます。
// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)
strings.contains
strings.contains( str, substr )
説明
指定された文字列に指定された部分文字列が含まれている場合に true を返します。それ以外の場合は false を返します。
パラメータのデータ型
STRING
、STRING
戻り値の型
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 を返します。
パラメータのデータ型
STRING
、STRING
戻り値の型
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_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)
説明
指定した文字列の先頭の空白文字を削除します。この関数は、そのカットセットの先頭にある文字を削除します。
パラメータのデータ型
STRING
、STRING
戻り値の型
STRING
コードサンプル
ユースケースの例を次に示します。
例 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)
説明
指定した文字列の末尾の空白文字を削除します。そのカットセットに存在する末尾の文字を削除します。
パラメータのデータ型
STRING
、STRING
戻り値の型
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 引数で指定)を削除します。
パラメータのデータ型
STRING
、STRING
戻り値の型
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+"¶m2=2;'
timestamp.as_unix_seconds
timestamp.as_unix_seconds(timestamp [, time_zone])
説明
この関数は、指定されたタイムスタンプ文字列の Unix エポックからの経過秒数を表す整数を返します。
timestamp
は、有効なエポック タイムスタンプを表す文字列です。形式は%F %T
にする必要があります。time_zone
は省略可能で、タイムゾーンを示す文字列です。省略した場合、デフォルトはGMT
です。文字列リテラルを使用してタイムゾーンを指定できます。以下のオプションがあります。- TZ データベース名(
America/Los_Angeles
など)。詳細については、Wikipedia の tz データベースのタイムゾーン一覧をご覧ください。 (+|-)H[H][:M[M]]
形式の UTC からのタイムゾーン オフセット(例: 「-08:00」)。
- TZ データベース名(
以下に、有効な 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"
パラメータのデータ型
STRING
、STRING
戻り値の型
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"
パラメータのデータ型
INT
、STRING
戻り値の型
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"
パラメータのデータ型
INT
、STRING
戻り値の型
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"
パラメータのデータ型
INT
、STRING
戻り値の型
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"
パラメータのデータ型
INT
、STRING
戻り値の型
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, optional timezone)
説明
この関数は、タイムスタンプの日付を表す YYYY-MM-DD
形式の文字列を返します。
unix_seconds
は、$e.metadata.event_timestamp.seconds
などの Unix エポックからの経過秒数を表す整数か、その値を含むプレースホルダです。timestamp_format
は省略可能で、タイムスタンプの形式を表す文字列です。省略した場合、デフォルトは%F %T
です。形式は文字列リテラルを使用して指定できます。オプションについては、日付と時刻の部分の形式設定要素をご覧ください。time_zone
は省略可能で、タイムゾーンを示す文字列です。省略した場合、デフォルトはGMT
です。文字列リテラルを使用してタイムゾーンを指定できます。以下のオプションがあります。- IANA タイムゾーン(TZ)データベース名(例:
America/Los_Angeles
)。詳細については、Wikipedia の tz データベースのタイムゾーン一覧をご覧ください。 (+|-)H[H][:M[M]]
形式の UTC からのタイムゾーン オフセット(例: 「-08:00」)。
- IANA タイムゾーン(TZ)データベース名(例:
以下に、有効な 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"
パラメータのデータ型
INT
、STRING
、STRING
戻り値の型
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"
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"
パラメータのデータ型
INT
、STRING
戻り値の型
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 を取得することがあります。
パラメータのデータ型
INT
、STRING
戻り値の型
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 を取得するといったユースケースがあります。
パラメータのデータ型
INT
、STRING
戻り値の型
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|FLOAT
、BOOL
戻り値の型
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
関数からプレースホルダへの割り当て
関数呼び出しの結果は、events
セクションのプレースホルダに割り当てることができます。次に例を示します。
$placeholder = strings.concat($e.principal.hostname, "my-string").
その後、match
、condition
、outcome
セクションでプレースホルダ変数を使用できます。
ただし、関数からプレースホルダへの代入には 2 つの制限があります。
関数からプレースホルダへの代入のすべてのプレースホルダは、イベント フィールドを含む式に割り当てる必要があります。たとえば、次の例は有効です。
$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.
関数呼び出しは、いずれか 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
// REGEX 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
ステートメントの最大数: 4cidr
演算子を使用したin
ステートメントの最大数: 2
型チェック
インターフェース内でルールを作成する際に、Google Security Operations は 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 で検出結果を表示している場合は、検出結果のすべてのイベント サンプルをダウンロードできます。詳細については、イベントをダウンロードするをご覧ください。