Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
YARA-Performance-Guidelines — Una guida su come scrivere regole YARA veloci ed efficienti in termini di memoria. | Kitploit
Strumenti/GitHubGitHub/neo23x0/yara-performance-guidelines
Analisi StaticaAnalisi MalwareApprendimento e Formazione
GitHubneo23x0/yara-performance-guidelines

YARA-Performance-Guidelines

Una guida su come scrivere regole YARA veloci ed efficienti in termini di memoria.

Vedi Repository

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
174231 anno faRevisionato da Kitploit

Linee Guida sulle Prestazioni di YARA

Scrivere regole YARA efficienti è essenziale per mantenere prestazioni di scansione rapide e accurate. Questa guida fornisce principi chiave e buone pratiche per aiutarti a ottimizzare le tue regole, ridurre i calcoli non necessari ed evitare le insidie più comuni. Include approfondimenti di esperti del settore, tra cui Victor M. Alvarez, WXS, e contributi della community YARA.

  • Revisione 1.6, febbraio 2025, si applica a tutte le versioni di YARA successive alla 3.7

Concetti Chiave

Questa sezione fornisce un riepilogo conciso delle buone pratiche sulle prestazioni di YARA. Per spiegazioni dettagliate ed esempi, fai riferimento alla guida completa qui sotto.

Comprendere il Processo di Scansione di YARA

"Pensa a YARA come a un processo in due fasi: prima, la ricerca di tutti i pattern elencati nelle stringhe, e poi, la valutazione delle condizioni. Non puoi usare condizioni ben formate per compensare stringhe scelte male."
— Wesley Shields

YARA segue quattro passaggi principali quando scansiona un file:

  1. Compilazione delle regole – Estrazione degli atomi (sottostringhe di 4 byte) dalle stringhe definite.
  2. Ricerca Aho-Corasick – Scansione dei file alla ricerca di questi atomi.
  3. Motore bytecode – Verifica delle corrispondenze complete delle stringhe.
  4. Valutazione delle condizioni – Verifica della logica aggiuntiva della regola.

Selezione delle Stringhe – Il Fattore Più Importante

YARA cerca prima le stringhe, rendendo la selezione delle stringhe il fattore singolarmente più importante per l'efficienza delle regole.

✅ Buone Pratiche per le Stringhe:

  • Evita le stringhe corte (<4 byte) – Creano troppi falsi positivi.
  • Usa atomi unici di 4 byte – YARA si affida a essi per una scansione rapida.
  • Riduci al minimo i caratteri jolly nelle stringhe esadecimali – Mantieni almeno un segmento concreto lungo.
  • Usa le regex con parsimonia – Se necessario, includi un'ancora fissa di 4 byte per migliorare l'efficienza.
  • Evita i pattern ripetuti di un singolo byte – Ad es., \x00\x00\x00\x00 appare troppo di frequente.
  • Usa nocase con cautela – Genera esponenzialmente più varianti di ricerca.

Ottimizzare le Condizioni e lo Short-Circuit

YARA valuta le condizioni in sequenza e si ferma al primo insuccesso.

✅ Buone Pratiche per le Condizioni:

  • Metti prima i controlli rapidi (ad es., filesize < X) prima delle condizioni costose.
  • Evita i cicli su grandi quantità di dati (for all i in (1..filesize) è inefficiente).
  • Usa offset diretti (@) invece delle regex per i controlli di sequenza.

⚠ Nota: Le condizioni regex non applicano lo short-circuit e vengono sempre valutate per ultime.

Moduli – Usare con Cautela

Moduli come pe, elf o magic devono analizzare l'intero file prima della valutazione, aumentando il tempo di scansione.

✅ Alternative:

  • Invece di pe.is_pe, usa uint16(0) == 0x5A4D per identificare i file PE.
  • Evita di usare i moduli a meno che non sia richiesta un'ispezione approfondita del file.

Gestire i Troppi Match e la Scansione Lenta

I match eccessivi rallentano la scansione e possono attivare errori di "too many matches".

✅ Correggere i Match Inefficienti:

  • Controlla i quantificatori delle regex – Evita .*, .+ o {x,} senza un limite superiore.
  • Riduci i caratteri jolly nelle stringhe esadecimali.
  • Dividi le alternanze in stringhe separate dove possibile.

Video Tutorial

@herrcore ha creato un utile video tutorial che copre gli argomenti discussi in questa guida sulle prestazioni.

Introduzione a YARA - Scrivere Regole YARA Efficienti

Le Basi

Per capire meglio cosa e dove può essere ottimizzato nelle prestazioni di YARA, è utile comprendere il processo di scansione. È fondamentalmente suddiviso in 4 fasi che verranno spiegate in modo molto semplificato usando questa regola di esempio:

root@kitploit:~
import "math"
rule example_php_webshell_rule
{
    meta:
        description = "Just an example php webshell rule"
        date = "2021/02/16"
    strings:
        $php_tag = "<?php"
        $input1   = "GET"
        $input2   = "POST"
        $payload = /assert[\t ]{0,100}\(/
    condition:
        filesize < 20KB and
        $php_tag and
        $payload and
        any of ( $input* ) and
        math.entropy(500, filesize-500) >= 5
}

1. Compilazione delle regole

Questo passaggio avviene prima della scansione vera e propria. YARA cercherà i cosiddetti atoms nelle stringhe di ricerca per alimentare l'automa di Aho-Corasick. I dettagli sono spiegati nel capitolo atomo, ma per ora è sufficiente sapere che sono lunghi al massimo 4 byte e che YARA li sceglie in modo piuttosto intelligente per evitare troppi match. Nel nostro esempio, YARA potrebbe selezionare i seguenti 4 atomi:

  • <?ph
  • GET
  • POST
  • sser (da assert)

2. Automa di Aho-Corasick

Qui la scansione è iniziata. I passaggi 2.-4. verranno eseguiti su tutti i file. YARA cercherà in ogni file i 4 atomi definiti sopra utilizzando un albero dei prefissi chiamato automa di Aho-Corasick. Qualsiasi corrispondenza viene passata al motore bytecode.

3. Motore bytecode

Se, ad esempio, c'è una corrispondenza su sser, YARA verificherà se è preceduta da una a e continua con una t. Se è così, proseguirà con la regex [\t ]{0,100}\(. Con questo approccio intelligente, YARA evita di far passare un lento motore regex sull'intero file e seleziona solo alcune parti da esaminare più da vicino.

4. Condizioni

Dopo che tutto il pattern matching è stato completato, vengono verificate le condizioni. YARA ha un altro meccanismo di ottimizzazione per eseguire il controllo ad alta intensità di CPU math.entropy della nostra regola di esempio solo se le 4 condizioni precedenti sono soddisfatte. Spiegato in maggior dettaglio nel capitolo Condizioni e Valutazione Short-Circuit

Se le condizioni sono soddisfatte, viene segnalato un match. La scansione continua con il file successivo al passaggio 2.

Atomi

YARA estrae dalle stringhe brevi sottostringhe lunghe fino a 4 byte chiamate "atoms". Questi atomi possono essere estratti da qualsiasi punto della stringa e YARA li cerca durante la scansione del file; se trova uno degli atomi, verifica che la stringa corrisponda effettivamente.

Ad esempio, considera queste stringhe:

root@kitploit:~
/abc.*cde/

=> i possibili atomi sono abc e cde; si può usare l'uno o l'altro. L'atomo abc è attualmente preferito perché hanno la stessa qualità ed è il primo dei due.

root@kitploit:~
/(one|two)three/

=> i possibili atomi sono one, two, thre e hree; possiamo cercare solo thre (o hree), oppure sia one che two. L'atomo thre è preferito perché porterà a meno corrispondenze potenziali rispetto a one e two (che sono più corti) e non contiene la doppia e (più la lettera è unica, meglio è).

YARA fa del suo meglio per selezionare i migliori atomi da ogni stringa, per esempio:

root@kitploit:~
{ 00 00 00 00 [1-4] 01 02 03 04 }

=> qui YARA usa l'atomo 01 02 03 04, perché 00 00 00 00 è troppo comune

root@kitploit:~
{ 01 02 [1-4] 01 02 03 04 }

=> 01 02 03 04 è preferito rispetto a 01 02 perché è più lungo

Quindi, il punto importante è che le stringhe dovrebbero contenere buoni atomi. Queste sono stringhe pessime perché contengono atomi troppo corti o troppo comuni:

root@kitploit:~
{00 00 00 00 [1-2] FF FF [1-2] 00 00 00 00}
{AB  [1-2] 03 21 [1-2] 01 02}
/a.*b/
/a(c|d)/

Le stringhe peggiori sono quelle che non contengono alcun atomo, come:

root@kitploit:~
/\w.*\d/
/[0-9]+\n/

Questa espressione regolare non contiene alcuna sottostringa fissa che possa essere usata come atomo, quindi deve essere valutata a ogni offset del file per vedere se corrisponde.

Troppe Iterazioni dei Cicli

Un'altra buona e importante raccomandazione è evitare cicli con troppe iterazioni, specialmente se l'istruzione all'interno del ciclo è troppo complessa, per esempio:

root@kitploit:~
strings:
	$a = {00 00}
condition:
	for all i in (1..#a) : (@a[i] < 10000)

Questa regola ha due problemi. Il primo è che la stringa $a è troppo comune; il secondo è che, poiché $a è troppo comune, #a può essere troppo alto e può essere valutata migliaia di volte.

Anche quest'altra condizione è inefficiente perché il numero di iterazioni dipende da filesize, che può essere anch'esso molto alto:

root@kitploit:~
for all i in (1..filesize) : ($a at i)

Modulo Magic

Evita di usare il "modulo magic", che non è disponibile sulla piattaforma Windows. L'uso del modulo "magic" rallenta la scansione ma fornisce corrispondenze esatte.

Definizione personalizzata dell'header magic GIF:

root@kitploit:~
rule gif_1 {
  condition:
    (uint32be(0) == 0x47494638 and uint16be(4) == 0x3961) or
    (uint32be(0) == 0x47494638 and uint16be(4) == 0x3761)
}

Usando il modulo "magic":

root@kitploit:~
import "magic"
rule gif_2 {
  condition:
    magic.mime_type() == "image/gif"
}

Stringhe Troppo Corte

Evita di definire stringhe troppo corte. Qualsiasi stringa con meno di 4 byte apparirà probabilmente in molti file O come contenuto uniforme in un file XORato.

Contenuto Uniforme

Alcune stringhe sono abbastanza lunghe ma non dovrebbero essere usate per un motivo diverso: l'uniformità. Questi sono alcuni esempi di stringhe che non dovrebbero essere usate perché potrebbero causare troppi match nei file.

root@kitploit:~
$s1 = "22222222222222222222222222222222222222222222222222222222222222"
$s2 = "\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20"  // wide formatted spaces

Il messaggio di errore sarebbe simile a:

root@kitploit:~
error scanning yara-killer.dat: string "$mz" in rule "shitty_mz" caused too many matches

Consigli sulle Stringhe

Cerca di rendere le definizioni delle stringhe il più ristrette possibile. Evita l'attributo "nocase" se possibile, perché verranno generati e cercati molti atomi (maggiore utilizzo di memoria, più iterazioni). Ricorda che in assenza di modificatori, per impostazione predefinita viene assunto "ascii". Le combinazioni possibili sono:

BASSO - viene generato un solo atomo

root@kitploit:~
$s1 = "cmd.exe"		       // (ascii only)
$s2 = "cmd.exe" ascii          // (ascii only, same as $s1)
$s3 = "cmd.exe" wide           // (UTF-16 only)
$s4 = "cmd.exe" ascii wide     // (both ascii and UTF-16) two atoms will be generated 
$s5 = { 63 6d 64 2e 65 78 65 } // ascii char code in hex

ALTO - Verranno generate come atomi tutte le combinazioni di lettere maiuscole e minuscole per i 4 byte scelti da YARA

root@kitploit:~
$s5 = "cmd.exe" nocase      (all different cases, e.g. "Cmd.", "cMd.", "cmD." ..)

Se vuoi trovare comandi di scripting, verifica se il linguaggio è completamente case insensitive (ad es. php, batch di Windows) prima di usare nocase. Se hai solo bisogno di una diversa capitalizzazione per una o due lettere, è meglio usare una regex, ad es.

root@kitploit:~
$re = /[Pp]assword/

Fai attenzione quando lavori con alternanze come:

root@kitploit:~
$re = /(a|b)cde/
$hex = {C7 C3 00 (31 | 33)}

Queste stringhe generano atomi corti che possono rallentare la scansione. Nei casi in cui c'è un piccolo numero di varianti, si consiglia di scrivere la stringa separatamente:

root@kitploit:~
$re1 = /acde/
$re2 = /bcde/
$hex1 = {C7 C3 00 31}
$hex2 = {C7 C3 00 33}

Espressioni Regolari

Usa le espressioni regolari solo quando necessario. La valutazione delle espressioni regolari è intrinsecamente più lenta del semplice matching di stringhe e consuma una quantità significativa di memoria. Non usarle se le stringhe esadecimali con salti e caratteri jolly possono risolvere il problema.

Se devi usare espressioni regolari, evita il .* greedy e persino i quantificatori reluctant .*?. Usa invece numeri esatti come .{1,30} o anche .{1,3000}. Inoltre, non dimenticare il limite superiore (evita ad es. .{2,}).

Quando si usano i quantificatori, possono verificarsi due situazioni:

Se l'inizio dell'espressione regolare è ancorato a una posizione e può variare solo il suffisso, YARA troverà la corrispondenza più lunga possibile. In casi come .* e .+ o .{2,}, questo può portare a stringhe molto lunghe e a problemi di rallentamento della scansione.

Se ci sono più inizi possibili per l'espressione regolare, YARA troverà tutti quelli possibili.

root@kitploit:~
$re1 = /Tom.{0,2}/		// will find Tomxx in "Tomxx"
$re2 = /.{0,2}Tom/      // will find Tom, xTom, xxTom in "xxTom"

Il numero di corrispondenze più corte può facilmente superare il limite e generare l'errore "too many matches".

L'esempio seguente è l'espressione regolare per un indirizzo e-mail. Quando si usa [-a-z0-9._%+] con quantificatori, YARA troverà lo stesso indirizzo più volte, il che non è ideale. In questo caso, si consiglia di individuare un sottoinsieme ragionevolmente piccolo di indirizzi che fornisca informazioni sufficienti per l'analisi.

DA USARE

root@kitploit:~
/[-a-z0-9._%+]@[-a-z0-9.]{2,10}\.[a-z]{2,4}/
OR
/@[-a-z0-9.]{2,10}\.[a-z]{2,4}/ 

DA EVITARE

root@kitploit:~
/[-a-z0-9._%+]*@[-a-z0-9.]{2,10}\.[a-z]{2,4}/
/[-a-z0-9._%+]+@[-a-z0-9.]{2,10}\.[a-z]{2,4}/
/[-a-z0-9._%+]{x,y}@[-a-z0-9.]{2,10}\.[a-z]{2,4}/

Se vuoi assicurarti che, ad esempio, exec sia seguito da /bin/sh, puoi usare gli offset forniti dal simbolo @. Questa sarebbe la versione lenta con regex:

root@kitploit:~
$ = /exec.*\/bin\/sh/

Questo è il metodo più veloce con gli offset:

root@kitploit:~
strings:
  $exec = "exec" 
  $sh   = "/bin/sh"
conditions:
  $exec and $sh and
  @exec < @sh

Cerca anche di includere lunghe sequenze di stringhe che possano fungere da ancore nel processo di matching. Ancora una volta, più sono lunghe, meglio è.

PESSIMO

root@kitploit:~
$s1 = /http:\/\/[.]*\.hta/	// greedy [.]*

MIGLIORE

root@kitploit:~
$s1 = /http:\/\/[a-z0-9\.\/]{3,70}\.hta/ 	// better, with an the upper bound

OTTIMO

root@kitploit:~
$s1 = /mshta\.exe http:\/\/[a-z0-9\.\/]{3,70}\.hta/

Errore di Troppi Match e Rallentamento della Scansione

Gli errori "too many matches" sono causati da stringhe troppo generiche presenti nell'input con troppa frequenza, oppure da YARA che trova la stessa occorrenza più volte.

Il rallentamento della scansione è causato da stringhe che generano atomi troppo corti, o nessun atomo. Di conseguenza, YARA utilizza un algoritmo di pattern matching ingenuo, che causa il rallentamento.

Entrambi questi problemi possono, in alcuni casi, essere risolti con questi passaggi:

  1. Controlla i quantificatori .* e .+, .*?
  2. Controlla i quantificatori senza limite superiore come x{14,}
  3. Controlla gli intervalli troppo ampi (ad es. x{1,300000})
  4. Controlla i grandi salti nelle stringhe esadecimali
  5. Controlla i caratteri jolly - possono essere specificati in modo più preciso, o la stringa potrebbe essere divisa in 2, omettendo il carattere jolly?
  6. Controlla le alternanze: possono essere divise in 2 o più stringhe?
  7. Prova ad aggiungere specifiche per il matching di parole (fullword, \b,...)

Nota: nel prossimo capitolo Condizioni e Valutazione Short-Circuit vengono menzionati alcuni suggerimenti per le condizioni. Tuttavia, modificarle non risolverà gli errori di troppi match e di rallentamento della scansione.

Condizioni e Valutazione Short-Circuit

Cerca di scrivere le istruzioni della condizione in modo che gli elementi che hanno maggiori probabilità di essere "False" siano posti per primi. La condizione viene valutata da sinistra a destra. Prima il motore identifica che una regola non è soddisfatta, prima può saltare la regola corrente e valutare la successiva. Il miglioramento di velocità derivante da questo modo di ordinare le istruzioni della condizione dipende dalla differenza nei cicli di CPU necessari per elaborare ciascuna istruzione. Se tutte le istruzioni hanno più o meno lo stesso costo, riordinarle non produce alcun miglioramento evidente. Se una delle istruzioni può essere elaborata molto rapidamente, si consiglia di metterla per prima, in modo da saltare la valutazione dell'istruzione costosa nei casi in cui la prima istruzione è FALSE.

Cambiare l'ordine nella seguente istruzione non produce un miglioramento significativo:

root@kitploit:~
$string1 and $string2 and uint16(0) == 0x5A4D

Tuttavia, se il tempo di esecuzione delle istruzioni è molto diverso, riordinarle per attivare lo short-circuit migliorerà significativamente la velocità di scansione:

LENTO

root@kitploit:~
// EXPENSIVE and CHEAP
math.entropy(0, filesize) > 7.0 and uint16(0) == 0x5A4D

VELOCE

root@kitploit:~
// CHEAP and EXPENSIVE
uint16(0) == 0x5A4D and math.entropy(0, filesize) > 7.0

La valutazione short-circuit è stata introdotta per aiutare a ottimizzare le istruzioni costose, in particolare le istruzioni "for". Alcune persone usavano condizioni come quella nell'esempio seguente:

root@kitploit:~
strings:
	$mz = "MZ"
	...
condition:
	$mz at 0 and for all i in (1..filesize) : ( whatever )

Poiché filesize può essere un numero molto grande, "whatever" può essere eseguito molte volte, rallentando l'esecuzione. Ora, con la valutazione short-circuit, l'istruzione "for" verrà eseguita solo se la prima parte della condizione è soddisfatta, quindi questa regola sarà lenta solo per i file MZ. Un ulteriore miglioramento potrebbe essere:

root@kitploit:~
$mz at 0 and filesize < 100KB and for all i in (1..filesize) : ( whatever )

In questo modo viene impostato un limite superiore al numero di iterazioni.

Dalla versione 3.10, anche i cicli su intervalli interi sono stati ottimizzati:

root@kitploit:~
for all i in (0..100): (false)
for any i in (0..100): (true)

Both of these loops will stop iterating after the first time through.

Nessuno Short-Circuit per le Espressioni Regolari

Purtroppo questo non funziona con le espressioni regolari, perché vengono tutte inizialmente inserite nel motore di matching delle stringhe. L'esempio seguente rallenterà la ricerca per qualsiasi file e non solo per quelli con filesize inferiore a 200 byte:

root@kitploit:~
strings:
  $expensive_regex = /\$[a-z0-9_]+\(/ nocase
conditions:
  filesize < 200 and
  $expensive_regex

Questa valutazione "short-circuit" viene applicata dalla versione 3.4 di YARA.

Metadati

Qualsiasi dato nella sezione metadata viene letto nella RAM da YARA. (Puoi facilmente verificarlo inserendo 100.000 hash in una regola e controllando l'utilizzo della RAM della scansione YARA prima e dopo.) Naturalmente non vorrai rimuovere permanentemente i metadati dalle regole, ma se hai poca RAM, potresti rimuovere alcune parti non necessarie nel tuo flusso di lavoro, subito prima della scansione.

Scarica lo strumento