Problemas y limitaciones conocidos de YARA-L 2.0
Este documento está destinado a los ingenieros de detección que desean depurar la lógica de las reglas y optimizar la ejecución de YARA-L 2.0. En él, se explica cómo controlar los comportamientos no estándar del motor, como la eliminación de anidación de campos, la expansión del producto cartesiano en agregaciones y la coherencia eventual del enriquecimiento. Si sigues estos métodos, puedes evitar errores lógicos que generen valores de resultados inflados o detecciones perdidas.
YARA-L 2.0 usa un modelo de ejecución específico en el que los campos repetidos se expanden en filas de eventos individuales durante la evaluación. Debido a que esta transformación ocurre a nivel del motor, hacer referencia a varios campos repetidos o realizar operaciones aritméticas en tipos UDM sin signo requiere soluciones alternativas de sintaxis específicas para evitar errores del compilador o conjuntos de resultados incorrectos. En este documento, se describen esas restricciones técnicas y los patrones lógicos necesarios para resolverlas.
Antes de comenzar
Asegúrate de que tu cuenta tenga los siguientes derechos técnicos antes de probar o modificar las reglas de YARA-L 2.0:
Roles de IAM obligatorios
roles/chronicle.viewer(lector de Security Operations): Para ver las reglas existentes y los metadatos de detecciónroles/chronicle.editor(editor de Security Operations): Para modificar la lógica de las reglas y guardar los cambios
Permisos necesarios
chronicle.rules.runTest: Es necesario para ejecutar la función Ejecutar prueba en datos históricos.chronicle.detections.get: Para inspeccionar el resultado de los eventos sin anidación en el panel de detección
Terminología clave
- UDM (modelo de datos unificado): Es el esquema normalizado que se usa para estructurar toda la telemetría de seguridad ingerida en la plataforma.
- Eliminación de anidación: Es la expansión a nivel del motor de un solo evento UDM que contiene un campo repetido (array) en varias filas. Cada fila representa un elemento único del array, lo que puede generar la multiplicación de filas durante la evaluación de reglas.
- T₀ (ejecución inicial): Es la primera ejecución de una regla en la telemetría entrante. Esto ocurre durante la fase de "transmisión", a menudo antes de que finalicen los procesos de enriquecimiento en segundo plano (como GeoIP o ASN).
Agregaciones de resultados con eliminación de anidación de campos repetidos
Cuando una regla hace referencia a un campo repetido en una variable de evento con varios elementos, cada elemento se divide en una fila de evento separada.
Por ejemplo, las dos direcciones IP del campo repetido target.ip en el evento $e se dividen en dos instancias de $e, cada una con un valor target.ip diferente.
rule outbound_ip_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$outbound_ip_count = count($e.target.ip) // yields 2.
condition:
$e
}
Registros de eventos: Antes y después de la eliminación de anidación
En las tablas de esta sección, se muestra cómo un solo evento que contiene un array de direcciones IP se transforma en dos registros distintos.
Antes de la eliminación de anidación
En la siguiente tabla, se muestra el registro de eventos antes de la eliminación de anidación del campo repetido:
| metadata.id | principal.application | target.ip |
|---|---|---|
aaaaaaaaa |
Google SecOps |
[192.0.2.20, 192.0.2.28] |
Después de la eliminación de anidación
En la siguiente tabla, se muestra el registro de eventos después de la eliminación de anidación del campo repetido:
| metadata.id | principal.application | target.ip |
|---|---|---|
aaaaaaaaa |
Google SecOps |
192.0.2.20 |
aaaaaaaaa |
Google SecOps |
192.0.2.28 |
Campos repetidos anidados (producto cartesiano)
Cuando una regla hace referencia a un campo repetido anidado dentro de otro, como security_results.action, la eliminación de anidación ocurre en ambos niveles (superior y secundario) de forma simultánea. Esto genera un producto cartesiano de todos los elementos.
En el siguiente ejemplo, un evento $e con dos valores repetidos en security_results y dos valores repetidos en security_results.actions se eliminan de la anidación en cuatro instancias.
rule security_action_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$security_action_count = count($e.security_results.actions) // yields 4.
condition:
$e
}
Registro de eventos antes de la eliminación de anidación anidada
El registro original almacena las acciones dentro de una estructura de array anidada.
| metadata.id | principal.application | security_results |
|---|---|---|
aaaaaaaaa |
Google SecOps |
[ { actions: [ ALLOW, FAIL ] }, { actions: [ CHALLENGE, BLOCK ] } ] |
Registros de eventos después de la eliminación de anidación anidada
Después de la expansión, cada acción única se convierte en su propia fila, lo que puede generar recuentos inesperados en agregaciones no distintas.
| metadata.id | principal.application | security_results.actions |
|---|---|---|
aaaaaaaaa |
Google SecOps |
PERMITIR |
aaaaaaaaa |
Google SecOps |
REPROBADA |
aaaaaaaaa |
Google SecOps |
DESAFÍO |
aaaaaaaaa |
Google SecOps |
BLOQUEAR |
Impacto en campos no relacionados
Este comportamiento de eliminación de anidación en la evaluación de reglas puede producir agregaciones de resultados inesperadas cuando la regla hace referencia a uno o más campos repetidos con un campo superior que también es un campo repetido. Las agregaciones no distintas, como sum(), array() y count(), no pueden tener en cuenta los valores duplicados en otros campos del mismo evento producido por el comportamiento de eliminación de anidación.
En el siguiente ejemplo, el evento $e tiene un solo nombre de host (google.com), pero el resultado (hostnames) se agrega en cuatro instancias sin anidación del mismo evento $e, cada una con un valor principal.hostname duplicado. Este resultado genera cuatro nombres de host (en lugar de uno) debido a la eliminación de anidación de valores repetidos en security_results.actions.
rule security_action_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$hostnames = array($e.principal.hostname) // yields 4.
$security_action_count = count($e.security_results.action) // yields 4.
condition:
$e
}
Registro de eventos antes de la eliminación de anidación con campos no relacionados
El nombre de host es un valor único, pero se encuentra junto a los resultados de seguridad repetidos.
| metadata.id | principal.application | principal.hostname | security_results |
|---|---|---|---|
aaaaaaaaa |
Google SecOps |
google.com |
[ { action: [ ALLOW, FAIL ] }, { action: [ CHALLENGE, BLOCK ] } ] |
Registro de eventos después de la eliminación de anidación con campos no relacionados
El nombre de host ahora está duplicado en cuatro filas, lo que hace que la función array() lo recupere cuatro veces.
| metadata.id | principal.application | principal.hostname | security_results.action |
|---|---|---|---|
aaaaaaaaa |
Google SecOps |
google.com |
PERMITIR |
aaaaaaaaa |
Google SecOps |
google.com |
REPROBADA |
aaaaaaaaa |
Google SecOps |
google.com |
DESAFÍO |
aaaaaaaaa |
Google SecOps |
google.com |
BLOQUEAR |
Solución alternativa para el comportamiento de eliminación de anidación
Para asegurarte de que los valores de los resultados sean precisos cuando se produce la eliminación de anidación, usa la versión distinta de la agregación seleccionada. Las siguientes funciones ignoran las filas duplicadas creadas por la eliminación de anidación:
max()min()array_distinct()count_distinct()
Agregaciones de resultados con varias variables de evento
Si una regla contiene varias variables de evento, hay un elemento separado en la agregación para cada combinación de eventos que se incluye en la detección. Por ejemplo, si la siguiente regla de ejemplo se ejecuta en los eventos enumerados:
events:
$e1.field = $e2.field
$e2.somefield = $ph
match:
$ph over 1h
outcome:
$some_outcome = sum(if($e1.otherfield = "value", 1, 0))
condition:
$e1 and $e2
event1:
// UDM event 1
field="a"
somefield="d"
event2:
// UDM event 2
field="b"
somefield="d"
event3:
// UDM event 3
field="c"
somefield="d"
La suma se calcula en cada combinación de eventos, lo que te permite usar ambas variables de evento en los cálculos de valores de resultados. Los siguientes elementos se usan en el cálculo:
1: $e1 = event1, $e2 = event2
2: $e1 = event1, $e2 = event3
3: $e1 = event2, $e2 = event1
4: $e1 = event2, $e2 = event3
5: $e1 = event3, $e2 = event1
5: $e1 = event3, $e2 = event2
Esto genera una suma máxima potencial de 6, aunque $e2 solo puede corresponder a 3 eventos distintos.
Esto afecta la suma, el recuento y el array. Para el recuento y el array, usar count_distinct o array_distinct puede resolver el problema, pero no hay una solución alternativa para la suma.
Paréntesis al comienzo de una expresión
No se admite comenzar una expresión con paréntesis, lo que activa un error de análisis en el editor de reglas.
Sintaxis no válida
parsing: error with token: ")"
invalid operator in events predicate
En el siguiente ejemplo, se genera este tipo de error:
($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1
Variaciones de sintaxis válidas
Las siguientes variaciones de sintaxis muestran el mismo resultado, pero con una sintaxis válida:
$event.metadata.ingested_timestamp.seconds / 3600 -
$event.metadata.event_timestamp.seconds / 3600 > 1
1 / 3600 * ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) > 1
1 < ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600
El array de índice en el resultado requiere agregación
No se permite indexar directamente un array dentro de la sección outcome para campos repetidos. Requiere una variable de marcador de posición temporal.
outcome:
$principal_user_dept = $suspicious.principal.user.department[0]
Solución alternativa
Captura el índice de array específico en una variable de marcador de posición dentro de la sección events y, luego, haz referencia a ese marcador de posición en tu resultado.
events:
$principal_user_dept = $suspicious.principal.user.department[0]
outcome:
$principal_user_department = $principal_user_dept
Condición OR con no existencia
Si aplicas una condición OR entre dos variables de evento separadas y la regla coincide con la no existencia, la regla se compila correctamente, pero puede producir detecciones de falsos positivos.
Por ejemplo, la siguiente sintaxis de regla puede coincidir con eventos que tienen $event_a.field = "something", aunque no debería hacerlo:
events:
not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
$event_a and #event_b >= 0
Solución alternativa
Separa las verificaciones de no existencia en bloques individuales para cada variable para mantener la integridad lógica.
events:
not ($event_a.field = "something")
not ($event_b.field = "something")
condition:
$event_a and #event_b >= 0
Aritmética con campos de eventos sin signo
Si intentas usar una constante de número entero en una operación aritmética con un campo UDM cuyo tipo es un número entero sin signo, obtendrás un error. Por ejemplo:
events:
$total_bytes = $e.network.received_bytes * 2
Las constantes de números enteros estándar usan números enteros con signo de forma predeterminada, que son incompatibles con los campos UDM definidos como números enteros sin signo, como network.received_bytes.
Solución alternativa
Puedes omitir este error si fuerzas a la constante de número entero a comportarse como un número de punto flotante a través de una operación de división.
events:
$total_bytes = $e.network.received_bytes * (2/1)
Enriquecimiento de GeoIP y coherencia eventual
El sistema prioriza la velocidad por sobre la precisión inmediata en las etapas iniciales de enriquecimiento (transmisión y sensible a la latencia), lo que puede generar la falta de datos y posibles falsos positivos. El sistema continúa enriqueciendo los datos en segundo plano, pero es posible que los datos no estén disponibles cuando se ejecute la regla. Esto es parte del proceso normal de coherencia eventual.
Para evitar falsos positivos causados por el retraso del enriquecimiento, verifica de forma explícita que el campo no esté vacío antes de evaluar su valor.
Por ejemplo, considera este evento de regla:
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
La regla se basa en el hecho de que el evento debe tener $e.principal.ip_geo_artifact.network.asn = "16509" Y $e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom", que son campos enriquecidos. Si el enriquecimiento no se completa a tiempo, la regla producirá un falso positivo.
Para evitar esto, una mejor verificación para esta regla sería la siguiente:
$e.principal.ip_geo_artifact.network.asn != "" AND
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region != "" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
Esta regla elimina la posibilidad de que el evento se active con IPs con el ASN 16509, pero que se encuentren fuera del Reino Unido. Esto mejora la precisión general de la regla.
Obtén más información para solucionar problemas relacionados con el retraso del enriquecimiento.
Soluciona problemas
En esta sección, se describen las expectativas de rendimiento y se proporcionan correcciones de autoservicio para problemas comunes en los que el comportamiento de detección en vivo difiere de los resultados de las pruebas.
Eventos con fechas futuras
Las reglas de varios eventos están diseñadas para procesar eventos en orden cronológico en relación con la transferencia. Si especificas y activas una regla de varios eventos, no crea detecciones para eventos con marcas de tiempo futuras, por ejemplo, cuando event.timestamp tiene una fecha y hora establecidas después de ingest.timestamp.
Retraso del enriquecimiento
Google SecOps prioriza la velocidad de transferencia para exponer las alertas iniciales lo más rápido posible. Sin embargo, los procesos de enriquecimiento en segundo plano, como la resolución de metadatos GeoIP, ASN o UDM, siguen un modelo de coherencia eventual.
Ejecución inicial (T₀)
El motor en vivo puede evaluar una regla antes de que se complete el enriquecimiento en segundo plano. Según si tu lógica se basa en campos enriquecidos para detecciones o exclusiones, esto puede generar las siguientes discrepancias temporales:
Falsos negativos (retraso de detección): Este es un resultado común. Si una regla depende de un campo enriquecido para activarse (por ejemplo,
target.user.department == "Finance") y ese campo esnull, la regla no coincide durante la ejecución inicial.Falsos positivos (exclusión perdida): Si tu regla usa campos enriquecidos para filtrar la actividad conocida como correcta (por ejemplo,
NOT target.ip_geo_country == "US"), la regla puede activar un falso positivo porque los datos de "exclusión" aún no se aplicaron.
Ejecuciones de actualización
Estas ejecuciones en segundo plano vuelven a evaluar los datos después de una demora (por ejemplo, 45 minutos o 30 horas). Esto "actualiza" los estados de detección de la siguiente manera:
Detecciones tardías: Los eventos que fueron "falsos negativos" en T₀ ahora producen una detección una vez que finaliza el enriquecimiento.
Corrección: Los falsos positivos de T₀ permanecen en el sistema, pero los datos completamente enriquecidos son visibles en el visor de UDM para la clasificación manual.
Discrepancia de la prueba de ejecución
La herramienta Ejecutar prueba opera con datos históricos que ya se reconciliaron. Debido a que los datos están completamente enriquecidos cuando ejecutas una prueba manual, puedes ver los resultados de "actualización" de inmediato. Esto significa que no verás los falsos negativos de T₀ ni los falsos positivos basados en exclusiones que ocurrieron durante la ejecución inicial en vivo.
Corrección de errores
Usa la siguiente tabla para resolver las discrepancias entre las alertas en vivo y los resultados de las pruebas.
| Problema | Descripción | Corrección procesable |
|---|---|---|
| Falla de exclusión | Se activa una regla a pesar de una exclusión (por ejemplo, != "ASN_123") porque el campo era nulo durante la ejecución inicial. |
Agrega una verificación no nula a la sección de eventos para asegurarte de que los datos se enriquezcan antes de la evaluación, por ejemplo:$e.principal.ip_geo_artifact.network.asn != ""
|
| Comparación entre la coincidencia en vivo y la de la prueba | Las reglas en vivo activan alertas, pero la prueba de ejecución en los mismos datos muestra "No Results". |
Agrega $e.field != "" que verifica todos los campos enriquecidos (GeoIP, ASN, File Path) para sincronizar el comportamiento en vivo y el histórico. |
| Faltan metadatos | Las detecciones aparecen en el panel con campos GeoIP o File Path vacíos. |
Esto es lo esperado para las ejecuciones T0. Para corregir este problema, incluye una verificación field != "" o aumenta el desplazamiento de la primera ejecución en tu programación de ejecución para permitir más tiempo para la transferencia.
|
Validación y prueba
Para verificar que una regla controle correctamente el enriquecimiento retrasado, haz lo siguiente:
Identifica el retraso: Busca una detección que creas que es un falso positivo. En la columna Tipo de detección, busca el ícono
<span class="material-icons">lightbulb</span>. Las alertas sin este ícono son de la ejecución inicial, en la que el retraso del enriquecimiento es más común.Actualiza la lógica de la regla: Agrega una verificación
field != ""para todos los datos enriquecidos que se usan en tu lógica.
Ejemplo (ruta de acceso a archivos):
$e.target.process.parent_process.file.full_path != ""Prueba y verifica lo siguiente:
- Usa la función Ejecutar prueba para asegurarte de que tu lógica aún coincida con los datos históricos deseados.
- Verifica que la regla ahora solo se active (o excluya correctamente) durante las ejecuciones de actualización una vez que se propaguen los campos de enriquecimiento.
Para obtener más detalles, consulta Administra tu programación de ejecución de reglas y Configura programaciones personalizadas para reglas.
¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.