YARA-L の既知の問題と制限事項
このドキュメントでは、YARA-L の既知の問題と制限事項について説明します。
繰り返しフィールドのネスト解除による結果の集計
ルールで複数の要素を持つイベント変数の繰り返しフィールドを参照すると、各要素が個別のイベント行に分割されます。
たとえば、イベント $e の繰り返しフィールド target.ip にある 2 つの IP アドレスは、それぞれが異なる target.ip 値を持つ $e の 2 つのインスタンスに分割されます。
rule outbound_ip_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $outbound_ip_count = count($e.target.ip) // yields 2.
  condition:
    $e
}
フィールドのネスト解除前のイベント レコード
次の表は、繰り返しフィールドのネスト解除前のイベント レコードを示しています。
| metadata.id | principal.application | target.ip | 
|---|---|---|
aaaaaaaaa | 
Google SecOps | 
[192.0.2.20、192.0.2.28] | 
繰り返しフィールドのネスト解除後のイベント レコード
次の表は、繰り返しフィールドのネスト解除後のイベント レコードを示しています。
| metadata.id | principal.application | target.ip | 
|---|---|---|
aaaaaaaaa | 
Google SecOps | 
192.0.2.20 | 
aaaaaaaaa | 
Google SecOps | 
192.0.2.28 | 
ルールが、security_results.action のように別のフィールド内にネストされた繰り返しフィールドを参照する場合、親レベルと子レベルの両方でネスト解除が行われます。単一イベントのネスト解除から得られるインスタンスは、親フィールドと子フィールドの要素のデカルト積を形成します。次の例のルールでは、security_results で 2 つの値が繰り返され、security_results.actions で 2 つの値が繰り返されるイベント $e は、4 つのインスタンスにネスト解除されます。
rule security_action_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $security_action_count = count($e.security_results.actions) // yields 4.
  condition:
    $e
}
フィールドのネスト解除前のイベント レコード
次の表は、繰り返しフィールドのネスト解除前のイベント レコードを示しています。
| metadata.id | principal.application | security_results | 
|---|---|---|
aaaaaaaaa | 
Google SecOps | 
[ { actions: [ ALLOW, FAIL ] }、{ actions: [ CHALLENGE, BLOCK ] } ] | 
フィールドのネスト解除を繰り返した後のイベント レコード
次の表は、繰り返しフィールドのネスト解除後のイベント レコードを示しています。
| metadata.id | principal.application | security_results.actions | 
|---|---|---|
aaaaaaaaa | 
Google SecOps | 
許可 | 
aaaaaaaaa | 
Google SecOps | 
失敗 | 
aaaaaaaaa | 
Google SecOps | 
CHALLENGE | 
aaaaaaaaa | 
Google SecOps | 
ブロック | 
ルールの評価でこのネスト解除動作が行われると、ルールが親フィールド(これも繰り返しフィールド)で 1 つ以上の繰り返しフィールドを参照している場合に、予期しない結果の集計が生成される可能性があります。sum()、array()、count() などの個別でない集計では、ネスト解除の動作によって生成された同じイベントにおける他のフィールドの重複値は考慮できません。次の例のルールでは、イベント $e に単一のホスト名 google.com がありますが、結果 hostnames は同じイベント $e のネストされていない 4 つのインスタンスに集計され、それぞれ重複した principal.hostname 値を持ちます。この結果、security_results.actions の重複する値がネスト解除されるため、1 つではなく 4 つのホスト名が生成されます。
rule security_action_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $hostnames = array($e.principal.hostname) // yields 4.
    $security_action_count = count($e.security_results.action) // yields 4.
  condition:
    $e
}
フィールドのネスト解除前のイベント レコード
次の表は、繰り返しフィールドのネスト解除前のイベント レコードを示しています。
| metadata.id | principal.application | principal.hostname | security_results | 
|---|---|---|---|
aaaaaaaaa | 
Google SecOps | 
google.com | 
[ { action: [ ALLOW, FAIL ] }、{ action: [ CHALLENGE, BLOCK ] } ] | 
繰り返しフィールドのネスト解除後のイベント レコード
次の表は、繰り返しフィールドのネスト解除後のイベント レコードを示しています。
| metadata.id | principal.application | principal.hostname | security_results.action | 
|---|---|---|---|
aaaaaaaaa | 
Google SecOps | 
google.com | 
許可 | 
aaaaaaaaa | 
Google SecOps | 
google.com | 
失敗 | 
aaaaaaaaa | 
Google SecOps | 
google.com | 
CHALLENGE | 
aaaaaaaaa | 
Google SecOps | 
google.com | 
ブロック | 
回避策
重複値を無視または除外する集計は、このネスト解除動作の影響を受けません。ネスト解除が原因で予期しない結果値が発生している場合は、集計の個別のバージョンを使用します。
次の集計は、前述のネスト解除の動作の影響を受けません。
max()min()array_distinct()count_distinct()
複数のイベント変数を含む結果の集計
ルールに複数のイベント変数が含まれている場合は、検出に含まれるイベントの組み合わせごとに、集計に別々の項目があります。たとえば、次のサンプルルールがリスト内のイベントに対して実行された場合:
events:
  $e1.field = $e2.field
  $e2.somefield = $ph
match:
  $ph over 1h
outcome:
   $some_outcome = sum(if($e1.otherfield = "value", 1, 0))
condition:
  $e1 and $e2
event1:
  // UDM event 1
  field="a"
  somefield="d"
event2:
  // UDM event 2
  field="b"
  somefield="d"
event3:
  // UDM event 3
  field="c"
  somefield="d"
合計はイベントのすべての組み合わせで計算されるため、結果の値の計算では両方のイベント変数を使用できます。計算には次の要素が使用されます。
1: $e1 = event1, $e2 = event2
2: $e1 = event1, $e2 = event3
3: $e1 = event2, $e2 = event1
4: $e1 = event2, $e2 = event3
5: $e1 = event3, $e2 = event1
5: $e1 = event3, $e2 = event2
これにより、$e2 が 3 つの異なるイベントにのみ対応する場合でも、とりうる最大合計値は 6 になります。
これは、合計、カウント、配列に影響します。count と array では、count_distinct または array_distinct を使用して問題を解決できますが、sum に対する代替策はありません。
式の先頭にある括弧
式の先頭で括弧を使用すると、次のエラーが発生します。
parsing: error with token: ")"
invalid operator in events predicate
次の例では、このタイプのエラーが発生します。
($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1
次の構文のバリエーションは、有効な構文で同じ結果を返します。
$event.metadata.ingested_timestamp.seconds / 3600 -
$event.metadata.event_timestamp.seconds / 3600 > 1
    1 / 3600 * ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) > 1
    1 < ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600
結果のインデックス配列では繰り返しフィールドの単一値の集計が必要
結果セクションの配列のインデックス化には引き続き集計が必要です。 たとえば、次は機能しません。
outcome:
  $principal_user_dept = $suspicious.principal.user.department[0]
ただし、配列インデックスの出力をプレースホルダ変数に保存し、ここに示すように、結果変数でその変数を使用できます。
events:
  $principal_user_dept = $suspicious.principal.user.department[0]
outcome:
  $principal_user_department = $principal_user_dept
存在しない場合に OR 条件
2 つの別々のイベント変数間で OR 条件が適用され、ルールの一致が存在しない場合に、ルールは正常にコンパイルされますが、誤って正の検出が発生する可能性があります。たとえば、次のルール構文は $event_a.field = "something" を持つイベントと、一致すべきでなくても、一致する可能性があります。
events:
     not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
     $event_a and #event_b >= 0
回避手段は、条件が 2 つのブロックに分け、ここで各ブロックはここで示すように単一の変数にのみフィルタを適用することです。
events:
     not ($event_a.field = "something")
     not ($event_b.field = "something")
condition:
     $event_a and #event_b >= 0
符号なしイベント フィールドを使用した演算
型が符号なし整数の UDM フィールドを含む演算で整数定数を使用すると、エラーが発生します。次に例を示します。
events:
  $total_bytes = $e.network.received_bytes * 2
フィールド udm.network.received_bytes は符号なし整数です。これは、整数の定数がデフォルトで符号付き整数になるためです。符号付き整数は、算術演算で符号なし整数と連携しません。
回避策として、整数の定数を強制的に浮動小数点数にすることで、符号なし整数で動作するようにします。次に例を示します。
events:
  $total_bytes = $e.network.received_bytes * (2/1)
GeoIP 拡充における結果整合性と誤検出
システムは、初期の拡充ステージ(ストリーミングとレイテンシに敏感)で即時精度よりも速度を優先するため、データの欠落や誤検出が発生する可能性があります。システムはバックグラウンドでデータの拡充を継続しますが、ルールの実行時にデータが利用できない場合があります。これは、通常の結果整合性プロセスの一部です。このような誤検出を回避するには、検出をトリガーするために、イベント内に拡充フィールドが存在することを前提としないでください。
たとえば、次のルールイベントについて考えてみましょう。
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
このルールは、イベントに $e.principal.ip_geo_artifact.network.asn = "16509" と $e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom" の両方(どちらも拡充フィールド)が含まれている必要があるという事実に基づいています。拡充が期限までに完了しなかった場合、ルールは誤検出を生成します。
これを回避するには、このルールのチェックを次のように変更します。
$e.principal.ip_geo_artifact.network.asn != "" AND 
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region != "" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
このルールにより、ASN 16509 の IP アドレスで、英国外に存在する IP アドレスによってイベントがトリガーされる可能性を排除できます。これにより、ルールの全体的な精度が向上します。