Übersicht über die Sprache YARA-L 2.0

YARA-L 2.0 ist eine Computersprache, die verwendet wird, um Regeln für die Suche in Ihren Protokolldaten zu erstellen, während diese in Ihr Chronicle-Konto aufgenommen wird. Die YARA-L-Syntax wird von der YARA-Sprache abgeleitet, die von VirusTotal entwickelt wurde. Die Sprache wird in Verbindung mit der Chronicle Detection Engine verwendet und kann Sie bei der Suche nach Bedrohungen und anderen Ereignissen mit großen Datenmengen unterstützen. Siehe auch die Syntax der YARA-L 2.0-Sprache

Regelstruktur

Für YARA-L 2 müssen Sie Variablendeklarationen, -definitionen und -verwendungen in der folgenden Reihenfolge angeben:

  1. Meta
  2. Ereignisse
  3. Übereinstimmung (optional)
  4. Bedingung

Im Folgenden wird die allgemeine Struktur einer Regel dargestellt:

rule <rule Name>
{
  meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.
    // Identical to the meta section in YARA-L.
    //
    // For example:
    // author = "Analyst #2112"
    // date = "08/09/2020"
    // description = "suspicious domain detected"

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  condition:
    // Condition to check events and the variables used to find matches.
}

YARA-L 2.0 Beispielregeln

Die folgenden Beispiele zeigen Regeln, die in YARA-L 2.0 geschrieben wurden. Jede zeigt, wie Ereignisse in der Regelsprache in Beziehung gesetzt werden.

Anmeldungen aus verschiedenen Städten

Mit der folgenden Regel wird nach Nutzern gesucht, die sich in weniger als fünf Minuten in zwei oder mehr Städten bei 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:
    #city > 1
}

Übereinstimmungsvariable: $user

Ereignisvariable:$udm

Platzhaltervariable: $city $user

Im Folgenden wird die Funktionsweise dieser Regel beschrieben:

  • Gruppiert Ereignisse mit dem Nutzernamen ($user) und gibt sie ($user) zurück, wenn eine Übereinstimmung gefunden wurde.
  • Die Zeitspanne beträgt 5 Minuten. Dies bedeutet, dass nur Ereignisse mit einem Abstand von weniger als 5 Minuten korrelieren.
  • Suche nach einer Ereignisgruppe ($udm) mit dem Ereignistyp USER_LOGIN
  • Für diese Ereignisgruppe ruft die Regel die Nutzer-ID $user und die Anmeldestadt als $city. auf.
  • Gibt eine Übereinstimmung zurück, wenn die eindeutige Anzahl von $city-Werten in der Ereignisgruppe ($udm) innerhalb des 5-Minuten-Zeitraums größer als 1 ist.

Schnelles Erstellen und Löschen von Nutzern

Mit der folgenden Regel wird nach Nutzern gesucht, die innerhalb von vier Stunden erstellt und 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 die Funktionsweise dieser Regel beschrieben:

  • Gruppiert Ereignisse mit dem Nutzernamen ($user) und gibt sie ($user) zurück, wenn eine Übereinstimmung gefunden wurde.
  • Das Zeitfenster beträgt vier Stunden, sodass nur Ereignisse, die weniger als vier Stunden getrennt sind, korreliert sind.
  • Sucht nach zwei Ereignisgruppen ($create und $delete, wobei $create gleich #create >= 1 ist).
  • $create entspricht USER_CREATION-Ereignissen und ruft die Nutzer-ID als $user auf.
  • Mit $user werden die beiden Ereignisgruppen zusammengeführt.
  • $delete entspricht USER_DELETION-Ereignissen und ruft die Nutzer-ID als $user auf. Diese Regel sucht nach einer Übereinstimmung, bei der die Nutzerkennung in den beiden Ereignisgruppen identisch ist.
  • Diese Regel sucht nach Fällen, bei denen das Ereignis von $delete später als das Ereignis von $create eingeht und bei Übereinstimmung eine Übereinstimmung zurückgibt.

Einzelereignis im Vergleich zu mehreren Ereignissen

Die folgenden Beispielregeln zeigen, wie Sie eine Regel erstellen, um nach einem einzelnen Ereignis zu suchen, und diese dann ändern, um nach mehreren Ereignissen zu suchen.

Hier sehen Sie die Version des einzelnen Ereignisses der Regel:

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

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

  condition:
    $e
}

Diese Regel sucht nur nach einem Nutzer-Anmeldeereignis und gibt das erste Ereignis zurück, das auf die Unternehmensdaten angewendet wird, die in Ihrem Chronicle-Konto gespeichert sind.

Version der Regel mit mehreren Ereignissen:

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
}

Die Regel sucht nach einem Nutzer, der sich mindestens zehnmal in weniger als zehn Minuten angemeldet hat.

Einzelnes Ereignis innerhalb des IP-Adressbereichs

Das folgende Beispiel zeigt eine einzelne Ereignisregel, die nach einer Übereinstimmung zwischen zwei bestimmten Nutzern und einem bestimmten IP-Adressbereich sucht:

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
}

Wiederkehrende Felder

In YARA-L 2.0 werden wiederkehrende Felder als Arrays dargestellt.

Ein Host kann beispielsweise mehrere IP-Adressen haben:

principal.ip [192.168.1.2, 10.3.4.100, 192.168.12.16]

Oder eine E-Mail-Adresse kann mehrere Empfänger haben:

network.email.to ["a@google.com", "b@google.com", "c@google.com"]

Syntax

Wiederkehrende Felder können auf dieselbe Weise wie nicht wiederkehrende Felder bezeichnet werden. In diesem Fall werden sie automatisch eindeutig, d. h. die Bedingungen werden mit den einzelnen Elementen des wiederkehrenden Felds verglichen.

Beispiel: Sie fügen die folgende Anweisung in eine Regel ein:

$e.principal.ip = "192.168.12.16"

Chronicle sucht nach einer IP-Adresse im Array, die mit "192.168.12.16" übereinstimmt. In diesem Beispiel wird eine übereinstimmende Adresse gefunden und eine Erkennung zurückgegeben.

Beispiel: Sie fügen die folgende Anweisung in eine Regel ein:

$e.principal.ip = "192.168.12.16" and $e.principal.ip = "10.3.4.100"

Chronicle sucht nach einer IP-Adresse im Array, die sowohl mit "192.168.12.16" als auch mit "10.3.4.100" übereinstimmt. In diesem Beispiel würde keine übereinstimmende Adresse gefunden und keine Erkennung zurückgegeben.

Beispiel für wiederkehrende Felder

Die folgende Regel sucht nach Ereignissen, bei denen eine Quell-IP-Adresse mit einer Ziel-IP-Adresse verbunden ist, während Anfragen an mehr als 50 verschiedene Zielports innerhalb eines Zeitraums von weniger als einer Minute gestellt werden. Das ist wahrscheinlich eine schädliche Entität, die nach einem nicht gesicherten Netzwerkport sucht.

rule RepeatedFieldsRuleExample {
  meta:
    author = "noone@google.com"

  events:
    $e.principal.ip = $source_ip
    $e.target.ip = $target_ip
    $e.target.port = $target_port

  match:
    $source_ip, $target_ip over 1m

  condition:
    #target_port > 50
}

Alle Operatoren

Auf die wiederkehrenden Felder kann auch mit den Operatoren any und all verwiesen werden. Wenn das der Fall ist, werden sie nicht eindeutig, d. h., die Bedingungen werden mit allen Elementen des wiederkehrenden Felds verglichen.

Beispiel: Sie fügen die folgende Anweisung in eine Regel ein:

any $e.principal.ip = "192.168.12.16"

Chronicle prüft, ob eine IP-Adresse im Array mit "192.168.12.16" übereinstimmt. In diesem Beispiel würde das Array die Diagnose erfüllen und eine Erkennung zurückgeben.

Wenn Sie die folgende Anweisung in Ihre Regel aufnehmen, gilt:

all $e.principal.ip = "192.168.12.16"

Chronicle prüft, ob alle IP-Adressen im Array mit "192.168.12.16" übereinstimmen. In diesem Beispiel würde das Array die Prüfung nicht erfüllen und keine Erkennung zurückgeben.

Wenn Sie die folgende Anweisung in Ihre Regel aufnehmen, gilt:

any $e.principal.ip = "192.168.12.16" and any $e.principal.ip = "10.3.4.100"

Chronicle prüft, ob eine IP-Adresse im Array mit "192.168.12.16" übereinstimmt und ob eine IP-Adresse im Array mit "10.3.4.100" übereinstimmt. In diesem Beispiel würde das Array die Diagnose erfüllen und eine Erkennung zurückgeben.

Beispiele für gültige Prädikate mit den Operatoren any und all:

  • any $e.principal.ip = "192.168.12.16"
  • net.ip_in_range_cidr(any $e.principal.ip, "192.168.12.16/24")
  • all $e.network.email.to = /.*@google\.com/
  • re.regex(all $e.network.email.to, `.*google\.com`)

Beispiele für ungültige Prädikate mit den Operatoren any und all:

  • any $ip = "192.168.12.16"
  • any $e.principal.ip = all $e.target.ip
  • any $e.principal.ip in %reference_list

Einschränkungen der Operatoren "all" und "all"

Die Operatoren any und all können nur mit wiederkehrenden Feldern verwendet werden. Außerdem können sie nicht verwendet werden, wenn einer Platzhaltervariablen ein wiederkehrendes Feld zugewiesen oder ein Feld mit einem anderen Ereignis verknüpft wird.

Beispielsweise sind any $e.principal.ip = $ip und any $e1.principal.ip = $e2.principal.ip keine gültige Syntax. Zum Abgleichen oder Zusammenführen eines wiederkehrenden Felds verwenden Sie $e.principal.ip = $ip. Für jedes Element des wiederkehrenden Felds gibt es einen Wert für die Übereinstimmungsvariable oder einen Join.

Beachten Sie beim Schreiben einer Bedingung mit any oder all, dass die Negation der Bedingung mit not nicht dieselbe Bedeutung hat wie die Verwendung des negierten Operators.

Beispiel:

  • not all $e.principal.ip = "192.168.12.16" prüft, ob nicht alle IP-Adressen mit "192.168.12.16" übereinstimmen. Die Regel prüft also, ob IP-Adressen nicht mit "192.168.12.16" übereinstimmen.
  • all $e.principal.ip != "192.168.12.16" prüft, ob alle IP-Adressen nicht mit "192.168.12.16" übereinstimmen. Dies bedeutet, dass durch die Regel sichergestellt wird, dass keine IP-Adressen mit "192.168.12.16" übereinstimmen.

Beispiel für alle Regeln

Mit der folgenden Regel wird nach Anmeldeereignissen gesucht, bei denen alle Quell-IP-Adressen mit einer IP-Adresse übereinstimmen, die innerhalb von fünf Minuten als sicher bekannt ist.

rule SuspiciousIPLogins {
  meta:
    author = "noone@google.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

Mit dem folgenden Beispiel für einen regulären YARA-L 2.0-Ausdruck werden Ereignisse mit E-Mails gesucht, die von der Domain altostrat.com empfangen wurden. Da nocase dem Vergleich der $host-Variable regex und der Funktion regex hinzugefügt wurde, wird bei beiden Vergleichen die Groß-/Kleinschreibung nicht berücksichtigt.

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
}

YARA-L-Fenster mit Text

Standardmäßig werden YARA-L 2.0-Regeln mithilfe von Hop-Fenstern ausgewertet. Ein Zeitraum von Unternehmensereignisdaten wird in mehrere sich überschneidende Hop-Fenster unterteilt, von denen jedes die im Abschnitt match angegebene Dauer aufweist. Ereignisse werden dann in jedem Hop-Fenster korreliert. Bei Hop-Fenstern ist es nicht möglich, nach Ereignissen zu suchen, die in einer bestimmten Reihenfolge auftreten (z. B. tritt e1 bis zu zwei Minuten nach e2 auf). Ein Auftreten des Ereignisses e1 und das Auftreten des Ereignisses e2 werden korreliert, solange sie sich innerhalb der Hop-Fensterdauer befinden.

Regeln können auch mithilfe von fließenden Fenstern ausgewertet werden. Bei fließenden Fenstern werden die fließenden Fenster mit der im Abschnitt match angegebenen Dauer am Anfang oder am Ende mit der angegebenen Pivot-Ereignisvariablen generiert. Die Ereignisse sind dann innerhalb jedes Sliding Window korreliert. Dies ermöglicht die Suche nach Ereignissen, die in einer bestimmten Reihenfolge stattfinden (z. B. e1 findet innerhalb von zwei Minuten nach e2 statt). Ein Auftreten des Ereignisses e1 und das Auftreten des Ereignisses e2 werden korreliert, wenn das Ereignis e1 innerhalb der Dauer des gleitenden Fensters nach dem Ereignis e2 auftritt.

Syntax der Sliding-Window-Regel

So können Sie fließende Fenster im Abschnitt "Übereinstimmung" einer Regel angeben:

<match-variable-name-1>, <match-variable-name-2>, ... over <sliding-window- duration> before|after <pivot-event-variable-name>

Die Pivot-Ereignisvariable ist die Ereignisvariable, auf der Sliding-Windows basiert. Wenn Sie das Keyword before verwenden, werden Schiebefenster generiert, die mit jedem Auftreten des Pivot-Ereignisses enden. Wenn das Keyword after verwendet wird, werden die fließenden Fenster mit jedem Vorkommen des Pivot-Ereignisses generiert.

Beispiel für eine fließende Fensterregel

Im folgenden Beispiel für das fließende YARA-L 2.0-Fenster wird nach fehlenden firewall_2-Ereignissen nach firewall_1-Ereignissen gesucht. Das Keyword after wird mit der Pivot-Ereignisvariablen $e1 verwendet, um anzugeben, dass nur 10 Minuten Fenster nach jedem firewall_1-Ereignis überprüft werden, wenn Ereignisse korreliert werden.

rule SlidingWindowRuleExample {
  meta:
    author = "noone@google.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
}