Saltar al contenido
Nuevo

DeepSeek V4.1 Flash gratis por 7 días: 10M tokens al día tras cualquier recarga. Hasta el 30/11.

Cómo funciona

Escribe una regla YARA contra un archivo de prueba inofensivo

Escribe tu primera regla YARA que coincida con un archivo inofensivo y no con otro, y aprende por qué toda regla necesita pruebas positivas y negativas.

Principiante10 min de lecturaPor NotHoly

Qué hace una regla YARA

YARA es una herramienta de coincidencia de patrones. Escribes una regla que describe cómo es un archivo, y YARA enumera los archivos que encajan con esa descripción. Lo usan sobre todo los analistas de malware. Escriben reglas para cadenas, estructuras de archivo y secuencias de bytes, y luego escanean carpetas, imágenes de disco y volcados de memoria. El mismo mecanismo sirve para cualquier archivo que controles, por ejemplo una plantilla que nunca debe llevar un marcador interno, o un archivo de configuración que nunca debe contener un token.

YARA no sabe qué es peligroso. Coincide con lo que dice la regla. Una regla es una afirmación sobre bytes, y solo vale lo que valga esa afirmación.

El proyecto está alojado en GitHub, bajo VirusTotal. La guía oficial de escritura, en Read the Docs, es la referencia de sintaxis. VirusTotal también mantiene YARA-X, una reescritura en Rust que conserva la mayor parte del lenguaje de reglas. Los dos se parecen, pero no son idénticos, así que lee las notas de compatibilidad antes de pasar una regla de uno a otro.

Por qué importan las reglas

Un hash de archivo responde a una pregunta estrecha: ¿este archivo exacto ya es conocido? Si cambias un byte, el hash cambia. El artículo sobre hashes de archivo lo explica con detalle. Una regla YARA hace una pregunta más amplia: ¿este archivo contiene las piezas que esperamos? Una sola regla puede coincidir con muchos archivos que comparten una cadena, una estructura o un patrón de bytes, aunque ninguno comparta hash.

Ahí también empieza el problema. Un hash casi nunca coincide con un archivo que no debería. Una regla descuidada puede coincidir con la mitad de tu servidor de archivos. Por eso lo que hay que aprender no es tanto la sintaxis. Lo importante es escribir una regla que coincida con lo que quieres, y solo con eso, y luego demostrarlo con archivos que controlas.

Anatomía de una regla

Toda regla tiene un nombre y, dentro de llaves, hasta tres secciones:

yara
rule Ejemplo_De_Regla {
  meta:
    description = "Para qué sirve esta regla"

  strings:
    $texto = "algún texto"

  condition:
    $texto
}

Los nombres de regla usan letras, números y guiones bajos, y no pueden empezar con un número. El nombre aparece en cada reporte de coincidencias, así que elige uno que le diga al lector de qué trata la regla.

meta

La sección meta guarda pares clave-valor para las personas: una descripción, un autor, una fecha, un enlace a la investigación que originó la regla. YARA nunca usa meta para decidir una coincidencia. Aun así, manténla exacta, porque la siguiente persona que abra el archivo va a confiar en ella.

strings

Cada cadena recibe un identificador que empieza con $. La condición se refiere a las cadenas por ese identificador. Hay tres tipos.

Las cadenas de texto van entre comillas dobles:

yara
$marcador = "LAB-TRAINING-MARKER"

Los modificadores cambian la forma en que se compara el texto. nocase ignora mayúsculas y minúsculas. wide coincide con texto UTF-16LE, donde cada carácter ASCII va seguido de un byte cero, algo común en binarios de Windows. fullword exige que la coincidencia aparezca sola, no dentro de una palabra más larga.

Las cadenas hexadecimales van entre llaves y coinciden con bytes en crudo:

yara
$mz = { 4D 5A }

Esos dos bytes son la firma MZ al inicio de muchos ejecutables de Windows. ?? coincide con cualquier byte, [2-4] admite un hueco de dos a cuatro bytes desconocidos, y ( 90 | 91 ) coincide con uno u otro.

Las expresiones regulares van entre barras:

yara
$version = /LAB-[A-Z]+ v[0-9]+/

Las regex son el tipo más flexible y también el más fácil de volver demasiado amplio. Usa una cadena de texto o hexadecimal siempre que pueda expresar el patrón.

condition

La condición es una expresión booleana. Combina cadenas y propiedades del archivo en una sola respuesta: coincide o no coincide.

  • $marcador es verdadero cuando la cadena aparece al menos una vez.
  • any of them y all of them cubren todas las cadenas de la regla. 2 of ($a, $b, $c) exige dos de tres.
  • $marcador at 0 exige la cadena en el primer byte. $marcador in (0..512) la exige en los primeros 512 bytes.
  • #marcador > 3 cuenta las ocurrencias.
  • filesize < 2KB revisa el tamaño del archivo.
  • uint16(0) == 0x5A4D lee los dos primeros bytes como un entero little-endian y revisa la firma MZ.

Toda regla necesita una condición. Una regla con cadenas y sin una condición razonable está rota o no sirve de nada.

Cómo lee YARA una regla

  1. YARA interpreta el archivo de reglas y lo compila. Un error de sintaxis detiene la ejecución antes de leer cualquier archivo.
  2. Para cada archivo que escanea, YARA busca todas las cadenas de la sección strings.
  3. Evalúa la condición con los resultados del paso 2.
  4. Si la condición es verdadera, el archivo coincide. Con -s, YARA también imprime cada cadena encontrada, con el desplazamiento en bytes donde apareció.

Las cadenas van primero y la condición después. Una condición como $a and $b es estricta, porque las dos cadenas deben encontrarse antes de que la regla pueda coincidir.

Laboratorio: un archivo positivo y uno negativo

La salida esperada de abajo se describe en lugar de pegarse, porque el formato exacto puede variar entre versiones de YARA. Compara lo que veas en tu terminal con esas descripciones.

Trabaja en una carpeta vacía. En Windows, ejecuta los comandos en Git Bash. El heredoc del paso 3 no funciona igual en PowerShell.

1. Instala yara

En Debian y Ubuntu:

bash
sudo apt install yara

En macOS con Homebrew:

bash
brew install yara

En Windows, descarga el zip de la versión desde https://github.com/VirusTotal/yara/releases, extráelo y pon el ejecutable en tu PATH. El archivo puede llamarse yara64.exe. Renómbralo a yara.exe, o cópialo con ese nombre, para que los comandos de abajo funcionen tal cual.

Verifica la instalación:

bash
yara --version

Deberías ver un número de versión. Este artículo no fija una versión, así que usa la versión más reciente que te dé tu método de instalación.

2. Crea un archivo positivo y uno negativo

bash
mkdir yara-lab && cd yara-lab
printf 'LAB-TRAINING-MARKER v1\n' > match.txt
printf 'archivo de texto común\n' > nomatch.txt

Ambos archivos son texto plano que tú escribiste. El primero debe coincidir con la regla. El segundo no debe.

3. Escribe la regla

Las comillas alrededor de EOF importan. Sin ellas, el shell reemplaza $m por una variable vacía antes de que YARA lea el archivo, y la regla deja de compilar.

bash
cat > lab.yar <<'EOF'
rule Lab_Training_Marker {
  meta: description = "Coincide con el marcador del laboratorio"
  strings: $m = "LAB-TRAINING-MARKER"
  condition: $m
}
EOF

Léela en tres partes. La meta dice para qué sirve la regla. La cadena dice que el archivo debe contener el texto del marcador. La condición dice que un archivo coincide cuando esa cadena se encuentra al menos una vez.

4. Ejecuta la prueba positiva

bash
yara -s lab.yar match.txt

YARA debería imprimir el nombre de la regla y la ruta del archivo. Gracias a -s, también imprime una línea para la cadena encontrada, con el desplazamiento en bytes y el texto hallado. El marcador empieza en el primer byte de match.txt, así que el desplazamiento debe ser 0x0.

5. Ejecuta la prueba negativa

bash
yara lab.yar nomatch.txt

Salida esperada: nada. YARA imprime solo las coincidencias, así que el silencio significa que el archivo no coincidió.

El silencio solo significa algo si la prueba positiva funcionó. Ejecuta primero el paso 4. Si el paso 4 no imprimió nada, la regla o la instalación están mal, y el silencio del paso 5 no te dice nada.

6. Agrega un casi-acierto

Un casi-acierto es el archivo negativo más útil, porque falla por una razón concreta y estrecha.

bash
printf 'LAB-TRAINING\n' > near.txt
yara lab.yar near.txt

Salida esperada: nada. El archivo tiene el inicio del marcador pero no la cadena completa, así que la cadena no se encuentra y la condición es falsa.

7. Escanea la carpeta completa

bash
yara -r lab.yar .

La opción -r escanea la carpeta de forma recursiva. Espera ver match.txt en la salida. Lo más probable es que también veas lab.yar, el archivo de la regla. Contiene el texto del marcador, así que la regla coincide con su propio código fuente. Es un error común, y la siguiente sección lo explica. Guarda las reglas en una carpeta distinta de los datos que escaneas.

Haz la regla más estricta

La regla del laboratorio sirve para un marcador de práctica. Las reglas reales suelen necesitar una restricción que la cadena por sí sola no da. Supongamos que solo quieres archivos pequeños que contengan el marcador:

yara
rule Lab_Training_Marker_Pequeno {
  strings: $m = "LAB-TRAINING-MARKER"
  condition: $m and filesize < 1KB
}

Pruébala igual. match.txt debe coincidir. nomatch.txt y near.txt no deben. Cada cambio en las cadenas o en la condición exige volver a correr los dos archivos de prueba.

Evita reglas que coinciden con todo

Esta regla parece razonable:

yara
rule Demasiado_Amplia {
  strings: $a = "texto"
  condition: $a
}

Va a coincidir con nomatch.txt, porque la frase archivo de texto común contiene la palabra texto. Puedes comprobarlo con el archivo negativo que ya creaste. Una regla que coincide con él falló su propia prueba.

Patrones que coinciden demasiado:

  • Cadenas cortas, o palabras comunes como texto, error, copyright o este programa.
  • Un byte o un patrón hexadecimal muy corto, como { 00 } o { 90 }.
  • nocase sobre una palabra común.
  • any of them sobre una lista de cadenas que aparecen en archivos normales.
  • Una condición que solo revisa el tamaño, como filesize < 10KB, que coincide con la mayoría de los archivos pequeños.
  • Una regex floja, como /.+/.

Formas de ajustar una regla:

  • Elige cadenas más largas y distintivas. Pregúntate si la cadena aparecería en un documento que tu organización escribe todos los días. Si aparece, elige otra.
  • Exige más de una cadena con and, o con 2 of (...), para que ninguna cadena común decida sola el resultado.
  • Ancla la búsqueda con at o in cuando sepas dónde debería aparecer la cadena.
  • Combina la prueba de contenido con una revisión de cabecera o de tamaño, como uint16(0) == 0x5A4D.

Errores comunes

  1. Probar solo el archivo positivo. Una regla que coincide con el archivo para el que se escribió demuestra poco. Puede coincidir con todo.
  2. Saltarse los casi-aciertos. Los archivos normales rara vez fallan de forma interesante. Un archivo que casi coincide es la prueba que detecta una cadena demasiado floja.
  3. Olvidar las comillas del heredoc. El shell reemplaza $m antes de que YARA lea el archivo. Mira el paso 3.
  4. Escanear la carpeta donde están las reglas. El archivo de la regla coincide con su propio texto.
  5. Confiar en la meta. Una descripción que dice "detecta X" no detecta X. Solo lo demuestran los archivos de prueba.
  6. Editar sin volver a probar. Cualquier cambio en las cadenas o en la condición puede cambiar el resultado. Vuelve a ejecutar las dos pruebas después de cada edición.

Pruebas positivas y negativas antes de desplegar cualquier regla

Esta es la regla que más importa en este artículo. Toda regla YARA necesita los dos tipos de archivo de prueba antes de que alguien la despliegue.

  • Archivos positivos son los que la regla debe coincidir. En el laboratorio, es match.txt. En el trabajo real, provienen de muestras que estás autorizado a guardar, según las reglas de manejo de tu organización.
  • Archivos negativos son los que la regla no debe coincidir. Incluye documentos comunes, los tipos de archivo habituales en tu entorno, archivos limpios de los sistemas que planeas escanear y casi-aciertos como near.txt.

Una regla pasa cuando coincide con todos los archivos positivos y con ningún negativo. Guarda los dos conjuntos junto a la regla, en control de versiones si tu equipo lo usa, y vuelve a ejecutarlos después de cada edición. Una regla que pasó la prueba positiva pero nunca se probó contra negativos no está probada.

Cómo seguir

  • Lee la guía de escritura de reglas de principio a fin. Cubre módulos como pe, que permite a una regla revisar cabeceras y secciones de un ejecutable de Windows en lugar de bytes en crudo.
  • Ejecuta la misma regla del laboratorio con YARA-X y compara los resultados. La documentación de YARA-X indica qué es compatible y qué no.
  • Construye un corpus limpio: una carpeta con archivos normales de máquinas que controlas. Toda regla nueva debe pasarlo antes de ir a cualquier lugar.
  • Lee después el artículo sobre SIEM. Trata el otro lado de la detección: reglas que corren sobre registros en lugar de sobre archivos.

Fuentes

Fuentes

  1. YARA: Writing rules
  2. VirusTotal/yara on GitHub
  3. YARA-X documentation (VirusTotal)

Más en Malware y forense