Sintaxis del lenguaje YARA-L 2.0

En esta sección, se describen los elementos principales de la sintaxis de YARA-L. Consulta también la Descripción general del lenguaje YARA-L 2.0.

Estructura de reglas

Para YARA-L 2.0, debes especificar las declaraciones, definiciones y usos de variables en el siguiente orden:

  1. meta
  2. eventos
  3. coincidencia (opcional)
  4. resultado (opcional)
  5. de transición
  6. opciones (opcional)

A continuación, se muestra la estructura genérica de una regla:

rule <rule Name>
{
    meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  outcome:
    // Additional information extracted from each detection.

  condition:
    // Condition to check events and the variables used to find matches.

  options:
    // Options to turn on or off while executing this rule.
}

Sintaxis de la sección meta

La sección meta se compone de varias líneas, y cada una de ellas define un par clave-valor. Una parte de clave debe ser una cadena sin comillas, y una parte de valor debe ser una cadena entrecomillada:

<key> = "<value>"

El siguiente es un ejemplo de una línea de sección meta válida:

meta:
    author = "Google"
    severity = "HIGH"

Sintaxis de la sección Eventos

En la sección events, enumera los predicados para especificar lo siguiente:

  • Declaraciones de variables
  • Filtros de variables de eventos
  • Uniones de variables de evento

Declaraciones de variables

Para las declaraciones de variables, usa la siguiente sintaxis:

  • <EVENT_FIELD> = <VAR>
  • <VAR> = <EVENT_FIELD>

Ambos son equivalentes, como se muestra en los siguientes ejemplos:

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

Esta declaración indica que esta variable representa el campo especificado para la variable del evento. Cuando el campo de evento es un campo repetido, la variable de coincidencia puede representar cualquier valor en el array. También es posible asignar varios campos de evento a una sola variable de coincidencia o de marcador de posición. Esta es una condición de unión transitiva.

Por ejemplo:

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

Son equivalentes a lo siguiente:

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

Cuando se usa una variable, esta se debe declarar mediante la declaración de variables. Si se usa una variable sin ninguna declaración, se considera un error de compilación.

Filtros de variables de eventos

Una expresión booleana que actúa sobre una sola variable de evento se considera un filtro.

Uniones de variables de evento

Todas las variables de evento que se usan en la regla deben unirse con las demás variables de evento de cualquiera de las siguientes maneras:

  • Directamente a través de una comparación de igualdad entre campos de evento de las dos variables de evento unidas, por ejemplo: $e1.field = $e2.field La expresión no debe incluir aritmética.

  • Indirectamente a través de una unión transitiva que involucra solo un campo de evento (consulta la declaración de variables para conocer la definición de "unión transitiva"). La expresión no debe incluir aritmética.

Por ejemplo, si se usan $e1, $e2 y $e3 en la regla, las siguientes secciones de events son válidas.

events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
  $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
  // $e1 joins with $e2 via function to event comparison
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
  // $e1 joins with $e2 via an `or` expression
  $e1.principal.hostname = $e2.src.hostname
  or $e1.principal.hostname = $e2.target.hostname
  or $e1.principal.hostname = $e2.principal.hostname
events:
  // all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  // $e1 and $e2 are transitively joined via function to event comparison
  re.capture($e2.principal.application, ".*") = $app
  $e1.principal.hostname = $app

Sin embargo, aquí tienes ejemplos de secciones events no válidas.

events:
  // Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.port = $e2.src.port + 1
events:
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
  $e1.src.port = $port

  // Arithmetic to placeholder comparison is an invalid transitive join condition.
  $e2.principal.port + 800 = $port

Sintaxis de sección de coincidencia

En la sección match, enumera las variables de coincidencia para los eventos grupales antes de verificar las condiciones de coincidencia. Esos campos se devuelven con cada coincidencia.

  • Especifica qué representa cada variable de coincidencia en la sección events.
  • Especifica la duración que se usará para correlacionar eventos después de la palabra clave over. Se ignoran los eventos fuera de la duración.
  • Usa la siguiente sintaxis para especificar la duración: <number><m/h/d>

    En el ejemplo anterior, m/h/d significa minutos, horas y días, respectivamente.

  • El tiempo mínimo que puedes especificar es 1 minuto.

  • El tiempo máximo que puedes especificar es de 48 horas.

A continuación, se muestra un ejemplo de un match válido:

$var1, $var2 over 5m

Esta sentencia muestra $var1 y $var2 (definidos en la sección events) cuando la regla encuentra una coincidencia. El tiempo especificado es de 5 minutos. Los eventos con una diferencia de más de 5 minutos no se correlacionan y, por lo tanto, la regla los ignora.

Este es otro ejemplo de una sección match válida:

$user over 1h

Esta sentencia muestra $user cuando la regla encuentra una coincidencia. El período especificado es de 1 hora. Los eventos con más de una hora de diferencia no están correlacionados. La regla no los considera una detección.

Este es otro ejemplo de una sección match válida:

$source_ip, $target_ip, $hostname over 2m

Esta sentencia muestra $source_ip, $target_ip y $hostname cuando la regla encuentra una coincidencia. El período especificado es de 2 minutos. Los eventos con una diferencia de más de 2 minutos no se correlacionan. La regla no los considera una detección.

En los siguientes ejemplos, se ilustran secciones match no válidas:

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

Manejo de valores cero en la sección de coincidencia

El motor de reglas filtra de forma implícita los valores cero para todos los marcadores de posición que se usan en la sección de coincidencia ("" para strings, 0 para números, false para valores booleanos y el valor en la posición 0 para tipos enumerados). En el siguiente ejemplo, se ilustran las reglas que filtran los valores cero.

rule ZeroValuePlaceholderExample {
  meta:
  events:
    // Because $host is used in the match section, the rule behaves
    // as if the following predicate was added to the events section:
    // $host != ""
    $host = $e.principal.hostname

    // Because $otherPlaceholder was not used in the match section,
    // there is no implicit filtering of zero values for $otherPlaceholder.
    $otherPlaceholder = $e.principal.ip

  match:
    $host over 5m

  condition:
    $e
}

Sin embargo, si se asigna un marcador de posición a una función, las reglas no filtran de forma implícita los valores cero de los marcadores de posición que se usan en la sección de coincidencia. En el siguiente ejemplo, se ilustran las reglas que filtran los valores cero:

rule ZeroValueFunctionPlaceholder {
  meta:
  events:
    // Even though $ph is used in the match section, there is no
    // implicit filtering of zero values for $ph, because $ph is assigned to a function.
    $ph = re.capture($e.principal.hostname, "some-regex")

  match:
    $ph over 5m

  condition:
    $e
}

Para inhabilitar el filtrado implícito de los valores cero, puedes usar la opción allow_zero_values en la sección de opciones.

Ventana de salto

De forma predeterminada, las reglas YARA-L 2.0 con una sección de coincidencia se evalúan usando ventanas de salto. El intervalo de tiempo de ejecución de la regla se divide en un conjunto de ventanas de salto superpuestas, cada una con la duración especificada en la sección match. Luego, los eventos se correlacionan dentro de cada ventana de salto.

Por ejemplo, para una regla que se ejecuta en el intervalo de tiempo [1:00, 2:00], con una sección match sobre 30m, un conjunto posible de ventanas de salto superpuestas que se podrían generar es [1:00, 1:30], [1:03, 1:33] y [1:06, 1:36]. Estas ventanas se usan para correlacionar múltiples eventos.

Ventana deslizante

El uso de ventanas de salto no es una manera eficaz de buscar eventos que suceden en un orden específico (por ejemplo, e1 ocurre hasta 2 minutos después de e2). Un caso de evento e1 y un caso de evento e2 se correlacionan solo si entran en la misma ventana de salto generada.

Una forma más eficaz de buscar secuencias de eventos de este tipo es usar ventanas deslizantes. Las ventanas variables con la duración especificada en la sección match se generan cuando comienzan o finalizan con una variable de evento de tabla dinámica especificada. Luego, los eventos están correlacionados dentro de cada ventana deslizante. Esto permite buscar eventos que ocurran en un orden específico (por ejemplo, e1 ocurre dentro de los 2 minutos posteriores a e2). Un caso de evento e1 y un caso de evento e2 se correlacionan si el evento e1 ocurre dentro de la duración de la ventana variable después del evento e2.

Especifica ventanas variables en la sección match de una regla, como se indica a continuación:

<match-var-1>, <match-var-2>, ... over <duration> before|after <pivot-event-var>

La variable del evento dinámico es la variable del evento en la que se basan las ventanas deslizantes. Si usas la palabra clave before, se generan ventanas variables que finalizan con cada caso del evento dinámico. Si se usa la palabra clave after, las ventanas deslizantes se generan a partir de cada caso del evento dinámico.

Los siguientes son ejemplos de usos válidos de ventanas deslizantes:

  • $var1, $var2 over 5m after $e1
  • $user over 1h before $e2

Consulta un ejemplo de regla de ventana deslizante.

Google recomienda no usar ventanas variables para las reglas de evento único, ya que están diseñadas para detectar varios eventos. Si una de tus reglas entra en esta categoría, Google recomienda una de las siguientes soluciones alternativas:

  • Convierte la regla para usar múltiples variables de evento y actualiza la sección de condición si la regla requiere más de un caso del evento.
    • De forma opcional, considera agregar filtros de marca de tiempo en lugar de usar una ventana deslizante. Por ejemplo, $permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds
  • Quita la ventana deslizante.

Sintaxis de la sección de resultados

En la sección outcome, puedes definir hasta 20 variables de resultado con nombres arbitrarios. Estos resultados se almacenarán en las detecciones que genere la regla. Cada detección puede tener valores diferentes para los resultados.

El nombre del resultado, $risk_score, es especial. De manera opcional, puedes definir un resultado con este nombre y, si lo haces, debe ser de tipo entero o de número de punto flotante. Si se propaga, risk_score se mostrará en la vista Enterprise Insights para las alertas que provienen de las detecciones de reglas.

Si no incluyes una variable $risk_score en la sección de resultado de una regla, se establece uno de los siguientes valores predeterminados:

  • Si la regla está configurada para generar una alerta, $risk_score se establece en 40.
  • Si la regla no está configurada para generar una alerta, $risk_score se establece en 15.

El valor de $risk_score se almacena en el campo de UDM security_result.risk_score.

Tipos de datos de las variables de resultado

Cada variable de resultado puede tener un tipo de datos diferente, determinado por la expresión usada para calcularlo. Admitimos los siguientes tipos de datos de resultados:

  • integer
  • flotadores
  • string
  • listas de números enteros
  • listas de flotantes
  • listas de cadenas

Lógica condicional

Puedes usar la lógica condicional para calcular el valor de un resultado. Los condicionales se especifican con el siguiente patrón de sintaxis:

if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)

Puedes leer una expresión condicional como "si BOOL_CLAUSE es verdadero, luego muestra THEN_CLAUSE, de lo contrario muestra ELSE_CLAUSE".

BOOL_CLAUSE debe evaluarse como un valor booleano. Una expresión BOOL_CLAUSE toma una forma similar a las expresiones de la sección events. Por ejemplo, puede incluir lo siguiente:

  • Nombres de campos de UDM con operador de comparación, por ejemplo:

    if($context.graph.entity.user.title = "Vendor", 100, 0)

  • variable de marcador de posición que se definió en la sección events, por ejemplo:

    if($severity = "HIGH", 100, 0)

  • otra variable de resultado definida en la sección outcome, por ejemplo:

    if($risk_score > 20, "HIGH", "LOW")

  • funciones que muestran un valor booleano, por ejemplo:

    if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)

  • buscar en una lista de referencia, por ejemplo:

    if($u.principal.hostname in %my_reference_list_name, 100, 0)

  • y agregaciones, como se muestra a continuación:

    if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)

THEN_CLAUSE y ELSE_CLAUSE deben ser del mismo tipo de datos. Admitimos números enteros, números de punto flotante y cadenas.

Puedes omitir ELSE_CLAUSE si el tipo de datos es un número entero o un número de punto flotante. Si se omite, ELSE_CLAUSE se evalúa como 0. Por ejemplo:

`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`

Debes proporcionar ELSE_CLAUSE si el tipo de datos es string o si THEN_CLAUSE es una variable de marcador de posición o una variable de resultado.

Operaciones matemáticas

Puedes usar operaciones matemáticas para calcular tipos de datos de números enteros o de números de punto flotante en las secciones outcome y events de una regla. Google Security Operations admite suma, resta, multiplicación, división y módulo como operadores de nivel superior en un cálculo.

El siguiente fragmento es un ejemplo de cálculo en la sección outcome:

outcome:
  $risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))

Las operaciones matemáticas están permitidas en los siguientes tipos de operandos, siempre que cada operando y toda la expresión aritmética se agreguen de forma correcta (consulta Agregaciones):

  • Campos de eventos numéricos
  • Variables numéricas de marcador de posición definidas en la sección events
  • Variables numéricas de resultado definidas en la sección outcome
  • Funciones que muestran valores enteros o de número de punto flotante
  • Agregaciones que muestran números enteros o de punto flotante

No se permite el módulo en los números de punto flotante.

Variables de marcadores de posición en los resultados

Cuando calculas variables de resultado, puedes usar variables de marcador de posición que se definieron en la sección de eventos de tu regla. En este ejemplo, supongamos que se definió $email_sent_bytes en la sección de eventos de la regla:

Ejemplo de evento único:

// No match section, so this is a single-event rule.

outcome:
  // Use placeholder directly as an outcome value.
  $my_outcome = $email_sent_bytes

  // Use placeholder in a conditional.
  $other_outcome = if($file_size > 1024, "SEVERE", "MODERATE")

condition:
  $e

Ejemplo de varios eventos:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Use placeholder directly in an aggregation function.
  $max_email_size = max($email_sent_bytes)

  // Use placeholder in a mathematical computation.
  $total_bytes_exfiltrated = sum(
    1024
    + $email_sent_bytes
    + $file_event.principal.file.size
  )

condition:
  $email_event and $file_event

Variables de resultado en expresiones de asignación de resultado

Las variables de resultado se pueden usar para derivar otras variables de resultado, similares a las variables de marcador de posición definidas en la sección events. Puedes hacer referencia a una variable de resultado en la asignación de otra con un token $ seguido del nombre de la variable. Las variables de resultado se deben definir antes de que se pueda hacer referencia a ellas en el texto de la regla. Cuando se usan en una expresión de asignación, las variables de resultado no deben agregarse (consulta Agregaciones).

En el siguiente ejemplo, la variable de resultado $risk_score obtiene su valor de la variable de resultado $event_count:

Ejemplo de varios eventos:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Aggregates all timestamp on login events in the 5 minute match window.
  $event_count = count($login.metadata.event_timestamp.seconds)
  
  // $event_count cannot be aggregated again.
  $risk_score = if($event_count > 5, "SEVERE", "MODERATE")

  // This is the equivalent of the 2 outcomes above combined.
  $risk_score2 = if(count($login.metadata.event_timestamp.seconds) > 5, "SEVERE", "MODERATE")

condition:
  $e

Las variables de resultado se pueden usar en cualquier tipo de expresión en el lado derecho de una asignación de resultados, excepto en las siguientes expresiones:

  • Agregaciones
  • Llamadas a la función Arrays.length()
  • Con modificadores any o all

Agregaciones

Los campos de eventos repetidos son valores no escalares. Es decir, una sola variable apunta a varios valores. Por ejemplo, la variable del campo de evento $e.target.ip es un campo repetido y puede tener cero, uno o muchos valores de IP. Es un valor no escalar. Por otro lado, la variable del campo de evento $e.principal.hostname no es un campo repetido y solo tiene 1 valor (es decir, un valor escalar).

De manera similar, los campos de eventos no repetidos y los campos de eventos repetidos que se usan en la sección de resultado de una regla con una ventana de coincidencia son valores no escalares. Por ejemplo, la siguiente regla agrupa eventos con una sección de coincidencia y hace referencia a un campo de evento no repetido en la sección de resultados:

rule OutcomeAndMatchWindow{
  ...
  match:
    $userid over 5m
  outcome:
    $hostnames = array($e.principal.hostname)
  ...
}

Cualquier período de 5 minutos durante el cual se ejecute la regla puede contener cero, uno o muchos eventos. La sección de resultados opera en todos los eventos de una ventana de coincidencias. Cualquier variable de campo de evento a la que se haga referencia en la sección de resultados puede apuntar a cero, uno o muchos valores del campo en cada evento de la ventana de coincidencia. En la regla anterior, si un período de 5 minutos contiene 5 eventos $e, $e.principal.hostname en la sección de resultados apunta a 5 nombres de host diferentes. Por lo tanto, la variable de campo de evento $e.principal.hostname es un valor no escalar en la sección de resultado de esta regla.

Debido a que las variables de resultado siempre deben producir un solo valor escalar, cualquier valor no escalar del que dependa una asignación de resultado debe agregarse para obtener un solo valor escalar. En una sección de resultado, los siguientes son valores no escalares y deben agregarse:

  • Campos de evento (repetidos o no repetidos) cuando la regla usa una sección de coincidencia
  • Marcadores de posición de eventos (repetidos o no) cuando la regla usa una sección de coincidencia
  • Campos de eventos repetidos cuando la regla no utiliza una sección de coincidencia
  • Marcadores de posición de eventos repetidos cuando la regla no usa una sección de coincidencia

Los campos de eventos escalares, los marcadores de posición de eventos escalares y las constantes pueden unirse en una agregación en una regla que no usa una sección de coincidencia. Sin embargo, la mayoría de las agregaciones producirán el valor unido y, por lo tanto, no son necesarias. La excepción es la agregación array(), que se puede usar para convertir un valor escalar en un array.

Las variables de resultado se tratan como agregaciones: no deben volver a agregarse cuando se hace referencia a ellas en otra asignación de resultados.

Puedes usar las siguientes funciones de agregación:

  • max(): Muestra el máximo de todos los valores posibles. Solo funciona con números enteros y números de punto flotante.
  • min(): Muestra el mínimo sobre todos los valores posibles. Solo funciona con números enteros y números de punto flotante.
  • sum(): Muestra la suma de todos los valores posibles. Solo funciona con números enteros y números de punto flotante.
  • count_distinct(): Recopila todos los valores posibles y, luego, muestra el recuento distinto de los valores posibles.
  • count(): se comporta como count_distinct(), pero muestra un recuento no distinto de los valores posibles.
  • array_distinct(): Recopila todos los valores distintos posibles y, luego, da como resultado una lista de estos valores. truncará la lista de valores distintos a 25 elementos aleatorios. Primero, se aplica la anulación de duplicación para obtener una lista distinta y, luego, el truncamiento.
  • array(): se comporta como array_distinct(), pero muestra una lista de valores no distintas. También trunca la lista de valores a 25 elementos aleatorios.

La función de agregación es importante cuando una regla incluye una sección condition que especifica que deben existir varios eventos, ya que la función de agregación operará en todos los eventos que generaron la detección.

Por ejemplo, si tus secciones outcome y condition contienen lo siguiente:

outcome:
  $asset_id_count = count($event.principal.asset_id)
  $asset_id_distinct_count = count_distinct($event.principal.asset_id)

  $asset_id_list = array($event.principal.asset_id)
  $asset_id_distinct_list = array_distinct($event.principal.asset_id)

condition:
  #event > 1

Dado que la sección de condición requiere que haya más de un event para cada detección, las funciones de agregación operarán en varios eventos. Supongamos que los siguientes eventos generaron una detección:

event:
  // UDM event 1
  asset_id="asset-a"

event:
  // UDM event 2
  asset_id="asset-b"

event:
  // UDM event 3
  asset_id="asset-b"

Entonces, los valores de tus resultados serán los siguientes:

  • $asset_id_count = 3
  • $asset_id_distinct_count = 2
  • $asset_id_list = ["asset-a", "asset-b", "asset-b"]
  • $asset_id_distinct_list = ["asset-a", "asset-b"]

Ten en cuenta la siguiente información cuando uses la sección de resultados:

Otras notas y restricciones:

  • La sección outcome no puede hacer referencia a una nueva variable de marcador de posición que aún no se definió en la sección events ni en la sección outcome.
  • En la sección outcome, no se pueden usar variables de evento que no se hayan definido en la sección events.
  • En la sección outcome, se puede usar un campo de evento que no se usó en la sección events, dado que la variable de evento a la que pertenece el campo del evento ya se definió en la sección events.
  • La sección outcome solo puede correlacionar variables de eventos que ya se correlacionaron en la sección events. Las correlaciones ocurren cuando dos campos de evento de diferentes variables de evento se igualan.

Puedes encontrar un ejemplo en la sección de resultados de Descripción general de YARA-L 2.0. Consulta Crea estadísticas adaptadas al contexto para obtener más información sobre la anulación de duplicación de detección en la sección de resultados.

Sintaxis de la sección de condición

  • Especifica una condición de coincidencia para los eventos y marcadores de posición definidos en la sección events. Para obtener más detalles, consulta la siguiente sección, Condicionales de eventos y marcadores de posición.
  • Usa la palabra clave and para especificar una condición de concordancia mediante las variables de resultado definidas en la sección outcome (opcional). Para obtener más detalles, consulta la siguiente sección, Condicionales de los resultados.

Contar caracteres

El carácter # es un carácter especial de la sección condition. Si se usa antes de cualquier evento o nombre de variable de marcador de posición, representa la cantidad de eventos o valores distintos que cumplen con todas las condiciones de la sección events.

Por ejemplo, #c > 1 significa que la variable c debe ocurrir más de 1 vez.

Carácter de valor

El carácter $ es un carácter especial de la sección condition. Si se usa antes de cualquier nombre de variable de resultado, representa el valor de ese resultado.

Si se usa antes de cualquier evento o nombre de variable de marcador de posición (por ejemplo, $event), representa #event > 0.

Condicionales de eventos y marcadores de posición

Aquí, los predicados de condición de lista para eventos y variables de marcador de posición, unidos con la palabra clave and o or. La palabra clave and se puede usar entre cualquier condición, pero la palabra clave or solo se puede usar cuando la regla solo tiene una única variable de evento.

Este es un ejemplo válido del uso de or entre dos marcadores de posición en el mismo evento:

rule ValidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"

      // Note that all placeholders use the same event variable.
      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.
      $ph2 = $e.principal.ip  // Define a second placeholder variable to put in condition section.
      $ph3 = $e.principal.hostname  // Define a third placeholder variable to put in condition section.

  match:
    $ph over 5m

  condition:
    $ph2 or $ph3
}

Ejemplo no válido del uso de or entre dos condiciones en eventos diferentes:

rule InvalidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"
      $e2.graph.metadata.entity_type = "FILE"
      $e2.graph.entity.hostname  = $e.principal.hostname

      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.

  match:
    $ph over 5m

  condition:
    $e or $e2 // This line will cause an error because there is an or between events.
}

Condiciones delimitadas y no delimitadas

Las siguientes condiciones son delimitadas. Fuerzan la variable de evento asociada para que exista, lo que significa que debe aparecer al menos un caso del evento en cualquier detección.

  • $var // equivalent to #var > 0
  • #var > n // where n >= 0
  • #var >= m // where m > 0

Las siguientes condiciones son no delimitadas. Permiten que no exista la variable de evento asociada, lo que significa que es posible que no aparezca ningún caso en una detección y que cualquier referencia a los campos de la variable de evento produzca un valor de cero. Se pueden usar condiciones no delimitadas para detectar la ausencia de un evento. Por ejemplo, un evento de amenaza sin un evento de mitigación en un período de 10 minutos. Las reglas que usan condiciones no delimitadas se denominan reglas de inexistencia.

  • !$var // equivalent to #var = 0
  • #var >= 0
  • #var < n // where n > 0
  • #var <= m // where m >= 0

Requisitos para la inexistencia

Para que se compile una regla sin existencia, debe cumplir los siguientes requisitos:

  1. Al menos un evento de UDM debe tener una condición delimitada (es decir, debe existir al menos un evento de UDM).
  2. Si un marcador de posición tiene una condición no delimitada, debe estar asociado con, al menos, un evento UDM delimitado.
  3. Si una entidad tiene una condición no delimitada, debe estar asociada con al menos un evento UDM delimitado.

Considera la siguiente regla en la que se omite la sección de condición:

rule NonexistenceExample {
  meta:
  events:
      $u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
      $u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
      $e1.graph.metadata.entity_type = "FILE"        // $e1 is an Entity.
      $e2.graph.metadata.entity_type = "FILE"        // $e2 is an Entity.

      $user = $u1.principal.user.userid // Match variable is required for Multi-Event Rule.

      // Placeholder Associations:
      //   u1        u2 
      //   |  \    /
      // port   ip
      //   |       \
      //   e1        e2
      $u1.target.port = $port
      $e1.graph.entity.port = $port
      $u1.principal.ip = $ip
      $u2.target.ip = $ip
      $e2.graph.entity.ip = $ip

      // UDM-Entity Associations:
      // u1 - u2
      // |  \  |
      // e1   e2
      $u1.metadata.event_type = $u2.metadata.event_type
      $e1.graph.entity.hostname = $u1.principal.hostname
      $e2.graph.entity.hostname = $u1.target.hostname
      $e2.graph.entity.hostname = $u2.principal.hostname

  match:
    $user over 5m

  condition:
      <condition_section>
}

Los siguientes son ejemplos válidos para <condition_section>:

  • $u1 and !$u2 and $e1 and $e2
    • Todos los eventos y entidades de UDM están presentes en la sección de condiciones.
    • Al menos un evento de UDM está delimitado.
  • $u1 and !$u2 and $e1 and !$e2
    • $e2 no está delimitado, lo que está permitido porque está asociado con $u1, que está delimitado. Si $e2 no se asoció con $u1, esto no sería válido.
  • #port > 50 and #ip = 0
    • No hay eventos ni entidades de UDM en la sección de condiciones. Sin embargo, los marcadores de posición que están presentes abarcan todos los eventos y entidades de UDM.
    • $ip se asigna a $u1 y $u2, y #ip = 0 es una condición no delimitada. Sin embargo, las condiciones delimitadas son más fuertes que las no delimitadas. Como $port se asigna a $u1 y #port > 50 es una condición delimitada, $u1 todavía está delimitada.

Los siguientes ejemplos son no válidos para <condition_section>:

  • $u1 and $e1
    • Cada evento y entidad de UDM que aparece en la sección Eventos debe aparecer en la sección Condición (o tener un marcador de posición asignado que aparece en la sección Condición).
  • $u1, $u2, $e1, $u2, #port > 50
    • No se permiten las comas como separadores de condiciones.
  • !$u1 and !$u2 and $e1 and $e2
    • Infringe el primer requisito de que al menos un evento de UDM está delimitado.
  • ($u1 or #port < 50) and $u2 and $e1 and $e2
    • La palabra clave or no es compatible con condiciones no delimitadas.
  • ($u1 or $u2) and $e1 and $e2
    • La palabra clave or no es compatible entre diferentes variables de evento.
  • not $u1 and $u2 and $e1 and $e2
    • No se permite la palabra clave not para las condiciones de eventos y marcadores de posición.
  • #port < 50 and #ip = 0
    • Los marcadores de posición que están presentes abarcan todos los eventos y entidades de UDM; sin embargo, todas las condiciones no están delimitadas. Esto significa que ninguno de los eventos UDM está delimitado, lo que provoca que la regla no se compile.

Condicionales de resultados

Aquí, enumera los predicados de condición para las variables de resultado, unidos con la palabra clave and o or, o precedidos por la palabra clave not.

Especifica condicionales de resultado de manera diferente según el tipo de variable de resultado:

  • integer: se compara con un literal de número entero con los operadores =, >, >=, <, <=, !=, por ejemplo:

    $risk_score > 10

  • float: Compara con un literal de número de punto flotante con los operadores =, >, >=, <, <=, !=, por ejemplo:

    $risk_score <= 5.5

  • string: Compara con un literal de string con = o !=, por ejemplo:

    $severity = "HIGH"

  • Lista de números enteros o arreglos: Especifica la condición con la función arrays.contains, por ejemplo:

    arrays.contains($event_ids, "id_1234")

Clasificación de reglas

Especificar un resultado condicional en una regla que tiene una sección de coincidencia significa que la regla se clasificará como una de varios eventos para la cuota de reglas. Consulta Regla de evento único y Regla de evento múltiple para obtener más información sobre las clasificaciones de uno o varios eventos.

Sintaxis de la sección de opciones

En la sección options, puedes especificar las opciones de la regla. Este es un ejemplo de cómo especificar la sección de opciones:

rule RuleOptionsExample {
  // Other rule sections

  options:
    allow_zero_values = true
}

Puedes especificar opciones con la sintaxis key = value, en la que key debe ser un nombre de opción predefinido y value debe ser un valor válido para la opción, como se especifica en las siguientes opciones:

allow_zero_values

Los valores válidos para esta opción son true y false, que determinan si esta opción está habilitada o no. El valor predeterminado es false. Esta opción se inhabilita si no se especifica en la regla.

Para habilitar esta configuración, agrega lo siguiente a la sección de opciones de tu regla: allow_zero_values = true. Si lo haces, evitarás que la regla filtre de manera implícita los valores cero de los marcadores de posición que se usan en la sección de coincidencia, como se describe en Manejo de valores cero en la sección de coincidencias.

Expresiones booleanas

Las expresiones booleanas son expresiones de tipo booleano.

Comparaciones

Para usar una expresión binaria como condición, usa la siguiente sintaxis:

  • <EXPR> <OP> <EXPR>

La expresión puede ser un campo de evento, una variable, un literal o una expresión de función.

Por ejemplo:

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port
  • $e1.source.hostname != $e2.target.hostname
  • $e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
  • $port >= 25
  • $host = $e2.target.hostname
  • "google-test" = strings.concat($e.principal.hostname, "-test")
  • "email@google.org" = re.replace($e.network.email.from, "com", "org")

Si ambos lados son literales, se considera un error de compilación.

Funciones

Algunas expresiones de función muestran un valor booleano, que se puede usar como un predicado individual en la sección events. Estas funciones son las siguientes:

  • re.regex()
  • net.ip_in_range_cidr()

Por ejemplo:

  • re.regex($e.principal.hostname, `.*\.google\.com`)
  • net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

Expresiones de lista de referencia

Puedes usar listas de referencia en la sección de eventos. Consulta la sección Listas de referencia para obtener más información.

Expresiones lógicas

Puedes usar los operadores lógicos and y or en la sección events, como se muestra en los siguientes ejemplos:

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

De forma predeterminada, el orden de prioridad de mayor a menor es not, and, or.

Por ejemplo, “a o b y c” se evalúa como “a o (b y c)” cuando los operadores or y and se definen de forma explícita en la expresión.

En la sección events, los predicados se unen con el operador and si no se definió de forma explícita un operador.

El orden de evaluación puede ser diferente si el operador and está implícito en la expresión.

Por ejemplo, considera las siguientes expresiones de comparación en las que or se define de forma explícita. El operador and está implícito.

$e1.field = "bat"
or $e1.field = "baz"
$e2.field = "bar"

Este ejemplo se interpreta de la siguiente manera:

($e1.field = "bat" or $e1.field = "baz")
and ($e2.field = "bar")

Como or se define de forma explícita, los predicados que rodean a or se agrupan y evalúan primero. El último predicado, $e2.field = "bar", se une de forma implícita con and. El resultado es que cambia el orden de la evaluación.

Tipos enumerados

Puedes usar los operadores con tipos enumerados. Puede aplicarse a reglas para simplificar y optimizar (usa un operador en lugar de listas de referencia) el rendimiento.

En el siguiente ejemplo, “USER_UNCATEGORIZED” y “USER_RESOURCE_DELETION” corresponden a 15,000 y 15,014, por lo que la regla buscará todos los eventos de la lista:

$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"

Lista de eventos:

  • USER_RESOURCE_DELETION
  • USER_RESOURCE_UPDATE_CONTENT
  • USER_RESOURCE_UPDATE_PERMISSIONS
  • USER_STATS
  • USER_UNCATEGORIZED

Modificador de casos

Cuando tienes una expresión de comparación entre valores de cadena o una expresión regular, puedes agregar no case al final de la expresión para ignorar el uso de mayúsculas.

  • $e.principal.hostname != "http-server" nocase
  • $e1.principal.hostname = $e2.target.hostname nocase
  • $e.principal.hostname = /dns-server-[0-9]+/ nocase
  • re.regex($e.target.hostname, `client-[0-9]+`) nocase

No se puede usar cuando un tipo de campo es un valor enumerado. Los siguientes ejemplos no son válidos y generarán errores de compilación:

  • $e.metadata.event_type = "NETWORK_DNS" nocase
  • $e.network.ip_protocol = "TCP" nocase

Campos repetidos

En el modelo de datos unificados (UDM), algunos campos se etiquetan como repetidos, lo que indica que son listas de valores o algún otro tipo de mensaje.

Campos repetidos y expresiones booleanas

Existen 2 tipos de expresiones booleanas que actúan sobre campos repetidos:

  1. Modificado
  2. Sin modificar

Considera el siguiente evento:

event_original {
  principal {
    // ip is a repeated field
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "host"
  }
}

Expresiones modificadas

En las siguientes secciones, se describe el propósito y cómo usar los modificadores any y all en expresiones.

cualquiera

Si algún elemento del campo repetido satisface la condición, el evento en conjunto cumple con la condición.

  • event_original cumple con any $e.principal.ip = "192.0.2.1".
  • event_original falla con any $e.repeated_field.field_a = "9.9.9.9.
todos

Si todos los elementos del campo repetido satisfacen la condición, el evento en su totalidad cumple la condición.

  • event_original cumple con net.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8").
  • event_original falla con all $e.principal.ip = "192.0.2.2".

Cuando escribas una condición con any o all, ten en cuenta que anular la condición con not puede no tener el mismo significado que usar el operador negado.

Por ejemplo:

  • not all $e.principal.ip = "192.168.12.16" verifica si no todas las direcciones IP coinciden con 192.168.12.16, lo que significa que la regla comprueba si al menos una dirección IP no coincide con 192.168.12.16.
  • all $e.principal.ip != "192.168.12.16" verifica si todas las direcciones IP no coinciden con 192.168.12.16, lo que significa que la regla comprueba que ninguna dirección IP coincida con 192.168.12.16.

Restricciones:

  • Los operadores any y all solo son compatibles con campos repetidos (no con campos escalares).
  • any y all no se pueden usar para unir dos campos repetidos. Por ejemplo, any $e1.principal.ip = $e2.principal.ip no es válido.
  • Los operadores any y all no son compatibles con la expresión de la lista de referencia.

Expresiones sin modificar

Con las expresiones sin modificar, cada elemento del campo repetido se trata de forma individual. Si el campo repetido de un evento contiene n elementos, la regla se aplicará en n copias del evento, en las que cada copia tiene uno de los elementos del campo repetido. Estas copias son transitorias y no se almacenan.

La regla se aplica a las siguientes copias:

texto del evento principal.ip principal.hostname
event_copy_1 “192.0.2.1” "anfitrión"
event_copy_2 “192.0.2.2” "anfitrión"
event_copy_3 “192.0.2.3” "anfitrión"

Si alguna copia de un evento satisface todas las condiciones sin modificar en el campo repetido, el evento en su conjunto satisface todas las condiciones. Esto significa que, si tienes varias condiciones en un campo repetido, la copia del evento debe cumplir con todas las condiciones. Los siguientes ejemplos de reglas usan el conjunto de datos del ejemplo anterior para demostrar este comportamiento.

La siguiente regla muestra una coincidencia cuando se ejecuta con el conjunto de datos de ejemplo event_original, porque event_copy_1 cumple con todos los predicados de eventos:

rule repeated_field_1 {
  meta:
  events:
    net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/8") // Checks if IP address matches 192.x.x.x
    $e.principal.ip = "192.0.2.1"
  condition:
    $e
}

La siguiente regla no muestra una coincidencia cuando se ejecuta en el conjunto de datos de ejemplo event_original, porque no hay una copia del evento en $e.principal.ip que cumpla con todos los predicados del evento.

rule repeated_field_2 {
  meta:
  events:
    $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.2"
  condition:
    $e
}

Las expresiones modificadas en campos repetidos son compatibles con expresiones no modificadas en campos repetidos porque la lista de elementos es la misma para cada copia de evento. Considera la siguiente regla:

rule repeated_field_3 {
  meta:
  events:
    any $e.principal.ip = "192.0.2.1" 
    $e.principal.ip = "192.0.2.3"
  condition:
    $e
}

La regla se aplica a las siguientes copias:

texto del evento principal.ip cualquier $e.principal.ip
event_copy_1 “192.0.2.1” [“192.0.2.1”, “192.0.2.2”, “192.0.2.3”]
event_copy_2 “192.0.2.2” [“192.0.2.1”, “192.0.2.2”, “192.0.2.3”]
event_copy_3 “192.0.2.3” [“192.0.2.1”, “192.0.2.2”, “192.0.2.3”]

En este caso, todas las copias satisfacen any $e.principal.ip = "192.0.2.1", pero solo event_copy_3 cumple con $e.principal.ip = "192.0.2.3". Como resultado, todo el evento coincidiría.

Otra forma de pensar en estos tipos de expresiones es la siguiente:

  • Las expresiones en campos repetidos que usan any o all operan en la lista en event_original.
  • Las expresiones en campos repetidos que no usan any ni all operan en eventos event_copy_n individuales.

Campos repetidos y marcadores de posición

Los campos repetidos funcionan con asignaciones de marcadores de posición. Al igual que con las expresiones sin modificar en campos repetidos, se crea una copia del evento para cada elemento. Con el mismo ejemplo de event_copy, el marcador de posición toma el valor del valor del campo repetido de event_copy_n para cada una de las copias del evento, donde n es el número de la copia del evento. Si el marcador de posición se usa en la sección de coincidencias, esto puede generar varias coincidencias.

En el siguiente ejemplo, se genera una coincidencia. El marcador de posición $ip es igual a 192.0.2.1 para event_copy_1, que cumple con los predicados de la regla. Las muestras de eventos de coincidencias contienen un solo elemento, event_original.

// Generates 1 match.
rule repeated_field_placeholder1 {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1"
    $host = $e.principal.hostname

  match:
    $host over 5m

  condition:
    $e
}

En el siguiente ejemplo, se generan tres coincidencias. El marcador de posición $ip es igual a valores diferentes para cada una de las diferentes copias de event_copy_n. La agrupación se realiza en $ip, ya que está en la sección de coincidencia. Por lo tanto, se obtienen tres coincidencias en las que cada coincidencia tiene un valor diferente para la variable de coincidencia $ip. Cada coincidencia tiene la misma muestra de evento: un solo elemento, event_original.

// Generates 3 matches.
rule repeated_field_placeholder2 {
  meta:
  events:
    $ip = $e.principal.ip
    net.ip_in_range_cidr($ip, "192.0.2.0/8") // Checks if IP matches 192.x.x.x

  match:
    $ip over 5m

  condition:
    $e
}

Resultados que usan marcadores de posición asignados a campos repetidos

Los marcadores de posición se asignan a cada elemento de cada campo repetido, no a la lista completa. Por lo tanto, cuando se usan en la sección de resultados, el resultado se calcula solo con los elementos que satisficieron las secciones anteriores.

Considera la siguiente regla:

rule outcome_repeated_field_placeholder {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1" or $ip = "192.0.2.2"
    $host = $e.principal.hostname

  match:
    $host over 5m

  outcome:
    $o = array_distinct($ip)

  condition:
    $e
}

La ejecución de esta regla tiene 4 etapas. La primera etapa es la copia del evento:

texto del evento $ip $host $e
event_copy_1 “192.0.2.1” "anfitrión" event_id
event_copy_2 “192.0.2.2” "anfitrión" event_id
event_copy_3 “192.0.2.3” "anfitrión" event_id

Luego, la sección de eventos filtrará las filas que no coincidan con los filtros:

texto del evento $ip $host $e
event_copy_1 “192.0.2.1” "anfitrión" event_id
event_copy_2 “192.0.2.2” "anfitrión" event_id

event_copy_3 se filtra porque "192.0.2.3" no cumple con $ip = "192.0.2.1" or $ip = "192.0.2.2".

La sección de coincidencia agrupará por variables de coincidencia y la sección de resultados realizará la agregación en cada grupo:

$host $o $e
"anfitrión" [“192.0.2.1”, “192.0.2.2”] event_id

$o = array_distinct($ip) se calcula con $ip de la etapa anterior y no la etapa de copia del evento.

Por último, la sección de condición filtrará cada grupo. Dado que esta regla solo comprueba la existencia de $e, la fila anterior producirá una sola detección.

$o no contiene todos los elementos de $e.principal.ip porque no todos los elementos cumplen con todas las condiciones de la sección de eventos. Sin embargo, todos los elementos de e.principal.ip aparecerán en la muestra del evento porque esta usa event_original.

Indexación de arrays

Puedes indexar arrays en campos repetidos. Para acceder al elemento de campo repetido enésimo, usa la sintaxis de lista estándar (los elementos tienen un índice 0). Un elemento fuera de los límites devuelve el valor predeterminado.

  • $e.principal.ip[0] = "192.168.12.16"
  • $e.principal.ip[999] = "" Si hay menos de 1,000 elementos, se evalúa como true.

Restricciones:

  • Un índice debe ser un literal de número entero no negativo. Por ejemplo, $e.principal.ip[-1] no es válido.
  • Los valores que tienen un tipo int (por ejemplo, un marcador de posición establecido en int) no cuentan.
  • La indexación de array no se puede combinar con any ni all. Por ejemplo, any $e.intermediary.ip[0] no es válido.
  • La indexación de arrays no se puede combinar con la sintaxis de mapa. Por ejemplo, $e.additional.fields[0]["key"] no es válido.
  • Si la ruta del campo contiene varios campos repetidos, todos estos deben usar la indexación de array. Por ejemplo, $e.intermediary.ip[0] no es válido porque intermediary y ip son campos repetidos, pero solo hay un índice para ip.

Mensajes repetidos

Cuando se repite un campo message, un efecto no deseado es reducir la probabilidad de una coincidencia. Esto se ilustra en los siguientes ejemplos.

Considera el siguiente evento:

event_repeated_message {
  // about is a repeated message field.
  about {
    // ip is a repeated string field.
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "alice"
  }
  about {
    hostname: "bob"
  }
}

Como se indica para las expresiones sin modificar en campos repetidos, se crea una copia temporal del evento para cada elemento del campo repetido. Considera la siguiente regla:

rule repeated_message_1 {
  meta:
  events:
    $e.about.ip = "192.0.2.1" 
    $e.about.hostname = "bob"
  condition:
    $e
}

La regla se aplica a las siguientes copias:

texto del evento about.ip about.hostname
event_copy_1 “192.0.2.1” “alicia”
event_copy_2 “192.0.2.2” “alicia”
event_copy_3 “192.0.2.3” “alicia”
event_copy_4 "" “roberto”

El evento no coincide con la regla porque no existe una copia del evento que satisfaga todas las expresiones.

Indexación de arrays y mensajes repetidos

Otro comportamiento inesperado puede ocurrir cuando se usa la indexación de arrays con expresiones sin modificar en campos de mensajes repetidos. Considera la siguiente regla de ejemplo que usa indexación de array:

rule repeated_message_2 {
  meta:
  events:
    $e.about.ip = "192.0.2.1" 
    $e.about[1].hostname = "bob"
  condition:
    $e
}

La regla se aplica a las siguientes copias:

texto del evento about.ip acerca de[1].nombredehost
event_copy_1 “192.0.2.1” “roberto”
event_copy_2 “192.0.2.2” “roberto”
event_copy_3 “192.0.2.3” “roberto”
event_copy_4 "" “roberto”

Como event_copy_1 satisface todas las expresiones de repeated_message_2, el evento coincide con la regla.

Esto puede generar un comportamiento inesperado porque la regla repeated_message_1 carecía de indexación de arrays y no produjo coincidencias, mientras que la regla repeated_message_2 usó la indexación de arrays y produjo una coincidencia.

Comentarios

Designa comentarios con dos caracteres de barra (// comment) o comentarios de varias líneas marcados con un asterisco de barras diagonales (/* comment */), como lo harías en C.

Literales

Se admiten números enteros no negativos y literales de números de punto flotante, de cadena, booleanos y de expresión regular.

Literales de string y de expresión regular

Puedes usar cualquiera de las siguientes comillas para encerrar cadenas en YARA-L 2.0. Sin embargo, el texto citado se interpreta de manera diferente según cuál utilices.

  1. Comillas dobles ("): Se usa para cadenas normales. Debe incluir caracteres de escape.
    Por ejemplo: “hello\tworld”:\t se interpreta como una pestaña

  2. Comillas inversas (`): Se usan para interpretar todos los caracteres literalmente.
    Por ejemplo: “hello\tworld”:\t no se interpreta como una pestaña.

Para las expresiones regulares, tienes dos opciones.

Si deseas usar expresiones regulares directamente sin la función re.regex(), usa /regex/ para los literales de expresión regular.

También puedes usar literales de string como literales de expresión regular cuando usas la función re.regex(). Ten en cuenta que, para los literales de cadena de comillas dobles, debes escapar los caracteres de barra inversa con caracteres de barra inversa, que pueden parecer incómodos.

Por ejemplo, las siguientes expresiones regulares son equivalentes:

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

Google recomienda usar caracteres de comillas hacia atrás para las cadenas en las expresiones regulares a fin de facilitar la legibilidad.

Operadores

Puedes usar los siguientes operadores en YARA-L:

Operador Descripción
= igual/declaración
!= no igual
< menor que
<= menor o igual que
> mayor que
>= mayor o igual que

Variables

En YARA-L 2.0, todas las variables se representan como $<variable name>.

Puedes definir los siguientes tipos de variables:

  • Variables de evento: Representa grupos de eventos en formato normalizado (UDM) o eventos de entidad. Especifica las condiciones para las variables de evento en la sección events. Para identificar las variables de evento, debes usar un nombre, una fuente de evento y campos de evento. Las fuentes permitidas son udm (para eventos normalizados) y graph (para eventos de entidad). Si se omite la fuente, udm se establece como la fuente predeterminada. Los campos de evento se representan como una cadena de .<nombre de campo> (por ejemplo, $e.field1.field2). Las cadenas de campos de eventos siempre comienzan en la fuente de nivel superior (UDM o entidad).

  • Variables de coincidencia: Declara en la sección match. Las variables de coincidencia se convierten en campos de agrupación para la consulta, ya que se muestra una fila para cada conjunto único de variables de coincidencia (y para cada período). Cuando la regla encuentra una coincidencia, se muestran los valores de la variable de coincidencia. Especifica qué representa cada variable de coincidencia en la sección events.

  • Variables de marcador de posición: Declara y define en la sección events. Las variables de marcador de posición son similares a las variables de coincidencia. Sin embargo, puedes usar variables de marcador de posición en la sección condition para especificar las condiciones de coincidencia.

Usa variables de coincidencia y de marcador de posición para declarar relaciones entre campos de eventos mediante condiciones de unión transitivas (consulta la sintaxis de la sección de eventos para obtener más detalles).

Palabras clave

Las palabras clave en YARA-L 2.0 no distinguen entre mayúsculas y minúsculas. Por ejemplo, and o AND son equivalentes. Los nombres de las variables no deben entrar en conflicto con las palabras clave. Por ejemplo, $AND o $outcome no son válidos.

Las siguientes son palabras clave para las reglas del motor de detección: rule, meta, match, over, events, condition, outcome, options, and, or, not, nocase, in, regex, cidr, before, after, all, any, if, max, min, if, max, min, sum, match y match.arrayarray_distinctcountcount_distinctisnull

Maps

YARA-L admite el acceso a mapas para structs y etiquetas.

structs y etiquetas

Algunos campos de UDM usan el tipo de datos Struct o Label.

Para buscar un par clave-valor específico en Struct y Label, usa la sintaxis de mapa estándar:

// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

El acceso a mapas siempre devuelve una cadena.

Casos admitidos

Sección Eventos y resultados
// Using a Struct field in the events section
events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"

// Using a Label field in the outcome section
outcome:
  $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
Cómo asignar un valor del mapa a un marcador de posición
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
Usa un campo de mapa en una condición de unión
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]

Casos no admitidos

No se admiten mapas en los siguientes casos.

Combinación de palabras clave any o all con un mapa

Por ejemplo, no se admite lo siguiente:

all $e.udm.additional.fields["pod_name"] = "kube-scheduler"
Otros tipos de valores

La sintaxis del mapa solo puede mostrar un valor de cadena. En el caso de los tipos de datos Struct, la sintaxis del mapa solo puede acceder a las claves cuyos valores sean cadenas. No es posible acceder a claves cuyos valores sean otros tipos primitivos, como números enteros.

Manejo de valores duplicados

Los accesos a mapas siempre muestran un solo valor. En el caso límite poco común en que el acceso al mapa podría hacer referencia a varios valores, el acceso al mapa mostrará de manera determinista el primer valor.

Esto puede suceder en cualquiera de los siguientes casos:

  • Una etiqueta tiene una clave duplicada.

    La estructura de etiquetas representa un mapa, pero no aplica de manera forzosa la unicidad de las claves. Por convención, un mapa debe tener claves únicas, por lo que Google Security Operations no recomienda propagar una etiqueta con claves duplicadas.

    El texto de la regla $e.metadata.ingestion_labels["dupe-key"] mostraría el primer valor posible, val1, si se ejecuta en el siguiente ejemplo de datos:

    // Disrecommended usage of label with a duplicate key:
    event {
      metadata{
        ingestion_labels{
          key: "dupe-key"
          value: "val1" // This is the first possible value for "dupe-key"
        }
        ingestion_labels{
          key: "dupe-key"
          value: "val2"
        }
      }
    }
    
  • Una etiqueta tiene un campo principal repetido.

    Un campo repetido puede contener una etiqueta como campo secundario. Dos entradas diferentes en el campo repetido de nivel superior pueden contener etiquetas que tengan la misma clave. El texto de la regla $e.security_result.rule_labels["key"] mostraría el primer valor posible, val3, si se ejecuta en el siguiente ejemplo de datos:

    event {
      // security_result is a repeated field.
      security_result {
        threat_name: "threat1"
        rule_labels {
          key: "key"
          value: "val3" // This is the first possible value for "key"
        }
      }
      security_result {
        threat_name: "threat2"
        rule_labels {
          key: "key"
          value: "val4"
        }
      }
    }
    

Funciones

En esta sección, se describen las funciones de YARA-L 2.0 que puedes usar en la búsqueda y en las reglas del motor de detección.

Estas funciones se pueden usar en las siguientes partes de una regla de YARA-L:

arrays.length

Compatible con:
arrays.length(repeatedField)

Descripción

Muestra la cantidad de elementos de campo repetidos.

Tipos de datos de parámetros

LIST

Tipo de datos que se muestra

NUMBER

Muestras de código

Ejemplo 1

Muestra la cantidad de elementos de campo repetidos.

arrays.length($e.principal.ip) = 2
Ejemplo 2

Si hay varios campos repetidos a lo largo de la ruta, muestra la cantidad total de elementos de campo repetidos.

arrays.length($e.intermediary.ip) = 3

Fingerprint

Compatible con:
hash.fingerprint2011(byteOrString)

Descripción

Esta función calcula el hash fingerprint2011 de una secuencia o cadena de bytes de entrada. Esta función muestra un valor de INT sin signo en el rango [2, 0xFFFFFFFFFFFFFFFF].

Tipos de datos de parámetros

BTYE, STRING

Tipo de datos que se muestra

INT

Muestra de código

id_fingerprint = hash.fingerprint2011("user123")

grupo

Compatible con:
group(field1, field2, field3, ...)

Descripción

Agrupa campos de tipo similar en una variable de marcador de posición.

En la búsqueda de UDM, los campos agrupados se usan para buscar en varios campos de un tipo similar. La función de grupo es similar a los campos agrupados, con la excepción de que te permite seleccionar qué campos deseas agrupar para activar una detección. Puedes usar la función de grupo para recopilar información sobre una entidad específica (por ejemplo, un nombre de host, una dirección IP o un ID de usuario) en diferentes tipos de sustantivos.

Muestras de código

Ejemplo 1

Agrupa todas las direcciones IP y proporciona un recuento descendente de la dirección IP más frecuente en el intervalo de tiempo analizado.

$ip = group(principal.ip, about.ip, target.ip)
$ip != ""
match:
  $ip
outcome:
  $count = count_distinct(metadata.id)
order:
  $count desc

math.abs

Compatible con:
math.abs(numericExpression)

Descripción

Muestra el valor absoluto de un número entero o una expresión de número de punto flotante.

Tipos de datos de parámetros

NUMBER

Tipo de datos que se muestra

NUMBER

Muestras de código

Ejemplo 1

En este ejemplo, se muestra el valor True si el evento se llevó a cabo a más de 5 minutos de la hora especificada (en segundos del epoch Unix), sin importar si el evento ocurrió antes o después de la hora especificada. Una llamada a math.abs no puede depender de múltiples variables o marcadores de posición. Por ejemplo, no puedes reemplazar el valor de tiempo codificado de 1643687343 en el siguiente ejemplo por $e2.metadata.event_timestamp.seconds.

300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)

math.log

Compatible con:
math.log(numericExpression)

Descripción

Muestra el valor de registro natural de una expresión de número entero o de número de punto flotante.

Tipos de datos de parámetros

NUMBER

Tipo de datos que se muestra

NUMBER

Muestras de código

Ejemplo 1
math.log($e1.network.sent_bytes) > 20

math.round

Compatible con:
math.round(numericExpression, decimalPlaces)

Descripción

Muestra un valor redondeado al número entero más cercano o al número de decimales especificado.

Tipos de datos de parámetros

NUMBER

Tipo de datos que se muestra

NUMBER

Muestras de código

math.round(10.7) // returns 11
math.round(1.2567, 2) // returns 1.25
math.round(-10.7) // returns -11
math.round(-1.2) // returns -1
math.round(4) // returns 4, math.round(integer) returns the integer

metrics

Compatible con:

Las funciones de métricas pueden agregar grandes cantidades de datos históricos. Puedes usarla en tu regla con metrics.functionName() en la sección de resultados.

Para obtener más información, consulta Métricas de YARA-L.

net.ip_in_range_cidr

Compatible con:
net.ip_in_range_cidr(ipAddress, subnetworkRange)

Descripción

Muestra true cuando la dirección IP proporcionada se encuentra dentro de la subred especificada.

Puedes usar YARA-L para buscar eventos UDM en todas las direcciones IP dentro de una subred mediante la declaración net.ip_in_range_cidr(). Se admite IPv4 e IPv6.

Para buscar en un rango de direcciones IP, especifica un campo de UDM de IP y un rango de CIDR. YARA-L puede controlar campos de direcciones IP singulares y repetidos.

Para buscar en un rango de direcciones IP, especifica un campo de UDM ip y un rango de enrutamiento entre dominios sin clases (CIDR). YARA-L puede controlar campos de direcciones IP singulares y repetidos.

Tipos de datos de parámetros

STRING y STRING

Tipo de datos que se muestra

BOOL

Muestras de código

Ejemplo 1

Ejemplo de IPv4:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
Ejemplo 2

Ejemplo de IPv6:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

Para ver una regla de ejemplo que usa la declaración net.ip_in_range_cidr(), consulta la regla de ejemplo en Evento único dentro del rango de direcciones IP).

re.regex

Compatible con:

Puedes definir la coincidencia de expresiones regulares en YARA-L 2.0 con cualquiera de las siguientes sintaxis:

  • Uso de la sintaxis de YARA-L: Relacionado con eventos. La siguiente es una representación genérica de esta sintaxis:

    $e.field = /regex/
    
  • Si usas la sintaxis de YARA-L, como una función que acepta los siguientes parámetros:

    • Campo al que se aplica la expresión regular.
    • Expresión regular especificada como una cadena.

    La siguiente es una representación genérica de esta sintaxis:

    re.regex($e.field, `regex`)
    

Descripción

Esta función muestra true si la string contiene una subcadena que coincide con la expresión regular proporcionada. No es necesario agregar .* al principio o al final de la expresión regular.

Notas
  • Para hacer coincidir la string exacta o solo un prefijo o sufijo, incluye los caracteres de anclaje ^ (inicio) y $ (final) en la expresión regular. Por ejemplo, /^full$/ coincide exactamente con "full", mientras que /full/ podría coincidir con "fullest", "lawfull" y "joyfully".
  • Si el campo UDM incluye caracteres de salto de línea, regexp solo coincide con la primera línea del campo UDM. Para aplicar la coincidencia de campos UDM completa, agrega un (?s) a la expresión regular. Por ejemplo, reemplaza /.*allUDM.*/ por /(?s).*allUDM.*/.
  • Puedes usar el modificador nocase después de las cadenas para indicar que la búsqueda debe ignorar el uso de mayúsculas.

Tipos de datos de parámetros

STRING y STRING

Tipos de expresiones de parámetros

ANY y ANY

Tipo de datos que se muestra

BOOL

Muestras de código

Ejemplo 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")

re.capture

Compatible con:
re.capture(stringText, regex)

Descripción

Captura (extrae) datos de una string mediante el patrón de expresión regular proporcionado en el argumento.

Esta función tiene dos argumentos:

  • stringText: Es la cadena original en la que se buscará.
  • regex: Es la expresión regular que indica el patrón que se debe buscar.

La expresión regular puede contener 0 o 1 grupos de captura entre paréntesis. Si la expresión regular contiene 0 grupos de captura, la función muestra la primera subcadena completa que coincide. Si la expresión regular contiene 1 grupo de captura, muestra la primera subcadena coincidente para ese grupo de captura. La definición de dos o más grupos de captura muestra un error del compilador.

Tipos de datos de parámetros

STRING y STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En este ejemplo, si $e.principal.hostname contiene “aaa1bbaa2”, lo siguiente sería verdadero, ya que la función muestra la primera instancia. En este ejemplo, no hay grupos de captura.

"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")
Ejemplo 2

En este ejemplo, se capta todo lo que está después del símbolo @ en un correo electrónico. Si el campo $e.network.email.from es test@google.com, el ejemplo muestra google.com. El siguiente ejemplo contiene un grupo de captura.

"google.com" = re.capture($e.network.email.from , "@(.*)")
Ejemplo 3

Si la expresión regular no coincide con ninguna subcadena en el texto, la función muestra una cadena vacía. Puedes omitir los eventos en los que no se produce ninguna coincidencia. Para ello, excluye la cadena vacía, lo cual es muy importante cuando usas re.capture() con una desigualdad:

// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")

// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")

re.replace

Compatible con:
re.replace(stringText, replaceRegex, replacementText)

Descripción

Realiza un reemplazo de expresiones regulares.

Esta función adopta tres argumentos:

  • stringText: Es la cadena original.
  • replaceRegex: Es la expresión regular que indica el patrón que se debe buscar.
  • replacementText: Es el texto que se insertará en cada coincidencia.

Muestra una nueva cadena derivada de la stringText original, en la que todas las subcadenas que coinciden con el patrón de replaceRegex se reemplazan por el valor en replacementText. Puedes usar dígitos con escape de barra inversa (\1 a \9) dentro de replacementText para insertar texto que coincida con el grupo entre paréntesis correspondiente en el patrón replaceRegex. Usa \0 para hacer referencia a todo el texto coincidente.

La función reemplaza las coincidencias que no se superponen y priorizará el reemplazo del primer caso encontrado. Por ejemplo, re.replace("banana", "ana", "111") muestra la string "b111na".

Tipos de datos de parámetros

STRING, STRING y STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En este ejemplo, se captura todo lo que está después del símbolo @ en un correo electrónico, se reemplaza com por org y, luego, se muestra el resultado. Observa el uso de funciones anidadas.

"email@google.org" = re.replace($e.network.email.from, "com", "org")
Ejemplo 2

En este ejemplo, se usan dígitos con escape de barra inversa en el argumento replacementText para hacer referencia a las coincidencias con el patrón replaceRegex.

"test1.com.google" = re.replace(
                       $e.principal.hostname, // holds "test1.test2.google.com"
                       "test2\.([a-z]*)\.([a-z]*)",
                       "\\2.\\1"  // \\1 holds "google", \\2 holds "com"
                     )
Ejemplo 3

Ten en cuenta los siguientes casos cuando trabajes con strings vacías y re.replace():

Usa una cadena vacía como replaceRegex:

// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")

Para reemplazar una cadena vacía, puedes usar "^$" como replaceRegex:

// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")

sample_rate

Compatible con:
optimization.sample_rate(byteOrString, rateNumerator, rateDenominator)

Descripción

Esta función determina si se debe incluir un evento según una estrategia de muestreo determinista. Esta función muestra lo siguiente:

  • true para una fracción de los valores de entrada, equivalente a (rateNumerator / rateDenominator), lo que indica que el evento se debe incluir en la muestra.
  • false: Indica que el evento no se debe incluir en la muestra.

Esta función es útil para situaciones de optimización en las que deseas procesar solo un subconjunto de eventos. Equivale a:

hash.fingerprint2011(byteOrString) % rateDenominator < rateNumerator

Tipos de datos de parámetros

  • byteOrString: Expresión que se evalúa como BYTE o STRING.
  • rateNumerator: “INT”
  • rateDenominator: 'INT'

Tipo de datos que se muestra

BOOL

Muestra de código

events:
    $e.metadata.event_type = "NETWORK_CONNECTION"
    $asset_id = $e.principal.asset.asset_id
    optimization.sample_rate($e.metadata.id, 1, 5) // Only 1 out of every 5 events

  match:
    $asset_id over 1h

  outcome:
    $event_count = count_distinct($e.metadata.id)
  // estimate the usage by multiplying by the inverse of the sample rate
    $usage_past_hour = sum(5.0 * $e.network.sent_bytes)

 condition:
  // Requiring a certain number of events after sampling avoids bias (e.g. a
  // device with just 1 connection will still show up 20% of the time and
  // if we multiply that traffic by 5, we'll get an incorrect estimate)
  $e and ($usage_past_hour > 1000000000) and $event_count >= 100

strings.base64_decode

Compatible con:
strings.base64_decode(encodedString)

Descripción

Muestra una cadena que contiene la versión decodificada en base64 de la cadena codificada.

Esta función toma una cadena codificada en base64 como argumento. Si encodedString no es una string codificada en base64 válida, la función muestra encodedString sin cambios.

Tipos de datos de parámetros

STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1
"test" = strings.base64_decode($e.principal.domain.name)

strings.coalesce

Compatible con:
strings.coalesce(a, b, c, ...)

Descripción

Esta función toma una cantidad ilimitada de argumentos y muestra el valor de la primera expresión que no se evalúa como una cadena vacía (por ejemplo, "valor distinto de cero"). Si todos los argumentos se evalúan como una cadena vacía, la llamada a función muestra una cadena vacía.

Los argumentos pueden ser literales, campos de eventos o llamadas a funciones. Todos los argumentos deben ser del tipo STRING. Si algún argumento es campos de evento, los atributos deben pertenecer al mismo evento.

Tipos de datos de parámetros

STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En el siguiente ejemplo, se incluyen variables de cadena como argumentos. La condición se evalúa como verdadera cuando (1) $e.network.email.from es suspicious@gmail.com o (2) $e.network.email.from está vacío y $e.network.email.to es suspicious@gmail.com.

"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
Ejemplo 2

En el siguiente ejemplo, se llama a la función coalesce con más de dos argumentos. Esta condición compara la primera dirección IP no nula del evento $e con los valores de la lista de referencia ip_watchlist. El orden en el que se fusionan los argumentos en esta llamada es el mismo que el orden en el que se enumeran en la condición de la regla:

  1. $e.principal.ip se evalúa primero.
  2. A continuación, se evaluará $e.src.ip.
  3. A continuación, se evaluará $e.target.ip.
  4. Por último, la string “Sin IP” se muestra como valor predeterminado si no se configuran los campos ip anteriores.
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
Ejemplo 3

En el siguiente ejemplo, se intenta combinar principal.hostname del evento $e1 y el evento $e2. Se mostrará un error del compilador porque los argumentos son variables de evento diferentes.

// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)

strings.concat

Compatible con:
strings.concat(a, b, c, ...)

Descripción

Muestra la concatenación de una cantidad ilimitada de elementos, cada uno de los cuales puede ser una cadena, un número entero o un número de punto flotante.

Si algún argumento es campos de evento, los atributos deben pertenecer al mismo evento.

Tipos de datos de parámetros

STRING, FLOAT, INT

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En el siguiente ejemplo, se incluye una variable de cadena y una variable de número entero como argumentos. Tanto principal.hostname como principal.port provienen del mismo evento, $e, y se concatenan para mostrar una cadena.

"google:80" = strings.concat($e.principal.hostname, ":", $e.principal.port)
Ejemplo 2

En el siguiente ejemplo, se incluye una variable de string y un literal de string como argumentos.

"google-test" = strings.concat($e.principal.hostname, "-test") // Matches the event when $e.principal.hostname = "google"
Ejemplo 3

En el siguiente ejemplo, se incluye una variable de string y un literal de número de punto flotante como argumentos. Cuando se representan como cadenas, los números de punto flotante que son números enteros reciben formato sin el punto decimal (por ejemplo, 1.0 se representa como "1"). Además, los números de punto flotante que superan los dieciséis dígitos decimales se truncan al decimosexto decimal.

"google2.5" = strings.concat($e.principal.hostname, 2.5)
Ejemplo 4

En el siguiente ejemplo, se incluye una variable de string, un literal de string, una variable de número entero y un literal de número de punto flotante como argumentos. Todas las variables provienen del mismo evento, $e, y se concatenan con los literales para mostrar una string.

"google-test802.5" = strings.concat($e.principal.hostname, "-test", $e.principal.port, 2.5)
Ejemplo 5

En el siguiente ejemplo, se intenta concatenar principal.port desde el evento $e1, con principal.hostname desde el evento $e2. Se mostrará un error de compilador porque los argumentos son variables de evento diferentes.

// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

strings.to_lower

Compatible con:
strings.to_lower(stringText)

Descripción

Esta función toma una cadena de entrada y muestra una cadena después de cambiar todos los caracteres a minúsculas.

Tipos de datos de parámetros

STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En el siguiente ejemplo, se muestra true.

"test@google.com" = strings.to_lower($e.network.email.to)

strings.to_upper

Compatible con:
strings.to_upper(stringText)

Descripción

Esta función toma una cadena de entrada y muestra una cadena después de cambiar todos los caracteres a mayúsculas.

Tipos de datos de parámetros

STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En el siguiente ejemplo, se muestra true.

"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)

timestamp.current_seconds

Compatible con:
timestamp.current_seconds()

Descripción

Muestra un número entero que representa la hora actual en segundos Unix. Esto es aproximadamente igual a la marca de tiempo de detección y se basa en el momento en que se ejecuta la regla.

Tipos de datos de parámetros

NONE

Tipo de datos que se muestra

INT

Muestras de código

Ejemplo 1

En el siguiente ejemplo, se muestra true si el certificado venció por más de 24 horas. Calcula la diferencia de tiempo restando los segundos Unix actuales y, luego, comparando con un operador mayor que.

86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after

timestamp.get_date

Compatible con:
timestamp.get_date(unix_seconds [, time_zone])

Descripción

Esta función muestra una cadena con el formato YYYY-MM-DD, que representa el día en que se encuentra una marca de tiempo.

  • unix_seconds es un número entero que representa la cantidad de segundos pasados del tiempo de Unix, como $e.metadata.event_timestamp.seconds, o un marcador de posición que contiene ese valor.
  • time_zone es opcional y es una cadena que representa una zona horaria. Si se omite, el valor predeterminado es "GMT". Puedes especificar zonas horarias con literales de string. Las opciones son las siguientes:
    • El nombre de la base de datos de TZ, por ejemplo, “America/Los_Angeles”. Para obtener más información, consulta la columna"TZ Database Name" de esta página.
    • El desplazamiento de la zona horaria desde UTC, en el formato (+|-)H[H][:M[M]], por ejemplo: “-08:00”.

Aquí hay ejemplos de especificadores válidos de zona horaria, que puedes pasar como el segundo argumento a las funciones de extracción de tiempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de datos de parámetros

INT, STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En este ejemplo, se omite el argumento time_zone, por lo que el valor predeterminado es "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts) = "2024-02-19"
Ejemplo 2

En este ejemplo, se usa un literal de string para definir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts, "America/Los_Angeles") = "2024-02-20"

timestamp.get_minute

Compatible con:
timestamp.get_minute(unix_seconds [, time_zone])

Descripción

Esta función muestra un número entero en el rango [0, 59] que representa el minuto.

  • unix_seconds es un número entero que representa la cantidad de segundos pasados del tiempo de Unix, como $e.metadata.event_timestamp.seconds, o un marcador de posición que contiene ese valor.
  • time_zone es opcional y es una cadena que representa una zona horaria. Si se omite, el valor predeterminado es "GMT". Puedes especificar zonas horarias con literales de string. Las opciones son las siguientes:
    • El nombre de la base de datos de TZ, por ejemplo, “America/Los_Angeles”. Para obtener más información, consulta la columna"TZ Database Name" de esta página.
    • El desplazamiento de la zona horaria desde UTC, en el formato (+|-)H[H][:M[M]], por ejemplo: “-08:00”.

Estos son ejemplos de especificadores time_zone válidos, que puedes pasar como segundo argumento a las funciones de extracción de tiempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de datos de parámetros

INT, STRING

Tipo de datos que se muestra

INT

Muestras de código

Ejemplo 1

En este ejemplo, se omite el argumento time_zone, por lo que el valor predeterminado es "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Ejemplo 2

En este ejemplo, se usa un literal de string para definir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_hour

Compatible con:
timestamp.get_hour(unix_seconds [, time_zone])

Descripción

Esta función muestra un número entero en el rango [0, 23] que representa la hora.

  • unix_seconds es un número entero que representa la cantidad de segundos pasados del tiempo de Unix, como $e.metadata.event_timestamp.seconds, o un marcador de posición que contiene ese valor.
  • time_zone es opcional y es una cadena que representa una zona horaria. Si se omite, el valor predeterminado es "GMT". Puedes especificar zonas horarias con literales de string. Las opciones son las siguientes:
    • El nombre de la base de datos de TZ, por ejemplo, “America/Los_Angeles”. Para obtener más información, consulta la columna"TZ Database Name" de esta página.
    • El desplazamiento de la zona horaria desde UTC, en el formato (+|-)H[H][:M[M]], por ejemplo: “-08:00”.

Estos son ejemplos de especificadores time_zone válidos, que puedes pasar como segundo argumento a las funciones de extracción de tiempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de datos de parámetros

INT, STRING

Tipo de datos que se muestra

INT

Muestras de código

Ejemplo 1

En este ejemplo, se omite el argumento time_zone, por lo que el valor predeterminado es "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Ejemplo 2

En este ejemplo, se usa un literal de string para definir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_day_of_week

Compatible con:
timestamp.get_day_of_week(unix_seconds [, time_zone])

Descripción

Esta función muestra un número entero en el rango [1, 7] que representa el día de la semana que comienza con el domingo. Por ejemplo, 1 = domingo y 2 = lunes.

  • unix_seconds es un número entero que representa la cantidad de segundos pasados del tiempo de Unix, como $e.metadata.event_timestamp.seconds, o un marcador de posición que contiene ese valor.
  • time_zone es opcional y es una cadena que representa una zona horaria. Si se omite, el valor predeterminado es "GMT". Puedes especificar zonas horarias con literales de string. Las opciones son las siguientes:
    • El nombre de la base de datos de TZ, por ejemplo, “America/Los_Angeles”. Para obtener más información, consulta la columna"TZ Database Name" de esta página.
    • El desplazamiento de la zona horaria desde UTC, en el formato (+|-)H[H][:M[M]], por ejemplo: “-08:00”.

Aquí hay ejemplos de especificadores válidos de zona horaria, que puedes pasar como el segundo argumento a las funciones de extracción de tiempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de datos de parámetros

INT, STRING

Tipo de datos que se muestra

INT

Muestras de código

Ejemplo 1

En este ejemplo, se omite el argumento time_zone, por lo que el valor predeterminado es "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts) = 6
Ejemplo 2

En este ejemplo, se usa un literal de string para definir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6

timestamp.get_timestamp

Compatible con:
timestamp.get_timestamp(unix_seconds, optional timestamp_format, optional timezone)

Descripción

Esta función muestra una cadena con el formato YYYY-MM-DD, que representa el día en que se encuentra una marca de tiempo.

  • unix_seconds es un número entero que representa la cantidad de segundos pasados del tiempo de Unix, como $e.metadata.event_timestamp.seconds, o un marcador de posición que contiene ese valor.
  • timestamp_format es opcional y es una cadena que representa el formato de la marca de tiempo. Si se omite, el valor predeterminado es %F %T. Puedes especificar el formato con literales de string. Para conocer las opciones, consulta Elementos de formato para partes de fecha y hora
  • time_zone es opcional y es una cadena que representa una zona horaria. Si se omite, el valor predeterminado es GMT. Puedes especificar zonas horarias con literales de string. Las opciones son las siguientes:
    • El nombre de la base de datos de la zona horaria de IANA (TZ), por ejemplo, America/Los_Angeles. Para obtener más información, consulta la lista de zonas horarias de la base de datos tz en Wikipedia.
    • El desplazamiento de la zona horaria desde UTC, en el formato (+|-)H[H][:M[M]], por ejemplo: “-08:00”.

Estos son ejemplos de especificadores time_zone válidos, que puedes pasar como segundo argumento a las funciones de extracción de tiempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de datos de parámetros

INT, STRING y STRING

Tipo de datos que se muestra

STRING

Muestras de código

Ejemplo 1

En este ejemplo, se omite el argumento time_zone, por lo que el valor predeterminado es GMT.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts) = "2024-02-22 10:43:51"
Ejemplo 2

En este ejemplo, se usa un literal de string para definir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts, "%F %T", "America/Los_Angeles") = "2024-02-22 10:43:51"
Ejemplo 3

En este ejemplo, se usa un literal de string para definir timestamp_format.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts, "%Y-%m", "GMT") = "2024-02"

timestamp.get_week

Compatible con:
timestamp.get_week(unix_seconds [, time_zone])

Descripción

Esta función muestra un número entero en el rango [0, 53] que representa la semana del año. Las semanas comienzan con el domingo. Las fechas anteriores al primer domingo del año están en la semana 0.

  • unix_seconds es un número entero que representa la cantidad de segundos pasados del tiempo de Unix, como $e.metadata.event_timestamp.seconds, o un marcador de posición que contiene ese valor.
  • time_zone es opcional y es una cadena que representa una zona horaria. Si se omite, el valor predeterminado es "GMT". Puedes especificar zonas horarias con literales de string. Las opciones son las siguientes:
    • El nombre de la base de datos de TZ, por ejemplo, “America/Los_Angeles”. Para obtener más información, consulta la columna"TZ Database Name" de esta página.
    • El desplazamiento de la zona horaria desde UTC, en el formato (+|-)H[H][:M[M]], por ejemplo: “-08:00”.

Estos son ejemplos de especificadores time_zone válidos, que puedes pasar como segundo argumento a las funciones de extracción de tiempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de datos de parámetros

INT, STRING

Tipo de datos que se muestra

INT

Muestras de código

Ejemplo 1

En este ejemplo, se omite el argumento time_zone, por lo que el valor predeterminado es "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts) = 0
Ejemplo 2

En este ejemplo, se usa un literal de string para definir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts, "America/Los_Angeles") = 0

Función en la asignación del marcador de posición

Puedes asignar el resultado de una llamada a función a un marcador de posición en la sección events. Por ejemplo:

$placeholder = strings.concat($e.principal.hostname, "my-string").

Luego, puedes usar las variables de marcador de posición en las secciones match, condition y outcome. Sin embargo, existen dos limitaciones con respecto a la asignación de funciones a marcadores de posición:

  1. Cada marcador de posición en la asignación de marcador de posición de función debe asignarse a una expresión que contenga un campo de evento. Por ejemplo, los siguientes ejemplos son válidos:

    $ph1 = $e.principal.hostname
    $ph2 = $e.src.hostname
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.concat($ph2, ".com")
    
    $ph1 = $e.network.email.from
    $ph2 = strings.concat($e.principal.hostname, "@gmail.com")
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.to_lower($ph2)
    

    Sin embargo, el siguiente ejemplo no es válido:

    $ph1 = strings.concat($e.principal.hostname, "foo")
    $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
    
  2. La llamada a función debe depender de un solo evento. Sin embargo, se puede usar más de un campo del mismo evento en los argumentos de llamada a función. Por ejemplo, se puede usar lo siguiente:

    $ph = strings.concat($event.principal.hostname, "string2")

    $ph = strings.concat($event.principal.hostname, $event.src.hostname)

    Sin embargo, los siguientes datos no son válidos:

    $ph = strings.concat("string1", "string2")

    $ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)

Sintaxis de las listas de referencia

Consulta nuestra página sobre listas de referencia para obtener más información sobre el comportamiento y la sintaxis de las listas de referencias.

Puedes usar listas de referencia en las secciones events o outcome. Esta es la sintaxis que necesitas para usar varios tipos de listas de referencia en una regla:

// STRING reference list
$e.principal.hostname in %string_reference_list

// REGEX reference list
$e.principal.hostname in regex %regex_reference_list

// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list

También puedes usar el operador not y el operador nocase con listas de referencia, como se muestra en el siguiente ejemplo:

// Exclude events whose hostnames match substrings in my_regex_list.
not $e.principal.hostname in regex %my_regex_list

// Event hostnames must match at least 1 string in my_string_list (case insensitive).
$e.principal.hostname in %my_string_list nocase

El operador nocase es compatible con listas STRING y REGEX.

Por motivos de rendimiento, Detection Engine restringe el uso de la lista de referencia.

  • Cantidad máxima de declaraciones in en una regla, con o sin operadores especiales: 7
  • Cantidad máxima de declaraciones in con el operador regex: 4
  • Cantidad máxima de declaraciones in con el operador cidr: 2

Verificación de tipos

Google Security Operations verifica el tipo de tu sintaxis YARA-L a medida que creas reglas en la interfaz. Los errores de comprobación de tipos que se muestran te ayudan a revisar la regla para garantizar que funcione como se espera.

Los siguientes son ejemplos de predicados no válidos:

// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"

// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"

Muestreo de eventos de detección

Las detecciones de reglas de varios eventos contienen muestras de eventos para proporcionar contexto sobre los eventos que causaron la detección. Hay un límite de hasta 10 muestras de eventos para cada variable de evento definida en la regla. Por ejemplo, si una regla define 2 variables de evento, cada detección puede tener hasta 20 muestras de eventos. El límite se aplica a cada variable del evento por separado. Si una variable de evento tiene 2 eventos aplicables en esta detección, y la otra variable tiene 15 eventos aplicables, la detección resultante contiene 12 muestras de eventos (2 + 10).

Las muestras de eventos que superen el límite se omitirán de la detección.

Si deseas obtener más información sobre los eventos que causaron tu detección, puedes usar agregaciones en la sección de resultados para generar información adicional en tu detección.

Si ves las detecciones en la IU, puedes descargar todas las muestras de eventos para una detección. Para obtener más información, consulta Descarga eventos.