Panoramica del linguaggio YARA-L 2.0
YARA-L 2.0 è un linguaggio informatico utilizzato per creare regole per la ricerca nei dati di log aziendali quando vengono importati nell'istanza Chronicle. La sintassi YARA-L è derivata dal linguaggio YARA sviluppato da VirusTotal. Il linguaggio funziona in combinazione con Chronicle Detection Engine e consente di ricercare minacce e altri eventi in grandi volumi di dati.
Per ulteriori informazioni, consulta le seguenti risorse:
Regole di esempio YARA-L 2.0
I seguenti esempi mostrano regole scritte in YARA-L 2.0. Ognuna mostra come correlare gli eventi all'interno del linguaggio delle regole.
Regole e ottimizzazione
La seguente regola verifica la presenza di pattern specifici nei dati sugli eventi e, se li trova, crea un rilevamento. 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
dell'espressione regolare con e1
. Quando si verifica l'evento $e1
, viene creato un rilevamento.
Una condizione not
è inclusa nella regola 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
}
Accessi da città diverse
La seguente regola cerca gli utenti che hanno eseguito l'accesso alla tua azienda da due o più città in meno di 5 minuti:
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
}
Variabile di corrispondenza: $user
Variabile evento:$udm
Variabile segnaposto: $city
e $user
Di seguito viene descritto il funzionamento di questa regola:
- Raggruppa gli eventi con il nome utente (
$user
) e lo restituisce ($user
) quando viene trovata una corrispondenza. - Il periodo di tempo è di 5 minuti, il che significa che sono correlati solo gli eventi a distanza di meno di 5 minuti.
- Ricerca di un gruppo di eventi (
$udm
) il cui tipo di evento è USER_LOGIN. - Per questo gruppo di eventi, la regola chiama l'ID utente
$user
e la città di accesso come$city.
- Restituisce una corrispondenza se il numero distinto di valori
city
(indicati da#city
) è maggiore di 1 nel gruppo di eventi ($udm
) nell'intervallo di tempo di 5 minuti.
Creazione ed eliminazione rapide degli utenti
La regola seguente cerca gli utenti che sono stati creati e poi eliminati entro 4 ore:
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
}
Variabili evento:$create
e $delete
Variabile di corrispondenza: $user
Variabile segnaposto: N/D
Di seguito viene descritto il funzionamento di questa regola:
- Raggruppa gli eventi con il nome utente (
$user
) e lo restituisce ($user
) quando viene trovata una corrispondenza. - La finestra temporale è di 4 ore, il che significa che sono correlati solo gli eventi separati da meno di 4 ore.
- Cerca due gruppi di eventi (
$create
e$delete
, dove$create
è equivalente a#create >= 1
). $create
corrisponde agli eventiUSER_CREATION
e chiama l'ID utente come$user
.$user
viene utilizzato per unire i due gruppi di eventi.$delete
corrisponde agli eventiUSER_DELETION
e chiama l'ID utente come$user
. Questa regola cerca una corrispondenza in cui l'identificatore utente nei due gruppi di eventi è lo stesso.- Questa regola cerca i casi in cui l'evento di
$delete
si verifica dopo l'evento di$create
, restituendo una corrispondenza quando viene rilevata.
Regola per evento singolo
Le regole per eventi singoli sono regole correlate a un singolo evento. Una singola regola per evento può essere:
- Qualsiasi regola senza una sezione di corrispondenza.
- Una regola con una sezione
match
e una sezionecondition
verifica soltanto l'esistenza di un evento (ad esempio, "$e", "#e > 0", "#e >= 1", "1 <= #e", "0 < #e").
Ad esempio, la regola seguente cerca un evento di accesso utente e restituisce il primo evento che rileva nei dati aziendali archiviati nel tuo account Chronicle:
rule SingleEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
Ecco un altro esempio di regola per un singolo evento con una sezione di corrispondenza. Questa regola cerca un utente che ha eseguito l'accesso almeno una volta in meno di 5 minuti. Verifica la semplice 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
}
rule MultiEventRule{
meta:
author = "alice@example.com"
description = "Rule with outcome condition and simple existence condition on one event variable"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 10m
outcome:
$num_events_in_match_window = count($e.metadata.id)
condition:
#e > 0 and $num_events_in_match_window >= 10 // Could be rewritten as #e >= 10
}
Regola per più eventi
Usare più regole di eventi per raggruppare molti eventi in un periodo di tempo specificato e provare a trovare correlazioni tra gli eventi. Una tipica regola per eventi multipli avrà quanto segue:
- Una sezione
match
che specifica l'intervallo di tempo durante il quale gli eventi devono essere raggruppati. - Una sezione
condition
che specifica quale condizione deve attivare il rilevamento e il controllo dell'esistenza di più eventi.
Ad esempio, la regola seguente 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
}
Singolo evento all'interno dell'intervallo di indirizzi IP
L'esempio seguente mostra una regola per un singolo evento che cerca una corrispondenza tra due utenti 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
}
esempio di una o tutte le regole
La regola seguente cerca gli eventi di accesso in cui tutti gli indirizzi IP di origine non corrispondono a un indirizzo IP noto per essere sicuro entro un periodo di tempo di 5 minuti.
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
}
Espressioni regolari in una 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 della variabile $host
regex
e alla funzione regex
, entrambi questi confronti non fanno distinzione tra maiuscole e minuscole.
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
}
Esempio di regola per le finestre scorrevoli
Il seguente esempio di finestra scorrevole YARA-L 2.0 cerca l'assenza di
eventi firewall_2
dopo gli eventi firewall_1
. La parola chiave after
viene utilizzata con la variabile evento pivot $e1
per specificare che solo le finestre di 10 minuti dopo ogni evento firewall_1
devono essere controllate durante la correlazione degli eventi.
rule SlidingWindowRuleExample {
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:
$host over 10m after $e1
condition:
$e1 and !$e2
}
Esempio di esclusione valore zero
Il Motore regole filtra in modo implicito i valori zero per tutti i segnaposto utilizzati nella sezione match
.
Per maggiori informazioni, consulta la sezione sulla gestione del valore pari a zero nella sezione match
.
Questa opzione può essere disattivata utilizzando l'opzione allow_zero_values
come
descritto in allow_zero_values.
Tuttavia, per altri campi evento di riferimento, i valori pari a zero non vengono esclusi, a meno che non specifichi esplicitamente queste condizioni.
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
}
Esempio di regola con sezione outcome
Puoi aggiungere la sezione facoltativa outcome
nella regola YARA-L 2.0 per estrarre informazioni aggiuntive su ogni rilevamento. Nella sezione Condizioni, puoi anche specificare
condizionali sulle variabili risultato. Puoi utilizzare la sezione outcome
di una regola di rilevamento per impostare variabili per il consumo downstream. Ad esempio, puoi impostare un punteggio di gravità in base ai dati degli eventi analizzati.
Per ulteriori informazioni, consulta le seguenti risorse:
- Sintassi della sezione dei risultati
- Sintassi delle condizioni condizionali dei risultati
- Panoramica della sezione
outcome
Regola per più eventi con sezione dei risultati:
La seguente regola esamina due eventi per ottenere il valore di
$hostname
. Se il valore di $hostname
corrisponde a un periodo di 5 minuti, viene applicato un punteggio di gravità. Se includi un periodo di tempo nella sezione match
, la regola esegue un controllo all'interno del 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")
}
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")
}
Regola per evento singolo con sezione dei risultati:
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.userid in %admin_users, "SEVERE", "MODERATE")
$severity_tag = if($file_size > 1024, $admin_severity, "LOW")
condition:
$u
}
Refactoring di una regola del risultato multi-evento in una regola del risultato singolo.
Puoi utilizzare la sezione outcome
sia per le regole per evento singolo (regole senza una sezione match
) sia per le regole per più eventi (regole con una sezione match
).
Se in precedenza hai progettato una regola in modo che sia multi-evento in modo da poter utilizzare la sezione dei risultati, se vuoi puoi eseguire il refactoring di queste regole eliminando la sezione match
per migliorare le prestazioni. Tieni presente che, poiché la tua regola non ha più una sezione match
che applica il raggruppamento, potresti ricevere più rilevamenti. Questo refactoring è possibile solo per le regole che utilizzano una variabile evento, come mostrato nell'esempio seguente.
Regola del risultato di più eventi che utilizza una sola variabile di evento (un buon candidato per un refactoring):
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
}
Puoi modificare i fattori della regola eliminando la sezione match
. Tieni presente che
devi rimuovere anche l'aggregazione nella sezione outcome
poiché la regola ora sarà
a evento singolo. Per saperne di più sulle aggregazioni, consulta la sezione relativa alle aggregazioni dei risultati.
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
}
Esempio di regola da funzione a segnaposto
Puoi assegnare una variabile segnaposto al risultato di una chiamata di funzione e
utilizzare la variabile segnaposto in altre sezioni della regola, ad esempio
la sezione match
, outcome
o condition
. Vedi l'esempio che segue:
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.from , "(.*)@")
// Use function-placeholder assignment to normalize an email:
// uid@??? -> uid@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, 10, 0) +
if($dayofweek = 7, 10, 0)
)
condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1
}
Esempio di regola condizionale per i risultati
Nella sezione condition
, puoi utilizzare le variabili risultato definite
nella sezione outcome
. L'esempio seguente mostra come filtrare in base ai 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
}