Einzel- und Mehrfachereignisregeln in YARA-L

Unterstützt in:

In diesem Dokument werden Abfragen in YARA-L 2.0 gezeigt. In jedem Beispiel wird gezeigt, wie Ereignisse in der Abfrageregel-Sprache korreliert werden, um Sicherheitsrisiken zu erkennen, das Verhalten von Entitäten zu überwachen und Erkennungen mit Geschäftslogik anzureichern.

Verwenden Sie die Beispiele als Bausteine von YARA-L 2.0, einschließlich der Erkennung einzelner Ereignisse, des Abgleichs regulärer Ausdrücke und der Filterung von Netzwerkbereichen. Die Beispiele sind in funktionale Kategorien unterteilt, damit Sie sich von der einfachen Logik zu erweiterten Multi-Event-Korrelationen und zusammengesetzten Erkennungen vorarbeiten können.

Grundlegende Syntax und Grundlagen

Die Beispiele in diesem Abschnitt zeigen, wie Sie UDM-Ereignisse effektiv in Beziehung setzen und Abfragen in der Regelsprache strukturieren.

Thema Beispiele
Abfrage für ein einzelnes Ereignis Erste Suche nach Nutzeranmeldung; Erkennung von Anmeldungen innerhalb von 5 Minuten
Abfragen und Optimieren Ausschlussbasierte Prozesserfassung
Netzwerkbereich und Logik Abgleich einzelner Ereignisse (IP-Bereich)
Reguläre Ausdrücke in Abfragen E-Mail-Filterung; Hostname-Regex; Rohlogsuche
Wiederkehrende Felder mit universellen Bedingungen IP-Validierung bei verdächtiger Anmeldung

Abfrage für ein einzelnes Ereignis

Anwendungsfall: Einfache Erkennung eines bestimmten Ereignistyps (z. B. USER_LOGIN), ohne dass ein Zeitfenster berücksichtigt werden muss.

Schlüssellogik: Es werden nur die Abschnitte „Ereignisse“ und „Bedingung“ verwendet, um ein einzelnes Vorkommen zu identifizieren. Eine Einzelereignisregel kann Folgendes sein:

  • Jede Regel ohne match-Abschnitt.
  • Regel mit einem match-Abschnitt und einem condition-Abschnitt, in dem nur das Vorhandensein eines Ereignisses geprüft wird (z. B. $e, #e > 0, #e >= 1, 1 <= #e, 0 < #e).

Regel

Im folgenden Regelbeispiel wird nach einem Nutzeranmeldeereignis (USER_LOGIN) gesucht und das erste Ereignis zurückgegeben, das in den Unternehmensdaten in Ihrem Google SecOps-Datenspeicher gefunden wird:

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

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

condition:
  $e
}

In diesem Beispiel für eine nicht aggregierte Suche werden einzelne Ereignisse direkt ausgegeben. Da für diese Abfrage keine Ereigniskorrelation erforderlich ist, werden Ereignisvariablen wie $e1 weggelassen.

metadata.event_type = "USER_LOGIN"

Dashboard

Da diese Abfragelogik darauf ausgerichtet ist, bestimmte, nicht korrelierte Ereignisse in ihrem Rohzustand zu präsentieren, werden die für Dashboard-Visualisierungen erforderlichen Abschnitte match oder outcome nicht verwendet.

Beispiel: Anmeldungserkennung innerhalb von fünf Minuten

Regel

Im folgenden Beispiel sehen Sie eine Regel für ein einzelnes Ereignis, in der im Abschnitt match nach Nutzern gesucht wird, die mindestens ein Anmeldeereignis innerhalb eines 5-Minuten-Zeitfensters (5m) ausgelöst haben. 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
}

Suchen

In diesem Beispiel für eine statistische Suche werden Aktivitäten in fünfminütigen (5m) rollierenden Fenstern zusammengefasst, wobei pro Nutzer und Fenster eine Zeile ausgegeben wird. Da sich die Abfrage auf Volumenzahlen pro Zeitraum konzentriert, werden event Variablen und condition Abschnitte ausgelassen, da die Ergebnisse von Natur aus ein oder mehrere Ereignisse enthalten. In dieser Version wird ein rollierendes Fenster anstelle eines springenden Fensters verwendet, damit die Ergebnisse auf der Plattform korrekt dargestellt werden.

metadata.event_type = "USER_LOGIN"
principal.user.userid = $user

match:
  $user by 5m

Dashboard

Im folgenden Beispiel wird ein outcome-Abschnitt verwendet, um die Gesamtzahl der Ereignisse pro Nutzer zu berechnen. So lassen sich die Daten als statistischer Wert im Zeitverlauf darstellen. In der Abfrage wird ein rollierendes Fenster anstelle eines springenden Fensters verwendet, damit die Datenpunkte diskreten, nicht überlappenden Buckets zugeordnet werden und eine übersichtlichere Visualisierung für Dashboard-Trends möglich ist.

metadata.event_type = "USER_LOGIN"
principal.user.userid = $user

match:
  $user by 5m

outcome:
  $event_count = count(metadata.id)

Abfragen und Optimieren

Anwendungsfall: Windows-svchost.exe erkennen, die aus nicht standardmäßigen Verzeichnissen gestartet werden.

Wichtige Logik: Negation (not) kombiniert mit Abgleich über einen regulären Ausdruck.

Beispiel: Prozesserkennung auf Grundlage von Ausschlüssen

Regel

Mit der folgenden Regel wird nach bestimmten Mustern in Ereignisdaten gesucht. Wenn die Muster gefunden werden, wird eine Erkennung erstellt. Diese Regel enthält eine Variable $e1 zum Erfassen des Ereignistyps und des UDM-Felds 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. In der Regel ist eine not-Bedingung enthalten, um bestimmte nicht 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
}

Suchen

In diesem Beispiel wird eine nicht aggregierte Suche durchgeführt, um einzelne Ereignisse auszugeben. Da für diese Suche keine Ereigniskorrelation über mehrere Instanzen hinweg erforderlich ist, sind Ereignisvariablen wie $e1 nicht notwendig.

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

Dashboard

Diese Syntax enthält die Abschnitte match und outcome, um das Ereignisvolumen im Zeitverlauf zu berechnen. Mit der Funktion timestamp.get_timestamp() werden Ergebnisse für die Trendvisualisierung nach Tag gruppiert.

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

match:
  $date

outcome:
  $event_count = count(metadata.id)

Netzwerkbereich und ‑logik

Anwendungsfall: Aktivitäten nach bestimmten IP-Subnetzen (CIDR) filtern und mit mehreren möglichen Hostnamen abgleichen.

Schlüssel-Logik: Verwenden Sie die Funktion net.ip_in_range_cidr() für den Subnetzabgleich und den Operator OR, um mehrere mögliche Hostnamen zu prüfen.

  • net.ip_in_range_cidr(): Mit dieser Funktion wird geprüft, ob eine bestimmte IP-Adresse in einem bestimmten CIDR-Subnetz (Classless Inter-Domain Routing) enthalten ist.
  • Logischer Operator OR: Wird verwendet, um mehrere Bedingungen zu kombinieren. Bedingungen im Ereignisbereich werden implizit mit AND kombiniert. Der Operator OR vergleicht mit mehreren möglichen Hostnamen.

Beispiel: Abgleich einzelner Ereignisse (IP-Bereich)

Regel

Das folgende Beispiel zeigt eine Regel für ein einzelnes Ereignis, mit der nach Übereinstimmungen zwischen zwei bestimmten Hostnamen 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
}

Suchen

Im folgenden Beispiel werden Ereignisse identifiziert, bei denen eine bestimmte IP-Adresse in einen definierten CIDR-Bereich fällt und der Hostname einem bestimmten Nutzermuster entspricht:

net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")

principal.hostname = /pbateman/ or principal.hostname = /sspade/

Da es sich um eine Suchanfrage und nicht um eine Erkennungsregel handelt, wird das gesamte Ereignis automatisch zurückgegeben, wenn die Filterkriterien erfüllt sind. In einem match-Abschnitt werden Daten nach principal.ip und principal.hostname gruppiert. Ein condition-Abschnitt ist nicht erforderlich und Ereignisvariablen ($e) werden weggelassen, da keine Ereigniskorrelation durchgeführt wird.

Dashboard

In der folgenden Beispielabfrage werden Ergebnisse durch Gruppieren eindeutiger IP- und Hostname-Paare zusammengefasst:

net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")

principal.hostname = /pbateman/ or principal.hostname = /sspade/

match:
  principal.ip, principal.hostname

Reguläre Ausdrücke in Abfragen

Anwendungsfall: Suche nach flexiblen Stringmustern (z. B. bestimmte Domains in E‑Mails) ohne Berücksichtigung der Groß- und Kleinschreibung. Dies wird am häufigsten in der Suche und in Regeln verwendet.

Schlüssel-Logik: Hier wird /regex/ nocase für einfache Übereinstimmungen und die Funktion re.regex() für komplexe Feldanalysen verwendet.

Beispiel: E‑Mail-Filterung

Regel

Im folgenden Beispiel für einen regulären Ausdruck in YARA-L 2.0 wird nach Ereignissen mit E-Mails gesucht, die von der Domain altostrat.com empfangen wurden. Da nocase der $host-Variablen regex-Vergleich und der regex-Funktion hinzugefügt wurde, wird bei diesen 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
}

Suchen

In der Suchoberfläche wird diese Logik für die Suche nach Bedrohungen und die Datenanalyse verwendet. Anstatt auf eine automatische Benachrichtigung zu warten, können Analysten die UDM manuell abfragen, um bestimmte Instanzen von Hostnamen zu ermitteln, die einer Namenskonvention entsprechen, sowie bestimmte E‑Mail-Domains. Dies ist die primäre Methode, um das Volumen dieser Ereignisse zu validieren, bevor sie in eine dauerhafte Erkennungsregel aufgenommen werden.

principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase
match:
 $host over 10m

Dashboard

Mit der folgenden Logik werden interessante Muster ermittelt, indem hostname- und email-Telemetriedaten in 10‑Minuten-Zeiträumen (10m) zusammengefasst werden. Wenn diese Logik in einem Dashboard verwendet wird, können Analysten die Kommunikationshäufigkeit von bestimmten Assets (die mit host übereinstimmen) zur Domain altostrat.com visualisieren. Diese Ansicht ist wichtig, um Trends bei der internen Datenverschiebung zu beobachten und Top Talker in kritischen Infrastrukturen zu identifizieren.

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

match:
  $host over 10m

Beispiel: Regulärer Ausdruck für Hostnamen

Regel

Im folgenden Beispiel wird jede Log-Aktivität identifiziert, bei der das Hauptkonto hostname als Webserver (webserver) oder Entwicklungsserver (devserver) identifiziert wird. Es wird ein regulärer Ausdruck verwendet, bei dem die Groß-/Kleinschreibung nicht berücksichtigt wird. So wird sichergestellt, dass Abweichungen bei den Namenskonventionen nicht dazu führen, dass Erkennungen übersehen werden.

rule WebServerOrDevServerActivity {
meta:
 author = "Alex"
 description = "Detects events where the principal hostname is 'webserver' or 'devserver', ignoring case."
 severity = "Informational"

events:
 $e.principal.hostname = /webserver|devserver/ nocase

condition:
 $e
}

Suchen

Im folgenden Beispiel entspricht principal.hostname = /webserver|devserver/ nocase Hostnamen wie "WebServer01", "devserver-test" und "MyWebServers". Dies ist ein häufiger Anwendungsfall, um ein bestimmtes Ereignis zu finden.

// Use /regex/ followed by nocase for a case-insensitive match
principal.hostname = /webserver|devserver/ nocase

Dashboard

Dieses spezielle Beispiel wird zwar nicht in einem Dashboard visualisiert, aber diese Regel bietet aktive Benachrichtigungen und eine kontinuierliche Erkennung. Im Gegensatz zu einem Dashboard, das eine manuelle Überprüfung erfordert, wird so dafür gesorgt, dass jede Aktivität auf diesen Servern automatisch gekennzeichnet und in der Erkennungs-Engine aufgezeichnet wird, damit sie sofort durchsucht werden kann.

Regel

Während Sie die manuelle Suche für Untersuchungen zu einem bestimmten Zeitpunkt verwenden, bieten Erkennungsregeln ein kontinuierliches Telemetrie-Monitoring rund um die Uhr. Sie können eine erfolgreiche Suchanfrage in eine YARA‑L-Regel umwandeln, um den Benachrichtigungsprozess zu automatisieren.

Wichtige Vorteile von Regeln:

  • Benachrichtigungen in Echtzeit: Übereinstimmungen werden automatisch gekennzeichnet, sobald sie in das System gelangen.
  • Persistenz: Suchbegriffe müssen nicht mehr manuell eingegeben werden.
  • Ergebnisaktionen: Werden direkt in die Erkennungsansicht für die Triage durch Analysten und die Incident Response eingespeist.

Suchen

Sicherheitsanalysten verwenden regex häufig, um in Google SecOps in unaufbereiteten, nicht geparsten Logs zu suchen. Diese Aktion ermöglicht einen flexiblen Musterabgleich, um bestimmte Artefakte zu finden, auch wenn sie nicht vollständig strukturiert oder indexiert sind. Die Syntax verwendet Schrägstriche:

raw = /host/

Diese Abfrage gibt alle Rohlogzeilen zurück, in denen die Zeichenfolge "host" vorkommt. Beispiele für übereinstimmende Rohloginhalte sind "hostname": "myhost123".

Dashboard

Für diesen bestimmten Ereignistyp gibt es keine spezielle Dashboard-Variante. So können Sie diese Erkennungen im großen Maßstab visualisieren:

  • Ordnen Sie metadata.event_type im Dashboard Builder einem Balken- oder Kreisdiagramm zu.
  • Verfolgen Sie die Häufigkeit dieser Ereignisse über Zeiträume von 7, 30 oder 90 Tagen, um Anomalien im Nutzerverhalten zu erkennen.

Wiederkehrende Felder mit universellen Bedingungen

Anwendungsfall: Audit-Ereignisse, die Datenlisten (wiederkehrende Felder) enthalten, um sicherzustellen, dass keine vertrauenswürdigen Ausnahmen vorhanden sind. Prüfen Sie beispielsweise, ob jede mit einer Anmeldung verknüpfte IP-Adresse außerhalb eines bekannten sicheren Bereichs liegt.

Wichtige Logik: Verwendet den Operator all, um jedes Element in einem wiederkehrenden Feld anhand einer bestimmten Bedingung zu bewerten. Außerdem wird gezeigt, wie durch das Zuweisen eines wiederkehrenden Felds zu einer Platzhaltervariablen (z. B. $ip) für jeden eindeutigen Wert in der Liste eine separate Erkennung erstellt wird.

Beispiel: Validierung der IP-Adresse bei verdächtiger Anmeldung

Regel

Mit der folgenden Regel wird nach Anmeldeereignissen gesucht, bei denen alle Quell-IP-Adressen innerhalb eines Zeitraums von fünf Minuten (5m) nicht mit einer als sicher bekannten IP-Adresse übereinstimmen.

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
}

Suchen

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 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.

principal.ip = $ip

match:
  $ip over 5m

Dashboard

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 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.

principal.ip = $ip

match:
  $ip over 5m

Erweiterte Fensterung

In diesem Abschnitt werden mehrstufige Muster und Erkennungen behandelt, die durch Aktivitäten aus anderen Regeln ausgelöst werden.

Thema Beispiele
Korrelation mehrerer Ereignisse Erkennung von Anmeldungen in mehreren Städten; Schnelles Erstellen und Löschen von Nutzern
Gleitendes Fenster in Abfragen Erkennung fehlender sequenzieller Ereignisse
Abfragen mit mehreren Ereignissen Erkennung von Anmeldungen mit hoher Häufigkeit
Abfragen mit mehreren Ereignissen und berechneten Ergebnissen Brute-Force-Angriff gefolgt von erfolgreicher Anmeldung; Zeitfensterbasierter Hostabgleich

Korrelation mehrerer Ereignisse

In diesem Abschnitt finden Sie Beispiele dafür, wie Sie Entitäten (Nutzer oder Hosts) über mehrere Ereignisse oder Zeiträume hinweg verfolgen können, um Verhaltensmuster zu erkennen.

Anwendungsfall: Erkennt unmögliche Reisen, bei denen sich ein einzelner Nutzer in weniger als fünf (5m) Minuten von zwei oder mehr Städten aus anmeldet.

Schlüssellogik: Verwenden Sie den Abschnitt match, um nach $user und #city > 1 zu gruppieren und eindeutige Standortwerte zu finden.

Beispiel: Erkennung von Anmeldungen in mehreren Städten

Regel

Die folgende Regel sucht nach Nutzern, die sich innerhalb von weniger als 5 Minuten (5m) in zwei oder mehr Städten in Ihrem Unternehmen angemeldet haben. Dabei ist $user die Variable match, $udm die Ereignisvariable und $city und $user die Platzhaltervariablen:

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
}

In der folgenden Erklärung wird die Funktionsweise dieser Regel beschrieben:

  • Gruppiert Ereignisse mit dem Nutzernamen ($user) und gibt sie zurück ($user), wenn eine Übereinstimmung gefunden wird.
  • Die Zeitspanne beträgt fünf Minuten (5m). Es werden nur Ereignisse korreliert, die weniger als fünf Minuten (5m) auseinanderliegen.
  • Sucht nach einer Ereignisgruppe ($udm), deren Ereignistyp USER_LOGIN ist.
  • Für diese Ereignisgruppe wird die Nutzer-ID in der Regel als $user und die Stadt der Anmeldung als $city aufgerufen.
  • Gibt eine Übereinstimmung zurück, wenn die Anzahl der eindeutigen city-Werte (angegeben durch #city) in der Ereignisgruppe ($udm) im 5-Minuten-Zeitraum (5m) größer als 1 ist.

Suchen

Mit der folgenden Beispielabfrage wird eine entsprechende statistische Suche ausgeführt, um Muster für unmögliche Fahrten zu erkennen. Dabei werden USER_LOGIN-Ereignisse nach Nutzer innerhalb eines 5m-Zeitraums gruppiert und die Ergebnisse so gefiltert, dass nur Fälle angezeigt werden, in denen für eine einzelne Identität mehrere unterschiedliche Städte erkannt werden.

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

match:
  $user over 5m

condition:
  #city > 1

Dashboard

Die folgende Beispielabfrage liefert eine entsprechende Dashboard-Visualisierung, um potenzielle Konto-Hacks zu verfolgen. Die USER_LOGIN-Ereignisse werden für einen Zeitraum von fünf Minuten (5m) nach Nutzer zusammengefasst und nach Fällen gefiltert, in denen eine einzelne Identität mit mehr als einer unterschiedlichen Stadt (#city) verknüpft ist. So können Sie diese geografischen Anomalien mit hohem Risiko im Zeitverlauf darstellen.

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

match:
  $user over 5m

condition:
  #city > 1

Schnelles Erstellen und Löschen von Nutzern

Anwendungsfall: Burner-Konten identifizieren, die innerhalb von vier Stunden erstellt und dann gelöscht wurden.

Wichtige Logik: Verknüpfen Sie zwei Ereignistypen (USER_CREATION und USER_DELETION) über eine gemeinsame $user-Variable und vergleichen Sie ihre Zeitstempel.

Beispiel: Schnelles Erstellen und Löschen von Nutzern

Regel

Im folgenden Beispiel wird nach Nutzern gesucht, die innerhalb von vier Stunden erstellt und dann gelöscht wurden (4h). Dabei sind $create und $delete die Ereignisvariablen, $user die Variable match und es gibt keine Platzhaltervariablen:

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
}

Suchen

Im folgenden Beispiel wird eine Suche nach Statistiken mit mehreren Ereignissen verwendet, um schnelle Änderungen im Kontolebenszyklus zu erkennen. Mit dieser Abfrage wird eine Zeile pro Nutzer innerhalb eines vierstündigen Zeitraums ausgegeben, in der die Erstellung und Löschung von Identitäten korreliert werden.

Da die Suche standardmäßig alle Fenster zurückgibt, die die angegebenen Ereignisse enthalten, ist kein condition-Abschnitt erforderlich.

$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

Dashboard

Im folgenden Beispiel wird eine Suche für ein Dashboard mit mehreren Ereignissen gezeigt, mit der Trends im Kontolebenszyklus im Zeitverlauf dargestellt werden sollen. Durch die Verwendung eines rollierenden Fensters (by 4h) werden die Ergebnisse diskreten, nicht überlappenden Zeiträumen zugeordnet, was sich ideal für die Visualisierung eignet.

Diese Variante enthält einen outcome-Abschnitt, um die eindeutige Anzahl von Erstellungsereignissen innerhalb jedes Zeitfensters zu berechnen. Im Gegensatz zur vorherigen Suche müssen bei dieser Version keine bestimmten Ereignisvariablen zurückgegeben werden, da der Schwerpunkt auf aggregierten statistischen Werten und nicht auf einzelnen Logzeilen liegt.

$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 by 4h

outcome:
  $event_count = count_distinct($create.metadata.id)

Gleitendes Fenster in Abfragen

Anwendungsfall: Erkennen eines potenziellen Sicherheitsproblems, bei dem auf ein anfängliches Ereignis (von firewall_1) nicht innerhalb eines bestimmten Zeitrahmens ein erwartetes nachfolgendes Ereignis (von firewall_2) auf demselben Host folgt.

Wichtige Logik:

  • Pivot-Ereignis: Die Regel basiert auf Ereignissen aus firewall_1, die als $e1 gekennzeichnet sind. Jedes Mal, wenn ein $e1-Ereignis eintritt, dient es als Pivot.
  • Zeitfenster: Im Abschnitt match ($host over 10m after $e1) wird ein 10-minütiges Zeitfenster definiert, das unmittelbar nach jedem $e1-Ereignis beginnt. Dieses Zeitfenster gleitet mit jedem neuen $e1-Ereignis.
  • Korrelation: Ereignisse werden nach Hostname ($host) gruppiert.
  • Bedingung für die Erkennung ($e1 und $e2): Eine Erkennung wird für einen bestimmten Host ausgelöst, wenn:
    • Ein Ereignis von firewall_1 ($e1) ist vorhanden.
    • AND: Innerhalb des 10-Minuten-Fensters nach diesem bestimmten $e1-Ereignis wird ein NO-Ereignis von firewall_2 ($e2) für denselben Host gefunden.

Beispiel: Erkennen fehlender sequenzieller Ereignisse

Regel

Im folgenden Beispiel werden Instanzen identifiziert, bei denen ein sekundäres Ereignis nach einem primären Trigger nicht auftritt. Durch die Verwendung der Bedingung !$e2 innerhalb eines 10-minütigen Zeitfensters werden mit dieser Regel fehlende Telemetriedaten gekennzeichnet, insbesondere wenn ein Firewall-Log an einem Ort angezeigt wird, aber nicht am nächsten erwarteten Hop erscheint. Dies deutet auf eine potenzielle Sichtbarkeitslücke oder einen Traffic-Abfall hin.

rule MissingSequentialEvent {
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:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2
}

Suchen

Im folgenden Beispiel wird eine sequenzielle Suche verwendet, um Lücken in der Telemetrie zwischen zwei Quellen zu identifizieren. Wenn Sie $e1 als Pivot verwenden, wird nach einem primären Firewallereignis gesucht, auf das innerhalb von 10 Minuten kein entsprechendes Ereignis auf einer zweiten Firewall folgt. Dies ist eine sehr effektive Methode, um während einer Untersuchung manuell nach „Black Holes“ im Netzwerkverkehr oder nach Logging-Fehlern zu suchen.

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

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

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2

Dashboard

Im folgenden Beispiel sehen Sie eine Analyse der Sichtbarkeitslücke, die für eine Dashboardansicht konzipiert ist. Wenn Sie Instanzen zusammenfassen, in denen ein sekundäres Ereignis nicht auf ein primäres Ereignis folgt, können Sie die Zuverlässigkeit Ihrer Logging-Pipeline im Zeitverlauf visualisieren. Durch das Darstellen dieser „fehlenden“ Ereignisse können Sie dauerhafte tote Zonen in der Netzwerksichtbarkeit oder Konfigurationsprobleme bei bestimmten Hostnamen identifizieren.

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

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

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2

Abfragen mit mehreren Ereignissen

  • Anwendungsfall: Aktivitäten mit hoher Häufigkeit oder Brute-Force-Aktivitäten erkennen, indem eine einzelne Einheit (z. B. ein Nutzer oder Host) über mehrere Vorkommen eines Ereignisses innerhalb eines bestimmten Zeitfensters hinweg verfolgt wird.

  • Schlüssel-Logik: Hier wird ein match-Abschnitt verwendet, um Ereignisse nach einer bestimmten Variablen zu gruppieren, und ein condition-Abschnitt, um innerhalb des definierten Zeitraums nach einer Schwellenwertanzahl (z. B. #e >= 10) zu suchen.

Eine typische Regel für mehrere Ereignisse umfasst:

  • Ereignisvariablen, um zwischen Ereignissen zu unterscheiden.
  • Ein match-Abschnitt, in dem der Zeitraum angegeben wird, über den Ereignisse gruppiert werden müssen.
  • Ein condition-Abschnitt, in dem angegeben wird, welche Bedingung die Erkennung auslösen soll, und in dem geprüft wird, ob mehrere Ereignisse vorhanden sind.

In der Google Suche werden Anfragen mit mehreren Ereignissen durch mehr als ein Ereignis in einer Anfrage definiert. Für Regeln gibt es zwei Möglichkeiten, dies zu definieren:

  • Mehrere Ereignisse: (z. B. event1 = successful login, event2 = failed login).

  • Bedingungsbasierte Trigger: Die Bedingung wird so formuliert, dass sie nur ausgelöst wird, wenn mehrere Ereignisse die Kriterien erfüllen (z. B. event1 > 10). Diese Art von Regel muss auch einen outcome-Abschnitt enthalten.

Beispiel: Erkennung von Anmeldungen mit hoher Frequenz

Regel

Mit der folgenden Regel wird 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
}

Suchen

Im folgenden Beispiel wird eine Statistiksuche mit mehreren Ereignissen verwendet, um Anmeldeaktivitäten mit hoher Häufigkeit zu identifizieren. Sie wird ausgelöst, wenn ein einzelner Nutzer innerhalb von 10 Minuten (10m) mindestens 10 Anmeldeereignisse generiert.

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

match:
  $user by 10m

condition:
  #e >= 10

Dashboard

Im folgenden Beispiel wird eine Suche mit mehreren Ereignissen verwendet, um nach potenziellen Konto-Hacks zu suchen. Durch die Korrelation von Anmeldeversuchen in einem gleitenden 10‑Minuten-Zeitfenster werden Fälle erkannt, in denen ein bestimmter Nutzer und Host mehrere fehlgeschlagene Anmeldungen gefolgt von einer erfolgreichen Anmeldung durchlaufen. So können Sie Authentifizierungsmuster mit hohem Risiko in Echtzeit visualisieren.

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

match:
  $user by 10m

condition:
  #e >= 10

Abfragen mit mehreren Ereignissen und berechneten Ergebnissen

  • Anwendungsfall: Bedingte Logik anwenden, um einen risk_score basierend auf dem Schweregrad des Assets oder dem Netzwerkvolumen festzulegen.

  • Schlüssellogik: Verwendet den Abschnitt outcome, um Variablen zu berechnen, und den Abschnitt mit der Bedingung, um nach diesen Variablen zu filtern.

Beispiel: Brute-Force-Angriff gefolgt von erfolgreicher Anmeldung

Im folgenden Beispiel wird der Abschnitt outcome verwendet, um Ereignisse innerhalb eines match-Fensters zu zählen. Diese Abfrage generiert dieselbe Ausgabe wie eine Standardabfrage mit mehreren Ereignissen, zeigt aber, wie berechnete Variablen in die Erkennungslogik eingebunden werden.

Regel

rule PossibleBruteForceThenSuccessfulLogin {
meta:
  author = "Alex"
  description = "Detects multiple failed login attempts followed by a successful login for the same user and host within a 10-minute window."
  severity = "High"
  tactic = "Credential Access"

events:
  // Define the first type of event: Failed Login
  // We use $failed to represent any event matching these criteria.
  $failed.metadata.event_type = "USER_LOGIN"
  $failed.security_result.action = "FAIL"
  // Extract common fields to correlate on
  $failed.target.user.userid = $user
  $failed.principal.hostname = $hostname

  // Define the second type of event: Successful Login
  // We use $success to represent any event matching these criteria.
  $success.metadata.event_type = "USER_LOGIN"
  $success.security_result.action = "ALLOW"
  // Correlate using the same user and hostname placeholders
  $success.target.user.userid = $user
  $success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a time window: by 10m.
  // The rule will evaluate all events matching $failed or $success that share the same $user and $hostname within any given 10-minute period.
  $user, $hostname by 10m

outcome:
  // Calculate aggregate values from the events within the match window.
  $failed_login_count = count($failed.metadata.id)
  $successful_login_count = count($success.metadata.id)

condition:
  // The conditions that must be met *within each matched group* ($user, $hostname over 10m).
  // - #failed >= 5: There must be 5 or more events matching the $failed criteria.
  // - #success >= 1: There must be at least 1 event matching the $success criteria.
  #failed >= 5 and #success >= 1
}

Suchen

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a sliding time window: over 10m.
  // The rule will evaluate all events matching $failed or $success that share
  // the same $user and $hostname within any given 10-minute period.
  $user, $hostname over 10m

Dashboard

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a sliding time window: over 10m.
  // The rule will evaluate all events matching $failed or $success that share
  // the same $user and $hostname within any given 10-minute period.
  $user, $hostname over 10m

Beispiel: Zeitfensterbasierter Hostabgleich

Regel

Bei der folgenden Regel werden zwei Ereignisse berücksichtigt, um den Wert von $hostname abzurufen. Wenn der Wert von $hostname über einen Zeitraum von 5 Minuten (5m) übereinstimmt, wird ein Schweregrad 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")
}

Suchen

 // Define the first type of event: Failed Login
 // We use $failed to represent any event matching these criteria.
 $failed.metadata.event_type = "USER_LOGIN"
 $failed.security_result.action = "FAIL"
 // Extract common fields to correlate on
 $failed.target.user.userid = $user
 $failed.principal.hostname = $hostname

 // Define the second type of event: Successful Login
 // We use $success to represent any event matching these criteria.
 $success.metadata.event_type = "USER_LOGIN"
 $success.security_result.action = "ALLOW"
 // Correlate using the same user and hostname placeholders
 $success.target.user.userid = $user
 $success.principal.hostname = $hostname

match:
 // This section is key for multi-event rules. It groups events:
 // - By the common placeholder variables: $user and $hostname.
 // - Within a sliding time window: over 10m.
 // The rule will evaluate all events matching $failed or $success that share
 // the same $user and $hostname within any given 10-minute period.
 $user, $hostname over 10m

outcome:
 // Calculate aggregate values from the events within the match window.
 $failed_login_count = count($failed.metadata.id)
 $successful_login_count = count($success.metadata.id)
 ```

Dashboard

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
 // This section is key for multi-event rules. It groups events:
 // - By the common placeholder variables: $user and $hostname.
 // - Within a sliding time window: over 10m.
 // The rule will evaluate all events matching $failed or $success that share
 // the same $user and $hostname within any given 10-minute period.
 $user, $hostname over 10m

outcome:
  // Calculate aggregate values from the events within the match window.
  $failed_login_count = count($failed.metadata.id)
  $successful_login_count = count($success.metadata.id)

Kontextsensitive Analysen

Mit YARA-L-Regeln können Sie UDM-Ereignisdaten anhand von Kontextdaten zu Kompromittierungsindikatoren (Indicator of Compromise, IOC) auswerten. Diese Kontextdaten werden als Entitätskontexte in Google SecOps gespeichert.

Die Beispiele in diesem Abschnitt zeigen, wie Sie kontextbezogene Analysen erstellen, indem Sie Ereignisfelder mit IOC-Feeds wie Google Safe Browsing und benutzerdefinierten Feeds verknüpfen.

Thema Beispiele
Hashwert-Abgleich von Dateien mit Kompromittierungsindikatoren Verdächtiger Prozessstart; Safe Browsing-Gefahrenlisten
Abgleich von IP-Adressen mit Kompromittierungsindikatoren Erkennung von Tor-Ausgangsknoten: Mehrere fehlgeschlagene Anmeldungen über das Tor-Netzwerk
Domainabgleich mit Kompromittierungsindikatoren Domains mit niedriger Verbreitung
URL-Abgleich mit Kompromittierungsindikatoren Übereinstimmung mit schädlicher URL aus Threat-Feed
Gleichzeitiger Abgleich mehrerer Feeds Erkennung von Tor-Ausgangsknoten und Remote-Zugriffstools

Abgleich von Dateihashwerten mit Kompromittierungsindikatoren

Anwendungsfall: Ausführung oder Vorhandensein von Dateien erkennen, die in Threat-Feeds als Kompromittierungsindikatoren (Indicators of Compromise, IOCs) identifiziert wurden.

Wichtige Logik: UDM-Prozess- oder ‑Dateiereignisse mit Datei-Entitäten (Hashes) aus IOC-Feeds im Entity Graph verknüpfen.

Beispiel: Verdächtiger Prozessstart

Regel

Mit der folgenden Regel werden UDM-Prozessdaten mit generischen IOC-Kontextdaten verglichen. Es wird nach einem Ereignis zum Starten eines Prozesses gesucht und der Dateihash aus dem Ereignis wird mit einem Dateihash aus einem IOC-Entitätsdiagramm verknüpft.

rule ProcessLaunch {
  meta:
  events:
    $ioc.graph.metadata.vendor_name = "ACME"
    $ioc.graph.metadata.product_name = "IOCs"
    $ioc.graph.metadata.entity_type = "FILE"
    $ioc.graph.entity.file.sha256 = $hash

    $process.metadata.event_type = "PROCESS_LAUNCH"
    $process.principal.hostname = $hostname
    (
        not $process.target.process.file.sha256 = "" and
        $process.target.process.file.sha256 = $hash
    )

  match:
    $hash over 15m

  condition:
    $ioc and $process
}

Beispiel: Safe Browsing-Bedrohungslisten

Regel

Google SecOps nimmt Daten aus Bedrohungslisten für Dateihashes auf, die als Entitäten gespeichert werden. Mit der folgenden Regel wird die Ausführung einer Datei erkannt, die von Google Safe Browsing als schädlich eingestuft wird.

rule safe_browsing_file_execution {
    meta:
        author = "Google Security Operations"
        description = "Example usage of Safe Browsing data, to detect execution of a file that's been deemed malicious"
        severity = "LOW"

    events:
        // find a process launch event, match on hostname
        $execution.metadata.event_type = "PROCESS_LAUNCH"
        $execution.principal.hostname = $hostname

        // join execution event with Safe Browsing graph
        $sb.graph.entity.file.sha256 = $execution.target.process.file.sha256

        // look for files deemed malicious
        $sb.graph.metadata.entity_type = "FILE"
        $sb.graph.metadata.threat_intel.severity = "SEVERITY_HIGH"
        $sb.graph.metadata.product_name = "Google Safe Browsing"
        $sb.graph.metadata.source_type = "GLOBAL_CONTEXT"

    match:
        $hostname over 1h

    outcome:
        $risk_score = max(if($sb.graph.metadata.threat_intel.severity = "SEVERITY_HIGH", 90, 0))

    condition:
        $execution and $sb
}

Abgleich von IP-Adressen mit Kompromittierungsindikatoren

Anwendungsfall: Netzwerkkommunikation mit bekannten schädlichen IP-Adressen erkennen, die in Threat-Feeds gespeichert sind.

Schlüssellogik: UDM-Netzwerkereignisse mit IP-Adressenentitäten aus IOC-Feeds im Entity Graph verknüpfen.

Beispiel: Erkennung von Tor-Ausgangsknoten

Regel

Netzwerkverkehr identifizieren, der von bekannten Tor-Ausgangsknoten stammt oder eine Verbindung zu diesen herstellt. In diesem Beispiel werden UDM-Ereignisse mit dem GCTI-Feed „Tor Exit Nodes“ verknüpft, der allen Kunden zur Verfügung steht.

rule TorExitNodeMatch {
  meta:
    author = "Google Security Operations"
    description = "Detects traffic from known Tor exit nodes."
    severity = "MEDIUM"

  events:
    // Event based on IP
    $principal_ip = $e.principal.ip

    // Filter Entity Graph to extract feed specific details
    $gcti.graph.metadata.entity_type = "IP_ADDRESS"
    $gcti.graph.metadata.feed = "Tor Exit Nodes"
    $gcti.graph.metadata.product_name = "GCTI Feed"

    // Join the IP data
    $principal_ip = $gcti.graph.entity.ip

  match:
    $principal_ip over 30m

  outcome:
    $threat_feed = array_distinct($gcti.graph.metadata.feed)

  condition:
    $e and $gcti
}

Beispiel: Mehrere fehlgeschlagene Anmeldeversuche über das Tor-Netzwerk

Regel

Erkennung mehrerer fehlgeschlagener Anmeldeversuche über ein Tor-Netzwerk. In diesem Beispiel werden login_failure-Ereignisse mit dem Tor-Exit-Knoten-Feed korreliert und ein Häufigkeitsschwellenwert mit der Zählsyntax (#) angewendet.

rule TorMultiLoginFailure {
  meta:
    author = "Google Security Operations"
    description = "Detects multiple failed logins from a Tor network."
    severity = "HIGH"

  events:
    $failed_login_event.metadata.product_name = "login"
    $failed_login_event.metadata.product_event_type = "login_failure"
    $failed_login_event.metadata.vendor_name = "Google Workspace"
    $sus_ip = $failed_login_event.principal.ip
    $sus_target_account = $failed_login_event.target.user.email_addresses
    $sus_target_account != ""

    $gcti.graph.metadata.entity_type = "IP_ADDRESS"
    $gcti.graph.metadata.feed = "Tor Exit Nodes"
    $gcti.graph.metadata.product_name = "GCTI Feed"

    // Join the IP data
    $sus_ip = $gcti.graph.entity.ip

  match:
    $sus_ip over 1h

  outcome:
    $event_count = count_distinct($failed_login_event.metadata.id)

  condition:
    $failed_login_event and #failed_login_event >= 10 and $gcti
}

Domainabgleich mit Kompromittierungsindikatoren

Anwendungsfall: Netzwerkaktivitäten für Domains erkennen, die als Kompromittierungsindikatoren (IOCs) gekennzeichnet sind oder eine geringe Prävalenz aufweisen.

Wichtige Logik: UDM-Netzwerkereignisse mit Domainentitäten aus IoC-Feeds oder Daten zur Verbreitung im Entity Graph verknüpfen, indem der Domainname oder Hostname verwendet wird.

Beispiel: Domains mit niedriger Verbreitung

Regel

Mit der folgenden Regel wird eine Benachrichtigung zur Erkennung generiert, indem eine Domain mit geringer Prävalenz mit einem bekannten IOC verglichen wird. Es verknüpft ein DNS-Abfrageereignis mit Prävalenzdaten und einer IOC-Entität aus dem ET_PRO_IOC-Feed.

rule network_prevalence_uncommon_domain_ioc_match {

  meta:
    author = "Google Security Operations"
    description = "Lookup Network DNS queries against Entity Graph for low prevalence domains with a matching IOC entry."
    severity = "MEDIUM"

  events:
    $e.metadata.event_type = "NETWORK_DNS"
    $e.network.dns.questions.name = $hostname

    //only match FQDNs, such as: exclude chrome dns access tests and other internal hosts
    $e.network.dns.questions.name = /(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/

    //prevalence entity graph lookup
    $p.graph.metadata.entity_type = "DOMAIN_NAME"
    $p.graph.entity.domain.prevalence.rolling_max > 0
    $p.graph.entity.domain.prevalence.rolling_max <= 3
    $p.graph.entity.domain.name = $hostname

    //ioc entity graph lookup
    $i.graph.metadata.vendor_name = "ET_PRO_IOC"
    $i.graph.metadata.entity_type = "DOMAIN_NAME"
    $i.graph.entity.hostname = $hostname

  match:
    $hostname over 10m

  outcome:
    $risk_score = max(
        //increment risk score based upon rolling_max prevalence
        if ( $p.graph.entity.domain.prevalence.rolling_max = 3, 50) +
        if ( $p.graph.entity.domain.prevalence.rolling_max = 2, 70) +
        if ( $p.graph.entity.domain.prevalence.rolling_max = 1, 90)
    )

  condition:
    $e and $p and $i
}

URL-Abgleich mit Kompromittierungsindikatoren

Anwendungsfall: Netzwerkaktivitäten mit bösartigen URLs erkennen, die in Threat-Feeds gespeichert sind.

Schlüssellogik: UDM-Netzwerkereignisse mit URL-Daten mit URL-Entitäten aus IOC-Feeds im Entitätsdiagramm verknüpfen.

Beispiel: Übereinstimmung mit schädlicher URL aus Threat-Feed

Regel

Mit der folgenden Regel werden Netzwerkereignisse erkannt, bei denen die angeforderte URL mit einer bekannten schädlichen URL aus einem Threat Intelligence-Feed übereinstimmt. Dabei wird die target.url des Ereignisses mit URL-Entitäten im Entitätendiagramm in Beziehung gesetzt.

rule ioc_url_threat_feed_match {
  meta:
    author = "Google Security Operations"
    description = "Matches network events against known malicious URLs from threat intelligence feeds."
    severity = "HIGH"

  events:
    // Filter for network traffic containing URL information
    $network_event.metadata.event_type = "NETWORK_HTTP" or $network_event.metadata.event_type = "NETWORK_CONNECTION"
    $url = $network_event.target.url

    // Entity Graph Join: URL Indicators
    $ioc.graph.metadata.entity_type = "URL"
    $ioc.graph.metadata.product_name = "GCTI Feed"
    $ioc.graph.metadata.feed = "Malicious URLs"
    $ioc.graph.entity.url = $url

  match:
    $url over 5m

  outcome:
    $risk_score = 85
    $threat_feed = array_distinct($ioc.graph.metadata.feed)
    $principal_ip = array_distinct($network_event.principal.ip)
    $principal_user = array_distinct($network_event.principal.user.userid)

  condition:
    $network_event and $ioc
}

Gleichzeitiger Abgleich mehrerer Feeds

Anwendungsfall: Sie können erweiterte Bedrohungen korrelieren, indem Sie mehrere Attribute (z. B. IP-Adresse und Datei-Hash) mit separaten Bedrohungsfeeds in einer einzigen Ereignisabfrage abgleichen.

Wichtige Logik: Ein einzelnes UDM-Ereignis wird mit mehreren Entity Graph-Platzhaltern verknüpft, die jeweils nach einem bestimmten threat_feed_name (z. B. Google Cloud Threat Intelligence-Feeds) filtern.

Beispiel: Erkennung von Tor-Ausgangsknoten und Remote-Zugriffstools

Regel

Die folgende Regel kennzeichnet Netzwerkverkehr, der anscheinend mit Remote Monitoring and Management (RMM) zusammenhängt und von einem Tor-Ausgangsknoten stammt oder eine Verbindung zu einem Tor-Ausgangsknoten herstellt. Dabei wird ein NETWORK_CONNECTION-Ereignis sowohl mit einem IP-Feed (Tor-Ausgangsknoten) als auch mit einem Datei-Hash-Feed (Remote-Access-Tools) verknüpft.

rule tor_and_remote_access_tool_match {
  meta:
    author = "Google Security Operations"
    description = "Matches network connections involving both a Tor exit node and Remote Access Tool malware hashes."
    severity = "CRITICAL"

  events:
    // Filter for network connection events, often recorded by EDR agents
    $e.metadata.event_type = "NETWORK_CONNECTION"
    $target_ip = $e.target.ip
    $process_hash = $e.principal.process.file.sha256

    // IP Feed Join: Tor Exit Nodes
    $gcti_ip.graph.metadata.entity_type = "IP_ADDRESS"
    $gcti_ip.graph.metadata.product_name = "GCTI Feed"
    $gcti_ip.graph.metadata.feed = "Tor Exit Nodes"
    $gcti_ip.graph.entity.ip = $target_ip

    // Hash Feed Join: Remote Access Tools
    $gcti_hash.graph.metadata.entity_type = "FILE"
    $gcti_hash.graph.metadata.product_name = "GCTI Feed"
    $gcti_hash.graph.metadata.feed = "Remote Access Tools"
    $gcti_hash.graph.entity.file.sha256 = $process_hash

  match:
    $target_ip over 10m

  outcome:
    $risk_score = 95
    $ip_feed = array_distinct($gcti_ip.graph.metadata.feed)
    $hash_feed = array_distinct($gcti_hash.graph.metadata.feed)

  condition:
    $e and $gcti_ip and $gcti_hash
}

Zusammengesetzte Erkennungen

Zusammengesetzte Erkennungen verbessern die Bedrohungserkennung durch die Verwendung zusammengesetzter Regeln. Diese zusammengesetzten Regeln verwenden Erkennungen aus anderen Regeln als Eingabe. So lassen sich komplexe Bedrohungen erkennen, die mit einzelnen Regeln möglicherweise nicht erkannt werden. Weitere Informationen finden Sie unter Übersicht über zusammengesetzte Erkennungen.

Thema Beispiele
Filterung mit hohem Risiko Erkennung von Nutzern mit Administratorzugriff
Aggregation und Schwellenwerte Risikoaggregation
Taktikaggregation Aggregation von MITRE-Taktiken
Sequenzielle zusammengesetzte Erkennungen Brute-Force-Angriff gefolgt von erfolgreicher Anmeldung
Kontextsensitive Erkennungen Anreicherung mit Threat Intelligence
Erkennung von gemeinsam auftretenden Ereignissen Gleichzeitiges Auftreten von Rechteausweitung und Exfiltration

Filterung von hohem Risiko

Anwendungsfall: Filtern Sie vorhandene Erkennungen nach Attributen mit hohem Risiko, z. B. Aktivitäten mit Administratorkonten.

Schlüssellogik: Arbeitet mit Ergebnissen oder Metadatenfeldern in vorhandenen Ergebnissen.

Zusammengesetzte Erkennungen mit hohem Risiko sind die einfachste Form einer zusammengesetzten Erkennung, die auf Feldern innerhalb von Erkennungsergebnissen basiert, z. B. auf Ergebnisvariablen oder Regelmetadaten. Sie helfen dabei, Erkennungen nach Bedingungen zu filtern, die auf ein höheres Risiko hinweisen können, z. B. ein Administrator oder eine Produktionsumgebung.

Beispiel: Erkennung von Nutzern mit Administratorzugriff

Regel

Mit der folgenden zusammengesetzten Regel wird nach vorhandenen Erkennungen gesucht, bei denen der Akteur als Nutzer mit Administratorzugriff identifiziert wird, und es wird eine standardisierte Risikobewertung angewendet.

rule composite_admin_detection {
meta:
  rule_name = "Detection with Admin User"
  author = "Google Cloud Security"
  description = "Composite rule that looks for any detections where the actor is an admin user"
  severity = "Medium"

events:
  $rule_name = $d.detection.detection.rule_name
  $principal_user = $d.detection.detection.variables["principal_users"]
  $principal_user = /admin|root/ nocase

match:
  $principal_user over 1h
outcome:
  $risk_score = 75
  $upstream_rules = array_distinct($rule_name)

condition:
  $d
}

Suchen

Bei der folgenden statistischen Suche werden Aktivitäten für Konten mit hohen Berechtigungen ermittelt und zusammengefasst. Sie ist so konzipiert, dass alle eindeutigen Regelnamen gefunden werden, die Erkennungen mit „admin“- oder „root“-Nutzern ausgelöst haben.

In dieser spezifischen Abfrage wird das Zeitfenster entfernt, um eine einzelne statistische Analyse für alle Erkennungen innerhalb des ausgewählten Zeitraums durchzuführen. Da es sich außerdem um eine nicht aggregierte Suche handelt, die sich auf vorhandene Erkennungsdaten konzentriert, sind die Abschnitte „Ereignisse“, „Ereignisvariablen“ und „Bedingung“ nicht erforderlich.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase

match:
  $principal_user

outcome:
  $upstream_rules = array_distinct($rule_name)

Dashboard

Mit dieser Dashboard-Abfrage können Sie visualisieren, welche spezifischen Regeln am häufigsten Aktivitäten im Zusammenhang mit Administratoren erkennen. Sie soll einen allgemeinen Überblick über die Erkennungstrends in Ihrer Umgebung bieten.

Beachten Sie die Änderung der Variablen match und der Aggregation outcome im Vergleich zu den vorherigen Beispielen. In dieser Abfrage werden die Ergebnisse nach Regelname gruppiert und die Anzahl der für jede Regel erkannten Administratornutzer wird berechnet.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase

match:
  $rule_name

outcome:
  $admin_detections = count($principal_user)

Aggregation und Schwellenwerte

Anwendungsfall: Nutzer oder Hosts identifizieren, die im Laufe der Zeit eine große Anzahl von Warnungen generieren oder erhebliche Risikobewertungen ansammeln.

Schlüssel-Logik: Hier werden sum() oder count_distinct() verwendet, um aggregierte Erkennungsdaten zu analysieren.

Mit zusammengesetzten Aggregationserkennungsregeln können Sie Erkennungsergebnisse anhand gemeinsamer Attribute wie Hostname oder Nutzername gruppieren und die aggregierten Daten analysieren. Im Folgenden sind einige gängige Anwendungsfälle aufgeführt:

  • Nutzer identifizieren, die eine große Anzahl von Sicherheitswarnungen oder ein hohes aggregiertes Risiko verursachen.
  • Erkennen von Hosts mit ungewöhnlichen Aktivitätsmustern durch Aggregieren zugehöriger Erkennungen.

Beispiel: Risikoaggregation

Regel

Bei dieser Regel wird die Risikobewertung eines einzelnen Nutzers über einen Zeitraum von 48 Stunden aggregiert. Es werden Nutzer identifiziert, deren kumulatives Risiko über mehrere Erkennungen hinweg einen bestimmten Schwellenwert überschreitet.

In dieser aktualisierten Logik wird detection.detection.outcomes durch Variablen für Kartenfelder ersetzt, in denen sowohl match- als auch outcome-Variablen gespeichert werden. Außerdem wird die Ergebnisvariable $principal_users entfernt, da jede Erkennung genau einen Wert für die Abgleichsvariable enthält, der bereits erfasst wird.

rule composite_risk_aggregation {
meta:
  rule_name = "Risk Aggregation Composite"
  author = "Google Cloud Security"
  description = "Composite detection that aggregates risk of a user over 48 hours"
  severity = "High"

events:
  $rule_name = $d.detection.detection.rule_name
  $principal_user = $d.detection.detection.outcomes["principal_users"]
  $risk = $d.detection.detection.risk_score

match:
  $principal_user over 48h

outcome:
  $risk_score = 90
  $cumulative_risk = sum($risk)
  $upstream_rules = array_distinct($rule_name)

condition:
  $d and $cumulative_risk > 500
}

Suchen

Bei dieser statistischen Suche werden Erkennungsdaten zusammengefasst, um das Gesamtrisiko eines Nutzers über einen Zeitraum von 48 Stunden zu berechnen. Es wird eine Zeile pro Hauptnutzer für jedes Zeitfenster ausgegeben. So erhalten Sie einen allgemeinen Überblick über das Kontorisiko für verschiedene Erkennungstypen.

In dieser Variante sind keine Ereignisvariablen erforderlich. Die Regel-Engine filtert automatisch Erkennungen ohne Hauptnutzer heraus. Für diese Suche ist jedoch ein expliziter Filter ($principal_user != "") erforderlich, damit die Ergebnisse nur ausgefüllte Daten enthalten. Standardmäßig gibt die Abfrage nur dann Ergebnisse zurück, wenn für einen bestimmten Nutzer mindestens eine Erkennung vorliegt.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score

match:
  $principal_user over 48h

outcome:
  $risk_score = 90
  $cumulative_risk = sum($risk)
  $upstream_rules = array_distinct($rule_name)

condition:
  $cumulative_risk > 500

Dashboard

Diese Variante wurde speziell für Dashboards entwickelt, um das Nutzerrisiko und die Erkennungsaktivität im Zeitverlauf darzustellen. Es aggregiert Daten in diskrete Buckets und eignet sich daher ideal für die Visualisierung von Trends, z. B. der Anzahl der ausgelösten eindeutigen Regeln oder der Gesamtzahl der Erkennungen pro Nutzer.

In dieser Abfrage wird das Fenster von einem gleitenden (Hop-)Fenster zu einem rollierenden Fenster (by 48h) gewechselt. So werden Datenpunkte nicht überlappenden Zeitsegmenten zugeordnet, was eine übersichtlichere Visualisierung für Zeitreihendiagramme ermöglicht. Wie bei anderen nicht aggregierten Suchanfragen sind keine Ereignisvariablen erforderlich. Der Abschnitt outcome wird erweitert und enthält separate Zählungen für sowohl Regelnamen als auch Erkennungs-IDs.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score

match:
  $principal_user by 48h

outcome:
  $cumulative_risk = sum($risk)
  $rule_count = count_distinct($rule_name)
  $detection_count = count_distinct(detection.id)

condition:
  $cumulative_risk > 500

Taktikaggregation

Anwendungsfall: Identifizieren Sie Nutzer, deren Aktivitäten Erkennungen für mehrere unterschiedliche MITRE ATT&CK-Taktiken ausgelöst haben. Dies deutet auf einen fortschreitenden Angriffszyklus hin, z. B. von Erster Zugriff zu Exfiltration.

Wichtige Logik: Wird mit count_distinct($tactic) ausgelöst, wenn ein Nutzer innerhalb von 48 Stunden einen bestimmten Schwellenwert für verschiedene Taktiken überschreitet.

Beispiel: MITRE-Taktikaggregation

Regel

rule composite_tactic_aggregation {
meta:
  rule_name = "MITRE Tactic Aggregation Composite"
  author = "Google Cloud Security"
  description = "Composite detection that detects if a user has triggered detections over multiple mitre tactics."
  severity = "Medium"

events:
  $principal_user = $d.detection.detection.outcomes["principal_users"]
  $tactic = $d.detection.detection.outcomes["mitre_tactic"]
  $rule_name = $d.detection.detection.rule_name

match:
  $principal_user over 48h

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $upstream_rules = array_distinct($rule_name)

condition:
  $d and $mitre_tactics_count > 1 }

Suchen

Das folgende Beispiel zeigt eine Suchvariante für Sicherheitsentwickler, die vorhandene Erkennungen in Beziehung setzen und eine dynamische Risikogewichtung anwenden müssen. Mit dieser Abfragelogik werden MITRE ATT&CK-Taktiken und Nutzerinformationen aus der Datenquelle detection extrahiert, die Aktivitäten werden nach dem Hauptnutzer gruppiert und es wird ein benutzerdefinierter Risikowert basierend auf der Vielfalt der beobachteten Taktiken berechnet.

detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name

match:
  $principal_user

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $upstream_rules = array_distinct($rule_name)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $risk_score = if($calculated_risk > 100, 100,   $calculated_risk)

Dashboard

Das folgende Beispiel zeigt eine Dashboards-Variante derselben Erkennungsanalyselogik. Wenn diese Abfrage in Google SecOps-Dashboards verwendet wird, können Entwickler Nutzer mit hohem Risiko visualisieren, indem sie Erkennungsergebnisse aus verschiedenen Regeln korrelieren. Die Logik extrahiert den Prinzipal und die MITRE-Taktiken, aggregiert die Ergebnisse und wendet eine begrenzte Risikobewertung an, um die Ermittlungsbemühungen direkt in einem Dashboard-Widget zu priorisieren.

detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name

match:
  $principal_user

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $upstream_rules = array_distinct($rule_name)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $risk_score = if($calculated_risk > 100, 100,   $calculated_risk)
  ```

Sequenzielle zusammengesetzte Erkennungen

Anwendungsfall: Kritische Angriffsmuster identifizieren, bei denen die Reihenfolge der Vorgänge entscheidend ist, z. B. Erkennung einer erfolgreichen Kontoanmeldung, die erst nach einer Reihe von Warnungen zu Brute-Force-Angriffen von derselben IP-Adresse erfolgt.

Schlüssellogik: Korreliert eine vorherige Erkennung mit einem nachfolgenden rohen UDM-Ereignis, indem sie über eine gemeinsame Variable (z. B. $bruteforce_ip) verknüpft werden und ein Zeitstempelvergleich verwendet wird, um sicherzustellen, dass die Ereignisse in der richtigen Reihenfolge aufgetreten sind.

Bei sequenziellen zusammengesetzten Erkennungen werden Muster von zusammenhängenden Ereignissen identifiziert, bei denen die Reihenfolge der Erkennungen wichtig ist, z. B. die Erkennung eines Brute-Force-Anmeldeversuchs, gefolgt von einer erfolgreichen Anmeldung. Diese Muster können mehrere Basis-Erkennungen oder eine Kombination aus Basis-Erkennungen und Ereignissen umfassen.

Beispiel: Brute-Force-Angriff, gefolgt von einer erfolgreichen Anmeldung

Regel

Mit der folgenden zusammengesetzten Regel werden Muster von zusammenhängenden Ereignissen identifiziert, bei denen die Reihenfolge wichtig ist. Es wird speziell nach einer Brute-Force-Erkennung in Google Workspace gesucht, gefolgt von einem erfolgreichen Anmeldeereignis von derselben Quell-IP-Adresse innerhalb eines 24-Stunden-Fensters.

rule composite_bruteforce_login {
meta:
  rule_name = "Bruteforce Login Composite"
  author = "Google Cloud Security"
  description = "Detects when an IP address associated with a Workspace brute force attempt successfully logs in"
  severity = "High"

events:
  $bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
  $bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]

  $login_event.metadata.product_name = "login"
  $login_event.metadata.product_event_type = "login_success"
  $login_event.metadata.vendor_name = "Google Workspace"
  $login_ip = $login_event.principal.ip

  // Ensure the brute force detection and successful login occurred from the same IP
  $login_ip = $bruteforce_ip

  $target_account = $login_event.target.user.email_addresses

  // Ensure the brute force detection occurred before the successful login
  $bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds

match:
  $bruteforce_ip over 24h

outcome:
  $risk_score = 90
  $principal_users = array_distinct($target_account)

condition:
  $bruteforce_detection and $login_event
}

Suchen

$bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
$bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]

$login_event.metadata.product_name = "login"
$login_event.metadata.product_event_type = "login_success"
$login_event.metadata.vendor_name = "Google Workspace"
$login_ip = $login_event.principal.ip

// Ensure the brute force detection and successful login occurred from the same IP
$login_ip = $bruteforce_ip

$target_account = $login_event.target.user.email_addresses

// Ensure the brute force detection occurred before the successful login
$bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds

match:
  $bruteforce_ip over 24h

outcome:
  $principal_users = array_distinct($target_account)

condition:
  $bruteforce_detection and $login_event

Dashboard

Dashboards konzentrieren sich auf die Visualisierung von Rohereignisdaten, während die Logik für zusammengesetzte Erkennungen vorhandene Erkennungswarnungen mit nachfolgenden Ereignissen korreliert. Diese mehrschichtige Analyse ist für die Erkennungs-Engine und nicht für Echtzeit-Dashboard-Widgets optimiert.

Kontextsensitive Erkennungen

Anwendungsfall: Vorhandene Erkennungen mit externer Threat Intelligence anreichern, um zu prüfen, ob eine Benachrichtigung bekannte schädliche Entitäten enthält. So kann beispielsweise geprüft werden, ob eine IP-Adresse, die in einer Sicherheitserkennung gekennzeichnet ist, auch in einem globalen Threat-Feed für TOR-Exit-Knoten aufgeführt ist.

Schlüssel-Logik: Hier werden zusammengesetzte Regeln verwendet,um Erkennungsergebnisse mit GLOBAL_CONTEXT-Graphendaten (z. B. Google Cloud Threat Intelligence-Feeds) zusammenzuführen. Dazu wird ein gemeinsames Attribut wie eine IP-Adresse abgeglichen.

Kontextsensitive zusammengesetzte Erkennungen reichern Erkennungen mit zusätzlichem Kontext an, z. B. mit IP-Adressen, die in Bedrohungsfeeds gefunden wurden.

Beispiel: Threat Intelligence-Anreicherung

Regel

Mit der folgenden zusammengesetzten Regel wird Ihren vorhandenen Erkennungen automatisch zusätzlicher Kontext aus dem TOR-Intel-Feed hinzugefügt. Dabei wird eine IP-Adresse, die in einer früheren Erkennung gefunden wurde, mit dem TOR-Ausgangsknoten-Feed korreliert, um den Schweregrad und die Risikobewertung des Ergebnisses zu erhöhen.

rule composite_tor_enrichment {
meta:
  rule_name = "Detection with IP from TOR Feed"
  author = "Google Cloud Security"
  description = "Adds additional context from the TOR intel feed to detections"
  severity = "High"

events:
  $rule_name = $d.detection.detection.rule_name

  $gcti.graph.metadata.entity_type = "IP_ADDRESS"
  $gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
  $gcti.graph.metadata.source_type = "GLOBAL_CONTEXT"
  $gcti.graph.metadata.product_name = "GCTI Feed"
  $gcti.graph.metadata.feed = "Tor Exit Nodes"

  $detection_ip = $d.detection.detection.variables["principal_ips"]
  $detection_ip = $gcti.graph.entity.ip

match:
  $detection_ip, $rule_name over 1h

outcome:
  $risk_score = 80

condition:
  $d and $gcti
}

Suchen

$rule_name = $d.detection.detection.rule_name

$gcti.graph.metadata.entity_type = "IP_ADDRESS"
$gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
$gcti.graph.metadata.source_type = "GLOBAL_CONTEXT"
$gcti.graph.metadata.product_name = "GCTI Feed"
$gcti.graph.metadata.feed = "Tor Exit Nodes"

$detection_ip = $d.detection.detection.variables["principal_ips"]
$detection_ip = $gcti.graph.entity.ip

match:
  $detection_ip, $rule_name over 1h

condition:
  $d and $gcti

Dashboard

Erkennungen von gleichzeitigem Auftreten

Anwendungsfall: Erkennen einer Kombination verwandter Taktiken, die von derselben Entität innerhalb eines bestimmten Zeitraums ausgelöst wurden, z. B. Identifizieren eines Nutzers, der innerhalb von 48 Stunden sowohl eine Rechteausweitung als auch eine Daten-Exfiltration ausgelöst hat.

Schlüssel-Logik: Hier wird eine Form der Aggregation verwendet, um mehrere unterschiedliche Erkennungstypen zu korrelieren. Dazu werden sie im Abschnitt match über eine gemeinsame Entitätsvariable (z. B. $pe_user) verknüpft.

Zusammengesetzte Co-occurrence-Erkennungen sind eine Form der Aggregation, mit der eine Kombination aus zusammengehörigen Ereignissen erkannt werden kann, z. B. eine Kombination aus Erkennungen von Rechteausweitung und Datenexfiltration, die von einem Nutzer ausgelöst werden.

Beispiel: Gleichzeitiges Auftreten von Rechteausweitung und Exfiltration

Regel

Mit der folgenden zusammengesetzten Regel wird innerhalb eines Zeitraums von 48 Stunden nach einer bestimmten Sequenz oder Kombination von erkannten Ereignissen gesucht, die mit demselben Nutzer verknüpft sind: Rechteausweitung gefolgt von Exfiltration.

rule composite_privesc_exfil_sequential {
meta:
  rule_name = "Privilege Escalation and Exfiltration Composite"
  author = "Google Cloud Security"
  description = "Looks for a detection sequence of privilege escalation followed by exfiltration."
  severity = "High"

events:
  $privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
  $exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"

  $privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
  $exfil_user = $exfiltration.detection.detection.variables["principal_users"]

  $privesc_user = $exfil_user

  $privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds

match:
  $privesc_user over 48h

outcome:
  $risk_score = 75
  $privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
  $exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)

condition:
  $privilege_escalation and $exfiltration
}

Suchen

$privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
$exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"

$privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
$exfil_user = $exfiltration.detection.detection.variables["principal_users"]

$privesc_user = $exfil_user

$privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds

match:
  $privesc_user over 48h

outcome:
  $privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
  $exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)

condition:
  $privilege_escalation and $exfiltration

Dashboard

Ergebnis- und Variablenverwaltung

In diesem Abschnitt finden Sie Beispiele für die Berechnung des Risikos und die Normalisierung von Daten für die nachgelagerte Nutzung.

Thema Beispiele
Bedingungen für Ergebnisse Nach berechneter Risikobewertung filtern
Abfrage für ein einzelnes Ereignis mit Ergebnis Tagging von Schweregraden zu einem bestimmten Zeitpunkt
Netzwerkbasierte Risikobewertung Netzwerkbasierte Regel zur Risikobewertung
Logik für mehrere Ereignisse umgestalten (vor der Umgestaltung) Ergebnis-Refactoring (vor dem Refactoring)
Multi-Event-Logik umgestalten (nach der Umgestaltung) Ergebnis-Refaktorierung (nach der Refaktorierung)
Zuweisung von Funktionen zu Platzhaltern

Abfragen mit dem Abschnitt „outcome“

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

Hier finden Sie weitere Informationen:

Ergebnisbedingungen

Anwendungsfall: Erkennungen anhand von berechneten Risikobewertungen filtern, um Rauschen zu reduzieren und dafür zu sorgen, dass nur Ereignisse mit hoher Wahrscheinlichkeit oder hohem Schweregrad Benachrichtigungen auslösen. Das ist nützlich, um Aktivitäten mit geringem Risiko zu unterdrücken, die einen bestimmten geschäftlichen Schwellenwert nicht erreichen.

Schlüssellogik: Definiert Variablen im outcome-Abschnitt mithilfe von bedingter Mathematik (z. B. Hinzufügen von Risiko basierend auf Dateigröße oder Tageszeit) und verweist dann im condition-Abschnitt auf diese Variablen, um die Erkennung zu steuern.

Beispiel: Nach berechneter Risikobewertung filtern

Regel

Im condition-Abschnitt können Sie outcome-Variablen verwenden, die im outcome-Abschnitt definiert wurden. Im folgenden Beispiel wird gezeigt, wie Sie nach Risikobewertungen filtern, um das Rauschen in Erkennungen mithilfe von Ergebnisbedingungen 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
}

Suchen

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

// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(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

Dashboard

Mit dieser Abfrage wird die Ergebnisvariable $hostname hinzugefügt, um zu visualisieren, welche Hosts mit den einzelnen Risikobewertungen verknüpft sind.

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

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

outcome:
  $host = $hostname
  $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

Einzelereignisabfrage mit Ergebnis

Anwendungsfall: Momentaufnahmen mit sofortigem Kontext anreichern, z. B. Schweregrad-Tags basierend auf Nutzerlisten oder Dateiattributen zuweisen, ohne dass ein Zeitfenster oder eine Ereigniskorrelation erforderlich ist.

Schlüssellogik: Verwendet den outcome-Abschnitt in einer Regel, in der kein match-Abschnitt vorhanden ist. So können Sie Metadaten extrahieren und bedingte Logik ausführen (z. B. einen Nutzer mit einer Referenzliste abgleichen) für jedes einzelne Ereignis, das die Kriterien erfüllt.

Beispiel: Schweregrad-Tagging zu einem bestimmten Zeitpunkt

Regel

Im folgenden Beispiel wird gezeigt, wie Sie den Abschnitt outcome in einer Regel für ein einzelnes Ereignis verwenden, um Variablen für die nachgelagerte Nutzung festzulegen, z. B. einen Schweregrad basierend auf dem jeweiligen Nutzer und der Dateigröße, die an einem Dateikopierereignis beteiligt sind.

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.user.userid in %admin_users, "SEVERE", "MODERATE")
  $severity_tag = if($file_size > 1024, $admin_severity, "LOW")

condition:
  $u
}

Suchen

Im folgenden Beispiel werden Ereignisse zur Dateierstellung identifiziert und im Abschnitt outcome werden jedem Ergebnis dynamisch Schweregrade zugewiesen. Im Gegensatz zu Regeln für mehrere Ereignisse sind für diese nicht aggregierte Suche keine Ereignisvariablen oder ein match-Abschnitt erforderlich. Stattdessen wird jedes Protokoll einzeln verarbeitet, um 1 row per event auszugeben, angereichert mit benutzerdefinierter Logik basierend auf Dateigröße und Nutzerberechtigungen.

metadata.event_type = "FILE_CREATION"
principal.file.size = $file_size
principal.hostname = $hostname

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

Dashboard

Eine Dashboard-Variante ist für dieses Beispiel nicht relevant, da die primäre Absicht darin besteht, einzelne Ereignisse zu taggen und anzureichern. In einem Dashboard könnten diese Ereignisse zwar zusammengefasst werden (z. B. durch Berechnung der Gesamtzahl der Ereignisse pro Schweregrad-Tag), aber dadurch würden die detaillierten Informationen auf Zeilenebene, die mit dieser nicht aggregierten Suche gefunden werden sollen, verborgen bleiben.

Netzwerkbasierte Risikobewertung

Anwendungsfall: Identifizieren Sie riskante Datenübermittlungen, indem Sie das kumulative Volumen des Netzwerkverkehrs für eine Gruppe von Ereignissen berechnen. So können Sie Bedrohungen identifizieren, bei denen der Gesamtdatengrenzwert ein bestimmtes Limit überschreitet (z. B. 1024 Byte), und gleichzeitig die Schwere der Sicherheitslücke der beteiligten Assets berücksichtigen.

Wichtige Logik: Hier wird die Aggregatfunktion sum() im Abschnitt outcome verwendet, um sent_bytes und received_bytes für alle Ereignisse in einem match-Zeitraum zu kombinieren. Bei Regeln wird in der Abfrage eine IF-Anweisung verwendet, um eine höhere Risikobewertung anzuwenden, wenn die Summe einen definierten Grenzwert überschreitet.

Beispiel: Netzwerkbasierte Regel zur Risikobewertung

Regel

Im folgenden Beispiel wird gezeigt, wie Sie den Abschnitt outcome verwenden, um eine dynamische Risikobewertung basierend auf der Netzwerkaktivität zu berechnen. Durch die Summierung der insgesamt übertragenen Byte in einer Ereignisgruppe wendet die Regel eine höhere Priorität auf Übereinstimmungen an, die einen bestimmten Datenschwellenwert (1024 Byte) überschreiten. Gleichzeitig wird der Schweregrad der Sicherheitslücke des betroffenen Assets berücksichtigt.

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")
}

Suchen

Im folgenden Beispiel wird eine Suchvariante veranschaulicht, die UDM-Netzwerkereignisse mit dem Asset-Kontext aus dem Entity Context Graph (ECG) in Beziehung setzt. Dabei wird ein 5-minütiges match-Fenster verwendet, um den Netzwerkverkehr nach Hostnamen zu aggregieren. Außerdem wird eine Risikobewertung basierend auf dem Datenvolumen und dem Schweregrad der Sicherheitslücke berechnet und ein bedingter Filter angewendet, um bestimmte Asset-IDs aus dem endgültigen Ergebnissatz auszuschließen.

$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")

Dashboard

Das folgende Beispiel zeigt eine Dashboard-Variante, in der die Netzwerktelemetrie in Echtzeit mit Daten zur Asset-Sicherheitslücke angereichert wird. Durch den Abgleich von Hostnamen in einem gleitenden 5‑Minuten-Zeitfenster können Entwickler mit dieser Abfrage Dashboard-Widgets erstellen, die das Risikoniveau von Assets visualisieren. Die Logik passt eine Risikobewertung dynamisch an den Netzwerkdurchsatz und die Sicherheitslücke mit dem höchsten Schweregrad an, die auf dem Asset gefunden wurde. So erhalten Sie eine priorisierte Ansicht potenziell kompromittierter Systeme.

$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 mehrere Ereignisse outcome refaktorieren (vor der Refaktorierung)

Anwendungsfall: Systemleistung verbessern und Verarbeitungslatenz verringern, indem Regeln für mehrere Ereignisse in Regeln für einzelne Ereignisse umgewandelt werden. Das ist ideal für Regeln, die ursprünglich nur mit einem Abgleichsabschnitt konzipiert wurden, um den Ergebnisabschnitt zu aktivieren, aber keine Korrelation zwischen mehreren unterschiedlichen Ereignissen erfordern.

Wichtige Logik: Der Abschnitt match und alle Aggregatfunktionen (z. B. max(), sum() oder count()) werden aus dem Abschnitt outcome entfernt. Dadurch werden Ereignisse nicht mehr im Laufe der Zeit gruppiert, sondern einzeln ausgewertet, sobald sie eintreffen. match-Abschnitt) und Regeln für mehrere Ereignisse (Regeln mit einem match-Abschnitt).

Sie können den Abschnitt outcome sowohl für Regeln mit einem einzelnen Ereignis (Regeln ohne -Abschnitt) als auch für Regeln mit mehreren Ereignissen verwenden. Wenn Sie zuvor eine Regel mit mehreren Ereignissen entworfen haben, nur um den Abschnitt „outcome“ verwenden zu können, können Sie diese Regeln optional refaktorieren, indem Sie den Abschnitt match löschen, um die Leistung zu verbessern. Da Ihre Regel keinen match-Abschnitt mehr enthält, in dem eine Gruppierung angewendet wird, erhalten Sie möglicherweise mehr Erkennungen.

Beispiel: Ergebnis-Refactoring (vor dem Refactoring)

Regel

Im folgenden Beispiel sehen Sie eine Regel für mehrere Ereignisse, die nur eine Ereignisvariable verwendet. Da ein match-Abschnitt verwendet wird, muss die Rules Engine Ereignisse in einem 5-Minuten-Zeitraum gruppieren, bevor das Ergebnis berechnet wird. Das verbraucht mehr Ressourcen als die Auswertung eines einzelnen Ereignisses.

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
}

Suchen

Entsprechende Statistikabfrage

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

match:
  $hostname over 5m

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

condition:
  $u

Dashboard

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

match:
  $hostname over 5m

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

condition:
  $u

outcome-Regel für mehrere Ereignisse refaktorieren (nach der Refaktorierung)

Anwendungsfall: Optimierung einer Abfrage abschließen, um die Verarbeitungsgeschwindigkeit zu verbessern. Da die Gruppierungsanforderung entfernt wurde, wird durch die Abfrage jetzt sofort eine Erkennung ausgelöst, wenn ein einzelnes übereinstimmendes Ereignis eintrifft. Das ist für die Rules Engine deutlich effizienter.

Schlüssel-Logik: Löscht den Abschnitt match und entfernt die Funktion aggregate (z. B. max()) aus der Zuweisung der Variablen outcome. Die Logik in der IF-Anweisung bleibt unverändert, wird aber jetzt auf ein einzelnes Ereignis statt auf eine Gruppe angewendet.

Sie können die Abfrage refaktorieren, indem Sie den Abschnitt match löschen. Hinweis: Sie müssen das Aggregat auch im Abschnitt outcome entfernen, da die Abfrage jetzt ein Einzelereignis ist. Weitere Informationen zu Aggregationen finden Sie unter Ergebnisaggregationen.

Beispiel: Ergebnis-Refaktorierung

Regel

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
}

Suchen

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

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

Dashboard

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

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

Zuweisung von Funktion zu Platzhalter

Anwendungsfall: Daten normalisieren (z. B. E-Mail-Domains standardisieren), um zu prüfen, ob die Gruppierung im Abschnitt „Übereinstimmung“ korrekt ist.

Schlüssellogik: Weist das Ergebnis von re.capture() oder strings.concat() einer Platzhaltervariablen zu.

Beispiel: Zuweisung von Funktion zu Platzhaltervariable

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.

Regel

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.to , "(.*)@")

  // Use function-placeholder assignment to normalize an email:
  // address@-> address@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 or $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
}

Suchen

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(network.email.from , "(.*)@")

// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
  re.capture(network.email.to , "(.*)@"),
  "@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(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 or $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

Dashboard

Im folgenden Beispiel sehen Sie eine Dashboard-Variante, die für die Visualisierung von Zeitreihen optimiert ist. Durch die Verwendung eines rollierenden Fensters von einem Tag anstelle einer Granularität auf Minutenebene werden mit dieser Abfrage stabile, nicht überlappende Datenpunkte erzeugt, die sich ideal für die Darstellung von Risikobewertungen über einen längeren Zeitraum eignen. Die Logik normalisiert E-Mail-Entitäten und wendet höhere Risikogewichtungen auf Wochenendtransaktionen an. So entsteht ein klarer täglicher Trend verdächtiger E-Mail-Aktivitäten für die langfristige Überwachung.

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(network.email.from , "(.*)@")

// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
re.capture(network.email.to , "(.*)@"),
"@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(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 or $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

Optimierung und Filterung

Eine effektive Regeloptimierung hängt von einer präzisen Datenfilterung ab, damit die Erkennungs-Engine nur aussagekräftige Informationen verarbeitet. Wenn Sie „rauschende“ oder unvollständige Daten ausschließen, können Sie die Leistung von Regeln erheblich verbessern und dafür sorgen, dass generierte Benachrichtigungen umsetzbar sind.

Thema Beispiele
Ausschluss von Nullwerten Expliziter und impliziter Ausschluss von Nullwerten

Ausschluss von Nullwerten

Anwendungsfall: Sorgen Sie für die Genauigkeit der Regeln und reduzieren Sie falsch positive Ergebnisse, indem Sie leere Strings, Nullwerte oder generische Platzhalterkonten (z. B. „Gast“) explizit herausfiltern, die keine verwertbaren Sicherheitsdaten liefern.

Wichtige Logik: Nutzt die implizite Filterung von Nullwerten für Variablen, die im Abschnitt match verwendet werden, durch die Regel-Engine, während für andere Ereignisfelder explizite Ungleichheitsoperatoren (!= "") verwendet werden, um sicherzustellen, dass nur ausgefüllte Daten eine Erkennung auslösen.

Die Rules Engine filtert implizit die Nullwerte für alle Platzhalter heraus, die im Abschnitt match verwendet werden. Verwenden Sie die Option allow_zero_values, um die Funktion zu deaktivieren. Bei anderen referenzierten Ereignisfeldern werden Nullwerte jedoch nicht ausgeschlossen, sofern Sie solche Bedingungen nicht explizit angeben. Weitere Informationen finden Sie unter Nullwerte im Abschnitt „Übereinstimmung“.

Beispiel: Expliziter und impliziter Ausschluss von Nullwerten

Regel

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
}

Suchen

Sie müssen explizit angeben, dass hostname kein leerer String sein darf, da es keinen impliziten Nullwertfilter für Platzhalter im Abschnitt match gibt.

$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 and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""

match:
  $hostname over 1h

Dashboard

Sie müssen explizit angeben, dass hostname kein leerer String sein darf, da es im Abschnitt match keinen impliziten Nullwertfilter für Platzhalter gibt.

$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 and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""

match:
  $hostname over 1h

Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten