Chaînes YARA : texte, hexadécimal et regex
Écrire les chaînes d’une règle YARA : texte et échappements, modificateurs nocase, wide, xor et base64, chaînes hexadécimales avec jokers et sauts, regex.
Les motifs — YARA les appelle strings, même quand ce sont des octets ou des regex — sont ce que YARA recherche avant d’évaluer la condition. Bien les choisir décide à la fois de la précision et de la vitesse d’une règle. Ce guide couvre les trois types de motifs et leurs modificateurs.
Chaînes de texte
Une chaîne de texte s’écrit entre guillemets et est comparée octet par octet :
rule Text_Strings
{
strings:
$a = "Global\\MyMutex_2024"
$b = "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0)"
$c = "tab\there and a quote \" inside"
$d = "\x4D\x5A with raw bytes"
condition:
any of them
}
Échappements acceptés : \", \\, \t, \n, \r et \xNN pour un octet quelconque. YARA-X refuse les séquences inconnues au lieu de les ignorer silencieusement — source d’erreurs fréquente lors du portage d’anciennes règles (voir YARA-X vs YARA).
Modificateurs de chaînes
Les modificateurs suivent la valeur et changent la façon dont elle est recherchée.
| Modificateur | Effet | Remarques |
|---|---|---|
ascii | Octets tels quels | Par défaut en l’absence d’encodage |
wide | UTF-16LE (chaque caractère suivi de 00) | Combiner avec ascii pour chercher les deux |
nocase | Insensible à la casse | Multiplie les variantes internes ; à éviter sur des chaînes courtes |
fullword | Délimitée par des caractères non alphanumériques | "evil" ne trouvera plus "devil" |
xor | Aussi la chaîne XORée avec chaque clé d’un octet (1–255) | xor(1-255) ou xor(0x20) pour restreindre |
base64 / base64wide | La chaîne à l’intérieur de données base64 | Alphabet personnalisé possible ; incompatible avec nocase, xor, fullword |
private | Correspond mais n’apparaît pas dans les résultats | Utile pour des motifs auxiliaires |
rule Modifier_Examples
{
strings:
$cfg = "ConfigBlock" wide ascii
$cmd = "invoke-expression" nocase
$key = "SuperSecretKey!" xor(1-255)
$b64 = "powershell -nop" base64
$word = "backdoor" fullword
condition:
2 of them
}
Réservez xor, base64 et nocase aux chaînes d’au moins six à huit caractères : chaque modificateur démultiplie le motif, et des variantes courtes correspondent à des données aléatoires.
Chaînes hexadécimales
Les chaînes hexadécimales décrivent des octets bruts entre accolades. C’est l’outil de choix pour les séquences de code, les en-têtes et les blocs de configuration binaires.
rule Hex_Syntax
{
strings:
$fixed = { 4D 5A 90 00 03 00 00 00 }
$wild = { E8 ?? ?? ?? ?? 83 C4 04 }
$nibble = { 6A 4? 68 00 30 00 00 }
$jump = { 55 8B EC [2-6] 83 EC 20 }
$alt = { 68 ( 00 10 | 00 20 ) 00 00 }
condition:
any of them
}
| Syntaxe | Signification |
|---|---|
?? | N’importe quel octet |
4? / ?A | Joker sur un quartet |
[4], [2-6], [8-] | Saut d’exactement 4, de 2 à 6, ou d’au moins 8 octets |
( AA | BB CC ) | Alternatives, éventuellement de longueurs différentes |
~00 | Tout octet sauf 00 (YARA 4.3+ et YARA-X) |
Les instructions avec adresses relatives (call, jmp, lea rip) doivent avoir leurs opérandes en joker, sinon la règle ne correspond qu’à une seule compilation. Gardez au moins quatre octets fixes consécutifs pour que YARA puisse extraire un bon atome.
Expressions régulières
Les regex s’écrivent entre barres obliques, avec une syntaxe proche de Perl : classes, quantificateurs, alternatives, groupes, ancres. Deux options peuvent suivre la barre finale : i (insensible à la casse) et s (le point accepte les retours à la ligne). Les modificateurs ascii, wide, nocase, fullword et private s’appliquent aussi.
rule Regex_Examples
{
strings:
$url = /https?:\/\/[a-z0-9\-.]{3,64}\.(top|xyz|click)\/[a-z0-9]{8}/ nocase
$ip_port = /\b(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}:[0-9]{2,5}\b/
$mutex = /Global\\[A-F0-9]{8}-[A-F0-9]{4}/
condition:
any of them
}
Pièges classiques :
- Pas de partie littérale :
/[a-z]{10}\.exe/n’a que.execomme ancrage ;/[a-z]{5,}/n’en a aucun et doit être tentée presque partout. .*en tête : les motifs ne sont déjà pas ancrés ; un.*initial ajoute seulement du travail.- Répétitions non bornées : préférez
{1,64}à+ou*quand la longueur maximale est connue. - Échappements : la barre oblique s’écrit
\/. YARA-X est plus strict que YARA 4 sur les échappements invalides.
Choisir le bon type
| Vous cherchez… | Utilisez |
|---|---|
| Une chaîne lisible et unique (mutex, user agent, chemin PDB) | Texte, avec wide si elle peut être en UTF-16 |
| Du code, un en-tête, une structure binaire | Hexadécimal avec jokers sur les adresses |
| Quelques variantes d’une séquence d’octets | Alternatives hexadécimales ( … | … ) |
| Une partie variable ou structurée (URL, GUID) | Regex avec un ancrage littéral |
| Une chaîne obfusquée | xor ou base64 sur une chaîne assez longue |
La performance en un paragraphe
YARA extrait de chaque motif une courte séquence fixe (un atome) et recherche tous les atomes en une seule passe ; le motif complet n’est vérifié que là où son atome apparaît. Les chaînes de moins de quatre octets, les motifs hexadécimaux faits de jokers, les octets fréquents comme 00 00 00 00 et les regex sans littéral produisent de mauvais atomes et ralentissent tout le jeu de règles. Le guide performance détaille le mécanisme, et le linter signale ces cas automatiquement.
Étape suivante : combiner vos motifs dans les conditions YARA.
FAQ
- Que fait le modificateur wide ?
- wide recherche la chaîne encodée en UTF-16LE, c’est-à-dire chaque caractère ASCII suivi d’un octet nul. Ajoutez ascii si la chaîne peut apparaître dans les deux encodages.
- Comment accepter n’importe quel octet dans une chaîne hexadécimale ?
- ?? remplace un octet entier, un ? seul remplace un quartet (par exemple 4? ou ?A), et [n-m] saute entre n et m octets quelconques.
- Quand utiliser une regex plutôt qu’une chaîne de texte ?
- Seulement quand la partie variable ne peut pas s’exprimer en texte ou en hexadécimal. Les regex sont plus lentes et doivent contenir une partie littérale de quelques octets pour rester efficaces.