Sintaxis de la sección de resultados

Disponible en:

La sección outcome de una consulta de YARA-L define variables de resultado que especifican la salida de una consulta de búsqueda y de un panel de control, así como contexto e información adicionales para una detección cuando se activa una regla. Estas variables se pueden usar con varios fines, como mostrar datos relevantes en los paneles de control y crear puntuaciones de riesgo.

Definir la sección de resultados

Use el carácter $ seguido del nombre de una variable para definir una variable de resultado en la sección outcome de una sola consulta. Puede definir hasta 20 variables de resultado. Los nombres de las variables son arbitrarios. En el caso de las reglas, los valores de los resultados se calculan y se agregan en función de cada detección.

A cada variable de resultado se le asigna un valor mediante una expresión.

Esta regla busca inicios de sesión fallidos desde una nueva ubicación:

rule failed_logins
{
  meta:
   author = "Security Team"
   description = "Detects multiple failed user logins within 10-minute windows."
   severity = "HIGH"

  events:
   $e.metadata.event_type = "USER_LOGIN"
   $e.security_result.action = "FAIL"
   $user = $e.target.user.userid

  match:
   $user over 10m

  outcome:
   $failed_login_count = count($e.metadata.id)
   $first_fail_time = min($e.metadata.event_timestamp.seconds)

  condition:
   #e >= 5
}

La sección outcome realiza agregaciones en las variables de evento y de marcador de posición: cuenta los inicios de sesión fallidos, cuenta las IPs distintas y obtiene la hora en la que se produjo el fallo.

outcome:
   $failed_login_count = count($e.metadata.id)
   $first_fail_time = min($e.metadata.event_timestamp.seconds)

Si incluye y rellena la variable especial $risk_score outcome, su valor (entero o flotante) se muestra en la página Alerts and IoCs (Alertas e IoCs) de las alertas generadas por la consulta.

Si no incluye una variable $risk_score en la sección outcome de una consulta, se asignará uno de los siguientes valores predeterminados:

  • Si la consulta está configurada para generar una alerta, $risk_score se asigna el valor 40.

  • Si la consulta no está configurada para generar una alerta, $risk_score tiene el valor 15.

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

Variable de resultado de la puntuación de riesgo

Google SecOps Risk Analytics asocia automáticamente las detecciones y las alertas a las entidades relacionadas con ellas. La variable de resultado risk_score se usa para asignar una cantidad de riesgo. Si no se define este valor, se usa el valor de detección o alerta predeterminado. Puedes configurar valores predeterminados en Ajustes.

Para que haya coherencia en toda la plataforma, te recomendamos que utilices los siguientes intervalos de puntuación al asignar un risk_score a tus detecciones personalizadas. Esta alineación ayuda a estandarizar la priorización de alertas y los flujos de trabajo de respuesta.

Gravedad Intervalo de puntuación Descripción Ejemplo
Alertas - Críticas 90 - 100 Compromiso activo con el potencial de tener un impacto que vaya más allá de una sola cuenta de usuario o endpoint. Requiere una revisión inmediata. Mimikatz se ha ejecutado en el controlador de dominio.
Alertas - Alta 80 - 89 Compromiso activo de un solo endpoint o entidad. Debería recibir una revisión inmediata. El servidor de producción llama a un C2 reciente y conocido.
Alertas - Medio 50 - 79 Posible problema de seguridad que requiere una investigación. No se ha confirmado ninguna vulneración, pero es posible que se derive el caso. Una credencial expuesta sin indicios de uso inadecuado.
Sin alertas - Bajo 20 - 49 Evento de seguridad de bajo impacto que, cuando se combina con otros indicadores u observaciones, podría dar lugar a un incidente más importante. Por lo general, no es necesario revisarlo. Se puede combinar con otras detecciones mediante reglas compuestas para crear una alerta. Análisis de puertos internos.
Observaciones sin alertas 1 - 19 Por lo general, se trata de detecciones basadas en información cuyo objetivo es crear una conciencia situacional de una amenaza. Por lo general, no requiere una revisión. Se puede combinar con otras detecciones mediante reglas compuestas para generar alertas. Un evento de inicio de sesión, sin signos de uso inadecuado.

Como risk_score es una variable de resultado, tus reglas pueden expresar matices en función de factores como la información sobre amenazas u otras condiciones simultáneas.

Las puntuaciones de riesgo de entidades se pueden usar para generar alertas basadas en el riesgo prácticamente en tiempo real. Para obtener más información, consulta el artículo Descripción general de Risk Analytics.

Tipos de datos de variables de resultados

Cada variable de resultado puede tener un tipo de datos diferente, que se determina mediante la expresión utilizada para calcularla. En Google SecOps se admiten los siguientes tipos de datos de resultados:

  • entero
  • flotantes
  • cadena
  • 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. Las condicionales se especifican mediante 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 true, devuelve THEN_CLAUSE; de lo contrario, devuelve ELSE_CLAUSE".

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

  • Nombres de campos de UDM con operador de comparación:

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

  • Variable de marcador de posición definida en la sección events:

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

  • Otra variable de resultado definida en la sección outcome:

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

  • Funciones que devuelven un valor booleano:

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

  • Buscar en una lista de referencias:

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

  • Comparación de agregaciones:

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

Las cláusulas THEN_CLAUSE y ELSE_CLAUSE deben ser del mismo tipo de datos. Admitimos números enteros, números de coma flotante y cadenas.

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

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

Debe proporcionar la cláusula ELSE si el tipo de datos es una cadena o si la cláusula THEN es una variable de marcador de posición o una variable de resultado.

Operaciones matemáticas

Puede usar operaciones matemáticas para calcular el tipo de datos entero o flotante en las secciones outcome y events de una consulta. Google Security Operations admite la suma, la resta, la multiplicación, la división y el 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))

Se permiten operaciones matemáticas en los siguientes tipos de operandos, siempre que cada operando y toda la expresión aritmética estén agregados correctamente (consulta Agregaciones):

  • Campos de evento numéricos
  • Variables de marcador de posición numéricas definidas en la sección events
  • Variables de resultados numéricas definidas en la sección outcome
  • Funciones que devuelven números enteros o de coma flotante
  • Agregaciones que devuelven números enteros o de coma flotante

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

Variables de marcador de posición en los resultados

Al calcular las variables de resultado, puede usar variables de marcador de posición que se hayan definido en la sección de eventos de su consulta. En este ejemplo, supongamos que $email_sent_bytes se ha definido en la sección de eventos de la regla:

Ejemplo: evento único sin sección de coincidencias

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

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: multi-event con sección de coincidencias

match:
  // This is a multi event query 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 resultados

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

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

Ejemplo: variable de resultado derivada de otra variable de resultado

match:
  // This is a multi event query 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 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 de la parte derecha de una asignación de resultado, excepto en las siguientes expresiones:

  • Agregaciones
  • Arrays.length() llamadas de funciones
  • Con modificadores any o all

Agregaciones

Los campos de evento repetidos son valores no escalares. Es decir, una sola variable apunta a varios valores. Por ejemplo, la variable de 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 de campo de evento $e.principal.hostname no es un campo repetido y solo tiene un valor (es decir, un valor escalar).

Del mismo modo, tanto los campos de evento no repetidos como los repetidos que se usan en la sección outcome de una consulta con una ventana de coincidencia son valores no escalares.

Ejemplo: agrupar eventos con una sección de coincidencias y un campo no repetido

La siguiente consulta agrupa eventos mediante una sección `match` y hace referencia a un campo de evento no repetido en la sección `outcome`:

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

Cualquier ventana de 5 minutos durante la que se ejecute la consulta puede contener cero, uno o muchos eventos. La sección de resultados funciona con todos los eventos de una ventana de partido. Cualquier variable de campo de evento a la que se haga referencia en la sección resultado puede apuntar a cero, uno o varios valores del campo en cada evento de la ventana de coincidencia. Por ejemplo, si una ventana de 5 minutos contiene 5 eventos $e, $e.principal.hostname en la sección de resultados apunta a cinco nombres de host diferentes. La variable de campo de evento $e.principal.hostname se trata como un valor no escalar en la sección outcome de esta consulta.

Como las variables de resultado siempre deben dar un único valor escalar, cualquier valor no escalar del que dependa una asignación de resultado debe agregarse para dar un único valor escalar. En una sección de resultados, los siguientes valores no son escalares y deben agregarse:

  • Campos de evento (repetidos o no repetidos) cuando la consulta usa una sección match
  • Marcadores de posición de eventos (repetidos o no repetidos) cuando la consulta usa una sección match
  • Campos de evento repetidos cuando la consulta no usa una sección match
  • Marcadores de posición de eventos repetidos cuando la consulta no usa una sección match

Los campos de eventos escalares, los marcadores de posición de eventos escalares y las constantes se pueden incluir en funciones de agregación en consultas que no incluyan una sección match. Sin embargo, en la mayoría de los casos, estas agregaciones devuelven el valor envuelto, por lo que no son necesarias. Una excepción es la agregación array(), que puedes usar para convertir explícitamente un valor escalar en una matriz.

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

Puedes usar las siguientes funciones de agregación:

Función de agregación Descripción
max() Genera el máximo de todos los valores posibles. Solo funciona con números enteros y de coma flotante.
min() Genera el mínimo de todos los valores posibles. Solo funciona con números enteros y de coma flotante.
sum() Genera la suma de todos los valores posibles. Solo funciona con números enteros y de coma flotante.
count_distinct() Recoge todos los valores posibles y, a continuación, muestra el recuento de valores posibles distintos.
count() Se comporta como `count_distinct()`, pero devuelve un recuento no distinto de los valores posibles.
array_distinct() Recoge todos los valores distintos posibles y, a continuación, genera una lista con estos valores. Recorta la lista de valores distintos a 1000 elementos aleatorios. Primero se aplica la deduplicación para obtener una lista de elementos únicos y, después, se aplica el truncamiento.
array() Se comporta como array_distinct(), pero devuelve una lista de valores no distintos. También trunca la lista de valores a 1000 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 hayan generado la detección.

Ejemplo: condición para varios eventos

A continuación se muestra un ejemplo de una condición para varios eventos. Si la sección de resultados y condiciones contiene 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

Como la sección `condition` requiere que haya más de un `event` por cada detección, las funciones de agregación operarán en varios eventos. Supongamos que los siguientes eventos han generado 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"

Los valores de los 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"]

Limitaciones

  • La sección outcome no puede hacer referencia a una variable de marcador de posición nueva que no se haya definido en la sección events o en la sección outcome.

  • La sección outcome no puede 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 haya usado en la sección events, siempre que la variable de evento a la que pertenece el campo de evento ya se haya definido en la sección events.

  • En la sección outcome solo se pueden correlacionar las variables de evento que ya se hayan correlacionado en la sección events. Las correlaciones se producen cuando se igualan dos campos de evento de variables de evento diferentes.

Consulta la descripción general de YARA-L 2.0 para ver ejemplos de la sección outcome.

Consulta la sección outcome del artículo Crear analíticas contextuales para obtener información sobre la deduplicación de detecciones.

Siguientes pasos

Información adicional

¿Necesitas más ayuda? Recibe respuestas de los miembros de la comunidad y de los profesionales de Google SecOps.