Libreria di riferimento delle query YARA-L 2.0

Supportato in:

Questo documento mostra le query scritte in YARA-L 2.0. Ogni esempio mostra come correlare gli eventi all'interno del linguaggio delle regole di query per identificare le minacce alla sicurezza, monitorare il comportamento delle entità e arricchire i rilevamenti con la logica di business.

Utilizza gli esempi come elementi costitutivi di YARA-L 2.0, inclusi il rilevamento di singoli eventi, la corrispondenza delle espressioni regolari e il filtro dell'intervallo di rete. Questi esempi sono organizzati in categorie funzionali per aiutarti a passare dalla logica di base alla correlazione avanzata di più eventi e ai rilevamenti compositi.

Sintassi di base e nozioni di base

Gli esempi in questa sezione mostrano come correlare in modo efficace gli eventi UDM e strutturare le query nel linguaggio delle regole.

Argomento Esempi
Query su un singolo evento Ricerca dell'accesso iniziale dell'utente; Rilevamento dell'accesso di 5 minuti
Query e ottimizzazione Rilevamento dei processi basato sull'esclusione
Intervallo e logica di rete Corrispondenza di un singolo evento (intervallo IP)
Espressioni regolari nelle query Filtro email; Espressione regolare del nome host; Ricerca log non elaborati
Campi ripetuti con condizioni universali Convalida dell'IP di accesso sospetto

Query su un singolo evento

Caso d'uso: rilevamento di base di un tipo di evento specifico (ad esempio USER_LOGIN) senza necessità di correlazione in una finestra temporale.

Logica chiave: utilizza solo le sezioni degli eventi e delle condizioni per identificare una singola occorrenza. Una regola per un singolo evento può essere:

  • Qualsiasi regola senza una sezione match.
  • Regola con una sezione match e una sezione condition che controlla solo l'esistenza di un evento (ad esempio $e, #e > 0, #e >= 1, 1 <= #e, 0 < #e).

Regola

Il seguente esempio di regola cerca un evento di accesso utente (USER_LOGIN) e restituisce il primo che incontra nei dati aziendali archiviati nel tuo account Google SecOps:

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

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

condition:
  $e
}

Questo esempio di ricerca non aggregata restituisce direttamente i singoli eventi. Poiché questa query non richiede la correlazione degli eventi, le variabili evento, come $e1, vengono omesse.

metadata.event_type = "USER_LOGIN"

Dashboard

Poiché questa logica di query si concentra sulla visualizzazione di eventi specifici e non correlati nel loro stato non elaborato, non utilizza le sezioni match o outcome richieste per le visualizzazioni della dashboard.

Esempio: rilevamento dell'accesso in cinque minuti

Regola

Il seguente esempio mostra una regola a evento singolo che utilizza la sezione match per trovare qualsiasi utente con almeno un evento di accesso che si verifica in un intervallo di tempo di 5 minuti (5m). Verifica l'esistenza di un evento di accesso utente.

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
}

Cerca

Questo esempio di ricerca statistica aggrega l'attività in finestre temporali di cinque minuti (5m), con un output di una riga per utente per finestra. Poiché la query si concentra sui conteggi volumetrici per finestra, le variabili event e le sezioni condition vengono omesse perché i risultati includono intrinsecamente uno o più eventi. Questa versione utilizza una finestra mobile anziché una finestra a salti per garantire che i risultati vengano visualizzati correttamente all'interno della piattaforma.

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

match:
  $user by 5m

Dashboard

L'esempio seguente include una sezione outcome per calcolare il conteggio totale degli eventi per utente, il che consente di tracciare i dati come valore statistico nel tempo. La query utilizza una finestra a cascata anziché una finestra di hopping per assicurarsi che i punti dati vengano mappati in bucket discreti e non sovrapposti e fornisce una visualizzazione più chiara per l'andamento del dashboard.

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

match:
  $user by 5m

outcome:
  $event_count = count(metadata.id)

Esecuzione di query e ottimizzazione

Caso d'uso: rileva le finestre di Windows svchost.exeche vengono avviate da directory non standard.

Logica della chiave: negazione (not) combinata con la corrispondenza dell'espressione regolare.

Esempio: rilevamento dei processi basato sull'esclusione

Regola

La seguente regola verifica la presenza di pattern specifici nei dati degli eventi e crea un rilevamento se li trova. Questa regola include una variabile $e1 per il monitoraggio del tipo di evento e un campo UDM metadata.event_type. La regola verifica la presenza di occorrenze specifiche di corrispondenze di espressioni regolari con e1. Quando si verifica l'evento $e1, viene creata una rilevazione. Nella regola è inclusa una condizione not per escludere determinati percorsi non dannosi. Puoi aggiungere not condizioni per evitare falsi positivi.

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
}

Cerca

Questo esempio esegue una ricerca non aggregata per restituire singoli eventi. Poiché questa ricerca non richiede la correlazione degli eventi in più istanze, le variabili evento come $e1 non sono necessarie.

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

Dashboard

Questa sintassi incorpora le sezioni match e outcome per calcolare il volume degli eventi nel tempo. La funzione timestamp.get_timestamp() raggruppa i risultati per giorno per la visualizzazione delle tendenze.

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)

Intervallo e logica di rete

Caso d'uso: filtrare l'attività in base a subnet IP specifiche (CIDR) e confrontarle con più nomi host possibili.

Concetti chiave:

  • net.ip_in_range_cidr(): questa funzione verifica se un determinato indirizzo IP è contenuto in una determinata subnet CIDR (Classless Inter-Domain Routing) per la corrispondenza della subnet e l'operatore OR per gli array di stringhe.
  • Operatore logico OR: utilizzato per combinare più condizioni. Le condizioni all'interno della sezione dell'evento vengono combinate implicitamente con AND. L'operatore OR esegue il controllo su più nomi host possibili.

Esempio: corrispondenza di un singolo evento (intervallo IP)

Regola

L'esempio seguente mostra una regola a evento singolo che cerca corrispondenze tra due nomi host specifici e un intervallo specifico di indirizzi IP:

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
}

Cerca

Il seguente esempio di query identifica gli eventi in cui un indirizzo IP specifico rientra in un intervallo CIDR definito e il nome host corrisponde a un pattern utente specifico:

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

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

Poiché si tratta di una query di ricerca, non di una regola di rilevamento, l'intero evento viene restituito automaticamente se i filtri vengono soddisfatti. Una sezione match raggruppa i dati per principal.ip e principal.hostname. Una sezione condition non è obbligatoria e le variabili evento ($e) vengono omesse perché non viene eseguita alcuna correlazione degli eventi.

Dashboard

La seguente query di esempio aggrega i risultati raggruppando coppie univoche di IP e nome host:

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

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

match:
  principal.ip, principal.hostname

Espressioni regolari nelle query

Caso d'uso: cerca pattern di stringhe flessibili (ad esempio, domini specifici nelle email) ignorando le maiuscole. Questo è di uso più comune in Ricerca e regole.

Logica chiave: utilizza /regex/ nocase per le corrispondenze di base e la funzione re.regex() per l'analisi complessa dei campi.

Esempio: filtraggio email

Regola

Il seguente esempio di espressione regolare YARA-L 2.0 cerca eventi con email ricevute dal dominio altostrat.com. Poiché nocase è stato aggiunto al confronto tra variabili $host e alla funzione regex, questi confronti non fanno distinzione tra maiuscole e minuscole.regex

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
}

Cerca

Nell'interfaccia di ricerca, questa logica viene utilizzata per la ricerca di minacce ad alta fedeltà e l'esplorazione dei dati. Anziché attendere un avviso automatico, gli analisti possono eseguire query manualmente sulla UDM per scoprire istanze specifiche di nomi host che corrispondono a una convenzione di denominazione insieme a domini email mirati. Questo è il metodo principale per convalidare il volume di questi eventi prima di promuoverli in una regola di rilevamento persistente.

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

Dashboard

La seguente logica identifica i pattern di interesse aggregando la telemetria hostname e email in bucket di 10 minuti (10m). Se utilizzata in una dashboard, questa logica consente agli analisti di visualizzare la frequenza di comunicazione da asset specifici (corrispondenti a host) al dominio altostrat.com. Questa visualizzazione è essenziale per monitorare le tendenze di movimento dei dati interni e identificare i principali interlocutori nell'infrastruttura critica.

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

match:
  $host over 10m
  ```

Esempio: espressione regolare del nome host

Regola

L'esempio seguente identifica qualsiasi attività di log in cui l'entità hostname è identificata come server web (webserver) o di sviluppo (devserver). Utilizza un'espressione regolare senza distinzione tra maiuscole e minuscole per assicurarsi che le variazioni nelle convenzioni di denominazione non comportino rilevamenti mancanti.

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
}

Cerca

Nell'esempio seguente, principal.hostname = /webserver|devserver/ nocase corrisponde a nomi host come "WebServer01", "devserver-test", "MyWebServers". Si tratta di un caso d'uso comune per trovare un evento specifico.

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

Dashboard

Sebbene questo esempio specifico non venga visualizzato in una dashboard, questa regola fornisce avvisi attivi e rilevamento persistente. A differenza di una dashboard, che richiede una revisione manuale, questo garantisce che ogni istanza di attività su questi server venga automaticamente segnalata e registrata nel motore di rilevamento per una ricerca immediata.

Regola

Mentre utilizzi la ricerca manuale per le indagini in un determinato momento, le regole di rilevamento forniscono un monitoraggio continuo della telemetria 24 ore su 24, 7 giorni su 7. Puoi convertire una query di ricerca riuscita in una regola YARA-L per automatizzare il processo di generazione di avvisi.

Vantaggi principali delle regole:

  • Avvisi in tempo reale: contrassegna automaticamente le corrispondenze quando entrano nel sistema.
  • Persistenza: elimina la necessità di reinserire manualmente i termini di ricerca.
  • Azioni di risultato: vengono inserite direttamente nella visualizzazione di rilevamento per la classificazione iniziale degli analisti e la risposta agli incidenti.

Cerca

Gli analisti della sicurezza utilizzano spesso regex per eseguire ricerche nei log non analizzati e non elaborati all'interno di Google SecOps. Questa azione consente una corrispondenza flessibile dei pattern per trovare artefatti specifici, anche se non sono completamente strutturati o indicizzati. La sintassi utilizza le barre:

raw = /host/

Questa query restituisce qualsiasi riga di log non elaborata in cui viene visualizzata la sequenza di caratteri "host". Alcuni esempi di contenuti dei log non elaborati corrispondenti potrebbero includere "hostname": "myhost123".

Dashboard

Non esiste una variante della dashboard dedicata a questo tipo di evento specifico. Per visualizzare queste rilevazioni su larga scala, puoi:

  • Mappa metadata.event_type su un grafico a barre o a torta nel generatore di dashboard.
  • Monitora la frequenza di questi eventi in finestre di 7, 30 o 90 giorni per identificare anomalie nel comportamento degli utenti.

Campi ripetuti con condizioni universali

Caso d'uso: controlla gli eventi che contengono elenchi di dati (campi ripetuti) per assicurarti che non siano presenti eccezioni attendibili, ad esempio verifica che ogni indirizzo IP associato a un accesso sia al di fuori di un intervallo sicuro noto.

Logica chiave: utilizza l'operatore all per valutare ogni elemento in un campo ripetuto in base a una condizione specifica e mostra come l'assegnazione di un campo ripetuto a una variabile segnaposto (ad esempio $ip) crea un rilevamento distinto per ogni valore univoco nell'elenco.

Esempio: convalida dell'IP di accesso sospetto

Regola

La seguente regola cerca eventi di accesso in cui tutti gli indirizzi IP di origine non corrispondono a un indirizzo IP noto per essere sicuro in un intervallo di tempo di cinque minuti (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
}

Cerca

metadata.event_type = "USER_LOGIN"

// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".

all principal.ip != "100.97.16.0"

// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.

principal.ip = $ip

match:
  $ip over 5m

Dashboard

metadata.event_type = "USER_LOGIN"

// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".

all principal.ip != "100.97.16.0"

// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.

principal.ip = $ip

match:
  $ip over 5m

Finestre avanzate

Questa sezione copre i pattern e i rilevamenti multifase attivati dall'attività di altre regole.

Argomento Esempi
Correlazione di più eventi Rilevamento dell'accesso da più città; Creazione ed eliminazione rapida di utenti
Finestra scorrevole nelle query Rilevamento di eventi sequenziali mancanti
Query multi-evento Rilevamento di accessi ad alta frequenza
Query multi-evento con risultati calcolati Attacco di forza bruta seguito da accesso riuscito; Corrispondenza host in base alla finestra temporale

Correlazione di più eventi

Questa sezione mostra esempi su come monitorare le entità (utenti o host) in più eventi o intervalli di tempo per identificare i modelli comportamentali.

Caso d'uso: rileva viaggi impossibili in cui un singolo utente accede da due o più città in meno di cinque (5m) minuti.

Logica chiave: utilizza la sezione match per raggruppare per $user e #city > 1 per trovare valori di località distinti.

Esempio: rilevamento dell'accesso da più città

Regola

La seguente regola cerca gli utenti che hanno eseguito l'accesso alla tua azienda da due o più città in meno di 5 (5m) minuti, dove $user è la variabile match, $udm è la variabile evento e $city e $user sono le variabili segnaposto:

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
}

La seguente spiegazione descrive il funzionamento di questa regola:

  • Raggruppa gli eventi con il nome utente ($user) e lo restituisce ($user) quando viene trovata una corrispondenza.
  • L'intervallo di tempo è di cinque minuti (5m); vengono correlati solo gli eventi che si verificano a meno di 5 minuti (5m) di distanza.
  • Cerca un gruppo di eventi ($udm) il cui tipo di evento è USER_LOGIN.
  • Per questo gruppo di eventi, la regola chiama l'ID utente come $user e la città di accesso come $city.
  • Restituisce una corrispondenza se il numero distinto di valori city (indicato da #city) è maggiore di 1 nel gruppo di eventi ($udm) nell'intervallo di tempo di 5 minuti (5m).

Cerca

La seguente query di esempio esegue una ricerca statistica equivalente per identificare i pattern di spostamento impossibile. Raggruppa gli eventi USER_LOGIN per utente in un intervallo di cinque minuti (5m) e filtra i risultati in modo da visualizzare solo le istanze in cui vengono rilevate più città distinte per una singola identità.

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

match:
  $user over 5m

condition:
  #city > 1

Dashboard

La seguente query di esempio fornisce una visualizzazione della dashboard equivalente per monitorare la potenziale compromissione dell'account. Aggrega gli eventi USER_LOGIN per utente in un periodo di cinque minuti (5m) e filtra le istanze in cui una singola identità è associata a più di una città distinta (#city), il che ti consente di tracciare queste anomalie geografiche ad alto rischio nel tempo.

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

match:
  $user over 5m

condition:
  #city > 1

Creazione ed eliminazione rapide degli utenti

  • Caso d'uso: identifica gli account usa e getta creati e li elimina entro un periodo di 4 ore.

  • Logica chiave: unisce due tipi di eventi (USER_CREATION e USER_DELETION) in una variabile $user condivisa e confronta i timestamp.

Esempio: creazione ed eliminazione rapida di utenti

Regola

Il seguente esempio di regola cerca gli utenti che sono stati creati e poi eliminati entro 4 ore (4h), dove $create e $delete sono le variabili evento, $user è la variabile match e non sono presenti variabili segnaposto:

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
}

Cerca

L'esempio seguente mostra una ricerca di statistiche multi-evento utilizzata per identificare rapidi cambiamenti del ciclo di vita dell'account. Questa query restituisce una riga per utente in un intervallo di quattro ore, mettendo in correlazione la creazione e l'eliminazione delle identità.

Poiché la ricerca restituisce per impostazione predefinita qualsiasi finestra contenente gli eventi specificati, non è necessaria una sezione condition.

$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"

$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"

$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds

match:
  $user over 4h

Dashboard

L'esempio seguente mostra una ricerca nella dashboard multi-evento progettata per tracciare le tendenze del ciclo di vita dell'account nel tempo. Utilizzando una finestra mobile (by 4h), i risultati vengono mappati in bucket temporali discreti e non sovrapposti, il che è ideale per la visualizzazione.

Questa variante include una sezione outcome per calcolare il conteggio distinto degli eventi di creazione all'interno di ogni finestra. A differenza della ricerca precedente, questa versione non richiede la restituzione di variabili evento specifiche, perché l'attenzione è rivolta ai valori statistici aggregati anziché alle singole righe di log.

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

Finestra scorrevole nelle query

Caso d'uso: per rilevare un potenziale problema di sicurezza in cui un evento iniziale (da firewall_1) non è seguito da un evento successivo previsto (da firewall_2) sullo stesso host in un periodo di tempo specifico.

Logica chiave:

  • Evento pivot: la regola si basa sugli eventi di firewall_1, designati come $e1. Ogni volta che si verifica un evento $e1, funge da pivot.
  • Intervallo di tempo: la sezione match ($host over 10m after $e1) definisce un intervallo di 10 minuti che inizia immediatamente dopo ogni evento $e1. Questa finestra scorre a ogni nuovo evento $e1.
  • Correlazione: gli eventi vengono raggruppati per nome host ($host).
  • Condizione per il rilevamento ($e1 e $e2): viene attivato un rilevamento per un determinato host se:
    • È presente un evento di firewall_1 ($e1).
    • AND, entro 10 minuti da quell'evento $e1 specifico, viene trovato l'evento NO di firewall_2 ($e2) per lo stesso host.

Esempio: rilevamento di eventi sequenziali mancanti

Regola

L'esempio seguente identifica le istanze in cui un evento secondario non si verifica dopo un attivatore principale. Utilizzando la condizione !$e2 in un intervallo di 10 minuti, questa regola segnala la telemetria mancante, in particolare quando un log del firewall viene visualizzato in una posizione, ma non viene visualizzato nell'hop successivo previsto, il che indica un potenziale divario di visibilità o un calo del traffico.

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
}

Cerca

L'esempio seguente mostra una ricerca sequenziale utilizzata per identificare le lacune nella telemetria tra due origini. Utilizzando $e1 come pivot, la ricerca cerca un evento firewall principale che non sia seguito da un evento corrispondente su un secondo firewall entro 10 minuti. Si tratta di un modo molto efficace per cercare manualmente "buchi neri" nel traffico di rete o errori di logging durante un'indagine.

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

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

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

condition:
  $e1 and !$e2

Dashboard

L'esempio seguente fornisce un'analisi del gap di visibilità progettata per una visualizzazione della dashboard. Aggregando le istanze in cui un evento secondario non segue un evento principale, puoi visualizzare l'affidabilità della pipeline di logging nel tempo. Il tracciamento di questi eventi "mancanti" aiuta a identificare le zone morte persistenti nella visibilità della rete o i problemi di configurazione in nomi host specifici.

$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

Query multi-evento

  • Caso d'uso: identifica attività ad alta frequenza o di tipo brute force monitorando una singola entità (ad esempio, un utente o un host) in più occorrenze di un evento all'interno di una finestra temporale specifica.

  • Logica chiave: utilizza una sezione match per raggruppare gli eventi in base a una variabile specifica e una sezione condition per verificare un conteggio soglia (ad esempio, #e >= 10) all'interno dell'intervallo di tempo definito.

Una tipica regola multi-evento include:

  • Variabili evento per distinguere gli eventi.
  • Una sezione match che specifica l'intervallo di tempo in cui devono essere raggruppati gli eventi.
  • Una sezione condition che specifica quale condizione deve attivare il rilevamento e controllare l'esistenza di più eventi.

Nella Ricerca, le query multi-evento sono definite da più di un evento in una query. Per le regole, esistono due modi per definire questo aspetto:

  • Più eventi: ad esempio, event1 = successful login, event2 = failed login.

  • Attivatori basati sulle condizioni: la condizione è indicata per attivarsi solo quando più eventi soddisfano i criteri (ad esempio, event1 > 10). Questo tipo di regola deve includere anche una sezione outcome.

Esempio: rilevamento degli accessi ad alta frequenza

Regola

La seguente regola cerca un utente che ha eseguito l'accesso almeno 10 volte in meno di 10 minuti:

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
}

Cerca

L'esempio seguente utilizza una ricerca di statistiche su più eventi per identificare l'attività di accesso ad alta frequenza. Segnala qualsiasi istanza in cui un singolo utente genera 10 o più eventi di accesso in un periodo di 10 minuti (10m).

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

match:
  $user by 10m

condition:
  #e >= 10

Dashboard

Il seguente esempio utilizza una ricerca multi-evento per monitorare potenziali compromissioni dell'account. Correlano i tentativi di accesso in un intervallo di tempo mobile di 10 minuti e identificano i casi in cui un utente e un host specifici registrano più tentativi di accesso non riusciti seguiti da uno riuscito, consentendoti di visualizzare in tempo reale i pattern di autenticazione ad alto rischio.

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

match:
  $user by 10m

condition:
  #e >= 10

Query multi-evento con risultati calcolati

  • Caso d'uso: applica la logica condizionale per impostare un risk_score in base alla gravità della risorsa o al volume della rete.

  • Logica chiave: utilizza la sezione outcome per calcolare le variabili e la sezione delle condizioni per filtrare in base a queste variabili.

Esempio: attacco di tipo Brute Force seguito da accesso riuscito

L'esempio seguente utilizza la sezione outcome per conteggiare gli eventi all'interno di una finestra match. Questa query genera lo stesso output della query multievento standard, ma mostra come incorporare le variabili calcolate nella logica di rilevamento.

Regola

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
}

Cerca

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

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

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

Dashboard

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

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

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

Esempio: corrispondenza degli host con finestre temporali

Regola

La seguente regola esamina due eventi per ottenere il valore di $hostname. Se il valore di $hostname corrisponde a un periodo di 5 minuti (5m), viene applicato un punteggio di gravità. Quando includi un periodo di tempo nella sezione match, la regola esegue il controllo entro il periodo di tempo specificato.

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

Cerca

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

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

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

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

Dashboard

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

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

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

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

Rilevamenti compositi

I rilevamenti compositi migliorano il rilevamento delle minacce utilizzando regole composite. Queste regole composite utilizzano come input i rilevamenti di altre regole. Ciò consente il rilevamento di minacce complesse che le singole regole potrebbero non rilevare. Per maggiori informazioni, consulta la panoramica dei rilevamenti compositi.

Argomento Esempi
Filtro ad alto rischio Rilevamento degli utenti amministrativi
Aggregazione e definizione delle soglie Aggregazione dei rischi
Aggregazione delle tattiche Aggregazione delle tattiche MITRE
Rilevamenti compositi sequenziali Tentativo di attacco di tipo brute force seguito da accesso riuscito
Rilevamento sensibile al contesto Arricchimento della threat intelligence
Rilevamenti di co-occorrenza Co-occorrenza di escalation dei privilegi ed esfiltrazione

Filtro ad alto rischio

Caso d'uso: filtra le rilevazioni esistenti per attributi ad alto rischio, ad esempio attività che coinvolgono account amministrativi.

Logica chiave: opera su risultati o campi di metadati all'interno dei risultati esistenti.

I rilevamenti compositi di filtraggio ad alto rischio sono la forma più semplice di rilevamento composito che opera sui campi all'interno dei risultati del rilevamento, come le variabili di risultato o i metadati delle regole. Aiutano a filtrare i rilevamenti per le condizioni che potrebbero indicare un rischio maggiore, ad esempio un utente amministratore o un ambiente di produzione.

Esempio: rilevamento di utenti amministrativi

Regola

La seguente regola composita cerca eventuali rilevamenti esistenti in cui l'attore è identificato come utente amministrativo e applica un punteggio di rischio standardizzato.

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
}

Cerca

La seguente ricerca statistica identifica e aggrega l'attività per gli account con privilegi elevati. È progettato per mostrare tutti i nomi univoci delle regole che hanno attivato rilevamenti che coinvolgono utenti "amministratore" o "root".

In questa query specifica, l'intervallo di tempo viene rimosso per eseguire una singola analisi statistica su tutti i rilevamenti nel periodo di tempo selezionato. Inoltre, poiché si tratta di una ricerca non aggregata incentrata sui dati di rilevamento esistenti, le sezioni Eventi, Variabili evento e Condizione non sono obbligatorie.

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

match:
  $principal_user

outcome:
  $upstream_rules = array_distinct($rule_name)

Dashboard

Questa query della dashboard ti consente di visualizzare quali regole specifiche rilevano più spesso attività correlate all'amministrazione. È progettato per fornire una panoramica generale delle tendenze di rilevamento nel tuo ambiente.

Nota la variazione della variabile match e dell'aggregazione outcome rispetto agli esempi precedenti. Questa query raggruppa i risultati in base al nome della regola e calcola un conteggio degli utenti amministratore rilevati per ciascuna regola.

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

Aggregazione e definizione delle soglie

Caso d'uso: identifica gli utenti o gli host che generano un volume elevato di avvisi o accumulano punteggi di rischio significativi nel tempo.

Logica chiave: utilizza sum() o count_distinct() per analizzare i dati di rilevamento aggregati.

Le regole di rilevamento composite di aggregazione consentono di raggruppare i risultati del rilevamento in base ad attributi condivisi, come un nome host o un nome utente, e analizzare i dati aggregati. Ecco alcuni casi d'uso comuni:

  • Identificare gli utenti che generano un volume elevato di avvisi di sicurezza o un rischio aggregato.
  • Rilevamento di host con pattern di attività insoliti mediante l'aggregazione di rilevamenti correlati.

Esempio: aggregazione dei rischi

Regola

Questa regola aggrega il punteggio di rischio di un singolo utente in un periodo di 48 ore. Identifica gli utenti il cui rischio cumulativo in più rilevamenti supera una soglia specifica.

In questa logica aggiornata, detection.detection.outcomes viene sostituito dalle variabili del campo della mappa, che memorizzano sia le variabili match che outcome. Inoltre, la variabile di risultato $principal_users viene rimossa perché ogni rilevamento contiene esattamente un valore della variabile di corrispondenza, che è già acquisito.

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
}

Cerca

Questa ricerca statistica aggrega i dati di rilevamento per calcolare il rischio totale di un utente in un periodo di 48 ore. Restituisce una riga per ogni utente principale per ogni finestra, fornendo una visione generale del rischio dell'account in base a più tipi di rilevamento.

In questa variante, le variabili evento non sono obbligatorie. Mentre il motore delle regole filtra automaticamente i rilevamenti senza un utente principale, questa ricerca richiede un filtro esplicito ($principal_user != "") per assicurarsi che i risultati includano solo dati compilati. Per impostazione predefinita, la query restituisce risultati solo quando è presente una o più rilevazioni per un determinato utente.

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

match:
  $principal_user over 48h

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

condition:
  $cumulative_risk > 500

Dashboard

Questa variante è progettata specificamente per le dashboard per tracciare il rischio utente e l'attività di rilevamento nel tempo. Aggrega i dati in bucket discreti, il che lo rende ideale per visualizzare tendenze come il volume di regole uniche attivate o il conteggio totale dei rilevamenti per utente.

In questa query, la finestra viene cambiata da una finestra scorrevole (hop) a una finestra a cascata (by 48h). In questo modo, i punti dati vengono mappati a segmenti di tempo non sovrapposti, il che fornisce una visualizzazione più pulita per i grafici delle serie temporali. Come per le altre ricerche non aggregate, le variabili evento non sono obbligatorie e la sezione outcome viene espansa per includere conteggi distinti sia per i nomi delle regole sia per gli ID rilevamento.

$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

Aggregazione delle tattiche

Caso d'uso: identifica gli utenti la cui attività ha attivato rilevamenti in più tattiche MITRE ATT&CK distinte, suggerendo un ciclo di vita dell'attacco in corso (ad esempio, il passaggio da Accesso iniziale a Esfiltrazione).

Logica chiave: utilizza count_distinct($tactic) per attivarsi solo quando un utente supera una soglia specifica di tattiche diverse in un periodo di 48 ore.

Esempio: aggregazione delle tattiche MITRE

Regola

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 }

Cerca

L'esempio seguente mostra una variante di ricerca progettata per gli sviluppatori di sicurezza che devono correlare i rilevamenti esistenti e applicare la ponderazione dinamica del rischio. Questa logica di query estrae le tattiche MITRE ATT&CK e le informazioni utente dall'origine dati detection, raggruppa l'attività in base all'utente principale e calcola un punteggio di rischio personalizzato in base alla diversità delle tattiche osservate.

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

match:
  $principal_user

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

Dashboard

L'esempio seguente illustra una variante di Dashboard della stessa logica di analisi del rilevamento. Se utilizzata all'interno delle dashboard di Google SecOps, questa query consente agli sviluppatori di visualizzare gli utenti ad alto rischio mettendo in correlazione i risultati del rilevamento in diverse regole. La logica estrae l'utente principale e le tattiche MITRE, aggrega i risultati e applica un punteggio di rischio limitato per dare la priorità alle attività di indagine direttamente all'interno di un widget della dashboard.

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)
  ```

Rilevamenti compositi sequenziali

Caso d'uso: identifica i pattern di attacco critici in cui l'ordine delle operazioni è essenziale, ad esempio il rilevamento di un accesso all'account riuscito che si verifica solo dopo una serie di avvisi di tentativi di attacco di tipo brute force dallo stesso indirizzo IP.

Logica chiave: mette in correlazione un rilevamento precedente con un evento UDM non elaborato successivo unendoli in base a una variabile comune (ad esempio $bruteforce_ip) e utilizzando un confronto dei timestamp per garantire che gli eventi si siano verificati nella sequenza corretta.

I rilevamenti compositi sequenziali identificano pattern di eventi correlati in cui la sequenza di rilevamenti è importante, ad esempio un rilevamento di un tentativo di accesso con attacco di tipo brute force, seguito da un accesso riuscito. Questi pattern possono coinvolgere più rilevamenti di base o una combinazione di rilevamenti di base ed eventi.

Esempio: tentativo di attacco di tipo brute force seguito da accesso riuscito

Regola

La seguente regola composita identifica i pattern di eventi correlati in cui la sequenza è importante. Cerca in particolare un rilevamento di attacco di tipo brute force di Google Workspace seguito da un evento di accesso riuscito dalla stessa origine IP entro un periodo di 24 ore.

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
}

Cerca

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

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

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

$target_account = $login_event.target.user.email_addresses

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

match:
  $bruteforce_ip over 24h

outcome:
  $principal_users = array_distinct($target_account)

condition:
  $bruteforce_detection and $login_event

Dashboard

Le dashboard si concentrano sulla visualizzazione dei dati degli eventi non elaborati, mentre la logica di rilevamento composita correla gli avvisi di rilevamento esistenti con gli eventi successivi. Questa analisi multilivello è ottimizzata per il motore di rilevamento anziché per i widget della dashboard in tempo reale.

Rilevamento sensibile al contesto

Caso d'uso: arricchisci i rilevamenti esistenti con la threat intelligence esterna per verificare se un avviso riguarda entità dannose note, ad esempio controllando se un indirizzo IP segnalato in un rilevamento di sicurezza è presente anche in un feed globale di minacce dei nodi di uscita TOR.

Logica chiave: utilizza regole composite per unire i risultati del rilevamento con i dati del grafico GLOBAL_CONTEXT (ad esempio, i feed Google Cloud Threat Intelligence) abbinando un attributo condiviso come un indirizzo IP.

I rilevamenti compositi sensibili al contesto arricchiscono i rilevamenti con un contesto aggiuntivo, ad esempio gli indirizzi IP trovati nei feed delle minacce.

Esempio: arricchimento della threat intelligence

Regola

La seguente regola composita aggiunge automaticamente un contesto aggiuntivo dal feed di intelligence TOR ai rilevamenti esistenti. Correla un indirizzo IP trovato in un rilevamento precedente con il feed dei nodi di uscita TOR per aumentare la gravità e il punteggio di rischio del risultato.

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
}

Cerca

``` $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 ```

Dashboard

Rilevamenti di co-occorrenze

Caso d'uso: rileva una combinazione di tattiche correlate attivate dalla stessa entità in un periodo di tempo specifico, ad esempio, identifica un utente che ha attivato sia il rilevamento dell'escalation dei privilegi sia il rilevamento dell'esfiltrazione di dati entro 48 ore.

Logica chiave: utilizza una forma di aggregazione per correlare più tipi di rilevamento distinti unendoli in una variabile di entità condivisa (ad esempio $pe_user) all'interno della sezione match.

I rilevamenti compositi di co-occorrenza sono una forma di aggregazione che può rilevare una combinazione di eventi correlati, ad esempio una combinazione di rilevamenti di escalation dei privilegi esfiltrazione di datiti attivati da un utente.

Esempio: co-occorrenza di escalation dei privilegi ed esfiltrazione

Regola

La seguente regola composita cerca una sequenza o una combinazione specifica di rilevamenti (escalation dei privilegi seguita da esfiltrazione) associata allo stesso utente in un periodo di 48 ore.

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
}

Cerca

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

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

$privesc_user = $exfil_user

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

match:
  $privesc_user over 48h

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

condition:
  $privilege_escalation and $exfiltration

Dashboard

Gestione di risultati e variabili

Questa sezione mostra esempi di calcolo del rischio e normalizzazione dei dati per il consumo downstream.

Argomento Esempi
Condizionali per i risultati Filtrare in base al punteggio di rischio calcolato
Query su un singolo evento con risultato Tagging della gravità point-in-time
Punteggio di rischio basato sulla rete Regola di assegnazione del punteggio di rischio basata sulla rete
Refactor multi-event logic (pre-refactor) Refactoring dell'esito (pre-refactoring)
Refactor multi-event logic (post-refactor) Rifattorizzazione dell'esito (post-rifattorizzazione)
Assegnazione della funzione al segnaposto

Query con la sezione outcome

Puoi aggiungere la sezione facoltativa outcome in una regola YARA-L 2.0 per estrarre informazioni aggiuntive di ogni rilevamento. Nella sezione condition puoi anche specificare condizioni sulle variabili di risultato. Puoi utilizzare la sezione outcome di una regola di rilevamento per impostare le variabili per l'utilizzo a valle. Ad esempio, puoi impostare un punteggio di gravità in base ai dati degli eventi analizzati.

Per ulteriori informazioni, consulta le seguenti risorse:

Condizionali del risultato

Caso d'uso: filtra i rilevamenti in base ai punteggi di rischio calcolati per ridurre il rumore e assicurarti che solo gli eventi ad alta confidenza o gravità attivino avvisi. Ciò è utile per eliminare le attività a basso rischio che non soddisfano una soglia aziendale specifica.

Logica chiave: definisce le variabili nella sezioneoutcome utilizzando la matematica condizionale (ad esempio, aggiungendo il rischio in base alle dimensioni del file o all'ora del giorno) e poi fa riferimento a queste variabili nella sezionecondition per controllare il rilevamento.

Esempio: filtra per punteggio di rischio calcolato

Regola

Nella sezione condition, puoi utilizzare le variabili outcome definite nella sezione outcome. L'esempio seguente mostra come filtrare i punteggi di rischio per ridurre il rumore nei rilevamenti utilizzando le condizioni dei risultati.

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
}

Cerca

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

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

outcome:
  $risk_score =
      if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
      if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
      if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
      if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

Dashboard

Questa query aggiunge la variabile di risultato $hostname per visualizzare gli host associati a ciascun punteggio di rischio.

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

Query su un singolo evento con risultato

Caso d'uso: arricchisci i rilevamenti puntuali con il contesto immediato, ad esempio assegnando tag di gravità in base agli elenchi di utenti o agli attributi dei file senza richiedere una finestra temporale o la correlazione degli eventi.

Logica chiave: utilizza la sezione outcome in una regola che non ha una sezione match. In questo modo puoi estrarre i metadati ed eseguire la logica condizionale (ad esempio, il controllo di un utente rispetto a un elenco di riferimento) per ogni singolo evento che soddisfa i criteri.

Esempio: tagging della gravità in un momento specifico

Regola

Il seguente esempio mostra come utilizzare la sezione outcome in una regola a evento singolo per impostare le variabili per l'utilizzo a valle, ad esempio impostando un punteggio di gravità in base all'utente specifico e alle dimensioni del file coinvolti in un evento di copia del file.

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
}

Cerca

L'esempio seguente identifica gli eventi di creazione di file e utilizza la sezione outcome per assegnare dinamicamente i livelli di gravità a ogni risultato. A differenza delle regole multi-evento, questa ricerca non aggregata non richiede variabili evento o una sezione match. Elabora invece ogni log singolarmente per generare 1 row per event, arricchito con una logica personalizzata basata sulle dimensioni del file e sulle autorizzazioni utente.

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

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

Dashboard

Una variante della dashboard non è applicabile a questo esempio, in quanto l'intento principale è taggare e arricchire i singoli eventi. Anche se una dashboard potrebbe aggregare questi eventi (ad esempio, calcolando il conteggio totale degli eventi per tag di gravità), in questo modo si oscurerebbe il dettaglio granulare a livello di riga che questa ricerca non aggregata è progettata per mostrare.

Punteggio di rischio basato sulla rete

Caso d'uso: identifica i trasferimenti di dati ad alto rischio calcolando il volume cumulativo del traffico di rete in un gruppo di eventi. In questo modo, puoi identificare le minacce in cui la soglia di dati totale supera un limite specifico (ad esempio, 1024 byte), tenendo conto contemporaneamente della gravità della vulnerabilità delle risorse coinvolte.

Logica chiave: utilizza la funzione di aggregazione sum() nella sezione outcome per combinare sent_bytes e received_bytes in tutti gli eventi in una finestra match. Per le regole, la query utilizza un'istruzione if per applicare un punteggio di rischio più elevato se la somma supera una soglia definita.

Esempio: regola di assegnazione del punteggio di rischio basata sulla rete

Regola

L'esempio seguente mostra come utilizzare la sezione outcome per calcolare un punteggio di rischio dinamico in base all'attività di rete. Sommando i byte totali trasferiti in un gruppo di eventi, la regola applica una priorità più alta alle corrispondenze che superano una soglia di dati specifica (1024 byte), tenendo conto contemporaneamente della gravità della vulnerabilità dell'asset coinvolto.

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

Cerca

L'esempio seguente mostra una variante di ricerca che correla gli eventi di rete UDM con il contesto degli asset del grafico del contesto delle entità (ECG). Utilizza una finestra di match minuti per aggregare il traffico di rete per nome host, calcola un punteggio di rischio in base al volume di dati e alla gravità della vulnerabilità e applica un filtro condizionale per escludere ID asset specifici dal set di risultati finale.

$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname

$severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

  $risk_score = if($total_network_bytes > 1024, 100, 50) +
    max(
      if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
        "Empty asset id",
        $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")

Dashboard

L'esempio seguente illustra una variante di Dashboard che arricchisce la telemetria di rete in tempo reale con i dati sulle vulnerabilità degli asset. Corrispondendo i nomi host in una finestra mobile di 5 minuti, questa query consente agli sviluppatori di creare widget della dashboard che visualizzano i livelli di rischio degli asset. La logica regola dinamicamente un punteggio di rischio in base alla velocità effettiva di rete e alla vulnerabilità con la gravità più elevata rilevata nell'asset, fornendo una visualizzazione con priorità dei sistemi potenzialmente compromessi.

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

Refactoring di una regola outcome multi-evento (pre-refactoring)

Caso d'uso: migliora le prestazioni del sistema e riduci la latenza di elaborazione convertendo le regole multi-evento in regole single-event. Questa opzione è ideale per le regole originariamente progettate con una sola sezione di corrispondenza per abilitare la sezione dei risultati, ma che in realtà non richiedono la correlazione tra più eventi distinti.

Logica chiave: rimuove la sezione match e qualsiasi funzione aggregata (ad esempio max(), sum() o count()) dalla sezione outcome. Questa transizione sposta la regola dal raggruppamento degli eventi nel tempo alla valutazione di ogni evento singolarmente man mano che arriva. match) e regole a più eventi (regole con una sezione match).

Puoi utilizzare la sezione outcome sia per le regole a evento singolo (regole senza una Se in precedenza hai progettato una regola in modo che fosse multi-evento solo per poter utilizzare la sezione Risultato, puoi facoltativamente eseguire il refactoring di queste regole eliminando la sezione match per migliorare le prestazioni. Tieni presente che, poiché la regola non ha più una sezione match che applica il raggruppamento, potresti ricevere più rilevamenti.

Esempio: Refactoring del risultato (pre-refactoring)

Regola

Il seguente esempio mostra una regola di esito multi-evento che utilizza una sola variabile evento. Poiché utilizza una sezione match, il motore delle regole deve raggruppare gli eventi in un intervallo di 5 minuti prima di calcolare il risultato, il che consuma più risorse rispetto a una valutazione di un singolo evento.

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
}

Cerca

Query equivalente per le statistiche

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

match:
  $hostname over 5m

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

condition:
  $u

Dashboard

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

match:
  $hostname over 5m

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

condition:
  $u

Refactoring di una regola outcome multi-evento (post-refactoring)

Caso d'uso: finalizzazione dell'ottimizzazione di una query per migliorare la velocità di elaborazione. Rimuovendo il requisito di raggruppamento, la query ora attiva un rilevamento immediatamente all'arrivo di un singolo evento corrispondente, il che è molto più efficiente per il motore delle regole.

Logica chiave: elimina la sezione match e rimuove la funzione aggregate (ad esempio, max()) dall'assegnazione della variabile outcome. La logica all'interno dell'istruzione if rimane invariata, ma ora viene applicata a un singolo evento anziché a un gruppo.

Puoi eseguire il refactoring della query eliminando la sezione match. Nota: devi rimuovere anche l'aggregazione nella sezione outcome perché la query ora è un singolo evento. Per saperne di più sulle aggregazioni, consulta Aggregazioni dei risultati.

Esempio: Outcome refactor (: #outcome-post-refactor)

Regola

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
}

Cerca

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

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

Dashboard

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

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

Assegnazione funzione-segnaposto

Caso d'uso: normalizza i dati (ad esempio, standardizza i domini email) per verificare che il raggruppamento nella sezione Corrispondenza sia accurato.

Logica principale: assegna il risultato di re.capture() o strings.concat() a una variabile segnaposto.

Esempio: assegnazione di variabili da funzione a segnaposto

Puoi assegnare una variabile segnaposto al risultato di una chiamata di funzione e utilizzarla in altre sezioni della regola, ad esempio nelle sezioni match, outcome o condition.

Regola

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
}

Cerca

metadata.event_type = "EMAIL_TRANSACTION"

// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture(network.email.from , "(.*)@")

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

// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.event_timestamp.seconds)

match:
  // Use placeholder (from function-placeholder assignment) in match section.
  // Group by the normalized from email, and expose it in the detection.
  $email_from_normalized over 5m

outcome:
  // Use placeholder (from function-placeholder assignment) in outcome section.
  // Assign more risk if the event happened on weekend.
  $risk_score = max(
    if($dayofweek = 1 or $dayofweek = 7, 10, 0)
    )

condition:
  // Use placeholder (from function-placeholder assignment) in condition section.
  // Match if an email was sent to multiple addresses.
  #email_to_address_only > 1

Dashboard

L'esempio seguente mostra una variante di Dashboard ottimizzata per la visualizzazione delle serie temporali. Utilizzando una finestra a cascata di un giorno, anziché una granularità a livello di minuti, questa query produce punti dati stabili e non sovrapposti, ideali per tracciare i punteggi di rischio per un periodo di tempo prolungato. La logica normalizza le entità email e applica ponderazioni di rischio più elevate alle transazioni del fine settimana, fornendo una tendenza giornaliera chiara dell'attività email sospetta per il monitoraggio a lungo termine.

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

Ottimizzazione e filtri

L'ottimizzazione efficace delle regole si basa su un filtraggio preciso dei dati per garantire che il motore di rilevamento elabori solo informazioni significative. Escludendo i dati "rumorosi" o incompleti, puoi migliorare significativamente il rendimento delle regole e assicurarti che gli avvisi generati siano azionabili.

Argomento Esempi
Esclusione dei valori zero Esclusione esplicita e implicita del valore zero

Esclusione dei valori zero

Caso d'uso: assicurati dell'accuratezza delle regole e riduci i falsi positivi filtrando esplicitamente le stringhe vuote, i valori null o gli account segnaposto generici (ad esempio "Ospite") che non forniscono dati di sicurezza utilizzabili.

Logica chiave: sfrutta il filtro implicito dei valori zero per le variabili utilizzate nella sezione match del motore di regole, utilizzando operatori di disuguaglianza espliciti (!= "") per altri campi evento per assicurarsi che solo i dati compilati attivino un rilevamento.

Rules Engine filtra implicitamente i valori zero per tutti i segnaposto utilizzati nella sezione match. Utilizza l'opzione allow_zero_values per disattivarlo. Tuttavia, per gli altri campi evento a cui viene fatto riferimento, i valori pari a zero non vengono esclusi, a meno che tu non specifichi esplicitamente queste condizioni. Per maggiori informazioni, vedi Valori zero nella sezione Corrispondenza.

Esempio: esclusione di valori zero espliciti e impliciti

Regola

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
}

Cerca

Devi dichiarare esplicitamente che hostname non può essere una stringa vuota, poiché non esiste un filtro implicito con valore zero per i segnaposto nella sezione 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

Dashboard

Devi dichiarare esplicitamente che hostname non può essere una stringa vuota, poiché non esiste un filtro implicito con valore zero per i segnaposto nella sezione 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

Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.