Règles à événement unique et à événements multiples dans YARA-L
Ce document présente des requêtes écrites en YARA-L 2.0. Chaque exemple montre comment corréler des événements dans le langage des règles de requête pour identifier les menaces de sécurité, surveiller le comportement des entités et enrichir les détections avec la logique métier.
Utilisez les exemples comme blocs de construction de YARA-L 2.0, y compris la détection d'événements uniques, la correspondance des expressions régulières et le filtrage des plages réseau. Ces exemples sont organisés en catégories fonctionnelles pour vous aider à passer de la logique de base à la corrélation multi-événements avancée et aux détections composites.
Syntaxe de base
Les exemples de cette section montrent comment corréler efficacement les événements UDM et structurer les requêtes dans le langage des règles.
Requête à événement unique
Cas d'utilisation : détection de base d'un type d'événement spécifique (par exemple, USER_LOGIN) sans avoir besoin d'établir de corrélation sur une période donnée.
Logique clé : n'utilise que les sections "Événements" et "Conditions" pour identifier une seule occurrence. Une règle à événement unique peut être :
- Toute règle sans section
match. - Règle avec une section
matchet une sectionconditionqui ne vérifie que l'existence d'un seul événement (par exemple,$e,#e > 0,#e >= 1,1 <= #e,0 < #e).
Exemple : Recherche de la première connexion d'un utilisateur
Règle
L'exemple de règle suivant recherche un événement de connexion utilisateur (USER_LOGIN) et renvoie le premier qu'il rencontre dans les données d'entreprise stockées dans votre compte Google SecOps :
rule SingleEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
Rechercher
Cet exemple de recherche non agrégée génère directement des événements individuels. Comme cette requête ne nécessite pas de corrélation d'événements, les variables d'événement, telles que $e1, sont omises.
metadata.event_type = "USER_LOGIN"
Tableau de bord
Étant donné que cette logique de requête se concentre sur l'affichage d'événements spécifiques et non corrélés dans leur état brut, elle n'utilise pas les sections match ni outcome requises pour les visualisations de tableaux de bord.
Exemple : Détection de connexion de cinq minutes
Règle
L'exemple suivant montre une règle à événement unique qui utilise la section match pour trouver tous les utilisateurs ayant déclenché au moins un événement de connexion au cours d'une période de cinq minutes (5m). Elle vérifie l'existence d'un événement de connexion utilisateur.
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
}
Rechercher
Cet exemple de recherche statistique agrège l'activité dans des fenêtres glissantes de cinq minutes (5m), avec une ligne de sortie par utilisateur et par fenêtre. Étant donné que la requête se concentre sur les nombres volumétriques par fenêtre, les variables event et les sections condition sont omises, car les résultats incluent intrinsèquement un ou plusieurs événements. Cette version utilise une fenêtre bascule au lieu d'une fenêtre récurrente pour s'assurer que les résultats s'affichent correctement sur la plate-forme.
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
match:
$user by 5m
Tableau de bord
L'exemple suivant inclut une section outcome pour calculer le nombre total d'événements par utilisateur, ce qui permet de représenter les données sous forme de valeur statistique au fil du temps. La requête utilise une fenêtre bascule au lieu d'une fenêtre glissante pour s'assurer que les points de données correspondent à des buckets distincts et non chevauchants, et fournit une visualisation plus claire des tendances du tableau de bord.
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
match:
$user by 5m
outcome:
$event_count = count(metadata.id)
Requêtes et optimisation
Cas d'utilisation : détecter les svchost.exe Windows qui se lancent à partir de répertoires non standards.
Logique de la clé : négation (not) combinée à la correspondance d'expressions régulières.
Exemple : Détection des processus basée sur l'exclusion
Règle
La règle suivante recherche des schémas spécifiques dans les données d'événement et crée une détection si elle les trouve. Cette règle inclut une variable $e1 pour le suivi du type d'événement et un champ UDM metadata.event_type. La règle recherche des occurrences spécifiques de correspondances d'expressions régulières avec e1. Lorsqu'un événement $e1 se produit, une détection est créée. Une condition not est incluse dans la règle pour exclure certains chemins non malveillants. Vous pouvez ajouter des conditions not pour éviter les faux positifs.
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
}
Rechercher
Cet exemple effectue une recherche non agrégée pour générer des événements individuels. Comme cette recherche ne nécessite pas de corrélation d'événements sur plusieurs instances, les variables d'événement telles que $e1 sont inutiles.
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
Tableau de bord
Cette syntaxe intègre les sections match et outcome pour calculer le volume d'événements au fil du temps. La fonction timestamp.get_timestamp() regroupe les résultats par jour pour visualiser les tendances.
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)
Plage et logique réseau
Cas d'utilisation : filtrer l'activité en fonction de sous-réseaux IP spécifiques (CIDR) et la faire correspondre à plusieurs noms d'hôte possibles.
Concepts clés :
net.ip_in_range_cidr(): cette fonction vérifie si une adresse IP donnée est contenue dans un sous-réseau CIDR (Classless Inter-Domain Routing) donné pour la correspondance de sous-réseau et l'opérateur "ou" pour les tableaux de chaînes.- Opérateur logique
OR: utilisé pour combiner plusieurs conditions. Les conditions de la section "Événement" sont implicitement combinées avecAND. L'opérateurORvérifie plusieurs noms d'hôte possibles.
Exemple : Mise en correspondance d'un événement unique (plage d'adresses IP)
Règle
L'exemple suivant montre une règle à événement unique qui recherche les correspondances entre deux noms d'hôte spécifiques et une plage d'adresses IP spécifique :
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
}
Rechercher
L'exemple de requête suivant identifie les événements dans lesquels une adresse IP spécifique se trouve dans une plage CIDR définie et où le nom d'hôte correspond à un modèle utilisateur spécifique :
net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")
principal.hostname = /pbateman/ or principal.hostname = /sspade/
Comme il s'agit d'une requête de recherche et non d'une règle de détection, l'intégralité de l'événement est renvoyée automatiquement si les filtres sont respectés. Une section match regroupe les données par principal.ip et principal.hostname. Une section condition n'est pas requise, et les variables d'événement ($e) sont omises, car aucune corrélation d'événement n'est effectuée.
Tableau de bord
L'exemple de requête suivant agrège les résultats en regroupant les paires uniques d'adresses IP et de noms d'hôte :
net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")
principal.hostname = /pbateman/ or principal.hostname = /sspade/
match:
principal.ip, principal.hostname
Expressions régulières dans les requêtes
Cas d'utilisation : recherche des modèles de chaînes flexibles (par exemple, des domaines spécifiques dans les e-mails) en ignorant la casse. Ce type de certificat est le plus souvent utilisé dans la recherche et les règles.
Logique clé : utilise /regex/ nocase pour les correspondances de base et la fonction re.regex() pour l'analyse complexe des champs.
Exemple : Filtrage des e-mails
Règle
L'exemple d'expression régulière YARA-L 2.0 suivant recherche les événements avec des e-mails reçus du domaine altostrat.com. Étant donné que nocase a été ajouté à la comparaison de la variable $host regex et à la fonction regex, ces comparaisons ne sont pas sensibles à la casse.
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
}
Rechercher
Dans l'interface de recherche, cette logique est utilisée pour la chasse aux menaces et l'exploration des données de haute fidélité. Plutôt que d'attendre une alerte automatisée, les analystes peuvent interroger manuellement l'UDM pour identifier des instances spécifiques de noms d'hôte correspondant à une convention de dénomination, ainsi que des domaines de messagerie ciblés. Il s'agit de la principale méthode pour valider le volume de ces événements avant de les promouvoir dans une règle de détection persistante.
principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
```
Tableau de bord
La logique suivante identifie les modèles d'intérêt en agrégeant la télémétrie hostname et email dans des buckets de 10 minutes (10m). Lorsqu'elle est utilisée dans un tableau de bord, cette logique permet aux analystes de visualiser la fréquence de communication de certains composants (correspondant à host) vers le domaine altostrat.com. Cette vue est essentielle pour surveiller les tendances de déplacement des données internes et identifier les principaux émetteurs dans l'infrastructure critique.
principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
```
Exemple : Expression régulière pour le nom d'hôte
Règle
L'exemple suivant identifie toute activité de journal où le compte principal hostname est identifié comme serveur Web (webserver) ou de développement (devserver). Il utilise une expression régulière non sensible à la casse pour s'assurer que les variations dans les conventions de dénomination n'entraînent pas de détections manquées.
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
}
Rechercher
Dans l'exemple suivant, principal.hostname = /webserver|devserver/ nocase correspond à des noms d'hôte tels que "WebServer01", "devserver-test" et "MyWebServers". Il s'agit d'un cas d'utilisation courant pour trouver un événement spécifique.
// Use /regex/ followed by nocase for a case-insensitive match
principal.hostname = /webserver|devserver/ nocase
Tableau de bord
Bien que cet exemple spécifique ne soit pas visualisé dans un tableau de bord, cette règle fournit des alertes actives et une détection persistante. Contrairement à un tableau de bord, qui nécessite un examen manuel, cela garantit que chaque instance d'activité sur ces serveurs est automatiquement signalée et enregistrée dans le moteur de détection pour une recherche immédiate.
Exemple : Rechercher des journaux bruts
Règle
Alors que la recherche manuelle est utilisée pour les investigations ponctuelles, les règles de détection permettent une surveillance continue des données télémétriques, 24h/24 et 7j/7. Vous pouvez convertir une requête de recherche réussie en règle YARA-L pour automatiser le processus d'alerte.
Principaux avantages des règles :
- Alertes en temps réel : les correspondances sont automatiquement signalées lorsqu'elles entrent dans le système.
- Persistance : vous n'avez pas besoin de saisir à nouveau manuellement les termes de recherche.
- Actions de résultat : alimentent directement la vue de détection pour le tri des analystes et la réponse aux incidents.
Rechercher
Les analystes en sécurité utilisent fréquemment regex pour rechercher des journaux bruts et non analysés dans Google SecOps. Cette action permet une mise en correspondance flexible des modèles pour trouver des artefacts spécifiques, même s'ils ne sont pas entièrement structurés ni indexés. La syntaxe utilise des barres obliques :
raw = /host/
Cette requête renvoie toute ligne de journal brute où la séquence de caractères "host" apparaît. Voici quelques exemples de contenu de journaux bruts correspondants : "hostname": "myhost123".
Tableau de bord
Il n'existe aucune variante de tableau de bord dédiée à ce type d'événement spécifique. Pour visualiser ces détections à grande échelle, vous pouvez :
- Mappez
metadata.event_typeà un graphique à barres ou à secteurs dans l'outil de création de tableaux de bord. - Suivez la fréquence de ces événements sur des périodes de 7, 30 ou 90 jours pour identifier les anomalies dans le comportement des utilisateurs.
Champs répétés avec des conditions universelles
Cas d'utilisation : auditez les événements qui contiennent des listes de données (champs répétés) pour vous assurer qu'aucune exception approuvée n'est présente. Par exemple, vérifiez que chaque adresse IP associée à une connexion se trouve en dehors d'une plage sécurisée connue.
Logique clé : utilise l'opérateur all pour évaluer chaque élément d'un champ répété par rapport à une condition spécifique et montre comment l'attribution d'un champ répété à une variable d'espace réservé (par exemple, $ip) crée une détection distincte pour chaque valeur unique de la liste.
Exemple : Validation de l'adresse IP de connexion suspecte
Règle
La règle suivante recherche les événements de connexion où toutes les adresses IP sources ne correspondent pas à une adresse IP connue comme étant sécurisée dans un intervalle de cinq minutes (5m).
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
}
Rechercher
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
Tableau de bord
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
Fenêtrage avancé
Cette section couvre les schémas à plusieurs étapes et les détections déclenchées par l'activité d'autres règles.
Corrélation multi-événements
Cette section présente des exemples de suivi des entités (utilisateurs ou hôtes) dans plusieurs événements ou périodes pour identifier les schémas de comportement.
Cas d'utilisation : détecte les voyages impossibles lorsqu'un même utilisateur se connecte depuis deux villes ou plus en moins de cinq (5m) minutes.
Logique des clés : utilisez la section match pour regrouper les valeurs par $user et #city > 1 afin de trouver des valeurs de localisation distinctes.
Exemple : Détection de connexion multi-destinations
Règle
La règle suivante recherche les utilisateurs qui se sont connectés à votre entreprise depuis au moins deux villes en moins de 5 minutes (5m), où $user est la variable match, $udm est la variable d'événement, et $city et $user sont les variables d'espace réservé :
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
}
L'explication suivante décrit le fonctionnement de cette règle :
- Regroupe les événements avec le nom d'utilisateur (
$user) et le renvoie ($user) lorsqu'une correspondance est trouvée. - La période est de cinq minutes (
5m). Seuls les événements espacés de moins de cinq minutes (5m) sont corrélés. - Recherche un groupe d'événements (
$udm) dont le type d'événement estUSER_LOGIN. - Pour ce groupe d'événements, la règle appelle l'ID utilisateur sous la forme
$useret la ville de connexion sous la forme$city. - Renvoie une correspondance si le nombre distinct de valeurs
city(indiqué par#city) est supérieur à1dans le groupe d'événements ($udm) au cours de la période de cinq minutes (5m).
Rechercher
L'exemple de requête suivant exécute une recherche statistique équivalente pour identifier les schémas de déplacements impossibles. Il regroupe les événements USER_LOGIN par utilisateur dans une fenêtre de cinq minutes (5m) et filtre les résultats pour n'afficher que les cas où plusieurs villes distinctes sont détectées pour une même identité.
events:
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
principal.location.city = $city
match:
$user over 5m
condition:
#city > 1
Tableau de bord
L'exemple de requête suivant fournit une visualisation de tableau de bord équivalente pour suivre les éventuels piratages de compte. Il agrège USER_LOGIN événements par utilisateur sur une période de cinq minutes (5m) et filtre les instances où une seule identité est associée à plusieurs villes distinctes (#city), ce qui vous permet de représenter ces anomalies géographiques à haut risque au fil du temps.
events:
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
principal.location.city = $city
match:
$user over 5m
condition:
#city > 1
Création et suppression rapides d'utilisateurs
Cas d'utilisation : identifie les comptes jetables créés, puis les supprime dans un délai de quatre heures.
Logique clé : joint deux types d'événements (
USER_CREATIONetUSER_DELETION) sur une variable$userpartagée et compare les codes temporels.
Exemple : Création et suppression rapides d'utilisateurs
Règle
L'exemple de règle suivant recherche les utilisateurs qui ont été créés, puis supprimés dans un délai de quatre heures (4h), où $create et $delete sont les variables d'événement, $user est la variable match et il n'y a pas de variables d'espace réservé :
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
}
Rechercher
L'exemple suivant illustre une recherche de statistiques multi-événements utilisée pour identifier les changements rapides du cycle de vie d'un compte. Cette requête génère une ligne par utilisateur dans une fenêtre de quatre heures, en corrélant la création et la suppression d'identités.
Étant donné que la recherche renvoie par défaut toutes les fenêtres contenant les événements spécifiés, une section condition n'est pas requise.
$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
Tableau de bord
L'exemple suivant illustre une recherche de tableau de bord multi-événements conçue pour représenter les tendances du cycle de vie des comptes au fil du temps. En utilisant une fenêtre bascule (by 4h), les résultats sont mappés sur des buckets temporels discrets et non chevauchants, ce qui est idéal pour la visualisation.
Cette variante inclut une section outcome pour calculer le nombre distinct d'événements de création dans chaque fenêtre. Contrairement à la recherche précédente, cette version ne nécessite pas le renvoi de variables d'événement spécifiques, car l'accent est mis sur les valeurs statistiques agrégées plutôt que sur les lignes de journaux individuelles.
$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)
Fenêtre coulissante dans les requêtes
Cas d'utilisation : détecter un problème de sécurité potentiel lorsqu'un événement initial (provenant de firewall_1) n'est pas suivi de l'événement ultérieur attendu (provenant de firewall_2) sur le même hôte dans un délai spécifique.
Logique clé :
- Événement pivot : la règle est axée sur les événements de
firewall_1, désignés par$e1. Chaque fois qu'un événement$e1se produit, il sert de pivot. - Période : la section
match($host over 10m after $e1) définit une période de 10 minutes qui commence immédiatement après chaque événement$e1. Cette fenêtre glisse à chaque nouvel événement$e1. - Corrélation : les événements sont regroupés par nom d'hôte (
$host). - Condition de détection (
$e1et$e2) : une détection est déclenchée pour un hôte donné si :- Un événement de
firewall_1($e1) est présent. AND, dans les 10 minutes suivant cet événement$e1spécifique, l'événementNOdefirewall_2($e2) est trouvé pour le même hôte.
- Un événement de
Exemple : Détection d'événements séquentiels manquants
Règle
L'exemple suivant identifie les cas où un événement secondaire ne se produit pas après un déclencheur principal. En utilisant la condition !$e2 dans une fenêtre de 10 minutes, cette règle signale la télémétrie manquante, en particulier lorsqu'un journal de pare-feu est observé à un emplacement, mais n'apparaît pas au saut suivant attendu, ce qui indique un éventuel manque de visibilité ou une baisse du trafic.
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
}
Rechercher
L'exemple suivant illustre une recherche séquentielle utilisée pour identifier les écarts de télémétrie entre deux sources. En utilisant $e1 comme pivot, la recherche porte sur un événement de pare-feu principal qui n'est pas suivi d'un événement correspondant sur un deuxième pare-feu dans un délai de 10 minutes. Il s'agit d'un moyen très efficace de rechercher manuellement les "trous noirs" dans le trafic réseau ou les échecs de journalisation lors d'une investigation.
$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
Tableau de bord
L'exemple suivant fournit une analyse des écarts de visibilité conçue pour une vue de tableau de bord. En agrégeant les instances où un événement secondaire ne suit pas un événement principal, vous pouvez visualiser la fiabilité de votre pipeline de journalisation au fil du temps. Représenter ces événements "manquants" permet d'identifier les zones mortes persistantes dans la visibilité du réseau ou les problèmes de configuration sur des noms d'hôte spécifiques.
$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
Requêtes multi-événements
Cas d'utilisation : identifiez les activités à haute fréquence ou par force brute en suivant une seule entité (par exemple, un utilisateur ou un hôte) sur plusieurs occurrences d'un événement au cours d'une période spécifique.
Logique clé : utilise une section
matchpour regrouper les événements par variable spécifique et une sectionconditionpour vérifier un nombre seuil (par exemple,#e >= 10) dans la plage de temps définie.
Une règle à événements multiples type comprend les éléments suivants :
- Variables d'événement permettant de distinguer les événements.
- Une section
matchqui spécifie la période pendant laquelle les événements doivent être regroupés. - Une section
conditionqui spécifie la condition qui doit déclencher la détection et vérifie l'existence de plusieurs événements.
Dans la recherche, les requêtes multi-événements sont définies par plusieurs événements dans une requête. Pour les règles, vous pouvez définir cette valeur de deux manières :
Plusieurs événements : (par exemple,
event1 = successful login, event2 = failed login).Déclencheurs basés sur des conditions : la condition est définie pour ne se déclencher que lorsque plusieurs événements répondent aux critères (par exemple,
event1 > 10). Ce type de règle doit également inclure une sectionoutcome.
Exemple : Détection des connexions haute fréquence
Règle
La règle suivante recherche un utilisateur qui s'est connecté au moins 10 fois en moins de 10 minutes :
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
}
Rechercher
L'exemple suivant utilise une recherche de statistiques multi-événements pour identifier les activités de connexion à haute fréquence. Elle signale toute instance où un même utilisateur génère 10 événements de connexion ou plus au cours d'une période de 10 minutes (10m).
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user by 10m
condition:
#e >= 10
Tableau de bord
L'exemple suivant utilise une recherche multi-événements pour surveiller les éventuels piratages de compte. En corrélant les tentatives de connexion dans une fenêtre glissante de 10 minutes, il identifie les cas où un utilisateur et un hôte spécifiques ont connu plusieurs échecs de connexion suivis d'une connexion réussie. Vous pouvez ainsi visualiser les schémas d'authentification à haut risque en temps réel.
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user by 10m
condition:
#e >= 10
Requêtes multi-événements avec des résultats calculés
Cas d'utilisation : appliquez une logique conditionnelle pour définir un
risk_scoreen fonction de la gravité de l'élément ou du volume du réseau.Logique clé : utilise la section
outcomepour calculer les variables et la section "Condition" pour filtrer par ces variables.
Exemple : Force brute suivie d'une connexion réussie
L'exemple suivant utilise la section outcome pour comptabiliser les événements dans une fenêtre match. Cette requête génère le même résultat qu'une requête multi-événements standard, mais montre comment intégrer des variables calculées dans votre logique de détection.
Règle
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
}
Rechercher
// 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
Tableau de bord
// 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
Exemple : Mise en correspondance des hôtes avec une période
Règle
La règle suivante examine deux événements pour obtenir la valeur de $hostname. Si la valeur de $hostname correspond sur une période de cinq minutes (5m), un score de gravité est appliqué. Lorsque vous incluez une période dans la section match, la règle vérifie la période spécifiée.
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")
}
Rechercher
// 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)
```
Tableau de bord
// 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)
Détections composites
Les détections composites améliorent la détection des menaces à l'aide de règles composites. Ces règles composites utilisent les détections d'autres règles comme entrée. Cela permet de détecter les menaces complexes que les règles individuelles ne pourraient pas détecter. Pour en savoir plus, consultez Présentation des détections composites.
Filtrage des risques élevés
Cas d'utilisation : filtrez les détections existantes pour les attributs à haut risque, tels que l'activité impliquant des comptes d'administrateur.
Logique de clé : fonctionne sur les résultats ou les champs de métadonnées des conclusions existantes.
Les détections composites de filtrage à haut risque sont la forme la plus simple de détection composite. Elles fonctionnent sur les champs des résultats de détection, tels que les variables de résultat ou les métadonnées de règle. Ils permettent de filtrer les détections pour les conditions pouvant indiquer un risque plus élevé, comme un utilisateur administrateur ou un environnement de production.
Exemple : Détection des utilisateurs avec accès administrateur
Règle
La règle composite suivante recherche les détections existantes où l'acteur est identifié comme un utilisateur avec accès administrateur et applique un score de risque standardisé.
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
}
Rechercher
La recherche statistique suivante identifie et agrège l'activité des comptes à privilèges élevés. Il est conçu pour afficher tous les noms de règles uniques qui ont déclenché des détections impliquant des utilisateurs "admin" ou "root".
Dans cette requête spécifique, la période est supprimée pour effectuer une seule analyse statistique sur toutes les détections au cours de la période sélectionnée. De plus, comme il s'agit d'une recherche non agrégée axée sur les données de détection existantes, les sections "Événements", "Variables d'événement" et "Condition" ne sont pas requises.
$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)
Tableau de bord
Cette requête de tableau de bord vous permet de visualiser les règles spécifiques qui détectent le plus souvent les activités liées aux administrateurs. Il est conçu pour fournir une vue d'ensemble des tendances de détection dans votre environnement.
Notez la modification de la variable match et de l'agrégation outcome par rapport aux exemples précédents. Cette requête regroupe les résultats par nom de règle et calcule le nombre d'utilisateurs administrateurs détectés pour chacun d'eux.
$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)
Agrégation et seuils
Cas d'utilisation : identifiez les utilisateurs ou les hôtes qui génèrent un volume élevé d'alertes ou qui accumulent des scores de risque importants au fil du temps.
Logique clé : utilise sum() ou count_distinct() pour analyser les données de détection agrégées.
Les règles de détection composite d'agrégation vous permettent de regrouper les résultats de détection en fonction d'attributs partagés, tels qu'un nom d'hôte ou un nom d'utilisateur, et d'analyser les données agrégées. Voici quelques cas d'utilisation courants :
- Identifier les utilisateurs qui génèrent un volume élevé d'alertes de sécurité ou de risques agrégés.
- Détection des hôtes présentant des schémas d'activité inhabituels en agrégeant les détections associées.
Exemple : Agrégation des risques
Règle
Cette règle agrège le score de risque d'un même utilisateur sur une période de 48 heures. Il identifie les utilisateurs dont le risque cumulé sur plusieurs détections dépasse un seuil spécifique.
Dans cette logique mise à jour, detection.detection.outcomes est remplacé par des variables de champ de map, qui stockent à la fois les variables match et outcome. De plus, la variable de résultat $principal_users est supprimée, car chaque détection contient exactement une valeur de variable de correspondance, qui est déjà enregistrée.
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
}
Rechercher
Cette recherche statistique agrège les données de détection pour calculer le risque total d'un utilisateur sur une période de 48 heures. Il génère une ligne par utilisateur principal pour chaque période, ce qui permet d'obtenir une vue d'ensemble du risque présenté par le compte pour plusieurs types de détection.
Dans cette variante, les variables d'événement ne sont pas obligatoires. Alors que le moteur de règles filtre automatiquement les détections sans utilisateur principal, cette recherche nécessite un filtre explicite ($principal_user != "") pour s'assurer que les résultats n'incluent que les données renseignées. Par défaut, la requête ne renvoie des résultats que lorsqu'une ou plusieurs détections sont présentes pour un utilisateur donné.
$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
Tableau de bord
Cette variante est spécialement conçue pour les tableaux de bord. Elle permet de représenter le risque utilisateur et l'activité de détection au fil du temps. Il agrège les données dans des buckets distincts, ce qui le rend idéal pour visualiser les tendances telles que le volume de règles uniques déclenchées ou le nombre total de détections par utilisateur.
Dans cette requête, la fenêtre est remplacée par une fenêtre glissante (hop) par une fenêtre basculante (by 48h). Cela garantit que les points de données sont mappés sur des segments temporels non chevauchants, ce qui permet d'obtenir une visualisation plus claire pour les graphiques de séries temporelles. Comme pour les autres recherches non agrégées, les variables d'événement ne sont pas obligatoires. La section outcome est développée pour inclure des nombres distincts pour les noms de règles et les ID de détection.
$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
Agrégation des tactiques
Cas d'utilisation : identifiez les utilisateurs dont l'activité a déclenché des détections dans plusieurs tactiques MITRE ATT&CK distinctes, ce qui suggère un cycle de vie d'attaque en cours (par exemple, en passant de l'accès initial à l'exfiltration).
Logique clé : utilise count_distinct($tactic) pour se déclencher uniquement lorsqu'un utilisateur dépasse un seuil spécifique de tactiques différentes au cours d'une période de 48 heures.
Exemple : Agrégation de tactiques MITRE
Règle
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 }
Rechercher
L'exemple suivant illustre une variante de recherche conçue pour les développeurs de sécurité qui doivent corréler les détections existantes et appliquer une pondération dynamique des risques. Cette logique de requête extrait les tactiques MITRE ATT&CK et les informations utilisateur de la source de données detection, regroupe l'activité par utilisateur principal et calcule un score de risque personnalisé en fonction de la diversité des tactiques observées.
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)
Tableau de bord
L'exemple suivant illustre une variante de tableau de bord de la même logique d'analyse de détection. Lorsqu'elle est utilisée dans les tableaux de bord Google SecOps, cette requête permet aux développeurs de visualiser les utilisateurs à haut risque en corrélant les résultats de détection de différentes règles. La logique extrait l'utilisateur principal et les tactiques MITRE, agrège les résultats et applique un score de risque plafonné pour aider à hiérarchiser les efforts d'investigation directement dans un widget de tableau de bord.
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)
```
Détections composites séquentielles
Cas d'utilisation : identifiez les schémas d'attaque critiques où l'ordre des opérations est essentiel. Par exemple, détectez une connexion réussie à un compte qui ne se produit qu'après une série d'alertes de tentatives de piratage par force brute provenant de la même adresse IP.
Logique clé : met en corrélation une détection antérieure avec un événement UDM brut ultérieur en les associant sur une variable commune (par exemple, $bruteforce_ip) et en utilisant une comparaison d'horodatage pour s'assurer que les événements se sont produits dans le bon ordre.
Les détections composites séquentielles identifient des schémas d'événements associés où la séquence de détections est importante, comme une tentative de connexion par force brute suivie d'une connexion réussie. Ces schémas peuvent impliquer plusieurs détections de base ou une combinaison de détections de base et d'événements.
Exemple : tentative de force brute suivie d'une connexion réussie
Règle
La règle composite suivante identifie des schémas d'événements associés où la séquence est importante. Plus précisément, il recherche une détection de force brute Google Workspace suivie d'un événement de connexion réussi à partir de la même adresse IP source dans un délai de 24 heures.
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
}
Rechercher
$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
Tableau de bord
Les tableaux de bord se concentrent sur la visualisation des données d'événement brutes, tandis que la logique de détection composite met en corrélation les alertes de détection existantes avec les événements ultérieurs. Cette analyse multicouche est optimisée pour le moteur de détection plutôt que pour les widgets de tableau de bord en temps réel.
Détections contextuelles
Cas d'utilisation : enrichissez les détections existantes avec des informations externes sur les menaces pour vérifier si une alerte implique des entités malveillantes connues. Par exemple, vérifiez si une adresse IP signalée dans une détection de sécurité figure également dans un flux d'informations sur les menaces concernant les nœuds de sortie TOR mondiaux.
Logique clé : utilise des règles composites pour joindre les résultats de détection aux données du graphique GLOBAL_CONTEXT (par exemple, les flux Google Cloud Threat Intelligence) en faisant correspondre un attribut partagé tel qu'une adresse IP.
Les détections composites contextuelles enrichissent les détections avec des informations supplémentaires, telles que les adresses IP trouvées dans les flux de menaces.
Exemple : Enrichissement des renseignements sur les menaces
Règle
La règle composite suivante ajoute automatiquement du contexte supplémentaire à vos détections existantes à partir du flux d'informations TOR. Il met en corrélation une adresse IP détectée précédemment avec le flux de nœuds de sortie TOR pour augmenter la gravité et le score de risque du résultat.
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.threat.threat_feed_name = "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
}
Rechercher
``` $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.threat.threat_feed_name = "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 ```
Tableau de bord
Détections de co-occurrence
Cas d'utilisation : détectez une combinaison de tactiques associées déclenchées par la même entité au cours d'une période spécifique. Par exemple, identifiez un utilisateur qui a déclenché à la fois une détection d'élévation des privilèges et une détection d'exfiltration de données dans un délai de 48 heures.
Logique de clé : utilise une forme d'agrégation pour corréler plusieurs types de détection distincts en les joignant sur une variable d'entité partagée (par exemple, $pe_user) dans la section match.
Les détections composites de cooccurrence sont une forme d'agrégation qui peut détecter une combinaison d'événements associés, comme une combinaison de détections d'escalade de privilèges et d'exfiltration de données déclenchées par un utilisateur.
Exemple : Cooccurrence d'une élévation des privilèges et d'une exfiltration
Règle
La règle composite suivante recherche une séquence ou une combinaison spécifique de détections (élévation des privilèges suivie d'une exfiltration) associées au même utilisateur sur une période de 48 heures.
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
}
Rechercher
$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
Tableau de bord
Gestion des résultats et des variables
Cette section présente des exemples de calcul du risque et de normalisation des données pour la consommation en aval.
Section "Requêtes avec outcome"
Vous pouvez ajouter la section facultative outcome dans une règle YARA-L 2.0 pour extraire des informations supplémentaires sur chaque détection. Dans la section condition, vous pouvez également spécifier des conditions sur les variables de résultat. Vous pouvez utiliser la section outcome d'une règle de détection pour définir des variables à utiliser en aval. Par exemple, vous pouvez définir un score de gravité en fonction des données des événements analysés.
Pour en savoir plus, consultez les ressources suivantes :
- Syntaxe de la section "Résultat"
- Syntaxe de la section "Conditions"
- Section
outcome, "Analyse contextuelle"
Conditions de résultat
Cas d'utilisation : filtrez les détections en fonction des scores de risque calculés pour réduire le bruit et vous assurer que seules les détections à haut niveau de confiance ou de gravité déclenchent des alertes. Cela permet de supprimer les activités à faible risque qui ne répondent pas à un seuil commercial spécifique.
Logique clé : définit les variables dans la section outcome à l'aide de mathématiques conditionnelles (par exemple, en ajoutant le risque en fonction de la taille du fichier ou de l'heure de la journée), puis fait référence à ces variables dans la section condition pour contrôler la détection.
Exemple : Filtrer par score de risque calculé
Règle
Dans la section condition, vous pouvez utiliser les variables outcome définies dans la section outcome. L'exemple suivant montre comment filtrer les scores de risque pour réduire le bruit dans les détections à l'aide de conditions de résultat.
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
}
Rechercher
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
Tableau de bord
Cette requête ajoute la variable de résultat $hostname pour visualiser les hôtes associés à chaque score de risque.
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
Requête à événement unique avec résultat
Cas d'utilisation : enrichissez les détections ponctuelles avec un contexte immédiat, par exemple en attribuant des tags de gravité en fonction des listes d'utilisateurs ou des attributs de fichier, sans avoir besoin d'une période ni d'une corrélation d'événements.
Logique clé : utilise la section outcome dans une règle qui ne comporte pas de section match. Cela vous permet d'extraire des métadonnées et d'effectuer une logique conditionnelle (par exemple, vérifier si un utilisateur figure dans une liste de référence) pour chaque événement individuel qui répond aux critères.
Exemple : Tagging de la gravité à un moment précis
Règle
L'exemple suivant montre comment utiliser la section outcome dans une règle à événement unique pour définir des variables à utiliser en aval. Par exemple, il permet de définir un score de gravité en fonction de l'utilisateur et de la taille du fichier impliqués dans un événement de copie de fichier.
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
}
Rechercher
L'exemple suivant identifie les événements de création de fichiers et utilise la section outcome pour attribuer dynamiquement des niveaux de gravité à chaque résultat. Contrairement aux règles multi-événements, cette recherche non agrégée ne nécessite pas de variables d'événement ni de section match. Au lieu de cela, il traite chaque journal individuellement pour générer 1 row per event, enrichi d'une logique personnalisée basée sur la taille du fichier et les autorisations de l'utilisateur.
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")
Tableau de bord
Une variante de tableau de bord n'est pas applicable dans cet exemple, car l'intention première est de taguer et d'enrichir des événements individuels. Bien qu'un tableau de bord puisse agréger ces événements (par exemple, en calculant le nombre total d'événements par tag de gravité), cela masquerait les détails précis au niveau des lignes que cette recherche non agrégée est conçue pour afficher.
Score de risque basé sur le réseau
Cas d'utilisation : identifiez les transferts de données à haut risque en calculant le volume cumulé du trafic réseau pour un groupe d'événements. Cela vous permet d'identifier les menaces lorsque le seuil de données total dépasse une limite spécifique (par exemple, 1024 octets), tout en tenant compte de la gravité des failles des ressources concernées.
Logique clé : utilise la fonction d'agrégation sum() dans la section outcome pour combiner sent_bytes et received_bytes pour tous les événements d'une fenêtre match. Pour les règles, la requête utilise une instruction "if" pour appliquer un score de risque plus élevé si la somme dépasse un seuil défini.
Exemple : Règle de scoring des risques basée sur le réseau
Règle
L'exemple suivant montre comment utiliser la section outcome pour calculer un score de risque dynamique basé sur l'activité réseau. En additionnant le nombre total d'octets transférés dans un groupe d'événements, la règle applique une priorité plus élevée aux correspondances dépassant un seuil de données spécifique (1024 octets), tout en tenant compte de la gravité de la faille de l'asset concerné.
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")
}
Rechercher
L'exemple suivant illustre une variante de recherche qui met en corrélation les événements réseau UDM avec le contexte des composants du graphique de contexte des entités (ECG). Il utilise une fenêtre de 5 minutes match pour agréger le trafic réseau par nom d'hôte, calcule un score de risque basé sur le volume de données et la gravité des failles, et applique un filtre conditionnel pour exclure des ID d'assets spécifiques de l'ensemble de résultats final.
$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")
Tableau de bord
L'exemple suivant illustre une variante de tableaux de bord qui enrichit la télémétrie réseau en temps réel avec des données sur les failles des composants. En faisant correspondre les noms d'hôte sur une période glissante de cinq minutes, cette requête permet aux développeurs de créer des widgets de tableau de bord qui visualisent les niveaux de risque des composants. La logique ajuste dynamiquement un score de risque en fonction du débit réseau et de la faille la plus grave détectée sur le composant. Vous obtenez ainsi une vue hiérarchisée des systèmes potentiellement compromis.
$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")
Refactoriser une règle outcome à événements multiples (avant la refactorisation)
Cas d'utilisation : améliorez les performances du système et réduisez la latence de traitement en convertissant les règles à événements multiples en règles à événement unique. C'est idéal pour les règles qui ont été conçues à l'origine avec une section "Correspondance" uniquement pour activer la section "Résultat", mais qui ne nécessitent pas réellement de corrélation entre plusieurs événements distincts.
Logique clé : supprime la section match et toutes les fonctions d'agrégation (par exemple, max(), sum() ou count()) de la section outcome. Cette transition permet à la règle de passer du regroupement des événements au fil du temps à l'évaluation de chaque événement individuellement à son arrivée.
match) et les règles à événements multiples (règles avec une section match).
Vous pouvez utiliser la section outcome pour les règles à événement unique (règles sans section match). Si vous avez précédemment conçu une règle pour qu'elle soit multi-événements uniquement pour pouvoir utiliser la section "Résultat", vous pouvez éventuellement refactoriser ces règles en supprimant la section match pour améliorer les performances. Notez que, comme votre règle ne comporte plus de section match qui applique le regroupement, vous pouvez recevoir plus de détections.
Exemple : Refactorisation des résultats (avant refactorisation)
Règle
L'exemple suivant montre une règle de résultat à événements multiples qui n'utilise qu'une seule variable d'événement. Comme il utilise une section match, le moteur de règles doit regrouper les événements sur une période de cinq minutes avant de calculer le résultat, ce qui consomme plus de ressources qu'une évaluation d'événement unique.
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
}
Rechercher
Requête de statistiques équivalente
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
Tableau de bord
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
Refactoriser une règle outcome à événements multiples (après refactorisation)
Cas d'utilisation : finaliser l'optimisation d'une requête pour améliorer la vitesse de traitement. En supprimant l'exigence de regroupement, la requête déclenche désormais une détection dès l'arrivée d'un seul événement correspondant, ce qui est beaucoup plus efficace pour le moteur de règles.
Logique clé : supprime la section match et la fonction aggregate (par exemple, max()) de l'attribution de la variable outcome. La logique de l'instruction "if" reste la même, mais elle est désormais appliquée à un seul événement plutôt qu'à un groupe.
Vous pouvez refactoriser la requête en supprimant la section match. Remarque : Vous devez également supprimer l'agrégat dans la section outcome, car la requête est désormais un événement unique. Pour en savoir plus sur les agrégations, consultez Agrégations de résultats.
Exemple : Refactorisation des résultats (: #outcome-post-refactor)
Règle
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
}
Rechercher
events:
$u.udm.principal.hostname = $hostname
outcome:
$risk_score = if($hostname = "my-hostname", 100, 50)
Tableau de bord
events:
$u.udm.principal.hostname = $hostname
outcome:
$risk_score = if($hostname = "my-hostname", 100, 50)
Attribution d'une fonction à un espace réservé
Cas d'utilisation : normalisez les données (par exemple, standardisez les domaines d'adresse e-mail) pour vérifier que le regroupement dans la section "Correspondances" est exact.
Logique clé : attribue le résultat de re.capture() ou strings.concat() à une variable d'espace réservé.
Exemple : Attribution de variables de fonction à des espaces réservés
Vous pouvez attribuer une variable d'espace réservé au résultat d'un appel de fonction et l'utiliser dans d'autres sections de la règle, telles que les sections match, outcome ou condition.
Règle
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
}
Rechercher
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
Tableau de bord
L'exemple suivant illustre une variante de tableaux de bord optimisée pour la visualisation de séries temporelles. En utilisant une fenêtre bascule d'un jour au lieu d'une précision à la minute, cette requête produit des points de données stables et non chevauchants, idéaux pour représenter les scores de risque sur une période prolongée. La logique normalise les entités d'e-mails et applique des pondérations de risque plus élevées aux transactions du week-end, ce qui permet de dégager une tendance quotidienne claire de l'activité d'e-mails suspects pour une surveillance à long terme.
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
Optimisation et filtrage
Pour optimiser efficacement les règles, il est essentiel de filtrer précisément les données afin de s'assurer que le moteur de détection ne traite que les informations pertinentes. En excluant les données "bruyantes" ou incomplètes, vous pouvez améliorer considérablement les performances des règles et vous assurer que les alertes générées sont exploitables.
| Thème | Exemples |
|---|---|
| Exclusion des valeurs nulles | Exclusion des valeurs nulles explicites et implicites |
Exclusion des valeurs nulles
Cas d'utilisation : assurez-vous de l'exactitude des règles et réduisez les faux positifs en excluant explicitement les chaînes vides, les valeurs nulles ou les comptes d'espace réservé génériques (par exemple, "Invité") qui ne fournissent pas de données de sécurité exploitables.
Logique clé : utilise le filtrage implicite des valeurs nulles du moteur de règles pour les variables utilisées dans la section match, tout en utilisant des opérateurs d'inégalité explicites (!= "") pour les autres champs d'événement afin de s'assurer que seules les données renseignées déclenchent une détection.
Le moteur de règles filtre implicitement les valeurs nulles pour tous les espaces réservés utilisés dans la section match. Utilisez l'option allow_zero_values pour la désactiver. Toutefois, pour les autres champs d'événement référencés, les valeurs nulles ne sont pas exclues, sauf si vous spécifiez explicitement de telles conditions. Pour en savoir plus, consultez Valeurs nulles dans la section "Correspondances".
Exemple : Exclusion explicite et implicite de la valeur zéro
Règle
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
}
Rechercher
Vous devez indiquer explicitement que hostname ne peut pas être une chaîne vide, car il n'existe aucun filtre de valeur zéro implicite pour les espaces réservés dans la section match.
$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
Tableau de bord
Vous devez indiquer explicitement que hostname ne peut pas être une chaîne vide, car il n'existe aucun filtre de valeur zéro implicite pour les espaces réservés dans la section match.
$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
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.