Übersicht über die Sprache YARA-L 2.0
YARA-L 2.0 ist eine Computersprache, mit der Regeln für die Suche in Ihren Unternehmensprotokolldaten erstellt werden, wenn diese in Ihre Google Security Operations-Instanz aufgenommen werden. Die YARA-L-Syntax leitet sich von der von VirusTotal entwickelten YARA-Sprache ab. Die Sprache arbeitet mit der Google Security Operations Detection Engine zusammen und ermöglicht Ihnen die Suche nach Bedrohungen und anderen Ereignissen in großen Datenmengen.
Hier finden Sie weitere Informationen:
YARA-L 2.0-Beispielregeln
Die folgenden Beispiele zeigen in YARA-L 2.0 geschriebene Regeln. Jede davon zeigt, wie Ereignisse innerhalb der Regelsprache korreliert werden.
Regeln und Abstimmung
Die folgende Regel prüft bestimmte Muster in Ereignisdaten und erstellt eine Erkennung, wenn die Muster erkannt werden. Diese Regel enthält die Variable $e1
zum Verfolgen des Ereignistyps und das UDM-Feld metadata.event_type
. Die Regel prüft, ob ein regulärer Ausdruck in bestimmten Fällen mit e1
übereinstimmt. Wenn das Ereignis $e1
eintritt, wird eine Erkennung erstellt.
Die Regel enthält eine not
-Bedingung, 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
}
Anmeldungen aus verschiedenen Städten
Mit der folgenden Regel wird nach Nutzern gesucht, die sich in weniger als fünf Minuten in zwei oder mehr Städten in Ihrem Unternehmen angemeldet haben:
rule DifferentCityLogin {
meta:
events:
$udm.metadata.event_type = "USER_LOGIN"
$udm.principal.user.userid = $user
$udm.principal.location.city = $city
match:
$user over 5m
condition:
$udm and #city > 1
}
Übereinstimmungsvariable: $user
Ereignisvariable:$udm
Platzhaltervariable: $city
und $user
Im Folgenden wird die Funktionsweise dieser Regel beschrieben:
- Gruppiert Ereignisse mit dem Nutzernamen (
$user
) und gibt ihn zurück ($user
), wenn eine Übereinstimmung gefunden wird. - Die Zeitspanne beträgt 5 Minuten. Das bedeutet, dass nur Ereignisse, die weniger als 5 Minuten auseinanderliegen, korrelieren.
- Es wird nach einer Ereignisgruppe (
$udm
) mit dem Ereignistyp USER_LOGIN gesucht. - Für diese Ereignisgruppe ruft die Regel die User-ID als
$user
und den Anmeldeort$city.
auf. - Gibt eine Übereinstimmung zurück, wenn die eindeutige Anzahl von
city
-Werten (gekennzeichnet durch#city
) innerhalb des 5-Minuten-Zeitraums größer als 1 in der Ereignisgruppe ($udm
) ist.
Schnelles Erstellen und Löschen von Nutzern
Mit der folgenden Regel wird nach Nutzern gesucht, die erstellt und innerhalb von vier Stunden gelöscht wurden:
rule UserCreationThenDeletion {
meta:
events:
$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"
$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"
$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds
match:
$user over 4h
condition:
$create and $delete
}
Ereignisvariablen:$create
und $delete
Übereinstimmungsvariable: $user
Platzhaltervariable: –
Im Folgenden wird die Funktionsweise dieser Regel beschrieben:
- Gruppiert Ereignisse mit dem Nutzernamen (
$user
) und gibt ihn zurück ($user
), wenn eine Übereinstimmung gefunden wird. - Das Zeitfenster beträgt 4 Stunden. Das bedeutet, dass nur Ereignisse, die weniger als 4 Stunden voneinander entfernt sind, korrelieren.
- Sucht nach zwei Ereignisgruppen (
$create
und$delete
, wobei$create
#create >= 1
entspricht). $create
entsprichtUSER_CREATION
-Ereignissen und ruft die User-ID als$user
auf.- Mit
$user
werden die beiden Termingruppen zusammengefügt. $delete
entsprichtUSER_DELETION
-Ereignissen und ruft die User-ID als$user
auf. Diese Regel sucht nach einer Übereinstimmung, bei der die Nutzerkennung in den beiden Ereignisgruppen identisch ist.- Mit dieser Regel wird nach Fällen gesucht, in denen das Ereignis aus
$delete
nach dem Ereignis vom$create
eintritt und eine Übereinstimmung zurückgegeben wird, sobald es erkannt wurde.
Regel für ein einzelnes Ereignis
Regeln für einzelne Ereignisse sind Regeln, die für ein einzelnes Ereignis korrelieren. Eine einzelne Ereignisregel kann Folgendes sein:
- Beliebige Regel ohne Übereinstimmungsbereich.
- Regel mit einem
match
- und einemcondition
-Abschnitt, der nur prüft, ob ein Ereignis vorhanden ist (z. B. „$e“, „#e > 0“, „#e >= 1“, „1 <= #e“, „0 < #e“).
Die folgende Regel sucht beispielsweise nach einem Nutzeranmeldungsereignis und gibt das erste Ereignis zurück, das in den Unternehmensdaten in Ihrem Google Security Operations-Konto gespeichert ist:
rule SingleEventRule {
meta:
author = "[email protected]"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
Hier sehen Sie ein weiteres Beispiel für eine einzelne Ereignisregel mit einem Übereinstimmungsbereich. Mit dieser Regel wird nach einem Nutzer gesucht, der sich in weniger als 5 Minuten mindestens einmal angemeldet hat. Es wird geprüft, ob ein Ereignis zur Nutzeranmeldung vorhanden ist.
rule SingleEventRule {
meta:
author = "[email protected]"
description = "windowed single event example rule"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 5m
condition:
#e > 0
}
rule MultiEventRule{
meta:
author = "[email protected]"
description = "Rule with outcome condition and simple existence condition on one event variable"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 10m
outcome:
$num_events_in_match_window = count($e.metadata.id)
condition:
#e > 0 and $num_events_in_match_window >= 10 // Could be rewritten as #e >= 10
}
Regel für mehrere Ereignisse
Verwenden Sie mehrere Ereignisregeln, um viele Ereignisse innerhalb eines bestimmten Zeitfensters zu gruppieren, und versuchen Sie, Korrelationen zwischen Ereignissen zu finden. Eine typische Regel für mehrere Ereignisse sieht so aus:
- Ein
match
-Abschnitt, der den Zeitraum angibt, für den Ereignisse gruppiert werden sollen. - Ein
condition
-Abschnitt, der angibt, welche Bedingung die Erkennung und Prüfung auf das Vorhandensein mehrerer Ereignisse auslösen soll.
Beispiel: Die folgende Regel sucht nach einem Nutzer, der sich in weniger als 10 Minuten mindestens 10-mal angemeldet hat:
rule MultiEventRule {
meta:
author = "[email protected]"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 10m
condition:
#e >= 10
}
Einzelnes Ereignis innerhalb des IP-Adressbereichs
Das folgende Beispiel zeigt eine einzelne Ereignisregel, mit der nach einer Übereinstimmung zwischen zwei bestimmten Nutzern und einem bestimmten IP-Adressbereich gesucht wird:
rule OrsAndNetworkRange {
meta:
author = "[email protected]"
events:
// Checks CIDR ranges.
net.ip_in_range_cidr($e.principal.ip, "203.0.113.0/24")
// Detection when the hostname field matches either value using or.
$e.principal.hostname = /pbateman/ or $e.principal.hostname = /sspade/
condition:
$e
}
Beispiel für eine beliebige Regel
Mit der folgenden Regel wird nach Anmeldeereignissen gesucht, bei denen alle Quell-IP-Adressen innerhalb von 5 Minuten nicht mit einer IP-Adresse übereinstimmen, die als sicher bekannt ist.
rule SuspiciousIPLogins {
meta:
author = "[email protected]"
events:
$e.metadata.event_type = "USER_LOGIN"
// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".
all $e.principal.ip != "100.97.16.0"
// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.
$e.principal.ip = $ip
match:
$ip over 5m
condition:
$e
}
Reguläre Ausdrücke in einer Regel
Im folgenden Beispiel für einen regulären Ausdruck für YARA-L 2.0 wird nach Ereignissen mit E-Mails von der Domain altostrat.com gesucht. Da nocase
dem Vergleich der $host
-Variablen regex
und der regex
-Funktion hinzugefügt wurde, wird bei diesen Vergleichen die Groß-/Kleinschreibung nicht berücksichtigt.
rule RegexRuleExample {
meta:
author = "[email protected]"
events:
$e.principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex($e.network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
condition:
#e > 10
}
Beispiel für eine gleitende Fensterregel
Im folgenden Beispiel für ein gleitendes YARA-L 2.0-Fenster wird nach firewall_1
-Ereignissen gesucht, ob firewall_2
-Ereignisse vorhanden sind. Das Schlüsselwort after
wird mit der Pivot-Ereignisvariablen $e1
verwendet, um anzugeben, dass bei der Korrelation von Ereignissen nur 10-Minuten-Fenster nach jedem firewall_1
-Ereignis geprüft werden sollen.
rule SlidingWindowRuleExample {
meta:
author = "[email protected]"
events:
$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host
$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host
match:
$host over 10m after $e1
condition:
$e1 and !$e2
}
Beispiel für einen Nullwertausschluss
Das Rules Engine filtert implizit die Nullwerte für alle Platzhalter aus, die im Abschnitt match
verwendet werden.
Weitere Informationen finden Sie unter Umgang mit Nullwerten im Abschnitt match
.
Dies kann mithilfe der Option allow_zero_values
deaktiviert werden, wie unter allow_zero_values beschrieben.
Bei anderen referenzierten Ereignisfeldern werden Nullwerte jedoch nicht ausgeschlossen, sofern Sie solche Bedingungen nicht ausdrücklich angeben.
rule ExcludeZeroValues {
meta:
author = "[email protected]"
events:
$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname
// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"
$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname
// $e2.target.asset_id cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
match:
// $hostname cannot be empty string. The rule behaves as if the
// predicate, `$hostname != ""` was added to the events section, because
// `$hostname` is used in the match section.
$hostname over 1h
condition:
$e1 and $e2
}
Beispiel für eine Regel mit dem Abschnitt „outcome
“
Sie können den optionalen Abschnitt outcome
in der YARA-L 2.0-Regel hinzufügen, um zusätzliche Informationen zu jeder Erkennung zu extrahieren. Im Abschnitt „Bedingung“ können Sie auch Bedingungen für Ergebnisvariablen angeben. Mit dem Abschnitt outcome
einer Erkennungsregel können Sie Variablen für den nachgelagerten Verbrauch festlegen. Sie können beispielsweise einen Schweregradwert basierend auf Daten aus den analysierten Ereignissen festlegen.
Hier finden Sie weitere Informationen:
Mehrfachereignis-Regel mit Ergebnisbereich:
Die folgende Regel prüft zwei Ereignisse, um den Wert von $hostname
zu erhalten. Wenn der Wert von $hostname
über einen Zeitraum von 5 Minuten übereinstimmt, wird eine Schweregradbewertung angewendet. Wenn Sie im Abschnitt match
einen Zeitraum angeben, wird die Regel innerhalb des angegebenen Zeitraums geprüft.
rule OutcomeRuleMultiEvent {
meta:
author = "Google Cloud Security"
events:
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$risk_score =
max(
100
+ if($hostname = "my-hostname", 100, 50)
+ if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}
rule OutcomeRuleMultiEvent {
meta:
author = "[email protected]"
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")
}
Einzelereignis-Regel mit Bereich „Ergebnis“:
rule OutcomeRuleSingleEvent {
meta:
author = "[email protected]"
events:
$u.metadata.event_type = "FILE_COPY"
$u.principal.file.size = $file_size
$u.principal.hostname = $hostname
outcome:
$suspicious_host = $hostname
$admin_severity = if($u.principal.userid in %admin_users, "SEVERE", "MODERATE")
$severity_tag = if($file_size > 1024, $admin_severity, "LOW")
condition:
$u
}
Ergebnisregel für mehrere Ereignisse in eine Ergebnisregel für ein Ereignis umwandeln
Sie können den Abschnitt outcome
sowohl für Einzelereignisregeln (Regeln ohne match
-Abschnitt) als auch für Mehrfachereignisregeln (Regeln mit match
) verwenden.
Wenn Sie zuvor eine Regel für mehrere Ereignisse entwickelt haben, um den Bereich „Ergebnis“ verwenden zu können, können Sie diese Regeln optional refaktorieren. Löschen Sie dazu den Bereich match
, um die Leistung zu verbessern. Da die Regel keinen match
-Abschnitt mehr enthält, der die Gruppierung anwendet, erhalten Sie möglicherweise mehr Erkennungen. Diese Refaktorierung ist nur für Regeln möglich, die eine Ereignisvariable verwenden, wie im folgenden Beispiel gezeigt.
Ergebnisregel für mehrere Ereignisse, die nur eine Ereignisvariable verwendet (ein geeigneter Kandidat für eine Refaktorierung):
rule OutcomeMultiEventPreRefactor {
meta:
author = "[email protected]"
description = "Outcome refactor rule, before the refactor"
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
}
Sie können die Regel refaktorieren, indem Sie den Abschnitt match
löschen. Außerdem müssen Sie das Aggregat im Abschnitt outcome
entfernen, da die Regel jetzt ein einzelnes Ereignis ist. Weitere Informationen zu Aggregationen finden Sie unter Ergebnisaggregationen.
rule OutcomeSingleEventPostRefactor {
meta:
author = "[email protected]"
description = "Outcome refactor rule, after the refactor"
events:
$u.udm.principal.hostname = $hostname
// We deleted the match section.
outcome:
// We removed the max() aggregate.
$risk_score = if($hostname = "my-hostname", 100, 50)
condition:
$u
}
Beispiel für eine Regel von Funktion zu Platzhalter
Sie können dem Ergebnis eines Funktionsaufrufs eine Platzhaltervariable zuweisen und die Platzhaltervariable in anderen Abschnitten der Regel verwenden, z. B. im Abschnitt match
, outcome
oder condition
. Sehen Sie sich folgendes Beispiel an:
rule FunctionToPlaceholderRule {
meta:
author = "[email protected]"
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.
// [email protected] -> address
$email_to_address_only = re.capture($u.network.email.from , "(.*)@")
// Use function-placeholder assignment to normalize an email:
// uid@??? -> [email protected]
$email_from_normalized = strings.concat(
re.capture($u.network.email.from , "(.*)@"),
"@company.com"
)
// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)
match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m
outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
if($dayofweek = 1, 10, 0) +
if($dayofweek = 7, 10, 0)
)
condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1
}
Beispielregel für Ergebnisbedingungen
Im Abschnitt condition
können Sie Ergebnisvariablen verwenden, die im Abschnitt outcome
definiert wurden. Im folgenden Beispiel wird gezeigt, wie Sie mithilfe von Ergebnisbedingungen nach Risikobewertungen filtern, um Rauschen bei der Erkennung zu reduzieren.
rule OutcomeConditionalRule {
meta:
author = "[email protected]"
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
}