Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Sintassi del linguaggio YARA-L 2.0

Questa sezione descrive gli elementi principali della sintassi YARA-L. Vedi anche l'articolo Panoramica della lingua YARA-L 2.0.

Struttura della regola

Per YARA-L 2.0, devi specificare dichiarazioni, definizioni e utilizzi delle variabili nel seguente ordine:

  1. Meta
  2. eventi
  3. match (facoltativo)
  4. output (facoltativo)
  5. condizione
  6. options (facoltativo)

Di seguito è illustrata la struttura generica di una regola:

rule <rule Name>
{
  meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  outcome:
    // Additional information extracted from each detection.

  condition:
    // Condition to check events and the variables used to find matches.

  options:
    // Options to turn on or off while executing this rule.
}

Commenti

Designa due commenti con due barre (// comment) o su più righe impostate utilizzando una barra (/* comment */), come faresti in C.

Valori letterali

Sono supportati numeri interi non negativi (senza punti decimali), stringhe, valori booleani e regex.

Valori letterali stringa e regex

Puoi utilizzare una delle seguenti virgolette per includere le stringhe in YARA-L 2.0. Il testo tra virgolette viene interpretato diversamente a seconda del testo utilizzato.

  1. Virgolette doppie (") - Da utilizzare per le stringhe normali. Deve includere caratteri di escape.
    Ad esempio: "hello\tworld" —\t è interpretato come scheda.

  2. Citazioni retro (`): utilizza per interpretare tutti i caratteri alla lettera.
    Ad esempio: 'hello\tworld' - \t non viene interpretato come scheda

Per le espressioni regolari, hai due opzioni.

Se vuoi utilizzare espressioni regolari direttamente senza la funzione re.regex(), utilizza /regex/ per i valori letterali delle espressioni regolari.

Puoi anche utilizzare valori letterali stringa come valori letterali regex quando utilizzi la funzione re.regex(). Tieni presente che, per i valori letterali delle stringhe con virgolette doppie, devi eseguire l'escape di quei caratteri con una barra rovesciata, che possono sembrare strani.

Ad esempio, le seguenti espressioni regolari sono equivalenti:

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

Per agevolare la leggibilità, Google consiglia di utilizzare le virgolette per le stringhe nelle espressioni regolari.

Operatori

In YARA-L puoi utilizzare i seguenti operatori:

Operatore Descrizione
= uguale/dichiarazione
!= non uguale
< minore di
<= minore o uguale a
> maggiore di
>= maggiore o uguale a

Variabili

In YARA-L 2.0, tutte le variabili sono rappresentate come $<variable name>.

Puoi definire i seguenti tipi di variabili:

  • Variabili evento: rappresentano gruppi di eventi in forma normalizzata (UDM) o eventi di entità. Specifica le condizioni per le variabili evento nella sezione events. Puoi identificare le variabili evento utilizzando un nome, un'origine evento e i campi evento. Le origini consentite sono udm (per eventi normalizzati) e graph (per eventi entità). Se la sorgente è omessa, udm è impostato come origine predefinita. I campi evento sono rappresentati come una catena di .<field name> (ad esempio, $e.field1.field2). Le catene di campi di eventi iniziano sempre dall'origine di primo livello (UDM o Entità).

  • Variabili di corrispondenza: dichiara nella sezione match. Le variabili di corrispondenza diventano campi di raggruppamento per la query, in quanto viene restituita una riga per ogni insieme univoco di variabili di corrispondenza (e per ogni finestra temporale). Quando la regola trova una corrispondenza, vengono restituiti i valori della variabile di corrispondenza. Specifica cosa rappresenta ogni variabile di corrispondenza nella sezione events.

  • Variabili segnaposto: dichiara e definisci nella sezione events. Le variabili segnaposto sono simili alle variabili di corrispondenza. Tuttavia, puoi utilizzare le variabili segnaposto nella sezione condition per specificare le condizioni di corrispondenza.

Utilizza le variabili di corrispondenza e le variabili segnaposto per dichiarare le relazioni tra i campi evento tramite condizioni di join transitorie (consulta la sintassi della sezione Eventi per ulteriori dettagli).

Maps

Strutture ed etichette

Alcuni campi UDM utilizzano il tipo di dati Struct o Etichetta.

Per cercare una coppia chiave-valore specifica sia in Struct che in Label, utilizza la sintassi standard della mappa:

// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

Richieste supportate

Sezione Eventi e risultati
// Using a Struct field in the events section
events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"

// Using a Label field in the outcome section
outcome:
  $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
Assegnare un valore mappa a un segnaposto
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
Utilizzare un campo mappa in una condizione di unione
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]

Richieste non supportate

Combinazione di any o all parole chiave con una mappa

Ad esempio, quanto segue non è attualmente supportato: all $e.udm.additional.fields["pod_name"] = "kube-scheduler"

Functions

Questa sezione descrive le funzioni YARA-L 2.0 supportate da Chronicle in Detection Engine.

Queste funzioni possono essere utilizzate nelle seguenti aree di una regola:

Funzioni di stringa

Chronicle supporta le seguenti funzioni di manipolazione delle stringhe:

  • string.concat(a, b)
  • string.to_lower(stringText)
  • string.to_upper(stringText)
  • strings.base64_decode(encodedString)

Le sezioni seguenti descrivono come utilizzare ognuno di essi.

Concatena stringhe o numeri interi

Restituisce la concatenazione di due stringhe, due numeri interi o una combinazione dei due.

strings.concat(a, b)

Questa funzione prende due argomenti, che possono essere stringhe o numeri interi e restituisce i due valori concatenati come stringa. I numeri interi vengono trasmessi a una stringa prima della concatenazione. Gli argomenti possono essere valori letterali o campi evento. Se entrambi gli argomenti sono campi, i due attributi devono provenire dallo stesso evento.

Il seguente esempio include una variabile stringa e un valore letterale stringa come argomenti.

"google-test" = strings.concat($e.principal.hostname, "-test")

L'esempio seguente include una variabile di stringa e una variabile di tipo intero come argomenti. Le entità principal.nomehost e principal.port provengono dallo stesso evento, $e e vengono concatenate per restituire una stringa.

"google80" = strings.concat($e.principal.hostname, $e.principal.port)

L'esempio seguente tenta di concatenare entità.port dall'evento $e1, con principal.hostname dall'evento $e2. Verrà restituito un errore del compilatore perché gli argomenti sono variabili di evento diverse.

// returns a compiler error
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

Converti stringa in maiuscolo o minuscolo

Queste funzioni restituiscono un testo stringa dopo la modifica di tutti i caratteri in maiuscole o minuscole.

  • string.to_lower(stringText)
  • string.to_upper(stringText)
"test@google.com" = strings.to_lower($e.network.email.from)
"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)

Base64 decodifica una stringa

Restituisce una stringa contenente la versione decodificata base64 della stringa codificata.

strings.base64_decode(encodedString)

Questa funzione utilizza una stringa codificata base64 come argomento. Se encodedString non è una stringa codificata Base64 valida, la funzione restituisce encodedString così com'è.

Questo esempio restituisce True se principal.domain.name è "dGVzdA==", che è la codifica di base64 per la stringa "test".

"test" = strings.base64_decode($e.principal.domain.name)

Funzioni regex

Chronicle supporta le seguenti funzioni di espressione regolare:

  • re.regex(stringText, regex)
  • re.capture(stringText, regex)
  • re-replace(stringText, replaceRegex, sostitutivoText)

Corrispondenza con espressione regolare

Puoi definire la corrispondenza delle espressioni regolari in YARA-L 2.0 utilizzando una delle seguenti sintassi:

  • Utilizzo della sintassi YARA: correlato agli eventi. Di seguito è riportata una rappresentazione generica di questa sintassi: $e.field = /regex/
  • Utilizzo della sintassi YARA-L: come funzione che accetta i seguenti parametri:
    • Campo a cui si applica l'espressione regolare.
    • Espressione regolare specificata come stringa. Puoi utilizzare il modificatore nocase dopo le stringhe per indicare che la ricerca deve ignorare le lettere maiuscole. Di seguito è riportata una rappresentazione generica di questa sintassi: re.regex($e.field, `regex`)

Tieni presente quanto segue durante la definizione delle espressioni regolari in YARA-L 2.0:

  • In entrambi i casi, il predicato è vero se la stringa contiene una sottostringa che corrisponde all'espressione regolare fornita. Non è necessario aggiungere .* all'inizio o alla fine dell'espressione regolare.
  • Per far corrispondere la stringa esatta o solo un prefisso o un suffisso, includi i caratteri di ancoraggio ^ (inizio) e $ (fine) nell'espressione regolare. Ad esempio, /^full$/ corrisponde esattamente a "full", mentre /full/ potrebbe corrispondere a "fullest", "lawfull" e "joyfully".
  • Se il campo UDM include caratteri di nuova riga, regexp corrisponde solo alla prima riga del campo UDM. Per applicare la corrispondenza completa dei campi UDM, aggiungi (?s) all'espressione regolare. Ad esempio, sostituisci /.*allUDM.*/ con /(?s).*allUDM.*/.

Acquisizione espressione regolare

Acquisisce (estrae) i dati da una stringa utilizzando il pattern dell'espressione regolare fornito nell'argomento.

re.capture(stringText, regex)

Questa funzione prende due argomenti:

  • stringText: la stringa originale in cui eseguire la ricerca.
  • regex: l'espressione regolare che indica il pattern da cercare.

L'espressione regolare può contenere 0 o 1 gruppo Capture tra parentesi. Se l'espressione regolare contiene 0 gruppi Capture, la funzione restituisce la prima sottostringa corrispondente. Se l'espressione regolare contiene 1 gruppo Capture, restituisce la prima sottostringa corrispondente per il gruppo Capture. La definizione di due o più gruppi Capture restituisce un errore del compilatore.

In questo esempio, se $e.principal.nomehost contiene "aaa1bbaa2", il seguente valore sarà True, perché la funzione restituisce la prima istanza. In questo esempio non sono presenti gruppi Capture.

"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")

In questo esempio è presente tutto ciò che segue il simbolo @ in un'email. Se il campo $e.network.email.from è test@google.com, l'esempio restituisce google.com. Questo esempio contiene un gruppo Capture.

"google.com" = re.capture($e.network.email.from , "@(.*)")

Se l'espressione regolare non corrisponde ad alcuna sottostringa nel testo, la funzione restituisce una stringa vuota. Puoi omettere gli eventi per cui non si verifica alcuna corrispondenza escludendo la stringa vuota, il che è particolarmente importante quando utilizzi re.capture() con disuguaglianza:

// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")

// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")

Sostituzione regex

Esegue una sostituzione dell'espressione regolare.

re.replace(stringText, replaceRegex, replacementText)

Questa funzione prevede tre argomenti:

  • stringText: la stringa originale.
  • replaceRegex: l'espressione regolare che indica il pattern da cercare.
  • replaceText: il testo da inserire in ogni corrispondenza.

Restituisce una nuova stringa derivata dalla stringa originale Text, in cui tutte le sottostringhe che corrispondono al pattern in replaceRegex vengono sostituite con il valore in replacementText. Puoi utilizzare cifre con interpretazione letterale precedute da una barra rovesciata (da \1 a \9) all'interno di replacementText per inserire il testo che corrisponde al gruppo tra parentesi corrispondente nel motivo replaceRegex. Utilizza \0 per fare riferimento all'intero testo corrispondente.

La funzione sostituisce le corrispondenze non sovrapposte e assegna la priorità alla prima occorrenza trovata. Ad esempio, re.replace("banana", "ana", "111") restituisce la stringa "b111na".

Questo esempio acquisisce tutto ciò che segue il simbolo @ in un'email, sostituisce com con org e restituisce il risultato. Nota l'uso di funzioni nidificate.

"email@google.org" = re.replace($e.network.email.from, "com", "org")

In questo esempio vengono utilizzate cifre con barra rovesciata nell'argomento replaceText per fare riferimento alle corrispondenze con il pattern replaceRegex.

"test1.com.google" = re.replace(
                       $e.principal.hostname, // holds "test1.test2.google.com"
                       "test2\.([a-z]*)\.([a-z]*)",
                       "\\2.\\1"  // \\1 holds "google", \\2 holds "com"
                     )

Tieni presente i seguenti casi quando tratti con stringhe vuote e re.replace():

Utilizzo della stringa vuota come replaceRegex:

// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")

Per sostituire una stringa vuota, puoi utilizzare "^$" come replaceRegex:

// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")

Funzioni di data

Chronicle supporta le seguenti funzioni correlate alle date:

  • timestamp.get_minute(unix_seconds [, time_zone])
  • timestamp.get_hour(unix_seconds [, time_zone])
  • timestamp.get_day_of_week(unix_seconds [, time_zone])
  • timestamp.get_week(unix_seconds [, time_zone])
  • timestamp.current_seconds()

Chronicle supporta numeri interi negativi come argomento unix_seconds. I numeri interi negativi rappresentano i momenti precedenti al periodo Unix. Se fornisci un numero intero non valido, ad esempio un valore che risulta in un overflow, la funzione restituirà -1. Si tratta di uno scenario insolito.

Poiché YARA-L 2 non supporta i valori letterali interi negativi, assicurati di controllare questa condizione utilizzando l'operatore minore di o maggiore di. Ad esempio:

0 > timestamp.get_hour(123)

Estrazione del tempo

Restituisce un numero intero compreso nell'intervallo [0, 59].

timestamp.get_minute(unix_seconds [, time_zone])

La seguente funzione restituisce un numero intero compreso nell'intervallo [0, 23], che rappresenta l'ora del giorno.

timestamp.get_hour(unix_seconds [, time_zone])

La seguente funzione restituisce un numero intero compreso nell'intervallo [1, 7] che rappresenta il giorno della settimana che inizia con domenica. Ad esempio, 1 = domenica; 2 = lunedì ecc.

timestamp.get_day_of_week(unix_seconds [, time_zone])

La seguente funzione restituisce un numero intero compreso nell'intervallo [0, 53] che rappresenta la settimana dell'anno. Le settimane iniziano con la domenica. Le date antecedenti la prima domenica dell'anno sono alla settimana 0.

timestamp.get_week(unix_seconds [, time_zone])

Queste funzioni di estrazione del tempo hanno gli stessi argomenti.

  • unix_seconds è un numero intero che rappresenta il numero di secondi dopo il periodo Unix, ad esempio $e.metadata.event_timestamp.seconds, o un segnaposto contenente quel valore.
  • time_zone è facoltativo ed è una stringa che rappresenta un time_zone. Se omesso, il valore predefinito è "GMT". Puoi specificare i fusi orari utilizzando i valori letterali di stringa. Le opzioni sono:
    • Il nome del database TZ, ad esempio "America/Los_Angeles". Per ulteriori informazioni, consulta la colonna "Nome database TZ" in questa pagina
    • Lo scarto del fuso orario da UTC, nel formato (+|-)H[H][:M[M]], ad esempio: "-08:00".

In questo esempio, l'argomento time_zone viene omesso, quindi viene impostato su "GMT" per impostazione predefinita.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15

In questo esempio viene utilizzato un valore letterale stringa per definire il time_zone.

$ts = $e.metadata.collected_timestamp.seconds

2 = timestamp.get_day_of_week($ts, "America/Los_Angeles")

Ecco alcuni esempi di altri specificatori del fuso orario validi, che puoi trasmettere come secondo argomento alle funzioni di estrazione del tempo:

  • "America/Los_Angeles" o "-08:00". ("PST" non è supportato)
  • "America/New_York" o "-05:00". ("EST" non è supportato)
  • "Europe/London"
  • "UTC"
  • "GMT"

Timestamp corrente

Restituisce un numero intero che rappresenta l'ora corrente in secondi Unix. Questo valore è approssimativamente uguale al timestamp di rilevamento e si basa sul momento in cui viene eseguita la regola.

timestamp.current_seconds()

L'esempio seguente restituisce True se il certificato è scaduto da più di 24 ore. Calcola la differenza di tempo sottraendo gli attuali secondi Unix e quindi confrontandoli con un operatore maggiore di.

86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after

Funzioni matematiche

Valore assoluto

Restituisce il valore assoluto di un'espressione intera.

math.abs(intExpression)

Questo esempio restituisce True se gli eventi si sono verificati a più di 5 minuti di distanza, indipendentemente dall'evento che si è verificato per primo. Osserva in che modo l'esempio utilizza funzioni nidificate.

300 < math.abs($e1.metadata.event_timestamp.seconds
               - $e2.metadata.event_timestamp.seconds
      )

Funzioni di rete

Restituisce true quando l'indirizzo IP specificato si trova all'interno della subnet specificata.

net.ip_in_range_cidr(ipAddress, subnetworkRange)

Puoi utilizzare YARA-L per cercare eventi UDM in tutti gli indirizzi IP all'interno di una subnet utilizzando l'istruzione net.ip_in_range_cidr(). Sono supportati sia IPv4 sia IPv6.

Per eseguire una ricerca in un intervallo di indirizzi IP, specifica un campo IP UDM e un intervallo Classless Inter-Domain Routing (CIDR). YARA-L è in grado di gestire campi di indirizzi IP singoli e ripetuti.

Esempio IPv4:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

Esempio IPv6:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

Per una regola di esempio che utilizza l'istruzione net.ip_in_range_cidr(), consulta la regola di esempio. Singolo evento all'interno dell'intervallo di indirizzi IP

Funzione per assegnare un segnaposto

Puoi assegnare il risultato di una chiamata funzione a un segnaposto nella sezione events. Ad esempio:

$placeholder = strings.concat($e.principal.hostname, "my-string").

Puoi quindi utilizzare le variabili segnaposto nelle sezioni match, condition e outcome. Tuttavia, esistono due limitazioni con la funzione di assegnazione di segnaposto:

  1. Ogni segnaposto nella funzione per l'assegnazione del segnaposto deve essere assegnato a un'espressione contenente un campo evento. Ecco alcuni esempi validi:

    $ph1 = $e.principal.hostname
    $ph2 = $e.src.hostname
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.concat($ph2, ".com")
    
    $ph1 = $e.network.email.from
    $ph2 = strings.concat($e.principal.hostname, "@gmail.com")
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.to_lower($ph2)
    

    Tuttavia, l'esempio seguente non è valido:

    $ph1 = strings.concat($e.principal.hostname, "foo")
    $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
    
  2. La chiamata a funzione deve dipendere da un evento e da un solo. Tuttavia, è possibile utilizzare più di un campo per lo stesso evento negli argomenti delle chiamate di funzione. Ad esempio, quanto segue è valido:

    $ph = strings.concat($event.principal.hostname, "string2")

    $ph = strings.concat($event.principal.hostname, $event.src.hostname)

    Tuttavia, non è valido quanto segue:

    $ph = strings.concat("string1", "string2")

    $ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)

Sintassi degli elenchi di riferimenti

Consulta la pagina relativa agli elenchi di riferimento per ulteriori informazioni sul comportamento degli elenchi di riferimento e sulla sintassi degli elenchi di riferimenti.

Puoi utilizzare gli elenchi di riferimento nelle sezioni events o outcome. Ecco la sintassi per l'utilizzo di vari tipi di elenchi di riferimento in una regola:

// STRING reference list
$e.principal.hostname in %string_reference_list

// REGEX reference list
$e.principal.hostname in regex %regex_reference_list

// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list

Puoi anche utilizzare l'operatore not con gli elenchi di riferimento, come mostrato qui: not $e.principal.hostname in regex %my_regex_list.

Per migliorare le prestazioni, il motore di rilevamento limita l'utilizzo dell'elenco di riferimenti. In una regola puoi utilizzare fino a 7 istruzioni in e puoi utilizzare più tipi di istruzioni in nella stessa regola. Al massimo 2 delle 7 istruzioni in possono utilizzare gli operatori speciali regex o cidr.

L'operatore nocase non funziona con gli elenchi di riferimento. L'inserimento di nocase dopo una chiamata a un elenco di riferimento non ha alcun effetto e non è consigliato.

Sintassi delle meta tag

La sezione Meta è composta da più righe, dove ogni riga definisce una coppia chiave-valore. Una parte della chiave deve essere una stringa non tra virgolette e una parte del valore deve essere una stringa tra virgolette:

<key> = "<value>"

Di seguito è riportato un esempio di una riga di sezione meta valida: meta: author = "Chronicle" severity = "HIGH"

Sintassi della sezione Eventi

Nella sezione events, elenca i predicati per specificare quanto segue:

  • Cosa rappresenta ogni variabile di corrispondenza o segnaposto
  • Espressioni binarie semplici come condizioni
  • Espressioni di funzioni come condizioni
  • Espressioni elenco di riferimento come condizioni
  • Operatori logici

Dichiarazioni sulle variabili

Per le dichiarazioni delle variabili, utilizza la seguente sintassi:

  • <EVENT_FIELD> = <VAR>
  • <VAR> = <EVENT_FIELD>

Entrambi sono equivalenti, come illustrato negli esempi seguenti:

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

Questa dichiarazione indica che questa variabile rappresenta il campo specificato per la variabile evento. Quando il campo evento è un campo ripetuto, la variabile di corrispondenza può rappresentare qualsiasi valore nell'array. È anche possibile assegnare più campi evento a una singola corrispondenza o variabile segnaposto. Questa è una condizione di unione transitiva.

Ad esempio:

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

Equivale a:

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

Le variabili che vengono utilizzate devono essere dichiarate tramite la dichiarazione della variabile. Se una variabile viene utilizzata senza alcuna dichiarazione, viene considerata come errore di compilazione.

Espressioni binarie semplici come condizioni

Per utilizzare una semplice espressione binaria come condizione, utilizza la sintassi seguente:

  • <EXPR> <OP> <EXPR>

L'espressione può essere un campo evento, una variabile, un valore letterale o un'espressione di funzione.

Ad esempio:

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port
  • $e1.source.hostname != $e2.target.hostname
  • $e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
  • $port >= 25
  • $host = $e2.target.hostname
  • "google-test" = strings.concat($e.principal.hostname, "-test")
  • "email@google.org" = re.replace($e.network.email.from, "com", "org")

Se entrambi i lati sono valori letterali, vengono considerati errori di compilazione.

Espressioni di funzioni come condizioni

Alcune espressioni di funzione restituiscono un valore booleano, che può essere utilizzato come singolo predicato nella sezione events. Tali funzioni sono:

  • re.regex()
  • net.ip_in_range_cidr()

Ad esempio:

  • re.regex($e.principal.hostname, `.*\.google\.com`)
  • net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

Espressioni elenco di riferimento come condizioni

Puoi utilizzare gli elenchi di riferimento nella sezione Eventi. Per ulteriori dettagli, consulta la sezione Elenchi di riferimento.

Operatori logici

Puoi utilizzare gli operatori logici and e logici or nella sezione events, come mostrato negli esempi seguenti:

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

Per impostazione predefinita, l'ordine di precedenza dal più alto al più basso è not, and, or.

Ad esempio, "a or b and c" è valutato come "a or (b and c)". Puoi utilizzare le parentesi per modificare la precedenza, se necessario.

Per impostazione predefinita, nella sezione events tutti i predicati sono considerati and insieme.

Operatori negli eventi

Puoi utilizzare gli operatori con tipi enumerati. Può essere applicato alle regole per semplificare e ottimizzare il rendimento (utilizza l'operatore anziché gli elenchi di riferimento).

Nell'esempio seguente, "USER_UNCATEGORIZED" e "USER_RESOURCE_DELETION" corrispondono a 15000 e 15014, pertanto la regola cercherà tutti gli eventi elencati:

$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"

Elenco di eventi:

  • USER_RESOURCE_DELETION
  • USER_RESOURCE_UPDATE_CONTENT
  • USER_RESOURCE_UPDATE_PERMISSIONS
  • STATISTICHE UTENTE
  • USER_UNCATEGORIZED

Modificatori

Nocase

Quando hai un'espressione di confronto tra i valori della stringa o un'espressione regex, puoi aggiungere "maiuscole" alla fine dell'espressione per ignorare le lettere maiuscole.

  • $e.principal.hostname != "http-server" nocase
  • $e1.principal.hostname = $e2.target.hostname nocase
  • $e.principal.hostname = /dns-server-[0-9]+/ nocase
  • re.regex($e.target.hostname, `client-[0-9]+`) nocase

Non è possibile utilizzarlo quando un tipo di campo è un valore enumerato. Gli esempi di seguito non sono validi e genereranno errori di compilazione:

  • $e.metadata.event_type = "NETWORK_DNS" nocase
  • $e.network.ip_protocol = "TCP" nocase

Campi ripetuti

tutti, tutti

In UDM e nelle entità, alcuni campi sono etichettati come ripetuti, ovvero si tratta di elenchi di valori o altri tipi di messaggi. In YARA-L, ogni elemento nel campo ripetuto viene trattato individualmente. Ciò significa che, se nella regola viene utilizzato il campo ripetuto, valutiamo la regola per ogni elemento nel campo. Questo può causare un comportamento imprevisto. Ad esempio, se una regola ha sia $e.principal.ip = "1.2.3.4" che $e.principal.ip = "5.6.7.8" nella sezione events, la regola non genera mai corrispondenze, anche se "1.2.3.4" e "5.6.7.8" si trovano in principal.ip.

Per valutare il campo ripetuto nel suo complesso, puoi utilizzare gli operatori any e all. Quando viene utilizzato any, il predicato viene valutato come vero se un valore nel campo ripetuto soddisfa la condizione. Quando viene utilizzato all, il predicato viene valutato come vero se tutti i valori nel campo ripetuto soddisfano la condizione.

  • any $e.target.ip = "127.0.0.1"
  • all $e.target.ip != "127.0.0.1"
  • re.regex(any $e.about.hostname, `server-[0-9]+`)
  • net.ip_in_range_cidr(all $e.principal.ip, "10.0.0.0/8")

Gli operatori any e all possono essere utilizzati solo con i campi ripetuti. Inoltre, non possono essere utilizzati quando si assegna un campo ripetuto a una variabile segnaposto o quando si partecipa con un campo di un altro evento.

Ad esempio, any $e.principal.ip = $ip e any $e1.principal.ip = $e2.principal.ip non sono una sintassi valida. Per trovare una corrispondenza o un campo ripetuto, utilizza $e.principal.ip = $ip. Sarà presente un valore per la variabile di corrispondenza o un join per ogni elemento del campo ripetuto.

Quando scrivi una condizione con any o all, tieni presente che la modifica della condizione con not potrebbe non avere lo stesso significato dell'utilizzo dell'operatore negato.

Ad esempio:

  • not all $e.principal.ip = "192.168.12.16" controlla se non tutti gli indirizzi IP corrispondono a "192.168.12.16", ossia la regola verifica se gli indirizzi IP non corrispondono a "192.168.12.16".
  • all $e.principal.ip != "192.168.12.16" controlla se tutti gli indirizzi IP non corrispondono a "192.168.12.16", ossia la regola verifica che nessun indirizzo IP corrisponda a "192.168.12.16".

Requisiti di unione di variabili evento

Tutte le variabili evento utilizzate nella regola devono essere unite a ogni altra variabile evento in uno dei seguenti modi:

  • direttamente tramite un confronto di uguaglianza tra i campi evento delle due variabili evento unite, ad esempio $e1.field = $e2.field. L'espressione non deve includere chiamate aritmetiche o di funzione.

  • Indirettamente tramite un join transitivo che coinvolge solo un campo evento (consulta la dichiarazione variabile per una definizione di "unione transitiva"). L'espressione non deve includere chiamate aritmetiche o di funzione.

Ad esempio, supponendo che $e1, $e2 e $e3 siano utilizzati nella regola, le seguenti sezioni events sono valide.

events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
  $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
  // all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2

  // Function to event comparison is not a valid join condition for $e1 and $e2,
  // but the whole events section is valid because we have a valid join condition in the first line.
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname

Tuttavia, ecco alcuni esempi di sezioni events non valide.

events:
  // Event to function comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.hostname = re.capture($e2.principal.application, ".*")
events:
  // Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.port = $e2.src.port + 1
events:
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
  $e1.src.ip = $ip

  // Function to placeholder comparison is an invalid transitive join condition.
  re.capture($e2.target.ip, ".*") = $ip
events:
  $e1.src.port = $port

  // Arithmetic to placeholder comparison is an invalid transitive join condition.
  $e2.principal.port + 800 = $port

Sintassi della sezione di corrispondenza

Nella sezione match, elenca le variabili di corrispondenza per gli eventi del gruppo prima di verificare le condizioni di corrispondenza. Tali campi vengono restituiti a ogni corrispondenza.

  • Specifica cosa rappresenta ogni variabile di corrispondenza nella sezione events.
  • Specifica l'intervallo di tempo da utilizzare per mettere in correlazione gli eventi dopo la parola chiave over. Gli eventi al di fuori dell'intervallo di tempo vengono ignorati.
  • Per specificare l'intervallo di tempo, utilizza la seguente sintassi: <number><s/m/h/d> Dove s/m/h/d indica rispettivamente secondi, minuti, ore e giorni.
  • Il tempo minimo che puoi specificare è 1 minuto.
  • Puoi specificare un tempo massimo di 48 ore.

Di seguito è riportato un esempio di match valido:

$var1, $var2 over 5m

Questa istruzione restituisce $var1 e $var2 (definiti nella sezione events) quando la regola trova una corrispondenza. Il tempo specificato è di 5 minuti. Gli eventi che si verificano a più di cinque minuti di distanza non sono correlati e, di conseguenza, ignorati dalla regola.

Ecco un altro esempio di match valido:

$user over 1h

Questa istruzione restituisce $user quando la regola trova una corrispondenza. La finestra temporale specificata è di 1 ora. Gli eventi che si verificano oltre un'ora non sono correlati. La regola non li considera un rilevamento.

Ecco un altro esempio di match valido:

$source_ip, $target_ip, $hostname over 2m

Questa istruzione restituisce $source_ip, $target_ip e $hostname quando la regola trova una corrispondenza. La finestra temporale specificata è di 2 minuti. Gli eventi che si trovano a più di due minuti di distanza non sono correlati. La regola non li considera un rilevamento.

I seguenti esempi illustrano sezioni matchnon valide:

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

Finestra scorrevole

Per impostazione predefinita, le regole YARA-L 2.0 vengono valutate utilizzando le finestre di hop. Un intervallo di tempo dei dati degli eventi aziendali è diviso in un insieme di finestre di hop sovrapposte, ciascuna con la durata specificata nella sezione match. Gli eventi sono quindi correlati in ogni finestra dell'hop. Con le finestre di hop, è impossibile cercare eventi che si verificano in un ordine specifico (ad esempio, e1 fino a 2 minuti dopo e2). Un'occorrenza dell'evento e1 e un'occorrenza dell'evento e2 sono correlate fino a quando si verificano la stessa durata della finestra dell'hop.

Le regole possono anche essere valutate utilizzando finestre scorrevoli. Con le finestre scorrevoli, le finestre scorrevoli con la durata specificata nella sezione match vengono generate quando iniziano o terminano con una variabile evento pivot specifica. Gli eventi sono quindi correlati all'interno di ogni finestra scorrevole. Ciò consente di cercare gli eventi che si verificano in un ordine specifico (ad esempio, e1 avviene entro 2 minuti da e2). Un'occorrenza dell'evento e1 e un'occorrenza dell'evento e2 sono correlate se l'evento e1 si verifica nella durata della finestra temporale successiva all'evento e2.

Specifica le finestre scorrevoli nella sezione match di una regola come segue:

<match-var-1>, <match-var-2>, ... over <duration> before|after <pivot-event-var>

La variabile evento pivot è la variabile evento su cui si basano le finestre scorrevoli. Se utilizzi la parola chiave before, vengono generate finestre scorrevoli che terminano con ogni occorrenza dell'evento pivot. Se viene utilizzata la parola chiave after, le finestre scorrevoli vengono generate a partire da ogni occorrenza dell'evento pivot.

Di seguito sono riportati esempi di utilizzi validi di finestre scorrevoli:

  • $var1, $var2 over 5m after $e1
  • $user over 1h before $e2

Sintassi della sezione dei risultati

Nella sezione outcome, puoi definire fino a 10 variabili di risultato, con i nomi arbitrari. Questi risultati verranno archiviati nei rilevamenti generati dalla regola. Ogni rilevamento può avere valori diversi per i risultati.

Il nome del risultato, $risk_score, è speciale. Facoltativamente, puoi definire un risultato con questo nome e, se lo fai, deve essere un tipo intero. Se il campo è completato, risk_score viene mostrato nella vista Enterprise Insights per gli avvisi provenienti dai rilevamenti delle regole.

Tipi di dati variabili di risultato

Ogni variabile dei risultati può avere un tipo di dati diverso, che è determinato dall'espressione utilizzata per calcolarla. Sono supportati i seguenti tipi di dati relativi ai risultati:

  • integer
  • string
  • elenchi di numeri interi
  • elenchi di stringhe

Logica condizionale

Puoi utilizzare la logica condizionale per calcolare il valore di un risultato. Le condizioni sono specificate utilizzando il seguente pattern di sintassi:

if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)

Puoi leggere un'espressione condizionale come "se BOOL_CLAUSE è vera e poi restituire THEN_CLAUSE, altrimenti restituisce ELSE_CLAUSE".

BOOL_CLAUSE deve restituire un valore booleano. Un'espressione BOOL_CLAUSE ha una forma simile a quella della sezione events. Ad esempio, può contenere:

  • Nomi dei campi UDM con operatore di confronto, ad esempio:

    if($context.graph.entity.user.title = "Vendor", 100, 0)

  • una variabile segnaposto definita nella sezione events, ad esempio:

    if($severity = "HIGH", 100, 0)

  • che restituiscono un valore booleano, ad esempio:

    if(re.regex($e.network.email.from, .*altostrat\.com), 100, 0)

  • Cerca in un elenco di riferimento, ad esempio:

    if($u.principal.hostname in %my_reference_list_name, 100, 0)

THEN_CLAUSE ed ELSE_CLAUSE devono essere dello stesso tipo di dati. Supportiamo numeri interi e stringhe.

Puoi omettere l'ELSE_CLAUSE se il tipo di dati è un numero intero. Se omesso, ELSE_CLAUSE restituisce 0. Ad esempio:

`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`

È necessario fornire l'ELSE_CLAUSE se il tipo di dati è stringa.

Operazioni matematiche

Puoi utilizzare operazioni matematiche per calcolare i risultati di tipi di dati interi. Supportiamo l'aggiunta e la sottrazione (ma non la moltiplicazione, la divisione o il modulo). Ad esempio:

outcome:
  $risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))

Variabili segnaposto nei risultati

Quando calcoli le variabili dei risultati, puoi utilizzare le variabili segnaposto definite nella sezione degli eventi della regola. In questo esempio, supponiamo che $email_sent_bytes sia stato definito nella sezione degli eventi della regola:

Esempio di evento singolo:

// No match section, so this is a single-event rule.

outcome:
  // Use placeholder directly as an outcome value.
  $my_outcome = $email_sent_bytes

  // Use placeholder in a conditional.
  $other_outcome = if($file_size > 1024, "SEVERE", "MODERATE")

condition:
  $e

Esempio di più eventi:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Use placeholder directly in an aggregation function.
  $max_email_size = max($email_sent_bytes)

  // Use placeholder in a mathematical computation.
  $total_bytes_exfiltrated = sum(
    1024
    + $email_sent_bytes
    + $file_event.principal.file.size
  )

condition:
  $email_event and $file_event

Aggregazioni

La sezione dei risultati può essere utilizzata nelle regole per più eventi (regole che contengono una sezione con corrispondenza) e nelle regole per un singolo evento (regole che non contengono una sezione con corrispondenza). I requisiti per le aggregazioni sono i seguenti:

  • Regole per più eventi (con sezione delle corrispondenze)

    • L'espressione nei risultati di calcolo viene valutata per tutti gli eventi che hanno generato un determinato rilevamento.
    • L'espressione deve essere aggregata in una funzione aggregata
      • Esempio: $max_email_size = max($e.network.sent_bytes)
      • Se l'espressione contiene un campo ripetuto, l'aggregato opera su tutti gli elementi nel campo ripetuto, in tutti gli eventi che hanno generato il rilevamento.
  • Regole per un singolo evento (senza sezione delle corrispondenze)

    • L'espressione nei risultati di calcolo viene valutata per il singolo evento che ha generato un determinato rilevamento.
    • Devi utilizzare la funzione aggregata per le espressioni che comprendono almeno un campo ripetuto.
      • Esempio: $suspicious_ips = array($e.principal.ip)
      • L'aggregazione opera su tutti gli elementi nel campo ripetuto.
    • Impossibile utilizzare la funzione di aggregazione per le espressioni che non includono un campo ripetuto.
      • Esempio: $threat_status = if($e.principal.file.size > 1024, "SEVERE", "MODERATE")

Puoi utilizzare le seguenti funzioni di aggregazione:

  • max(): restituisce il valore massimo tra tutti i valori possibili. Funziona solo con un numero intero.
  • min(): restituisce il minimo per tutti i valori possibili. Funziona solo con un numero intero.
  • sum(): restituisce la somma di tutti i valori possibili. Funziona solo con un numero intero.
  • count_distinct(): raccoglie tutti i valori possibili e restituisce il conteggio distinto dei possibili valori.
  • count(): si comporta come count_distinct(), ma restituisce un conteggio non distinto di valori possibili.
  • array_distinct(): raccoglie tutti i valori possibili e restituisce un elenco di questi valori. Tronca l'elenco dei valori a 25 elementi casuali.
  • array(): si comporta come array_distinct(), ma restituisce un elenco di valori non distinto. Tronca l'elenco dei valori a 25 elementi casuali.

La funzione aggregata è importante quando una regola include una sezione condition che specifica più eventi, perché la funzione aggregata funzionerà su tutti gli eventi che hanno generato il rilevamento.

Ad esempio, se le sezioni outcome e condition contengono:

outcome:
  $asset_id_count = count($event.principal.asset_id)
  $asset_id_distinct_count = count_distinct($event.principal.asset_id)

  $asset_id_list = array($event.principal.asset_id)
  $asset_id_distinct_list = array_distinct($event.principal.asset_id)

condition:
  #event > 1

Poiché la sezione della condizione richiede che ci sia più di un event per ogni rilevamento, le funzioni aggregate operano su più eventi. Supponiamo che i seguenti eventi abbiano generato un rilevamento:

event:
  // UDM event 1
  asset_id="asset-a"

event:
  // UDM event 2
  asset_id="asset-b"

event:
  // UDM event 3
  asset_id="asset-b"

I valori dei risultati saranno quindi:

  • $asset_id_count = 3
  • $asset_id_distinct_count = 2
  • $asset_id_list = ["asset-a", "asset-b", "asset-b"]
  • $asset_id_distinct_list = ["asset-a", "asset-b"]

Aspetti da considerare quando si utilizza la sezione dei risultati:

Altre note e limitazioni:

  • La sezione outcome non può fare riferimento a una nuova variabile segnaposto che non era già stata definita nella sezione events.
  • La sezione outcome non può utilizzare le variabili evento che non sono state definite nella sezione events.
  • La sezione outcome può utilizzare un campo evento non utilizzato nella sezione events, dato che la variabile evento a cui appartiene il campo evento è già stata definita nella sezione events.
  • La sezione outcome può essere correlata solo alle variabili di eventi che sono già state correlate nella sezione events. Le correlazioni avvengono quando vengono equiparati due campi evento di diverse variabili evento.

Puoi trovare un esempio utilizzando la sezione dei risultati in Panoramica di YARA-L 2.0. Per informazioni dettagliate sulla deduplicazione dei dati di rilevamento nella sezione dei risultati, consulta l'articolo Creare analisi sensibili al contesto.

Sintassi della sezione Condizioni

Nella sezione condition puoi:

  • specifica una condizione di corrispondenza per gli eventi e i segnaposto definiti nella sezione events. Per ulteriori dettagli, consulta la sezione Condizionali per eventi e segnaposto.
  • (Facoltativo) utilizza la parola chiave and per specificare una condizione di corrispondenza utilizzando le variabili di risultato definite nella sezione outcome. Per ulteriori dettagli, consulta la sezione Condizionali dei risultati.

I seguenti pattern di condizioni sono validi:

condition:
  <event/placeholder conditionals>
condition:
  <event/placeholder conditionals> and <outcome conditionals>

Condizionali segnaposto e eventi

Elenca qui i predicati di condizioni per eventi e variabili segnaposto, uniti alla parola chiave and o or.

Le condizioni seguenti sono condizioni di delimitazione. Imponeno l'esistenza della variabile evento associata, il che significa che almeno un'occorrenza dell'evento deve apparire in qualsiasi rilevamento.

  • $var // equivalent to #var > 0
  • #var > n // where n >= 0
  • #var >= m // where m > 0

Le seguenti condizioni non sono vincolanti. Consentono alla variabile evento associata di non esistere, il che significa che è possibile che nessuna occorrenza dell'evento venga visualizzata in un rilevamento. Ciò consente la creazione di regole inesistenti, che cercano l'assenza di una variabile anziché la presenza di una variabile.

  • !$var // equivalent to #var = 0
  • #var >= 0
  • #var < n // where n > 0
  • #var <= m // where m >= 0

Nell'esempio seguente, il carattere speciale # in una variabile (la variabile evento o la variabile segnaposto) rappresenta il conteggio di eventi o valori distinti di tale variabile.

$e and #port > 50 or #event1 > 2 or #event2 > 1 or #event3 > 0

Anche il seguente esempio inesistente è valido e restituisce true se sono presenti più di due eventi distinti da $event1 e zero eventi distinti da $event2.

#event1 > 2 and !$event2

Di seguito sono riportati esempi di predicati non validi:

  • $e, #port > 50 // incorrect keyword usage
  • $e or #port < 50 // or keyword not supported with non-bounding conditions
  • not $e // not keyword is not allowed for event and placeholder conditions

Condizionali risultati

Elenca i predicati della condizione per le variabili di risultato qui, uniti alla parola chiave and o or o preceduti dalla parola chiave not.

Specifica le condizioni dei risultati in modo diverso in base al tipo di variabile dei risultati:

  • numero intero: esegui un confronto con un valore letterale intero con operatori =, >, >=, <, <=, !=, ad esempio:

    $risk_score > 10

  • string: esegui un confronto con un valore letterale di stringa con = o !=, ad esempio:

    $severity = "HIGH"

  • elenco di numeri interi o array: specifica la condizione utilizzando la funzione arrays.contains, ad esempio:

    arrays.contains($event_ids, "id_1234")

Classificazione regola

Se specifichi un risultato condizionale in una regola con una sezione corrispondente, la regola verrà classificata come regola di più eventi per la quota di regole. Per scoprire di più sulle classificazioni di singoli e più eventi, consulta le regole per singoli eventi e più regole per gli eventi.

Conteggio (#) carattere

Il carattere # è un carattere speciale nella sezione condition. Se è utilizzato prima di qualsiasi nome di variabile evento o segnaposto, rappresenta il numero di eventi o valori distinti che soddisfano tutte le condizioni della sezione events.

Carattere valore ($)

Il carattere $ è un altro carattere speciale nella sezione condition. Se viene utilizzato prima del nome della variabile di risultato, rappresenta il valore di tale risultato.

Se viene usato prima del nome di qualsiasi evento o variabile segnaposto (ad es. $event), è un'abbreviazione di #event > 0.

Sintassi della sezione Opzioni

Nella sezione options, puoi specificare le opzioni per la regola. La sintassi per la sezione options è simile a quella della sezione meta. Ma una chiave deve essere uno dei nomi di opzione predefinita e il valore non è limitato al tipo di stringa.

Attualmente, l'unica opzione disponibile è allow_zero_values.

  • allow_zero_value: se il valore è impostato su true, le corrispondenze generate dalla regola non possono avere valori corrispondenti. I valori zero vengono assegnati ai campi evento quando non vengono inseriti. Questa opzione è impostata su false per impostazione predefinita.

Di seguito è riportata la riga della sezione options valida:

  • allow_zero_values = true

Controllo del tipo

Chronicle esegue il controllo dei tipi in base alla sintassi YARA-L mentre crei le regole all'interno dell'interfaccia. Gli errori di verifica del tipo visualizzati consentono di rivedere la regola in modo da garantire che funzioni come previsto.

Di seguito sono riportati esempi di predicati non validi:

// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"

// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"