YARA-L 2.0 言語の構文

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

コメント

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

定数

整数、文字列、浮動小数点数、正規表現の定数がサポートされています。文字列定数の場合は、二重引用符を使用します。正規表現定数には /regex/ を使用します。

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

YARA-L を使用すると、net.ip_in_range_cidr() ステートメントを使用するサブネットワーク内のすべての IP アドレスにわたり UDM イベントを検索できます。IPv4 と IPv6 の両方がサポートされています。

IP アドレスの範囲を検索するには、IP UDM フィールドとクラスレス ドメイン間ルーティング(CIDR)範囲を指定します。YARA-L は、単一および繰り返しの IP アドレス フィールドの両方を処理できます。

IPv4 の例:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

IPv6 の例:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

net.ip_in_range_cidr() ステートメントを使用したルールの例については、サンプルのルール: IP アドレスの範囲内の単一イベントをご覧ください。

演算子

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

オペレーター Description
= 等しい
!= 等しくない
< 次より小さい
<= 以下
> 次より大きい
>= 以上

文字列の引用符

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

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

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

正規表現では、多くの場合、文字列にバックスラッシュ(\)文字を含める必要があります。ただし、二重引用符を使用する場合は、バックスラッシュ文字をバックスラッシュ文字でエスケープする必要がありますが、読みづらくなります。

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

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

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

変数

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

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

  • イベント変数 - イベントのグループを正規化された形式(UDM)で表します。events セクションで、イベント変数の条件を指定します。変数の後ろにあるイベント フィールドを使用して、イベント変数を識別します。イベント フィールドは、.<field name> のチェーンで表されます(例: $e.field1.field2)。イベント フィールド チェーンは常に最上位の UDM から始まります。

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

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

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

events セクションの構文

events セクションに述語のリストを表示して、次の項目を指定します。

  • 各一致変数またはプレースホルダ変数が表すもの
  • 単一のイベント変数に対するフィルタ条件
  • 2 つのイベント変数に対する結合条件。

変数の宣言

変数を宣言する場合は、次の構文を使用します。

  • 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

イベント変数のフィルタ条件

単一のイベント変数に対するフィルタ条件には、次の構文を使用します。

  • [EVENT_FIELD] [OP] [CONST]
  • [CONST] [OP] [EVENT_FIELD]

どちらも同等ですが、読みやすくするために前者([EVENT_FIELD] [OP] [CONST])を使用することをおすすめします。

次に例を示します。

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port

この述語はイベント変数のフィルタとして使用されます。つまり、イベント変数で表されるイベント グループがこの条件を満たす必要があります。

イベント変数の結合条件

2 つのイベント変数の結合条件を表すには、次の構文を使用します。

[EVENT_FIELD] [OP] [EVENT_FIELD]

次に例を示します。

  • $e1.source.hostname = $e2.target.hostname
  • $e1.metadata.timestamp < $e2.metadata.timestamp

この述語は、条件と 2 つのイベント変数を結合するために使用されます。

無効な述語の例を以下に示します。

  • $e.source.hostname != $hostname //comparison over match/placeholder var
  • $hostname != "host1234" //comparison over match/placeholder var
  • $var1 //variable itself does not mean anything

論理演算子

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

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

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

たとえば、"a or b and c""a or (b and c)" と評価されます。必要に応じて、括弧を使用して優先順位を変更できます。

一致セクションの構文

一致条件を確認する前に、一致セクションでグループ イベントの一致変数を一覧表示します。これらのフィールドは、一致するたびに返されます。

  • 各一致変数が表す内容を events セクションで指定します。
  • over キーワードに続くイベントを相関させる期間を指定します。期間外のイベントは無視されます。
  • 期間を指定するには、構文 <number><s/m/h/d> を使用します。ここで、s/m/h/d は秒、分、時、日を表します。
  • 指定できる最小時間は 1 分です。
  • 指定できる最大時間は 48 時間です。

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

$var1, $var2 over 5m

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

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

$user over 1h

次のステートメントは、ルールが一致した場合に $user を返します。指定する期間は 1 時間です。1 時間を超えるイベントは相関されません。これらのイベントは、ルールで検出対象と見なされません。

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

$source_ip, $target_ip, $hostname over 2m

次のステートメントは、ルールが一致した場合に $source_ip$target_ip$hostname を返します。指定する期間は 2 分です。間隔が 2 分を超えるイベントは相関されません。これらのイベントは、ルールで検出対象と見なされません。

次の例は、無効な match を示しています。

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

condition セクションの構文

condition セクションで、events セクションで定義されているイベントと変数に一致する条件を指定します。ここで一致する述語が一覧表示され、キーワード and または or に結合されます。

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

  • $var // equivalent to #var > 0
  • #var > n // where n is >= 0
  • #var >= m // where m > 0

次の条件は境界なし条件です。関連付けられたイベント変数が存在しないようにします。つまり、検出でイベントのオカレンスがない可能性があります。これにより、不在ルールを作成できます。このルールでは、変数の存在ではなく、変数の不在を検索します。

  • !$var // equivalent to #var = 0
  • #var < n // where n is > 0
  • #var <= m // where m >= 0

次の例では、変数(イベント変数またはプレースホルダ変数)の特殊文字 # が、その変数の個々のイベントまたは値の数を表します。

$e and #port > 50 or #event1 > 2 or #event2 > 1 or #event3 > 0

次の不在の例も有効で、$event1 とは異なるイベントが 3 つ以上存在し、$event2 とは異なるイベントがない場合に true と評価されます。

#event1 > 2 and !$event2

無効な述語の例を以下に示します。

  • $e, #port > 50 // incorrect keyword usage
  • $e or #port < 50 // or keyword not supported with non-bounding conditions

正規表現

YARA-L 2.0 では、次のいずれかの構文を使用して正規表現を定義できます。

  • YARA 構文の使用 - イベントに関連します。この構文の一般的な表現は次のとおりです。$e.field = /regex/
  • YARA-L 構文の使用 - 次のパラメータを受け取る関数として使用します。
    • 正規表現を適用するフィールド。
    • 文字列として指定された正規表現。文字列の後に nocase 修飾子を使用すると、検索で大文字小文字の区別が無視されるよう指定できます。この構文の一般的な表現は次のとおりです。re.regex($e.field, `regex`)

文字列と完全に一致する場合、またはプレフィックスまたはサフィックスのみと一致する場合は、正規表現に ^(開始)と $(終了)のアンカー文字を含めます。

たとえば、/^full$/"full" と正確に一致しますが、/full/"fullest""lawfull""joyfully" と一致します。

生の文字列

YARA-L 2.0 を使用して、企業のイベントデータ内の生の文字列を検索できます。

文字列を検索する場合は、文字列を二重引用符(`)ではなくバッククォート文字(`)で囲みます。

バッククォートは、文字列の内容が文字どおりに解釈されることを示します(エスケープ文字は解析されません)。