Problemas y limitaciones conocidos de YARA-L

En este documento, se describen los problemas y las limitaciones conocidos de YARA-L.

Agregaciones de resultados con anidamiento 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 independiente.

Por ejemplo, las dos direcciones IP en el campo repetido target.ip del 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
}

Registro de evento antes de desenredar el campo repetido

En la siguiente tabla, se muestra el registro del evento antes de desenredar el campo repetido:

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps [192.0.2.20, 192.0.2.28]

Registros de eventos después de anidar el campo repetido

En la siguiente tabla, se muestra el registro del evento después de desanidar el campo repetido:

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps 192.0.2.20
aaaaaaaaa Google SecOps 192.0.2.28

Cuando una regla hace referencia a un campo repetido anidado dentro de otro, como security_results.action, se anulan los anidamientos en los niveles superior y secundario. Las instancias resultantes de anidar un solo evento forman un producto cartesiano de los elementos de los campos superior e inferior. En la siguiente regla de ejemplo, el evento $e con dos valores repetidos en security_results y dos valores repetidos en security_results.actions se anidan 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 evento antes de desenredar el campo repetido

En la siguiente tabla, se muestra el registro del evento antes de desenredar el campo repetido:

metadata.id principal.application security_results
aaaaaaaaa Google SecOps [ { actions: [ ALLOW, FAIL ] }, { actions: [ CHALLENGE, BLOCK ] } ]

Registros de eventos después de anidar campos repetidos

En la siguiente tabla, se muestra el registro del evento después de desanidar el campo repetido:

metadata.id principal.application security_results.actions
aaaaaaaaa Google SecOps PERMITIR
aaaaaaaaa Google SecOps FAIL
aaaaaaaaa Google SecOps DESAFÍO
aaaaaaaaa Google SecOps BLOQUEO

Este comportamiento de anidación en la evaluación de reglas puede producir agregaciones de resultados inesperados 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 que produce el comportamiento de anidación. En la siguiente regla de ejemplo, el evento $e tiene un solo nombre de host google.com, pero el resultado hostnames agrega cuatro instancias no anidadas del mismo evento $e, cada una con un valor principal.hostname duplicado. Este resultado genera cuatro nombres de host en lugar de uno debido al anidamiento 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 evento antes de desenredar el campo repetido

En la siguiente tabla, se muestra el registro del evento antes de desenredar el campo repetido:

metadata.id principal.application principal.hostname security_results
aaaaaaaaa Google SecOps google.com [ { action: [ ALLOW, FAIL ] }, { action: [ CHALLENGE, BLOCK ] } ]

Registro de evento después de desenredar el campo repetido

En la siguiente tabla, se muestra el registro del evento después de desanidar el campo repetido:

metadata.id principal.application principal.hostname security_results.action
aaaaaaaaa Google SecOps google.com PERMITIR
aaaaaaaaa Google SecOps google.com FAIL
aaaaaaaaa Google SecOps google.com DESAFÍO
aaaaaaaaa Google SecOps google.com BLOQUEO

Solución alternativa

Las agregaciones que ignoran los valores duplicados o los eliminan no se ven afectadas por este comportamiento de anidación. Usa la versión distinta de una agregación si encuentras valores de resultados inesperados debido al anidamiento.

Las siguientes agregaciones no se ven afectadas por el comportamiento de anidación descrito anteriormente.

  • max()
  • min()
  • array_distinct()
  • count_distinct()

Agrupaciones de resultados con varias variables de evento

Si una regla contiene varias variables de evento, hay un elemento independiente en la agregación para cada combinación de eventos que se incluye en la detección. Por ejemplo, si se ejecuta la siguiente regla de ejemplo 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 valor del resultado. En el cálculo, se usan los siguientes elementos:

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 a la suma, el recuento y el array. En el caso del 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

El uso de paréntesis al comienzo de una expresión activa el siguiente error:

parsing: error with token: ")"
invalid operator in events predicate

El siguiente ejemplo generaría este tipo de error:

($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1

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 índices en el resultado requiere agregación para valores individuales en el campo repetido

El indexado de arrays en la sección de resultados aún requiere agregación. Por ejemplo, lo siguiente no funciona:

outcome:
  $principal_user_dept = $suspicious.principal.user.department[0]

Sin embargo, puedes guardar el resultado del índice del array en una variable de marcador de posición y usar esa variable en la sección de resultados, como se muestra a continuación:

events:
  $principal_user_dept = $suspicious.principal.user.department[0]

outcome:
  $principal_user_department = $principal_user_dept

Condición O con no existencia

Si se aplica una condición O entre dos variables de evento independientes y si la regla coincide con la no existencia, la regla se compila correctamente, pero puede producir detección de falsos positivos. Por ejemplo, la siguiente sintaxis de reglas puede coincidir con eventos que tienen $event_a.field = "something", aunque no debería.

events:
     not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
     $event_a and #event_b >= 0

La solución alternativa es separar las condiciones en dos bloques, en los que cada uno solo aplica el filtro a una sola variable, como se muestra a continuación:

events:
     not ($event_a.field = "something")
     not ($event_b.field = "something")
condition:
     $event_a and #event_b >= 0

Aritmética con campos de evento sin firmar

Si intentas usar una constante de número entero en una operación aritmética con un campo de UDM cuyo tipo es un número entero sin signo, se mostrará un error. Por ejemplo:

events:
  $total_bytes = $e.network.received_bytes * 2

El campo udm.network.received_bytes es un número entero sin firmar. Esto sucede porque las constantes de números enteros se establecen de forma predeterminada en números enteros con signo, que no funcionan con números enteros sin signo en operaciones aritméticas.

La solución es forzar la constante de número entero a un número de punto flotante que luego funcionará con el número entero sin firmar. Por ejemplo:

events:
  $total_bytes = $e.network.received_bytes * (2/1)

Coherencia eventual y falsos positivos en el enriquecimiento de GeoIP

El sistema prioriza la velocidad sobre la precisión inmediata en las etapas iniciales de enriquecimiento (transmisión y sensible a la latencia), lo que puede provocar la falta de datos y posibles falsos positivos. El sistema seguirá enriqueciendo los datos en segundo plano, pero es posible que no estén disponibles cuando se ejecute la regla. Esto forma parte del proceso normal de coherencia eventual. Para evitar estos tipos de falsos positivos, no dependas de que existan campos enriquecidos en los eventos para activar las detecciones.

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 generará 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 las IPs con el ASN 16509 activen el evento, pero que se encuentren fuera del Reino Unido. Esto mejora la precisión general de la regla.