Übersicht über die Sprache YARA-L 2.0

Unterstützt in:

YARA-L 2.0 ist eine Computersprache, mit der Regeln für die Suche in den Logdaten Ihres Unternehmens bei der Aufnahme in Ihre Google Security Operations-Instanz erstellt werden. Die YARA-L-Syntax leitet sich von der von VirusTotal entwickelten YARA-Sprache ab. Die Sprache funktioniert in Verbindung mit der Detection Engine von Google Security Operations und ermöglicht es Ihnen, in großen Datenmengen nach Bedrohungen und anderen Ereignissen zu suchen.

Hier finden Sie weitere Informationen:

Beispielregeln für YARA-L 2.0

Die folgenden Beispiele zeigen Regeln, die in YARA-L 2.0 geschrieben wurden. In jedem Beispiel wird gezeigt, wie Ereignisse in der Regelsprache in Beziehung gesetzt werden.

Regeln und Optimierung

Die folgende Regel prüft Ereignisdaten auf bestimmte Muster und erstellt eine Erkennung, wenn sie diese findet. Diese Regel enthält die Variable $e1 zum Erfassen des Ereignistyps und das UDM-Feld metadata.event_type. Die Regel prüft auf bestimmte Vorkommen von Übereinstimmungen mit regulären Ausdrücken mit e1. Wenn das Ereignis $e1 eintritt, wird eine Erkennung erstellt. Die Regel enthält eine not-Bedingung, um bestimmte schädliche Pfade auszuschließen. Sie können not-Bedingungen hinzufügen, um falsch positive Ergebnisse zu vermeiden.

rule suspicious_unusual_location_svchost_execution
{

 meta:
   author = "Google Cloud Security"
   description = "Windows 'svchost' executed from an unusual location"
   yara_version = "YL2.0"
   rule_version = "1.0"

 events:

   $e1.metadata.event_type = "PROCESS_LAUNCH"
   re.regex($e1.principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
   not re.regex($e1.principal.process.command_line, `\\Windows\\System32\\`) nocase

condition:

   $e1
}

Anmeldungen von verschiedenen Orten

Mit der folgenden Regel wird nach Nutzern gesucht, die sich in weniger als 5 Minuten von zwei oder mehr Städten aus in Ihrem Unternehmen angemeldet haben:

rule DifferentCityLogin {
  meta:

  events:
    $udm.metadata.event_type = "USER_LOGIN"
    $udm.principal.user.userid = $user
    $udm.principal.location.city = $city

  match:
    $user over 5m

  condition:
    $udm and #city > 1
}

Übereinstimmungsvariable: $user

Ereignisvariable:$udm

Platzhaltervariable: $city und $user

Im Folgenden wird beschrieben, wie diese Regel funktioniert:

  • Gruppiert Ereignisse nach Nutzername ($user) und gibt ihn ($user) zurück, wenn eine Übereinstimmung gefunden wird.
  • Die Zeitspanne beträgt 5 Minuten. Das bedeutet, dass nur Ereignisse, die weniger als 5 Minuten auseinanderliegen, miteinander in Beziehung gesetzt werden.
  • Es wird nach einer Ereignisgruppe ($udm) gesucht, deren Ereignistyp USER_LOGIN ist.
  • Für diese Ereignisgruppe ruft die Regel die Nutzer-ID als $user und die Stadt der Anmeldung als $city. auf.
  • Es wird eine Übereinstimmung zurückgegeben, wenn die eindeutige Anzahl der city-Werte (#city) in der Ereignisgruppe ($udm) innerhalb des 5-Minuten-Zeitraums größer als 1 ist.

Schnelle Nutzererstellung und ‑löschung

Mit der folgenden Regel wird nach Nutzern gesucht, die innerhalb von 4 Stunden erstellt und dann gelöscht wurden:

rule UserCreationThenDeletion {
  meta:

  events:
    $create.target.user.userid = $user
    $create.metadata.event_type = "USER_CREATION"

    $delete.target.user.userid = $user
    $delete.metadata.event_type = "USER_DELETION"

    $create.metadata.event_timestamp.seconds <=
       $delete.metadata.event_timestamp.seconds

  match:
    $user over 4h

  condition:
    $create and $delete
}

Ereignisvariablen:$create und $delete

Übereinstimmungsvariable: $user

Platzhaltervariable: –

Im Folgenden wird beschrieben, wie diese Regel funktioniert:

  • Gruppiert Ereignisse nach Nutzername ($user) und gibt ihn ($user) zurück, wenn eine Übereinstimmung gefunden wird.
  • Das Zeitfenster beträgt 4 Stunden. Das bedeutet, dass nur Ereignisse, die weniger als 4 Stunden auseinanderliegen, miteinander in Beziehung gesetzt werden.
  • Es wird nach zwei Ereignisgruppen gesucht ($create und $delete, wobei $create #create >= 1 entspricht).
  • $create entspricht USER_CREATION-Ereignissen und ruft die User-ID als $user auf.
  • $user wird verwendet, um die beiden Ereignisgruppen zusammenzuführen.
  • $delete entspricht USER_DELETION-Ereignissen und ruft die User-ID als $user auf. Bei dieser Regel wird nach einer Übereinstimmung gesucht, bei der die Nutzer-ID in den beiden Ereignisgruppen identisch ist.
  • Mit dieser Regel wird nach Fällen gesucht, in denen das Ereignis von $delete später als das Ereignis von $create eintritt. Wenn ein Übereinstimmung gefunden wird, wird ein Treffer zurückgegeben.

Regel für einzelne Ereignisse

Regeln für einzelne Ereignisse beziehen sich auf ein einzelnes Ereignis. Eine einzelne Ereignisregel kann:

  • Alle Regeln ohne Abgleichbereich
  • Regel mit einem match- und einem condition-Abschnitt, in dem nur nach dem Vorhandensein eines Ereignisses gesucht wird (z. B. „$e“, „#e > 0“, „#e >= 1“, „1 <= #e“, „0 < #e“).

Mit der folgenden Regel wird beispielsweise nach einem Nutzeranmeldeereignis gesucht und das erste Ereignis in den in Ihrem Google Security Operations-Konto gespeicherten Unternehmensdaten zurückgegeben:

rule SingleEventRule {
  meta:
    author = "noone@altostrat.com"

  events:
    $e.metadata.event_type = "USER_LOGIN"

  condition:
    $e
}

Hier ist ein weiteres Beispiel für eine Regel für ein einzelnes Ereignis mit einem Abgleichbereich. Mit dieser Regel wird nach einem Nutzer gesucht, der sich innerhalb von weniger als 5 Minuten mindestens einmal angemeldet hat. Es wird geprüft, ob ein Nutzeranmeldeereignis vorhanden ist.

rule SingleEventRule {
  meta:
    author = "alice@example.com"
    description = "windowed single event example rule"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.user.userid = $user

  match:
    $user over 5m

  condition:
    #e > 0
}
rule MultiEventRule{
  meta:
    author = "alice@example.com"
    description = "Rule with outcome condition and simple existence condition on one event variable"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.user.userid = $user

  match:
    $user over 10m

  outcome:
    $num_events_in_match_window = count($e.metadata.id)

  condition:
    #e > 0 and $num_events_in_match_window >= 10 // Could be rewritten as #e >= 10
}

Regel für mehrere Ereignisse

Mit mehreren Ereignisregeln können Sie viele Ereignisse in einem bestimmten Zeitraum gruppieren und versuchen, Korrelationen zwischen Ereignissen zu finden. Eine typische Regel für mehrere Ereignisse enthält Folgendes:

  • Einen Abschnitt match, in dem der Zeitraum angegeben wird, über den Ereignisse gruppiert werden sollen.
  • Ein Abschnitt condition, in dem angegeben wird, welche Bedingung die Erkennung auslösen soll, und in dem geprüft wird, ob mehrere Ereignisse vorliegen.

Mit der folgenden Regel wird beispielsweise nach einem Nutzer gesucht, der sich in weniger als 10 Minuten mindestens 10 Mal angemeldet hat:

rule MultiEventRule {
  meta:
    author = "noone@altostrat.com"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.user.userid = $user

  match:
    $user over 10m

  condition:
    #e >= 10
}

Einzelnes Ereignis innerhalb eines IP-Adressbereichs

Im folgenden Beispiel wird eine einzelne Ereignisregel gezeigt, bei der nach einer Übereinstimmung zwischen zwei bestimmten Nutzern und einem bestimmten IP-Adressbereich gesucht wird:

rule OrsAndNetworkRange {
  meta:
    author = "noone@altostrat.com"

  events:
    // Checks CIDR ranges.
    net.ip_in_range_cidr($e.principal.ip, "203.0.113.0/24")

    // Detection when the hostname field matches either value using or.
    $e.principal.hostname = /pbateman/ or $e.principal.hostname = /sspade/

  condition:
    $e
}

Beispiel für eine Regel

Mit der folgenden Regel wird nach Anmeldeereignissen gesucht, bei denen innerhalb von 5 Minuten keine der Quell-IP-Adressen mit einer als sicher bekannten IP-Adresse übereinstimmt.

rule SuspiciousIPLogins {
  meta:
    author = "alice@example.com"

  events:
    $e.metadata.event_type = "USER_LOGIN"

    // Detects if all source IP addresses in an event do not match "100.97.16.0"
    // For example, if an event has source IP addresses
    // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
    // it will be detected since "100.97.16.1", "100.97.16.2",
    // and "100.97.16.3" all do not match "100.97.16.0".

    all $e.principal.ip != "100.97.16.0"

    // Assigns placeholder variable $ip to the $e.principal.ip repeated field.
    // There will be one detection per source IP address.
    // For example, if an event has source IP addresses
    // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
    // there will be one detection per address.

    $e.principal.ip = $ip

  match:
    $ip over 5m

  condition:
    $e
}

Reguläre Ausdrücke in einer Regel

Im folgenden Beispiel für einen YARA-L 2.0-Regulären Ausdruck wird nach Ereignissen mit E-Mails gesucht, die von der Domain altostrat.com empfangen wurden. Da nocase dem Vergleich der Variablen $host mit regex und der Funktion regex hinzugefügt wurde, wird bei beiden Vergleichen nicht zwischen Groß- und Kleinschreibung unterschieden.

rule RegexRuleExample {
  meta:
    author = "noone@altostrat.com"

  events:
    $e.principal.hostname = $host
    $host = /.*HoSt.*/ nocase
    re.regex($e.network.email.from, `.*altostrat\.com`) nocase

  match:
    $host over 10m

  condition:
    #e > 10
}

Beispiel für eine Regel mit gleitendem Fenster

Im folgenden Beispiel für ein YARA-L 2.0-Fenster mit Text wird nach dem Fehlen von firewall_2-Ereignissen nach firewall_1-Ereignissen gesucht. Das Keyword after wird mit der Pivot-Ereignisvariablen $e1 verwendet, um anzugeben, dass bei der Korrelation von Ereignissen nur Zeiträume von 10 Minuten nach jedem firewall_1-Ereignis geprüft werden sollen.

rule SlidingWindowRuleExample {
  meta:
    author = "alice@example.com"

  events:
    $e1.metadata.product_name = "firewall_1"
    $e1.principal.hostname = $host

    $e2.metadata.product_name = "firewall_2"
    $e2.principal.hostname = $host

  match:
    $host over 10m after $e1

  condition:
    $e1 and !$e2
}

Beispiel für den Ausschluss von Nullwerten

Die Rules Engine filtert implizit die Nullwerte für alle Platzhalter heraus, die im Bereich match verwendet werden. Weitere Informationen finden Sie im Abschnitt match unter Nullwertbehandlung. Sie können dies mit der Option allow_zero_values deaktivieren, wie unter allow_zero_values beschrieben.

Bei anderen referenzierten Ereignisfeldern werden Nullwerte jedoch nicht ausgeschlossen, es sei denn, Sie geben solche Bedingungen ausdrücklich an.

rule ExcludeZeroValues {
  meta:
    author = "alice@example.com"

  events:
    $e1.metadata.event_type = "NETWORK_DNS"
    $e1.principal.hostname = $hostname

    // $e1.principal.user.userid may be empty string.
    $e1.principal.user.userid != "Guest"

    $e2.metadata.event_type = "NETWORK_HTTP"
    $e2.principal.hostname = $hostname

    // $e2.target.asset_id cannot be empty string as explicitly specified.
    $e2.target.asset_id != ""

  match:
    // $hostname cannot be empty string. The rule behaves as if the
    // predicate, `$hostname != ""` was added to the events section, because
    // `$hostname` is used in the match section.
    $hostname over 1h

  condition:
    $e1 and $e2
}

Beispiel für eine Regel mit outcome-Abschnitt

Sie können den optionalen Abschnitt outcome in der YARA-L 2.0-Regel hinzufügen, um zusätzliche Informationen zu jeder Erkennung zu extrahieren. Im Abschnitt „Bedingung“ können Sie auch Bedingungen für Ergebnisvariablen angeben. Im Abschnitt outcome einer Erkennungsregel können Sie Variablen für den Downstream-Verbrauch festlegen. Sie können beispielsweise einen Schweregrad basierend auf Daten aus den analysierten Ereignissen festlegen.

Hier finden Sie weitere Informationen:

Regel mit mehreren Ereignissen mit Ergebnisbereich:

In der folgenden Regel werden zwei Ereignisse berücksichtigt, um den Wert von $hostname zu ermitteln. Wenn der Wert von $hostname über einen Zeitraum von 5 Minuten übereinstimmt, wird eine Schweregradbewertung angewendet. Wenn Sie im Abschnitt match einen Zeitraum angeben, wird die Regel innerhalb des angegebenen Zeitraums geprüft.

rule OutcomeRuleMultiEvent {
    meta:
      author = "Google Cloud Security"
    events:
      $u.udm.principal.hostname = $hostname
      $asset_context.graph.entity.hostname = $hostname

      $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

    match:
      $hostname over 5m

    outcome:
      $risk_score =
        max(
            100
          + if($hostname = "my-hostname", 100, 50)
          + if($severity = "HIGH", 10)
          + if($severity = "MEDIUM", 5)
          + if($severity = "LOW", 1)
        )

      $asset_id_list =
        array(
          if($u.principal.asset_id = "",
             "Empty asset id",
             $u.principal.asset_id
          )
        )

      $asset_id_distinct_list = array_distinct($u.principal.asset_id)

      $asset_id_count = count($u.principal.asset_id)

      $asset_id_distinct_count = count_distinct($u.principal.asset_id)

    condition:
      $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

rule OutcomeRuleMultiEvent {
    meta:
      author = "alice@example.com"
    events:
      $u.udm.principal.hostname = $hostname
      $asset_context.graph.entity.hostname = $hostname

      $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

    match:
      $hostname over 5m

    outcome:
      $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

      $risk_score = if(total_network_bytes > 1024, 100, 50) + 
        max(
          if($severity = "HIGH", 10)
          + if($severity = "MEDIUM", 5)
          + if($severity = "LOW", 1)
        )

      $asset_id_list =
        array(
          if($u.principal.asset_id = "",
             "Empty asset id",
             $u.principal.asset_id
          )
        )

      $asset_id_distinct_list = array_distinct($u.principal.asset_id)

      $asset_id_count = count($u.principal.asset_id)

      $asset_id_distinct_count = count_distinct($u.principal.asset_id)

    condition:
      $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

Regel für ein einzelnes Ereignis mit Ergebnisbereich:

rule OutcomeRuleSingleEvent {
    meta:
        author = "alice@example.com"
    events:
        $u.metadata.event_type = "FILE_COPY"
        $u.principal.file.size = $file_size
        $u.principal.hostname = $hostname

    outcome:
        $suspicious_host = $hostname
        $admin_severity = if($u.principal.userid in %admin_users, "SEVERE", "MODERATE")
        $severity_tag = if($file_size > 1024, $admin_severity, "LOW")

    condition:
        $u
}

Eine Regel mit mehreren Ereignissen in eine Regel mit einem einzelnen Ereignis umwandeln.

Sie können den Bereich outcome sowohl für Einzelereignisregeln (Regeln ohne Bereich match) als auch für Mehrfachereignisregeln (Regeln mit Bereich match) verwenden. Wenn Sie zuvor eine Regel für mehrere Ereignisse erstellt haben, nur um den Bereich „Ergebnis“ verwenden zu können, können Sie diese Regeln optional umstrukturieren, indem Sie den Bereich match löschen, um die Leistung zu verbessern. Da Ihre Regel keinen Abschnitt match mehr enthält, in dem eine Gruppierung angewendet wird, erhalten Sie möglicherweise mehr Erkennungen. Diese Umstrukturierung ist nur für Regeln möglich, in denen eine Ereignisvariable verwendet wird, wie im folgenden Beispiel gezeigt.

Regel mit mehreren Ereignisergebnissen, für die nur eine Ereignisvariable verwendet wird (ein guter Kandidat für eine Umstrukturierung):

rule OutcomeMultiEventPreRefactor {
    meta:
      author = "alice@example.com"
      description = "Outcome refactor rule, before the refactor"

    events:
      $u.udm.principal.hostname = $hostname

    match:
      $hostname over 5m

    outcome:
      $risk_score = max(if($hostname = "my-hostname", 100, 50))

    condition:
      $u
}

Sie können die Regel umstrukturieren, indem Sie den Abschnitt match löschen. Beachten Sie, dass Sie auch die Gesamtsumme im Bereich outcome entfernen müssen, da die Regel jetzt auf ein einzelnes Ereignis beschränkt ist. Weitere Informationen zu Zusammenfassungen finden Sie unter Ergebniszusammenfassungen.

rule OutcomeSingleEventPostRefactor {
    meta:
      author = "alice@example.com"
      description = "Outcome refactor rule, after the refactor"

    events:
      $u.udm.principal.hostname = $hostname

    // We deleted the match section.

    outcome:
      // We removed the max() aggregate.
      $risk_score = if($hostname = "my-hostname", 100, 50)

    condition:
      $u
}

Beispiel für eine Regel vom Typ „Funktion zu Platzhalter“

Sie können dem Ergebnis eines Funktionsaufrufs eine Platzhaltervariable zuweisen und diese in anderen Abschnitten der Regel verwenden, z. B. im Abschnitt match, outcome oder condition. Sehen Sie sich folgendes Beispiel an:

rule FunctionToPlaceholderRule {
    meta:
      author = "alice@example.com"
      description = "Rule that uses function to placeholder assignments"

    events:
        $u.metadata.event_type = "EMAIL_TRANSACTION"

        // Use function-placeholder assignment to extract the
        // address from an email.
        // address@website.com -> address
        $email_to_address_only = re.capture($u.network.email.from , "(.*)@")

        // Use function-placeholder assignment to normalize an email:
        // uid@??? -> uid@company.com
        $email_from_normalized = strings.concat(
            re.capture($u.network.email.from , "(.*)@"),
            "@company.com"
        )

        // Use function-placeholder assignment to get the day of the week of the event.
        // 1 = Sunday, 7 = Saturday.
        $dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)

    match:
        // Use placeholder (from function-placeholder assignment) in match section.
        // Group by the normalized from email, and expose it in the detection.
        $email_from_normalized over 5m

    outcome:
        // Use placeholder (from function-placeholder assignment) in outcome section.
        // Assign more risk if the event happened on weekend.
        $risk_score = max(
            if($dayofweek = 1, 10, 0) +
            if($dayofweek = 7, 10, 0)
        )

    condition:
        // Use placeholder (from function-placeholder assignment) in condition section.
        // Match if an email was sent to multiple addresses.
        #email_to_address_only > 1
}

Beispielregel für bedingte Ergebnisse

Im Abschnitt condition können Sie Ergebnisvariablen verwenden, die im Abschnitt outcome definiert wurden. Im folgenden Beispiel wird gezeigt, wie Sie mithilfe von Ergebnisbedingungen nach Risikobewertungen filtern, um die Anzahl der Fehlalarme zu reduzieren.

rule OutcomeConditionalRule {
    meta:
        author = "alice@example.com"
        description = "Rule that uses outcome conditionals"

    events:
        $u.metadata.event_type = "FILE_COPY"
        $u.principal.file.size = $file_size
        $u.principal.hostname = $hostname

        // 1 = Sunday, 7 = Saturday.
        $dayofweek = timestamp.get_day_of_week($u.metadata.collected_timestamp.seconds)

    outcome:
        $risk_score =
            if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
            if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
            if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
            if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

    condition:
        $u and $risk_score >= 10
}