Reglas YARA: Anatomía, Patrones y Tu Primera Regla de Detección
Guía completa de YARA rules: sintaxis, strings (text, hex, regex), conditions, módulos (PE, ELF, math, hash), metadata. Casos prácticos: detectar Cobalt Strike beacon, identificar packers, y hunting con YARA en VirusTotal.
YARA es el bisturí del analista de malware
Si Sigma es el lenguaje universal para detectar comportamientos en logs, YARA es el lenguaje universal para detectar malware en ficheros. Cada vez que un analista examina un binario sospechoso, un documento Office con macros, o un script PowerShell ofuscado, YARA es la herramienta que permite escribir una firma precisa que diga: "este fichero contiene exactamente estos patrones, en esta combinación, bajo estas condiciones".
YARA no es un antivirus. No ejecuta nada. No descompila nada. Lee bytes, aplica patrones, y dice "match" o "no match". Esa simplicidad es su fortaleza: funciona en cualquier contexto, desde un script de respuesta a incidentes hasta un pipeline de threat hunting a escala en VirusTotal.
¿Qué es YARA? Origen y ecosistema
YARA fue creada por Victor Manuel Alvarez en 2008 mientras trabajaba en VirusTotal (adquirida por Google en 2012). El nombre es un acrónimo recursivo: Yet Another Ridiculous Acronym. A pesar del nombre, YARA se convirtió en el estándar de facto para la clasificación de malware por patrones.
Dónde se usa YARA hoy
| Contexto | Herramientas | Uso |
|---|---|---|
| Threat Hunting | VirusTotal Hunting, Retrohunt | Buscar samples nuevos y retroactivos |
| Incident Response | Loki, Thor, Fenrir | Escanear endpoints buscando IOCs |
| EDR/XDR | CrowdStrike Falcon, SentinelOne | Reglas custom de detección |
| Sandbox | ANY.RUN, CAPE, Cuckoo | Clasificar samples post-ejecución |
| Threat Intel | MISP, OpenCTI, YETI | Compartir firmas entre equipos |
| CI/CD Security | yara-ci, pre-commit hooks | Detectar código malicioso en repos |
| Mail Gateway | Filtrado de adjuntos | Bloquear documentos con macros maliciosas |
YARA vs otras herramientas de detección
YARA: matchea FICHEROS (binarios, docs, scripts, memoria)
Sigma: matchea EVENTOS/LOGS (process creation, network, registry)
Snort: matchea TRÁFICO DE RED (paquetes, payloads)
Suricata: matchea TRÁFICO DE RED (más potente que Snort)
YARA + Sigma = cobertura completa: detectas el artefacto Y el comportamiento
Anatomía de una regla YARA
Toda regla YARA tiene la misma estructura. No hay excepciones.
rule NombreDeLaRegla : tag1 tag2
{
meta:
author = "MalwareIntel Research"
description = "Detecta X basándose en Y"
date = "2026-06-05"
reference = "https://fuente.original/report"
strings:
$texto1 = "cadena de texto"
$hex1 = { 4D 5A 90 00 }
$regex1 = /patr[oó]n\s+regex/
condition:
uint16(0) == 0x5A4D and
filesize < 500KB and
2 of ($texto*, $hex*) and
$regex1
}
Desglose de cada sección
| Sección | Obligatoria | Función |
|---|---|---|
rule NombreDeLaRegla | Si | Identificador único. Solo alfanuméricos y _. No puede empezar por número |
: tag1 tag2 | No | Etiquetas para filtrar reglas (ej: apt, ransomware, loader) |
meta: | No | Metadatos descriptivos. No afectan al matching |
strings: | No | Patrones a buscar en el fichero |
condition: | Si | Lógica booleana que determina si hay match |
La sección condition es la única obligatoria junto con el nombre. Una regla válida minima es:
rule MatchTodo
{
condition:
true
}
Esa regla matchea cualquier fichero. No es útil, pero ilustra la estructura.
Strings: tres tipos de patrones
YARA soporta tres tipos de strings. Cada uno tiene su sintaxis y sus modificadores.
1. Text strings (cadenas de texto)
Buscan secuencias de caracteres ASCII o Unicode en el fichero.
strings:
$s1 = "cmd.exe /c"
$s2 = "powershell -enc"
$s3 = "CreateRemoteThread"
$s4 = "http://malicious.domain/beacon"
Modificadores de text strings
| Modificador | Efecto | Ejemplo |
|---|---|---|
nocase | Ignora mayúsculas/minúsculas | $s1 = "cmd.exe" nocase |
wide | Busca en encoding UTF-16LE (cada char ocupa 2 bytes) | $s1 = "password" wide |
ascii | Busca en ASCII (por defecto) | $s1 = "password" ascii |
wide ascii | Busca en ambos encodings | $s1 = "password" wide ascii |
fullword | Solo matchea si está delimitado por caracteres no alfanuméricos | $s1 = "evil" fullword |
xor | Busca con XOR aplicado (todas las keys 0x00-0xFF) | $s1 = "This program" xor |
xor(0x01-0xFF) | XOR con rango de keys específico | $s1 = "password" xor(0x01-0x0F) |
base64 | Busca la string en las 3 variantes de offset base64 | $s1 = "admin" base64 |
private | No aparece en el output, solo se usa en condition | $s1 = "interno" private |
El modificador wide es fundamental para malware en Windows. Muchas APIs de Windows usan strings UTF-16LE, donde "cmd.exe" se almacena como c\x00m\x00d\x00.\x00e\x00x\x00e\x00. Sin wide, YARA no lo encontraría.
2. Hex strings (patrones hexadecimales)
Buscan secuencias exactas de bytes. Son imprescindibles para matchear código máquina, cabeceras de fichero, y payloads binarios.
strings:
// Cabecera PE (MZ)
$mz = { 4D 5A }
// Secuencia exacta de opcodes x86
$shellcode = { 6A 40 68 00 10 00 00 6A 00 }
// Con wildcards: ?? matchea cualquier byte
$pattern = { 4D 5A ?? ?? ?? ?? ?? ?? 50 45 }
// Con jumps: [min-max] bytes de separación
$jump = { 4D 5A [4-8] 50 45 00 00 }
// Jump sin límite superior
$wide_jump = { E8 [0-100] C3 }
// Alternativas con paréntesis y pipes
$alt = { 4D 5A ( 90 00 | 00 00 | 50 00 ) }
// Nibble wildcards: ? matchea medio byte (4 bits)
$nibble = { 4D 5? }
Wildcards y jumps explicados
?? → cualquier byte (0x00-0xFF)
?A → nibble alto variable, nibble bajo 0xA (0x0A, 0x1A, 0x2A...)
[4] → exactamente 4 bytes de cualquier valor
[4-8] → entre 4 y 8 bytes de cualquier valor
[0-100] → entre 0 y 100 bytes (cuidado con performance)
(AA|BB) → byte 0xAA o byte 0xBB en esa posición
Los jumps son especialmente útiles para patrones que varían entre versiones de un mismo malware. Por ejemplo, un C2 beacon que mantiene la misma estructura pero cambia offsets entre compilaciones.
3. Regex (expresiones regulares)
YARA soporta un subconjunto de PCRE (Perl Compatible Regular Expressions). Las regex van delimitadas por /.
strings:
// URL con dominio variable
$url = /https?:\/\/[a-z0-9\-\.]+\.(xyz|top|tk|ml)\/[a-z0-9]{8,}/
// User-Agent sospechoso
$ua = /User-Agent:\s*Mozilla\/[45]\.0\s+\(compatible;\s*MSIE\s+[6-9]/
// Base64 de longitud sospechosa
$b64 = /[A-Za-z0-9+\/]{100,}={0,2}/
// Registry key de persistencia
$reg = /HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run/i
// PowerShell encoded command
$ps = /powershell[^;]{0,30}-e(nc|ncodedcommand)/i
Modificadores de regex
| Modificador | Efecto |
|---|---|
/i | Case insensitive |
/s | El punto . matchea también newlines |
wide | Busca en UTF-16LE |
ascii | Busca en ASCII |
fullword | Solo matchea como palabra completa |
Las regex en YARA son más lentas que text strings y hex strings. Usarlas solo cuando los otros tipos no son suficientes.
Conditions: la lógica de detección
La sección condition determina si un fichero matchea la regla. Usa operadores booleanos, funciones sobre strings, y funciones sobre el fichero.
Operadores booleanos
condition:
// AND: todas deben cumplirse
$s1 and $s2 and $s3
// OR: al menos una
$s1 or $s2
// NOT: negación
$s1 and not $s2
// Paréntesis para agrupar
($s1 or $s2) and $s3
Conteo y cuantificadores
condition:
// Al menos 2 de las strings definidas
2 of ($s*)
// Todas las strings que empiezan por $api_
all of ($api_*)
// Cualquiera de las strings
any of them
// Exactamente 3 de un conjunto
3 of ($s1, $s2, $s3, $s4, $s5)
// Número de ocurrencias de una string
#s1 > 5 // $s1 aparece más de 5 veces
Funciones sobre el fichero
condition:
// Tamaño del fichero
filesize < 500KB
filesize > 1MB and filesize < 10MB
// Primeros bytes del fichero (magic bytes)
uint16(0) == 0x5A4D // PE file (MZ header)
uint32(0) == 0x464C457F // ELF file
uint32(0) == 0x04034B50 // ZIP file
// Offset: string en posición específica
$mz at 0 // $mz debe estar en offset 0
// Rango: string dentro de un rango
$s1 in (0..1024) // $s1 en los primeros 1024 bytes
// Entrypoint (solo PE y ELF)
$code at entrypoint // código en el entry point
$s1 in (entrypoint..entrypoint + 100) // primeros 100 bytes desde EP
Expresiones for
Las expresiones for permiten iterar sobre ocurrencias de strings o sobre rangos.
condition:
// Para cada ocurrencia de $s1, verificar que está en los primeros 1024 bytes
for all i in (1..#s1) : (@s1[i] < 1024)
// Al menos una ocurrencia de $s1 seguida de $s2 en los 100 bytes siguientes
for any i in (1..#s1) : (
for any j in (1..#s2) : (
@s2[j] > @s1[i] and @s2[j] < @s1[i] + 100
)
)
Donde #s1 es el número de ocurrencias, @s1[i] es el offset de la i-esima ocurrencia, y !s1[i] es la longitud de la i-esima ocurrencia.
Metadata: documentar para compartir
La sección meta no afecta al matching, pero es fundamental para la operativa de un equipo de detección. Sin metadata, una regla que matchea no sirve: nadie sabe qué hacer con el resultado.
meta:
// Obligatorios (convención de la comunidad)
author = "MalwareIntel Research"
description = "Detecta Cobalt Strike beacon con configuración por defecto"
date = "2026-06-05"
reference = "https://malwareintel.es/blog/cobalt-strike-analysis"
// Clasificación
tlp = "WHITE"
mitre_att_ck = "T1071.001, T1059.001"
malware_family = "Cobalt Strike"
malware_type = "C2 Framework"
actor = ""
// Calidad
hash1 = "a1b2c3d4e5f6..."
hash2 = "f6e5d4c3b2a1..."
score = 75
quality = "production"
false_positive_rate = "low"
last_modified = "2026-06-05"
// Contexto operativo
severity = "critical"
in_the_wild = true
source = "internal_research"
Convención de metadatos en MalwareIntel
| Campo | Tipo | Descripción |
|---|---|---|
author | string | Autor o equipo |
description | string | Qué detecta y cómo |
date | string | Fecha de creación (YYYY-MM-DD) |
reference | string | URL del análisis o report |
tlp | string | Traffic Light Protocol (WHITE/GREEN/AMBER/RED) |
mitre_att_ck | string | Técnicas ATT&CK relacionadas |
hash1..hashN | string | Hashes de samples de referencia |
score | integer | Confianza de la regla (0-100) |
Módulos: potencia extendida
Los módulos de YARA extienden la funcionalidad base con parsers especializados. Los más usados en análisis de malware:
Módulo PE
El módulo pe parsea la cabecera PE (Portable Executable) de Windows. Es el módulo más importante para análisis de malware.
import "pe"
rule SuspiciousPE
{
condition:
// Timestamp de compilación en el futuro
pe.timestamp > 1900000000
// Menos de 3 secciones (posible packer)
pe.number_of_sections < 3
// Importa función sospechosa
pe.imports("kernel32.dll", "VirtualAllocEx")
// Entry point en sección diferente a .text
not pe.sections[pe.section_index(pe.entry_point)].name startswith ".text"
// Overlay presente (datos después de la última sección)
pe.overlay.size > 0
// Firmado con certificado expirado o inválido
pe.number_of_signatures > 0 and
not pe.signatures[0].verified
}
Funciones PE más usadas
| Función | Uso |
|---|---|
pe.imports("dll", "func") | Verifica imports por nombre |
pe.exports("func") | Verifica exports |
pe.sections[i].name | Nombre de sección |
pe.sections[i].characteristics | Flags de sección (RWX) |
pe.entry_point | Offset del entry point |
pe.timestamp | Timestamp de compilación |
pe.number_of_resources | Recursos embebidos |
pe.rich_signature.key | Rich header XOR key |
pe.imphash() | Import hash (clasificación rápida) |
Módulo ELF
Equivalente al módulo PE para binarios Linux.
import "elf"
rule SuspiciousELF
{
condition:
elf.type == elf.ET_EXEC and
elf.number_of_sections < 5 and
elf.entry_point != 0
}
Módulo math
Calcula propiedades estadísticas del fichero. La entropía es especialmente útil para detectar ofuscación y cifrado.
import "math"
rule HighEntropySection
{
condition:
// Entropía global alta (posible packing/cifrado)
math.entropy(0, filesize) > 7.5
// O entropía alta en los primeros 1024 bytes
// math.entropy(0, 1024) > 7.0
}
| Valor de entropía | Interpretación |
|---|---|
| 0-1 | Datos muy uniformes (nulls, repeticiones) |
| 1-4 | Texto plano, código fuente |
| 4-6 | Código compilado normal |
| 6-7 | Datos comprimidos o parcialmente cifrados |
| 7-8 | Cifrado fuerte, compresión alta, o packing |
Módulo hash
Calcula hashes de secciones específicas del fichero.
import "hash"
rule KnownMaliciousSection
{
condition:
// Hash de los primeros 1024 bytes
hash.sha256(0, 1024) == "a1b2c3..."
// Hash de una sección específica (combinado con pe)
// hash.md5(pe.sections[0].raw_data_offset,
// pe.sections[0].raw_data_size) == "d4e5f6..."
}
Caso practico 1: detectar Cobalt Strike beacon
Cobalt Strike es el C2 framework más usado tanto por red teams como por grupos APT. Detectar un beacon con la configuración por defecto es un ejercicio clasico.
import "pe"
rule CobaltStrike_Beacon_Default
{
meta:
author = "MalwareIntel Research"
description = "Detecta Cobalt Strike beacon con indicadores de configuración por defecto"
date = "2026-06-05"
reference = "https://malwareintel.es/blog/cobalt-strike-beacon"
tlp = "WHITE"
mitre_att_ck = "T1071.001, T1059.001, T1055"
malware_family = "Cobalt Strike"
score = 80
strings:
// Config block markers
$config1 = { 00 01 00 01 00 02 ?? ?? 00 02 00 01 00 }
$config2 = { 69 68 69 68 69 6B 69 6B 69 6A }
// Named pipe patterns (default)
$pipe1 = "\\\\.\\pipe\\msagent_" ascii wide
$pipe2 = "\\\\.\\pipe\\MSSE-" ascii wide
$pipe3 = "\\\\.\\pipe\\postex_" ascii wide
$pipe4 = "\\\\.\\pipe\\status_" ascii wide
// Default User-Agent
$ua = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" ascii
// Beacon commands
$cmd1 = "beacon.dll" ascii
$cmd2 = "beacon.x64.dll" ascii
$cmd3 = "%s%s: %s" ascii
$cmd4 = "ReflectiveLoader" ascii
// Sleep mask / XOR routines
$xor1 = { 8B ?? 83 ?? 04 33 ?? 89 ?? 83 ?? 04 3B }
$xor2 = { 0F B6 ?? 30 ?? ?? FF ?? 3B }
condition:
uint16(0) == 0x5A4D and
filesize < 1MB and
(
(1 of ($config*) and 1 of ($pipe*)) or
(2 of ($cmd*) and 1 of ($xor*)) or
($ua and 1 of ($cmd*) and 1 of ($pipe*))
)
}
Por qué funciona esta regla
La regla combina tres estrategias de detección independientes, unidas con or:
- Config block + named pipe: el beacon almacena su configuración en un bloque con estructura fija. Los named pipes por defecto son conocidos.
- Beacon commands + XOR routine: la cadena "ReflectiveLoader" es característica de la inyección reflectiva, y los patrones XOR corresponden al sleep mask.
- User-Agent + commands + pipe: la combinación del UA por defecto con otros indicadores es suficientemente específica.
Cada rama por separado podría dar falsos positivos. La combinación los reduce drásticamente.
Caso practico 2: identificar UPX packing
UPX es el packer más común. Detectar binarios empacados con UPX es útil como paso previo al análisis (desempacar antes de aplicar reglas de detección).
import "pe"
import "math"
rule UPX_Packed_PE
{
meta:
author = "MalwareIntel Research"
description = "Detecta ejecutables PE empacados con UPX"
date = "2026-06-05"
tlp = "WHITE"
score = 90
false_positive_rate = "very_low"
strings:
// UPX magic en secciones
$upx0 = "UPX0" ascii
$upx1 = "UPX1" ascii
$upx2 = "UPX2" ascii
$upx_sig = "UPX!" ascii
// String de versión UPX
$version = /UPX\s+[0-9]+\.[0-9]+/ ascii
condition:
uint16(0) == 0x5A4D and
filesize < 20MB and
(
// Secciones nombradas UPX0/UPX1
(
for any i in (0..pe.number_of_sections - 1) : (
pe.sections[i].name == "UPX0" or
pe.sections[i].name == "UPX1"
)
)
or
// Magic string UPX!
($upx_sig and ($upx0 or $upx1))
) and
// Entropía alta confirma packing
math.entropy(0, filesize) > 6.5
}
La combinación de nombres de sección UPX con entropía alta es casi infalible. UPX comprime el código, lo que eleva la entropía significativamente por encima de un PE normal.
Caso practico 3: detectar macro maliciosa en Office
Los documentos Office con macros maliciosas siguen patrones reconocibles en su estructura OLE.
rule Office_Malicious_Macro
{
meta:
author = "MalwareIntel Research"
description = "Detecta documentos Office con macros que descargan o ejecutan payloads"
date = "2026-06-05"
tlp = "WHITE"
mitre_att_ck = "T1566.001, T1204.002, T1059.005"
score = 70
strings:
// OLE magic (documentos Office legacy .doc, .xls)
$ole_magic = { D0 CF 11 E0 A1 B1 1A E1 }
// Indicadores de macro VBA
$vba1 = "VBAProject" ascii wide
$vba2 = "ThisDocument" ascii wide
$vba3 = "AutoOpen" ascii wide nocase
$vba4 = "Document_Open" ascii wide nocase
$vba5 = "Auto_Open" ascii wide nocase
$vba6 = "Workbook_Open" ascii wide nocase
// Funciones de ejecución
$exec1 = "Shell" ascii wide fullword
$exec2 = "WScript.Shell" ascii wide
$exec3 = "CreateObject" ascii wide
$exec4 = "PowerShell" ascii wide nocase
$exec5 = "cmd.exe" ascii wide nocase
$exec6 = "MSXML2.XMLHTTP" ascii wide
$exec7 = "URLDownloadToFile" ascii wide
// Ofuscación típica
$obf1 = "Chr(" ascii wide
$obf2 = "ChrW(" ascii wide
$obf3 = "StrReverse" ascii wide
$obf4 = "Replace(" ascii wide
condition:
$ole_magic at 0 and
$vba1 and
1 of ($vba3, $vba4, $vba5, $vba6) and
(
2 of ($exec*) or
(1 of ($exec*) and 2 of ($obf*))
)
}
La lógica: el fichero debe ser OLE (no OOXML), contener un VBAProject con auto-ejecución, y tener al menos dos funciones de ejecución o una funcion de ejecución combinada con técnicas de ofuscación.
Hunting con YARA en VirusTotal
VirusTotal ofrece dos funcionalidades para hunting con YARA:
VT Hunting (Livehunt)
Livehunt aplica tus reglas YARA a todos los ficheros que se suben a VirusTotal en tiempo real. Cuando un sample matchea, recibes una notificación.
Configuración:
1. Cuenta VirusTotal con licencia (Intelligence o Enterprise)
2. Subir regla YARA al panel Livehunt
3. Configurar notificaciones (email, webhook, Slack)
4. Definir filtro de prioridad (por score, por tag, por fuente)
Límites:
Free: 0 reglas Livehunt
Premium: 25 reglas Livehunt
Enterprise: 100+ reglas Livehunt
VT Retrohunt
Retrohunt aplica tus reglas YARA retroactivamente sobre los ficheros ya almacenados en VirusTotal (varios petabytes, meses de historia). Es la herramienta definitiva para responder: "¿ha existido este malware antes de que lo descubriéramos?"
Uso típico de Retrohunt:
1. Descubres un nuevo sample de malware
2. Escribes una regla YARA basada en sus patrones únicos
3. Lanzas Retrohunt para buscar variantes anteriores
4. Encuentras samples de hace 6 meses: el actor llevaba tiempo activo
5. Extraes IOCs adicionales de los samples históricos
Tips para reglas de Hunting en VT
1. Especificidad alta: VT procesa millones de ficheros/día.
Una regla con muchos falsos positivos es inútil.
2. Combinar strings con condiciones estructurales:
"filesize < 1MB and pe.imports(...)" reduce el espacio de búsqueda.
3. Evitar regex costosas: /.*/ o patrones con backtracking
causan timeouts en Retrohunt.
4. Usar pe.imphash() para familias conocidas:
el import hash agrupa variantes compiladas con el mismo código.
5. Testear antes con VT Intelligence search:
content:"cadena" type:peexe size:500kb-
Herramientas complementarias
| Herramienta | Función | URL |
|---|---|---|
| yarGen | Genera reglas YARA automáticamente a partir de samples | github.com/Neo23x0/yarGen |
| yaraQA | Valida calidad de reglas (performance, falsos positivos) | github.com/Neo23x0/yaraQA |
| YARA-X | Rewrite oficial de YARA en Rust. Más rápido, mejor soporte regex | github.com/VirusTotal/yara-x |
| yara-ci | Integración CI/CD para validar reglas en PRs | github.com/Neo23x0/yara-ci |
| Loki | Scanner IOC/YARA para endpoints (incident response) | github.com/Neo23x0/Loki |
| Thor Lite | Scanner avanzado con reglas Signature Base incluidas | nextron-systems.com |
| YARA Editor (VSCode) | Extensión con syntax highlighting y snippets | marketplace.visualstudio.com |
| YARAify | Servicio de abuse.ch para escanear samples con reglas YARA | yaraify.abuse.ch |
yarGen: generar reglas a partir de samples
yarGen analiza un directorio de samples maliciosos y genera reglas YARA basadas en strings únicas (excluyendo strings comunes de software legítimo usando Goodware strings DB).
# Instalar
pip install yargen
# Generar reglas a partir de un directorio de samples
yargen -m /path/to/malware_samples/ -o rules_output.yar
# Excluir strings comunes (reduce falsos positivos)
yargen -m /path/to/malware_samples/ \
--excludegood \
-o rules_output.yar
Las reglas generadas por yarGen son un punto de partida. Siempre necesitan revisión manual: eliminar strings genéricas, ajustar conditions, y añadir metadata.
Errores comunes y best practices
Errores que producen falsos positivos
| Error | Problema | Solución |
|---|---|---|
| Strings demasiado genéricas | "http://" matchea cualquier binario con URLs | Combinar con strings más específicas |
| Sin restricción de filesize | Matchea PDFs de 100MB o ISOs | Añadir filesize < X |
| Sin magic bytes | Matchea ficheros de tipos inesperados | Añadir uint16(0) == 0x5A4D para PE |
| Regex sin anclar | /[a-z]+/ matchea cualquier texto | Ser más específico: /\/api\/v[12]\/[a-z]{8,}/ |
| Solo 1 string en condition | Una string sola rara vez es suficiente | Combinar: 2 of ($s*) |
Errores que afectan performance
| Error | Problema | Solución |
|---|---|---|
Regex con .* | Backtracking exponencial | Limitar: .{0,100} |
| Muchas regex | Cada regex se evalúa independientemente | Preferir text/hex strings |
| Jumps muy amplios | { AA [0-10000] BB } escanea mucho | Reducir rango o reestructurar |
| Sin short-circuit | Conditions costosas primero | Poner filesize y uint16(0) al inicio |
Best practices
1. SIEMPRE incluir filesize en condition
→ Evita escanear ficheros enormes innecesariamente
2. SIEMPRE incluir magic bytes cuando aplique
→ uint16(0) == 0x5A4D para PE, OLE magic para Office
3. Usar al menos 2-3 strings en combinación
→ Reduce falsos positivos drásticamente
4. Testear contra goodware antes de desplegar
→ Escanear contra Windows System32, Office, browsers
5. Documentar con metadata completa
→ author, description, date, reference, hash, mitre_att_ck, tlp
6. Versionado en git con CI
→ Cada regla es código. Revisión por pares obligatoria
7. Organizar reglas por familia/actor/tipo
→ apt28.yar, cobalt_strike.yar, ransomware_generic.yar
8. Performance: short-circuit conditions
→ filesize < 500KB and uint16(0) == 0x5A4D and (strings...)
Los checks baratos primero, los costosos después
Recursos y referencias
- Victor Alvarez: YARA Documentation (referencia oficial)
- VirusTotal: YARA-X (rewrite en Rust, el futuro de YARA)
- Florian Roth (Neo23x0): Signature Base (miles de reglas YARA de producción)
- Florian Roth: yarGen (generador automático de reglas)
- Florian Roth: YARA Performance Guidelines (optimización)
- abuse.ch: YARAify (plataforma de scanning con YARA)
- MITRE ATT&CK: Software (referencia de familias para mapear reglas)
- InQuest Labs: YARA Rule Collection (curación comunitaria)
- MalwareIntel: Reglas Sigma: Sintaxis y Primer Caso (artículo complementario)
Siguiente paso
Con la anatomía de YARA dominada, el siguiente artículo de la serie aplica estos conceptos a un caso real: escribir reglas YARA para detectar infostealers (RedLine, Lumma, Vidar) basándose en sus patrones de comunicación C2 y sus artefactos en disco.
Preguntas frecuentes
Artículos relacionados
¿Qué es Detection Engineering? Del Alert Fatigue a Detecciones que Funcionan
Reglas Sigma: Sintaxis, Estructura y Tu Primer Caso Práctico
YARA para Infostealers: Patrones de Exfiltración, C2 y Credential Theft
Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.