Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
YARA-Performance-Guidelines — Una guía sobre cómo escribir reglas YARA rápidas y con un uso eficiente de la memoria. | Kitploit
Herramientas/GitHubGitHub/neo23x0/yara-performance-guidelines
Análisis EstáticoAnálisis de MalwareAprendizaje y Educación
GitHubneo23x0/yara-performance-guidelines

YARA-Performance-Guidelines

Una guía sobre cómo escribir reglas YARA rápidas y con un uso eficiente de la memoria.

Ver Repositorio

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
17423hace 1 añoRevisado por Kitploit

Guías de rendimiento de YARA

Escribir reglas YARA eficientes es esencial para mantener un velocidad de escaneo rápida y precisa. Esta guía proporciona principios clave y mejores prácticas para ayudarte a optimizar tus reglas, reducir cálculos innecesarios y evitar errores comunes. Incorpora conocimientos de expertos de la industria, incluidos Victor M. Alvarez, WXS, y contribuciones de la comunidad YARA.

  • Revisión 1.6, febrero de 2025, se aplica a todas las versiones de YARA superiores a 3.7

Puntos clave

Esta sección proporciona un resumen conciso de las mejores prácticas de rendimiento de YARA. Para explicaciones detalladas y ejemplos, consulta la guía completa a continuación.

Comprender el proceso de escaneo de YARA

"Piensa en YARA como un proceso de dos pasos: primero, buscar todos los patrones enumerados en las cadenas, y segundo, evaluar las condiciones. No puedes usar condiciones bien formadas para compensar cadenas mal elegidas."
— Wesley Shields

YARA sigue cuatro pasos principales al escanear un archivo:

  1. Compilación de las reglas – Extracción de átomos (subcadenas de 4 bytes) de las cadenas definidas.
  2. Búsqueda Aho-Corasick – Escaneo de archivos en busca de esos átomos.
  3. Motor de bytecode – Verificación de coincidencias completas de cadenas.
  4. Evaluación de condiciones – Comprobación de la lógica adicional de la regla.

Selección de cadenas: el factor más importante

YARA busca cadenas primero, lo que convierte la selección de cadenas en el factor más importante para la eficiencia de las reglas.

✅ Mejores prácticas para cadenas:

  • Evita cadenas cortas (<4 bytes) – Generan demasiados falsos positivos.
  • Usa átomos únicos de 4 bytes – YARA depende de ellos para un escaneo rápido.
  • Minimiza los comodines en cadenas hexadecimales – Mantén al menos un segmento concreto largo.
  • Usa expresiones regulares con moderación – Si es necesario, incluye un anclaje fijo de 4 bytes para mejorar la eficiencia.
  • Evita patrones repetidos de un solo byte – Por ejemplo, \x00\x00\x00\x00 aparece con demasiada frecuencia.
  • Usa nocase con cuidado – Genera exponencialmente más variaciones de búsqueda.

Optimización de condiciones y evaluación de cortocircuito

YARA evalúa las condiciones secuencialmente y se detiene en el primer fallo.

✅ Mejores prácticas para condiciones:

  • Coloca primero las comprobaciones rápidas (por ejemplo, filesize < X) antes que las condiciones costosas.
  • Evita bucles sobre grandes cantidades de datos (for all i in (1..filesize) es ineficiente).
  • Usa offsets directos (@) en lugar de expresiones regulares para comprobaciones de secuencia.

⚠ Nota: Las condiciones de expresiones regulares no se cortocircuitan y siempre se evalúan al final.

Módulos: úsalos con precaución

Módulos como pe, elf o magic deben analizar el archivo completo antes de la evaluación, lo que aumenta el tiempo de escaneo.

✅ Alternativas:

  • En lugar de pe.is_pe, usa uint16(0) == 0x5A4D para identificar archivos PE.
  • Evita usar módulos a menos que se requiera una inspección profunda del archivo.

Cómo manejar demasiadas coincidencias y escaneo lento

Las coincidencias excesivas ralentizan el escaneo y pueden provocar errores de "demasiadas coincidencias".

✅ Cómo corregir coincidencias ineficientes:

  • Revisa los cuantificadores de regex – Evita .*, .+ o {x,} sin un límite superior.
  • Reduce los comodines en cadenas hexadecimales.
  • Divide las alternancias en cadenas separadas cuando sea posible.

Video tutorial

@herrcore ha creado un útil video tutorial que cubre los temas tratados en esta guía de rendimiento.

Introducción a YARA: cómo escribir reglas YARA eficientes

Conceptos básicos

Para comprender mejor qué y dónde se puede optimizar el rendimiento de YARA, es útil entender el proceso de escaneo. Básicamente se divide en 4 pasos que se explicarán de forma muy simplificada usando esta regla de ejemplo:

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. Compilación de las reglas

Este paso ocurre antes del escaneo en sí. YARA buscará los llamados átomos en las cadenas de búsqueda para alimentar el autómata Aho-Corasick. Los detalles se explican en el capítulo átomo, pero por ahora basta con saber que tienen un máximo de 4 bytes de longitud y que YARA los elige de forma bastante inteligente para evitar demasiadas coincidencias. En nuestro ejemplo, YARA podría elegir los siguientes 4 átomos:

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

2. Autómata Aho-Corasick

Aquí ha comenzado el escaneo. Los pasos 2 a 4 se ejecutarán en todos los archivos. YARA buscará en cada archivo los 4 átomos definidos anteriormente mediante un árbol de prefijos llamado autómata Aho-Corasick. Cualquier coincidencia se entrega al motor de bytecode.

3. Motor de bytecode

Si hay, por ejemplo, una coincidencia con sser, YARA comprobará si estaba precedido por una a y continúa con una t. Si es así, continuará con la expresión regular [\t ]{0,100}\(. Con este ingenioso enfoque, YARA evita usar un motor de expresiones regulares lento sobre los archivos completos y solo selecciona ciertas partes para examinarlas más de cerca.

4. Condiciones

Después de completar todo el emparejamiento de patrones, se comprueban las condiciones. YARA tiene otro mecanismo de optimización para realizar la comprobación math.entropy, que consume mucha CPU, de nuestra regla de ejemplo solo si las 4 condiciones anteriores se cumplen. Se explica con más detalle en el capítulo Condiciones y evaluación de cortocircuito

Si se cumplen las condiciones, se informa de una coincidencia. El escaneo continúa con el siguiente archivo en el paso 2.

Átomos

YARA extrae de las cadenas subcadenas cortas de hasta 4 bytes de longitud llamadas "átomos". Esos átomos pueden extraerse de cualquier lugar de la cadena, y YARA los busca al escanear el archivo; si encuentra uno de los átomos, verifica que la cadena realmente coincida.

Por ejemplo, considera estas cadenas:

root@kitploit:~
/abc.*cde/

=> los átomos posibles son abc y cde; se puede usar uno u otro. Actualmente se prefiere el átomo abc porque tienen la misma calidad y es el primero de los dos.

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

=> los átomos posibles son one, two, thre y hree; podemos buscar solo thre (o hree), o tanto one como two. Se prefiere el átomo thre porque dará lugar a menos coincidencias potenciales que one y two (estos son más cortos) y no contiene doble e (cuanto más única sea la letra, mejor).

YARA hace todo lo posible por seleccionar los mejores átomos de cada cadena, por ejemplo:

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

=> aquí YARA usa el átomo 01 02 03 04, porque 00 00 00 00 es demasiado común

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

=> se prefiere 01 02 03 04 sobre 01 02 porque es más largo

Por lo tanto, el punto importante es que las cadenas deben contener buenos átomos. Estas son cadenas malas porque contienen átomos demasiado cortos o demasiado comunes:

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)/

Las peores cadenas son las que no contienen ningún átomo, como:

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

Esta expresión regular no contiene ninguna subcadena fija que pueda usarse como átomo, por lo que debe evaluarse en cada offset del archivo para ver si coincide.

Demasiadas iteraciones de bucle

Otra recomendación importante es evitar los bucles for con demasiadas iteraciones, especialmente si la declaración dentro del bucle es demasiado compleja, por ejemplo:

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

Esta regla tiene dos problemas. El primero es que la cadena $a es demasiado común; el segundo es que, debido a que $a es demasiado común, #a puede ser muy alto y evaluarse miles de veces.

Esta otra condición también es ineficiente porque el número de iteraciones depende de filesize, que también puede ser muy alto:

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

Módulo Magic

Evita usar el módulo "magic", que no está disponible en la plataforma Windows. Usar el módulo "magic" ralentiza el escaneo pero proporciona coincidencias exactas.

Definición personalizada de la cabecera mágica de GIF:

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

Usando el módulo "magic":

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

Cadenas demasiado cortas

Evita definir cadenas demasiado cortas. Cualquier cadena de menos de 4 bytes probablemente aparecerá en muchos archivos O como contenido uniforme en un archivo con XOR.

Contenido uniforme

Algunas cadenas son lo suficientemente largas pero no deberían usarse por una razón diferente: la uniformidad. Estos son algunos ejemplos de cadenas que no deberían usarse, ya que podrían causar demasiadas coincidencias en los archivos.

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

El mensaje de error tendría este aspecto:

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

Consejos para cadenas

Intenta definir las cadenas de la forma más específica posible. Evita el atributo "nocase" si es posible, porque se generarán y buscarán muchos átomos (mayor uso de memoria, más iteraciones). Recuerda que, en ausencia de modificadores, se asume "ascii" por defecto. Las combinaciones posibles son:

BAJO - solo se genera un átomo

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 - Todas las combinaciones de letras mayúsculas y minúsculas para los 4 bytes elegidos por YARA se generarán como átomos

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

Si quieres buscar comandos de scripting, comprueba si el lenguaje es insensible a mayúsculas y minúsculas (por ejemplo, PHP, batch de Windows) antes de usar nocase. Si solo necesitas diferentes variaciones de mayúsculas para una o dos letras, es mejor usar una expresión regular, por ejemplo:

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

Ten cuidado al trabajar con alternancias como:

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

Estas cadenas generan átomos cortos que pueden ralentizar el escaneo. En los casos en los que hay un pequeño número de variantes, se recomienda escribir las cadenas por separado:

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

Expresiones regulares

Usa expresiones regulares solo cuando sea necesario. La evaluación de expresiones regulares es inherentemente más lenta que la coincidencia simple de cadenas y consume una cantidad significativa de memoria. No las uses si las cadenas hexadecimales con saltos y comodines pueden resolver el problema.

Si tienes que usar expresiones regulares, evita los cuantificadores codiciosos .* e incluso los reticentes .*?. En su lugar, usa números exactos como .{1,30} o incluso .{1,3000}. Además, no olvides el límite superior (evita, por ejemplo, .{2,}).

Cuando usamos cuantificadores, pueden ocurrir dos situaciones:

Si el inicio de la expresión regular está anclado en una posición y solo el sufijo puede variar, YARA encontrará la coincidencia más larga posible. En casos como .*, .+ o .{2,}, esto puede dar lugar a cadenas grandes y a problemas de ralentización del escaneo.

Si hay más posibles inicios de la expresión regular, YARA encontrará todos ellos.

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

El número de coincidencias más cortas puede superar fácilmente el límite y provocar el error de "demasiadas coincidencias".

El siguiente ejemplo es la expresión regular para una dirección de correo electrónico. Al usar [-a-z0-9._%+] con cuantificadores, YARA coincidirá con una misma dirección varias veces, lo cual no es ideal. En este caso, se recomienda buscar un subconjunto razonablemente pequeño de direcciones que proporcione suficiente información para el análisis.

USA

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

EVITA

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}/

Si quieres asegurarte de que, por ejemplo, exec va seguido de /bin/sh, puedes usar los offsets proporcionados por el símbolo @. Esta sería la versión lenta con expresión regular:

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

Esta es la forma más rápida usando offsets:

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

Intenta también incluir secuencias largas de cadenas que puedan servir como anclas en el proceso de coincidencia. De nuevo, cuanto más largas, mejor.

MALO

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

MEJOR

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

EL MEJOR

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

Demasiadas coincidencias y error de ralentización del escaneo

Los errores de demasiadas coincidencias son causados por cadenas demasiado generales que están presentes en la entrada con demasiada frecuencia, o porque YARA encuentra la misma instancia varias veces.

La ralentización del escaneo es causada por cadenas que generan átomos demasiado cortos, o ninguno en absoluto. Como resultado, YARA utiliza un algoritmo ingenuo de coincidencia de patrones, lo que provoca la ralentización.

Ambos problemas pueden solucionarse, en algunos casos, con estos pasos:

  1. Revisa los cuantificadores .*, .+, .*?
  2. Revisa los cuantificadores sin límite superior, como x{14,}
  3. Revisa los rangos demasiado grandes (p. ej., x{1,300000})
  4. Revisa los saltos grandes en las cadenas hexadecimales
  5. Revisa los caracteres comodín: ¿pueden especificarse con más precisión, o podría dividirse la cadena en 2 omitiendo el carácter comodín?
  6. Revisa las alternancias: ¿pueden dividirse en 2 o más cadenas?
  7. Intenta añadir especificaciones para la coincidencia de palabras (fullword, \b,...)

Ten en cuenta que en el siguiente capítulo, Condiciones y evaluación de cortocircuito, se mencionan algunos consejos para las condiciones. Sin embargo, los cambios en ellas no resolverán los errores de demasiadas coincidencias ni de ralentización del escaneo.

Condiciones y evaluación de cortocircuito

Intenta escribir declaraciones de condición en las que los elementos que probablemente sean "False" se coloquen primero. La condición se evalúa de izquierda a derecha. Cuanto antes identifique el motor que una regla no se cumple, antes puede omitir la regla actual y evaluar la siguiente. La mejora de velocidad que produce esta forma de ordenar las declaraciones de condición depende de la diferencia en los ciclos de CPU necesarios para procesar cada una de ellas. Si todas las declaraciones tienen un coste más o menos similar, reordenarlas no supone una mejora notable. Si una de las declaraciones puede procesarse muy rápido, se recomienda colocarla primero para omitir la evaluación de la declaración costosa en los casos en que la primera declaración sea FALSE.

Cambiar el orden en la siguiente declaración no produce una mejora significativa:

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

Sin embargo, si el tiempo de ejecución de las declaraciones es muy diferente, reordenarlas para activar el cortocircuito mejorará significativamente la velocidad de escaneo:

LENTO

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

RÁPIDO

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

La evaluación de cortocircuito se introdujo para ayudar a optimizar las declaraciones costosas, especialmente las declaraciones "for". Algunas personas usaban condiciones como la del siguiente ejemplo:

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

Debido a que filesize puede ser un número muy grande, "whatever" puede ejecutarse muchas veces, ralentizando la ejecución. Ahora, con la evaluación de cortocircuito, la declaración "for" se ejecutará solo si se cumple la primera parte de la condición, por lo que esta regla solo será lenta para archivos MZ. Una mejora adicional podría ser:

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

Desde la versión 3.10, los bucles de rango de enteros también se optimizaron:

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.

Sin cortocircuito para expresiones regulares

Lamentablemente, esto no funciona con las expresiones regulares porque todas se introducen inicialmente en el motor de coincidencia de cadenas. El siguiente ejemplo ralentizará la búsqueda para cualquier archivo, y no solo para aquellos con un filesize menor de 200 bytes:

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

Esta evaluación de "cortocircuito" se aplica desde la versión 3.4 de YARA.

Metadatos

YARA lee todos los datos de la sección de metadatos en la RAM. (Puedes probar esto fácilmente insertando 100,000 hashes en una regla y comprobando el uso de RAM del escaneo de YARA antes y después). Por supuesto, no querrás eliminar permanentemente los metadatos de las reglas, pero si te falta RAM, puedes quitar algunas partes innecesarias de ellos en tu flujo de trabajo justo antes de escanear.

Descargar herramienta