Ausdrücke, Operatoren und andere Konstrukte
Dieses Dokument enthält Informationen, die Ihnen beim Erstellen von YARA-L-Regeln und ‑Abfragen mit Ausdrücken helfen.
Boolesche Ausdrücke
Boolesche Ausdrücke sind Ausdrücke mit einem booleschen Typ, einschließlich Vergleichsausdrücken, Funktionsausdrücken und Ausdrücken für Referenzlisten oder Datentabellen. Sie können boolesche Ausdrücke im Abschnitt events und outcome einer YARA-L-Regel oder -Abfrage verwenden.
Vergleichsausdrücke
Vergleichsausdrücke sind Ausdrücke, in denen ein Vergleichsoperator auf zwei Ausdrücke angewendet wird. Ausdrücke können Ereignisfelder, Variablen, Literale oder Funktionsausdrücke sein.
Beispiel: Vergleichsausdrücke
$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")
Funktionsausdrücke
Einige Funktionsausdrücke geben einen booleschen Wert zurück, der als einzelnes Prädikat im events-Abschnitt verwendet werden kann, z. B.:
re.regex()
net.ip_in_range_cidr()
Beispiel: Funktionsausdrücke
re.regex($e.principal.hostname, `.*\.google\.com`)
net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
Referenzliste oder Datentabelle
Sie können Referenzlisten oder Datentabellen in den Abschnitten events oder outcome verwenden. Weitere Informationen zum Verhalten und zur Syntax von Referenzlisten und Datentabellen finden Sie unter Referenzlisten und Datentabellen verwenden.
Beispiel: Syntax für Referenzlisten
In den folgenden Beispielen sehen Sie die Syntax für verschiedene Arten von Referenzlisten in einer Abfrage:
// 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
Beispiel: Syntax für Datentabellen
// STRING data table $e.target.hostname in %data_table_name.column_name // REGEX data table $e.target.hostname in regex %regex_table_name.column_name // CIDR data table $e.principal.ip in cidr %cidr_table_name.column_name
Beispiel: not und nocase in der Syntax von Referenzlisten verwenden
// 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
Der Operator nocase ist mit STRING- und REGEX-Listen kompatibel.
Aus Leistungsgründen unterliegt die Verwendung von Referenzlisten und Datentabellen den folgenden Einschränkungen:
- Maximale Anzahl von
in-Anweisungen in einer Abfrage, mit oder ohne Sonderoperatoren: 7 - Maximale Anzahl von
in-Anweisungen mit dem Operatorregex: 4 - Maximale Anzahl von
in-Anweisungen mit dem Operatorcidr: 2
Logische Ausdrücke
Sie können die logischen Operatoren and und or im Abschnitt events verwenden.
Beispiel: Logische Ausdrücke
$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"
Standardmäßig ist die Reihenfolge von der höchsten zur niedrigsten Priorität not, and, or. Beispiel: „a or b and c“ wird als „a or (b and c)“ ausgewertet, wenn die Operatoren or und and explizit im Ausdruck definiert sind.
Im Abschnitt events werden Prädikate mit dem Operator and verknüpft, wenn kein Operator explizit definiert ist. Die Reihenfolge der Auswertung kann sich ändern, wenn der Operator and im Ausdruck impliziert wird.
Sehen Sie sich die folgenden Vergleichsausdrücke an, in denen or explizit definiert ist und der Operator and impliziert wird.
$e1.field = "bat" or $e1.field = "baz" $e2.field = "bar"
Das wird so interpretiert:
($e1.field = "bat" or $e1.field = "baz") and ($e2.field = "bar")
Da or explizit definiert ist, werden die umgebenden Prädikate gruppiert und zuerst ausgewertet. Das letzte Prädikat, $e2.field = "bar". wird implizit mit and verknüpft. Dadurch ändert sich die Reihenfolge der Auswertung.
Aufzählungstypen
Sie können die Operatoren mit aufgezählten Typen verwenden. Sie kann auf Regeln angewendet werden, um die Leistung zu vereinfachen und zu optimieren (Operator anstelle von Referenzlisten verwenden).
Im folgenden Beispiel entsprechen „USER_UNCATEGORIZED“ und „USER_RESOURCE_DELETION“ den Werten 15000 und 15014. Die Regel sucht also nach allen aufgeführten Ereignissen:
$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"
Nocase-Modifikator
Wenn Sie die Groß- und Kleinschreibung in einem Vergleichsausdruck zwischen Stringwerten oder einem regulären Ausdruck ignorieren möchten, hängen Sie nocase an das Ende des Ausdrucks an, wie in den folgenden Beispielen gezeigt.
Beispiel: nocase-Modifikator
$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
Der Modifikator nocase kann nicht verwendet werden, wenn der Feldtyp ein aufgezählter Wert ist. Die folgenden Beispiele sind ungültig und führen zu Kompilierungsfehlern:
$e.metadata.event_type = "NETWORK_DNS" nocase
$e.network.ip_protocol = "TCP" nocase
Kommentare
Kommentare können in Anfragen verwendet werden, um zusätzliche Informationen bereitzustellen. Mit dem Schrägstrichzeichen wird ein Kommentar angegeben:
- Für einen einzeiligen Kommentar verwenden Sie zwei Schrägstriche (
// comment). - Für einen mehrzeiligen Kommentar verwenden Sie den Schrägstrich und das Sternchen (
/* comment */).
Literale
YARA-L unterstützt nicht negative Ganzzahlen und Gleitkommazahlen, String-, boolesche und reguläre Ausdrucksliterale. Literale sind feste Werte, die in Abfragebedingungen verwendet werden. In YARA-L werden auch andere literalähnliche Konstrukte verwendet, z. B. reguläre Ausdrücke (in Schrägstriche eingeschlossen) für den Musterabgleich und boolesche Werte (true/false) für die Logik.
Stringliterale
Stringliterale sind Folgen von Zeichen, die in doppelte Anführungszeichen (") oder Graviszeichen (`) eingeschlossen sind. Der String wird je nach verwendetem Anführungszeichen unterschiedlich interpretiert:
- Doppelte Anführungszeichen („hello\tworld“): Für normale Strings verwenden. Escape-Zeichen müssen enthalten sein, wobei \t als Tabulator interpretiert wird.
- Backquotes (`hello\tworld`): Verwenden Sie diese, wenn alle Zeichen wörtlich interpretiert werden sollen und \t nicht als Tabulator interpretiert werden soll.
Literale für reguläre Ausdrücke
Für Literale für reguläre Ausdrücke haben Sie zwei Möglichkeiten:
Wenn Sie reguläre Ausdrücke direkt ohne die Funktion
re.regex()verwenden möchten, verwenden Sie/regex/für die Literale für reguläre Ausdrücke.Wenn Sie String-Literale als reguläre Ausdrucksliterale verwenden möchten, verwenden Sie die Funktion
re.regex(). Bei Stringliteralen mit doppelten Anführungszeichen müssen Sie umgekehrte Schrägstriche mit umgekehrten Schrägstrichen maskieren, was etwas umständlich sein kann.
Die folgenden Beispiele zeigen gleichwertige reguläre Ausdrücke:
re.regex($e.network.email.from, `.*altostrat\.com`)
re.regex($e.network.email.from, ".*altostrat\\.com")
$e.network.email.from = /.*altostrat\.com/
Google empfiehlt, für Strings in regulären Ausdrücken Backquote-Zeichen zu verwenden, um die Lesbarkeit zu verbessern.
Operatoren
| Operator: | Beschreibung |
| = | gleich/Erklärung |
| != | ungleich |
| < | kleiner als |
| <= | kleiner oder gleich |
| > | größer als |
| >= | größer als oder gleich |
Variablen
In YARA-L verwenden alle Variablen die Syntax $<variable name>. In YARA-L können die folgenden Variablentypen verwendet werden.
Ereignisvariablen
Ereignisvariablen stellen Gruppen von Ereignissen oder Entität-Ereignissen dar. Sie geben Bedingungen für Ereignisvariablen im Abschnitt events mit einem Namen, einer Ereignisquelle und Ereignisfeldern an.
Ereignisquellen sind
udm(für normalisierte Ereignisse) undgraph(für Entitätsereignisse). Wenn die Quelle weggelassen wird, wirdudmals Standardquelle festgelegt.Ereignisfelder werden als Kette von .<field name> dargestellt, z. B. $e.field1.field2. Die Feldketten beginnen immer mit der Quelle der obersten Ebene (UDM oder Entity).
Abgleichsvariablen
Abgleichsvariablen werden im Abschnitt match verwendet, um Ereignisse anhand gemeinsamer Werte innerhalb eines angegebenen Zeitfensters zu gruppieren.
Sie werden zu Gruppierungsfeldern für die Abfrage, da für jede eindeutige Gruppe von Abgleichsvariablen (und für jedes Zeitfenster) eine Zeile zurückgegeben wird. Wenn die Abfrage eine Übereinstimmung findet, werden die Werte der Übereinstimmungsvariablen zurückgegeben.
Im Abschnitt events geben Sie an, wofür jede Abgleichsvariable steht.
Platzhaltervariablen
Mit Platzhaltervariablen werden bestimmte Werte aus UDM-Ereignisfeldern erfasst und gespeichert, auf die in einer Abfrage verwiesen und die in einer Abfrage verwendet werden können. Sie werden verwendet, um unterschiedliche Ereignisse miteinander zu verknüpfen, insbesondere in Abfragen mit mehreren Ereignissen. Wenn Sie einem Platzhalter einen gemeinsamen Wert zuweisen (z. B. userid oder hostname), können Sie diesen Platzhalter im Abschnitt match verwenden, um Ereignisse zu gruppieren, die diesen Wert innerhalb eines bestimmten Zeitraums gemeinsam haben.
Sie definieren Platzhaltervariablen im Abschnitt events, indem Sie den Wert eines UDM-Felds einem Variablennamen zuweisen, dem ein $ vorangestellt ist (z. B. $targetUser = $e.target.user.userid).
Sie können auch in den folgenden Abschnitten Platzhaltervariablen definieren:
- Im Bereich
conditionkönnen Sie die Abgleichbedingungen angeben. - Im
outcome-Abschnitt können Sie Berechnungen durchführen, Messwerte definieren oder bestimmte Datenpunkte aus den abgeglichenen Ereignissen extrahieren. match-Abschnitt, um Ereignisse nach gemeinsamen Werten zu gruppieren.
Keywords
In YARA-L sind Keywords reservierte Wörter, die die Struktur und Logik einer Erkennungsanfrage definieren. Sie werden verwendet, um verschiedene Abschnitte einer Abfrage anzugeben, logische und mathematische Operationen auszuführen und Bedingungen für übereinstimmende Ereignisse zu definieren. Diese Keywords können nicht als Kennungen für Abfragen, Strings oder Variablen verwendet werden.
Bei Keywords wird die Groß-/Kleinschreibung nicht berücksichtigt. and und AND sind also gleichwertig.
Wichtige Kategorien von YARA-L 2.0-Schlüsselwörtern
Diese Liste ist nicht vollständig, enthält aber die wichtigsten Schlüsselwörter, die in YARA-L 2.0 zum Erstellen robuster Erkennungsabfragen verwendet werden.
- Abfragedefinition:
rule: Leitet die Definition einer neuen YARA-L-Abfrage ein.private: Kennzeichnet eine Abfrage als privat, sodass sie nicht direkt offengelegt oder extern ausgelöst werden kann.global: Markiert eine Abfrage als global, was bedeutet, dass sie breit angewendet werden soll.
- Abfrageabschnitte:
meta: Leitet den Metadatenbereich für beschreibende Informationen zur Abfrage ein.strings: Gibt den Abschnitt an, in dem Stringmuster definiert werden.condition: Gibt den Abschnitt an, der die boolesche Logik für das Auslösen von Anfragen enthält.events: Definiert den Abschnitt zum Angeben von Ereignisvariablen und ihren Bedingungen.match: Leitet den Abschnitt zum Aggregieren von Werten über ein Zeitfenster ein.outcome: Definiert den Abschnitt zum Hinzufügen von Kontext und Scoring zu ausgelösten Anfragen.
- String-Modifikatoren:
ascii: Gibt an, dass ein String als ASCII-Text abgeglichen werden soll.wide: Gibt an, dass ein String als breite (UTF-16-)Zeichen abgeglichen werden soll.nocase: Führt einen Stringabgleich ohne Berücksichtigung der Groß-/Kleinschreibung durch.fullword: Erfordert, dass der String als vollständiges Wort übereinstimmt.xor: Wendet vor dem Abgleich eine XOR-Transformation auf den String an.base64,base64wide: Wendet vor dem Abgleich die Base64-Codierung an.
- Logische Operatoren:
and,or,not: Standardmäßige boolesche logische Operatoren zum Kombinieren von Bedingungen.all of,any of: Wird zum Auswerten mehrerer Ausdrücke in einer Bedingung verwendet.
- Vergleichs- und relationale Operatoren:
at: Gibt einen genauen Offset für den Stringabgleich an.contains: Prüft, ob ein String einen Teilstring enthält.startswith,endswith: Prüft, ob ein String mit einem Teilstring beginnt oder endet.icontains,istartswith,iendswith,iequals: Versionen, bei denen die Groß-/Kleinschreibung nicht berücksichtigt wird.matches: Wird für den Abgleich mit regulären Ausdrücken verwendet.
- Datentypen und Größenangaben:
int8,uint8,int16,uint16,int32,uint32: Ganzzahltypen mit angegebener Größe.int8be,uint8be,int16be,uint16be,int32be,uint32be: Big-Endian-Versionen von Ganzzahltypen.filesize: Gibt die Größe der analysierten Datei an.entrypoint: Bezieht sich auf den Einstiegspunkt einer ausführbaren Datei.
Maps
YARA-L unterstützt Maps für die Datentypen Struct und Label, die in einigen UDM-Feldern verwendet werden.
Wenn Sie in den Datentypen „Struct“ und „Label“ nach einem bestimmten Schlüssel/Wert-Paar suchen möchten, verwenden Sie die Standardsyntax für Maps:
- Syntax für Struct-Felder:
$e.udm.additional.fields["pod_name"] = "kube-scheduler" - Syntax für das Label-Feld:
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"
Beispiel: Gültige und ungültige Verwendung von Karten
Die folgenden Beispiele zeigen die zulässige und unzulässige Verwendung von Karten.
Gültige Verwendung von Karten
Struct-Feld im Bereich „Ereignisse“ verwenden:
events: $e.udm.additional.fields["pod_name"] = "kube-scheduler"
Label-Feld im Ergebnisbereich verwenden:
outcome: $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
Platzhalter einen Kartenwert zuweisen:
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
Kartenfeld in einer Join-Bedingung verwenden:
// 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"]
Nicht unterstützte Verwendung von Karten
any- oder all-Keywords mit einer Karte kombinieren
all $e.udm.additional.fields["pod_name"] = "kube-scheduler"
Andere Arten von Werten
Die Map-Syntax kann nur einen Stringwert zurückgeben. Bei [Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#struct)-Datentypen kann mit der Map-Syntax nur auf Schlüssel zugegriffen werden, deren Werte Strings sind. Der Zugriff auf Schlüssel, deren Werte andere primitive Typen wie Ganzzahlen sind, ist nicht möglich.
Umgang mit doppelten Werten in Karten
Der Zugriff auf die Karte ist dafür vorgesehen, einen einzelnen Wert abzurufen, der einem bestimmten Schlüssel zugeordnet ist. Das ist das Standardverhalten.
In seltenen Fällen kann der Kontext von map access jedoch versehentlich auf mehrere Werte verweisen. In dem seltenen Grenzfall, dass sich der Kartenzugriff auf mehrere Werte bezieht, gibt map access deterministisch den ersten Wert zurück. Das kann passieren, wenn ein Label einen doppelten Schlüssel oder ein wiederholtes Vorfahrenfeld hat.
Label hat einen doppelten Schlüssel
Die Labelstruktur stellt eine Map dar, erzwingt jedoch keine eindeutigen Schlüssel. Konventionsgemäß sollte eine Karte eindeutige Schlüssel haben. Daher wird in Google SecOps nicht empfohlen, ein Label mit doppelten Schlüsseln zu füllen.
Beispiel: Label mit doppeltem Schlüssel
Der Abfragetext $e.metadata.ingestion_labels["dupe-key"] würde bei Ausführung für das folgende Datenbeispiel den ersten möglichen Wert, val1, zurückgeben:
// 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"
}
}
}
Das Label hat ein übergeordnetes wiederkehrendes Feld
Ein wiederholtes Feld kann ein Label als untergeordnetes Feld enthalten. Zwei verschiedene Einträge im wiederholten Feld der obersten Ebene können Labels mit demselben Schlüssel enthalten.
Beispiel: Label mit wiederkehrendem übergeordneten Feld
Der Abfragetext $e.security_result.rule_labels["key"] würde bei Ausführung für das folgende Datenbeispiel den ersten möglichen Wert, „val3“, zurückgeben:
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"
}
}
}
Ergebnisvariablen in Karten aufrufen
In diesem Abschnitt wird beschrieben, wie Sie auf Ergebnisvariablen in Karten als ihre ursprünglichen Datentypen (z. B. Ganzzahlen, boolesche Werte oder Listen dieser Typen) und nicht nur als Strings zugreifen. So können Sie die Logik Ihrer Abfrage flexibler und genauer gestalten.
Ergebnisdaten sind in den folgenden Feldern verfügbar:
- Die Ergebniswerte behalten ihre ursprünglichen Typen im Feld
variablesbei. - Im Feld
outcomeswerdenstring-Versionen zur Abwärtskompatibilität gespeichert.
Sie können auf diese Ergebniswerte zugreifen, indem Sie die variables-Zuordnung verwenden, um den jeweiligen Typ abzurufen, oder indem Sie mit der Arrayindexierung auf Elemente in einer Sequenz zugreifen. Sie können entweder über den Index auf ein bestimmtes Element in der Sequenz zugreifen oder die gesamte Sequenz auswählen, um jeden Wert einzeln auszuwerten.
Syntax:
$d.detection.detection.variables[OUTCOME_NAME].TYPE_SUFFIX
Syntax für Sequenzen:
$d.detection.detection.variables[OUTCOME_NAME].SEQUENCE_TYPE_SUFFIX.TYPE_VALS_SUFFIX
Beispiele: Ergebnisvariablen in Karten aufrufen
Auf ein String-Ergebnis zugreifen:
$my_string_outcome = $d.detection.detection.variables["outcome_ip"].string_val
In diesem Beispiel wird der Stringwert direkt abgerufen, z. B. "1.1.1.1", wenn outcome_ip ein einzelner String war.
Ganzzahliges Ergebnis abrufen
$my_int_outcome = $d.detection.detection.variables["outcome_port"].int64_value
In diesem Beispiel wird der Ganzzahlwert abgerufen (z. B. 30).
Auf eine Liste von Ganzzahlen mit Int64Sequence zugreifen
$my_int_list = $d.detection.detection.variables["outcome_ports"].int64_seq.int64_vals
In diesem Beispiel wird die vollständige Liste der Ganzzahlen abgerufen und wie bei wiederholten Feldern (z. B. [2, 3, 4]) entnestet.
Auf ein bestimmtes Element aus einer Liste von Ganzzahlen zugreifen
$first_int = $d.detection.detection.variables["outcome_ports"].int64_seq.int64_vals[0]
In diesem Beispiel wird die erste Ganzzahl aus der Liste abgerufen (z. B. 2).
Auf eine Liste von Strings (StringSequence) zugreifen
$my_string_list = $d.detection.detection.variables["outcome_ips"].string_seq.string_vals
In diesem Beispiel wird die vollständige Liste der Strings abgerufen und wie bei wiederholten Feldern (z. B. ["1.1.1.1", "2.2.2.2"]) entnestet.
Auf ein bestimmtes Element aus einer Liste von Strings zugreifen
$first_ip = $d.detection.detection.variables["outcome_ips"].string_seq.string_vals[0]
In diesem Beispiel wird die erste IP-Adresse aus der Liste abgerufen (z. B. "1.1.1.1").
Verfügbare Typsuffixe für variables
Eine vollständige Liste der unterstützten Suffixe finden Sie unter FindingVariable.
Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten