Condiciones YARA: recuentos, posiciones y bucles
Escribe condiciones YARA: lógica booleana, recuentos y posiciones de cadenas, filesize y magic bytes, conjuntos any/all/N of, bucles for, with y referencias.
La condición es donde la regla decide. Los patrones solo dicen qué se encontró; la condición dice qué combinación de hallazgos, junto con las propiedades del archivo, constituye una detección.
Lógica booleana
Un identificador de patrón solo es verdadero si el patrón apareció al menos una vez. Se combinan con and, or, not y paréntesis:
rule Boolean_Logic
{
strings:
$a = "LoaderInit" ascii
$b = "GetProcAddress" ascii
$c = "debug build" ascii
condition:
($a and $b) and not $c
}
Recuentos, posiciones y longitudes
| Expresión | Significado |
|---|---|
#a | Número de coincidencias de $a |
@a[i] | Offset de la i-ésima coincidencia (desde 1) |
!a[i] | Longitud de la i-ésima coincidencia |
$a at 0x40 | $a exactamente en el offset 0x40 |
$a in (0..1024) | $a en el primer KB |
rule Counts_And_Offsets
{
strings:
$mz = "MZ"
$section = ".text" ascii
$marker = { DE AD BE EF }
condition:
$mz at 0 and #section >= 1 and $marker in (0..0x10000) and @marker[1] > 0x200
}
Tamaño y magic bytes
filesize es el tamaño en bytes (admite KB y MB). uint8/16/32 e int8/16/32 leen un entero en un offset (little-endian) y sus variantes be en big-endian:
| Tipo | Comprobación |
|---|---|
| PE de Windows | uint16(0) == 0x5A4D |
| ELF | uint32(0) == 0x464C457F |
uint32(0) == 0x46445025 | |
| ZIP / OOXML | uint32(0) == 0x04034B50 |
| OLE | uint32(0) == 0xE011CFD0 |
rule PE_With_PE_Header_Check
{
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550 and
filesize < 10MB
}
La segunda línea sigue el puntero e_lfanew en 0x3C y comprueba la firma PE\0\0, sin cargar el módulo pe. La división entera se escribe \ (filesize \ 2).
Conjuntos y cuantificadores
| Expresión | Verdadera cuando |
|---|---|
any of them | coincide al menos un patrón |
all of them | coinciden todos |
none of ($fp*) | no coincide ninguno del conjunto |
2 of ($x*) | al menos dos cuyo nombre empieza por $x |
50% of them | al menos la mitad |
rule Quantifier_Example
{
strings:
$x1 = "stage2_payload" ascii
$x2 = "BeaconSleep" ascii
$s1 = "cmd.exe" ascii
$s2 = "rundll32" ascii
$fp = "Microsoft Corporation" wide
condition:
uint16(0) == 0x5A4D and not $fp and (1 of ($x*) or 2 of ($s*))
}
Esta estructura «un indicador muy específico O varios débiles» es la base de muchas reglas públicas (ver convenciones).
Bucles
rule Loop_Examples
{
strings:
$hdr = { 50 4B 03 04 }
$a = "config" ascii
$b = "payload" ascii
condition:
for any i in (1..#hdr) : ( uint16(@hdr[i] + 26) > 64 ) and
for all of ($a, $b) : ( # >= 2 )
}
Dentro de for … of, $, # y @ se refieren al patrón actual. Limita los bucles con recuentos (1..#a), nunca con filesize.
Variables locales con with (YARA-X)
rule With_Example
{
condition:
with = uint32(0x3C) : (
uint16(0) == 0x5A4D and pe_offset < filesize and uint32(pe_offset) == 0x00004550
)
}
Las reglas con with no compilan con YARA 4.x.
El orden importa
YARA evalúa de izquierda a derecha y se detiene en cuanto conoce el resultado: pon primero lo barato y selectivo (magic bytes, filesize) y al final lo caro (módulos, math.entropy, bucles). Ver rendimiento y el linter; prueba los ejemplos en el editor y sigue con los módulos.
FAQ
- ¿Cómo compruebo el tipo de archivo en una condición?
- Lee los magic bytes en el offset 0, por ejemplo uint16(0) == 0x5A4D para un ejecutable de Windows o uint32(0) == 0x464C457F para ELF. Los enteros se leen en little-endian; las funciones con sufijo be, en big-endian.
- ¿Qué significa «N of them»?
- Que deben coincidir al menos N de los patrones declarados. them puede sustituirse por un conjunto como ($a*) o ($x1, $x2).
- ¿YARA deja de evaluar una condición antes de tiempo?
- Sí, los operadores booleanos cortocircuitan: poner primero las comprobaciones baratas (filesize, magic bytes) evita evaluar expresiones costosas en archivos que no pueden coincidir.