YARA-L 2.0 言語の構文
このセクションでは、YARA-L 構文の主な要素について説明します。YARA-L 2.0 言語の概要もご覧ください。
ルールの構造
YARA-L 2.0 では、変数の宣言、定義、用途を次の順序で指定する必要があります。
- メタ
- イベント
- 一致(省略可)
- outcome(省略可)
- 条件
- 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
変数を使用する場合、変数宣言でその変数を宣言する必要があります。変数が宣言なしで使用されていると、コンパイル エラーとみなされます。
イベント変数のフィルタ
1 つのイベント変数を操作するブール式はフィルタと見なされます。
イベント変数の結合
ルールで使用するすべてのイベント変数は、次のいずれかの方法で他のすべてのイベント変数と結合する必要があります。
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 フィールドに格納されます。
結果変数のデータ型
各結果変数には異なるデータ型を含めることができます。このデータ型は計算に使用される式によって決まります。次の結果データ型がサポートされています。
- 整数
- 浮動小数点数
- string
- 整数のリスト
- 浮動小数点数のリスト
- 文字列のリスト
条件付きロジック
条件付きロジックを使用して、結果の値を計算できます。条件は次の構文パターンを使用して指定します。
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
は、このルールの結果セクションではスカラー以外の値になります。
結果変数は常に 1 つのスカラー値を生成する必要があるため、結果の割り当てが依存するスカラー以外の値を集計して、単一のスカラー値を生成する必要があります。結果セクションでは、以下はスカラーではない値であり、集計する必要があります。
- ルールで一致セクションを使用する場合のイベント フィールド(繰り返しまたは繰り返しでない)
- ルールで一致セクションを使用する場合のイベントのプレースホルダ(繰り返しまたは繰り返しでない)
- ルールで一致セクションを使用しない場合の繰り返しイベント フィールド
- ルールで一致セクションが使用されない場合に繰り返されるイベント プレースホルダ
一致セクションを使用しないルールの集計には、スカラー イベント フィールド、スカラー イベント プレースホルダ、定数をラップできます。ただし、ほとんどの集計でラップされた値が生成されるため、不要です。例外は、スカラー値を配列に変換するために使用できる array()
集計です。
結果変数は集計と同様に扱われます。別の結果の割り当てで参照されたときに再集計することはできません。
次の集計関数を使用できます。
max()
: 可能性のあるすべての値の最大値を出力します。整数と浮動小数点数でのみ使用できます。min()
: 可能性のあるすべての値の最小値を出力します。整数と浮動小数点数でのみ使用できます。sum()
: 可能性のあるすべての値の和を出力します。整数と浮動小数点数でのみ使用できます。count_distinct()
: 可能性のあるすべての値を収集し、可能性のある値の一意の値の数を出力します。count()
:count_distinct()
のように動作しますが、可能性のある値の一意でない値の数を返します。array_distinct()
: 可能性のあるすべての一意の値を収集し、これらの値のリストを出力します。Distinct 値のリストを 25 個のランダムな要素に切り詰めます。一意のリストを取得するための重複除去が最初に適用され、次に切り捨てが適用されます。array()
:array_distinct()
のように動作しますが、一意でない値のリストを返します。また、値のリストを 25 個のランダムな要素に切り詰めます。
集計関数は、複数のイベントが存在することを指定する 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
float: 演算子
=, >, >=, <, <=, !=
を使用して float リテラルと比較します。次に例を示します。$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 の修飾子
文字列値または正規表現の比較式がある場合は、式の最後に 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 | 任意の $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"
を満たしますが、$e.principal.ip = "192.0.2.3" を満たすのは event_copy_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
でグループ化が行われます。したがって、$ip
一致変数に対して異なる値を持つ一致が 3 つ取得されます。各一致には、単一の要素 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 セクションの構文をご覧ください)。
Keywords
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"
その他の型の値
マップ構文は文字列値のみを返すことができます。Struct データ型の場合、マップ構文は値が文字列であるキーにのみアクセスできます。値が整数などの他のプリミティブ型であるキーにアクセスすることはできません。
重複値の処理
マップアクセスは常に単一の値を返します。マップアクセスが複数の値を参照できるという一般的ではないエッジケースでは、マップアクセスが決定論的に最初の値を返します。
これは、次のいずれかの場合に発生します。
ラベルに重複するキーがあります。
ラベル構造はマップを表しますが、キーの一意性は強制されません。慣例により、マップには一意のキーが必要です。そのため、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.length
arrays.length(repeatedField)
説明
繰り返しフィールド要素の数を返します。
パラメータのデータ型
LIST
戻り値の型
NUMBER
コードサンプル
例 1
繰り返しフィールド要素の数を返します。
arrays.length($e.principal.ip) = 2
例 2
複数の繰り返しフィールドがパスに沿っている場合、繰り返しフィールド要素の総数を返します。
arrays.length($e.intermediary.ip) = 3
Fingerprint
hash.fingerprint2011(byteOrString)
説明
この関数は、入力バイト シーケンスまたは文字列の fingerprint2011
ハッシュを計算します。この関数は、[2, 0xFFFFFFFFFFFFFFFF]
の範囲内の符号なし INT
値を返します。
パラメータのデータ型
BTYE
、STRING
戻り値の型
INT
コードサンプル
id_fingerprint = hash.fingerprint2011("user123")
グループ
group(field1, field2, field3, ...)
説明
類似した型のフィールドをプレースホルダ変数にグループ化します。
コードサンプル
例 1
すべての IP アドレスをグループ化し、スキャンされた期間で最も普及している IP アドレスを降順に並べます。
$ip = group(principal.ip, about.ip, target.ip)
$ip != ""
match:
$ip
outcome:
$count = count_distinct(metadata.id)
order:
$count desc
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.log
math.log(numericExpression)
説明
整数または浮動小数点式の自然ログ値を返します。
パラメータのデータ型
NUMBER
戻り値の型
NUMBER
コードサンプル
例 1
math.log($e1.network.sent_bytes) > 20
math.round
math.round(numericExpression, decimalPlaces)
説明
指定した小数点以下の桁数に丸めた float 式の値を返します。
パラメータのデータ型
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 Metrics をご覧ください。
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」が含まれている場合、この関数によって最初のインスタンスが返されるため、次の式になります。この例にはキャプチャ グループはありません。
"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")
サンプルレート
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
次の例では、3 個を超える引数を使用して 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.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(stringText)
説明
この関数は入力文字列を受け取り、すべての文字を大文字に変更してから文字列を返します。
パラメータのデータ型
STRING
戻り値の型
STRING
コードサンプル
例 1
次の例では、true
が返されます。
"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)
timestamp.current_seconds
timestamp.current_seconds()
説明
現在の時刻を Unix 秒数で表す整数を返します。これは検出のタイムスタンプとほぼ同じで、ルールが実行されるタイミングに基づきます。
パラメータのデータ型
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_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
関数からプレースホルダの割り当て
関数呼び出しの結果を 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 で検出を表示している場合は、検出のすべてのイベント サンプルをダウンロードできます。詳しくは、イベントをダウンロードするをご覧ください。