Sintaxis de la sección de resultados

Compatible con:

La sección outcome de una consulta de YARA-L define las variables de resultado que especifican el resultado de una consulta de búsqueda y de panel, y el contexto y la información adicionales para una detección cuando se activa una regla. Estas variables se pueden usar para varios propósitos, como mostrar datos relevantes en paneles y crear puntuaciones de riesgo.

Define outcome section

Usa el carácter $, seguido del nombre de una variable, para definir una variable de resultado en la sección outcome de una sola consulta. Puedes 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 agregan en función de cada detección.

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

Esta regla busca accesos fallidos desde una ubicación nueva:

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 accesos fallidos, cuenta las IPs distintas y obtiene la hora en que se produjo el error.

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

Si incluyes y completas la variable de resultado especial $risk_score, su valor (número entero o flotante) se muestra en la página Alertas e IoC para las alertas que genera la consulta.

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

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

  • Si la consulta 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.

Variable de resultado risk_score

El análisis de riesgos de Google SecOps asocia automáticamente las detecciones y las alertas con las entidades relacionadas con esa detección o alerta. La variable de resultado risk_score se usa para asignar una cantidad de riesgo. Si no se establece este valor, se usa el valor predeterminado de detección o alerta. Puedes configurar valores predeterminados en Configuración.

Para garantizar la coherencia en toda la plataforma, te recomendamos que uses los siguientes rangos de puntuación cuando asignes 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 Rango de puntuaciones Descripción Ejemplo
Alerta: Crítica 90 - 100 Vulneración activa con el potencial de tener un impacto más allá de una sola cuenta de usuario o un extremo. Requiere revisión inmediata. Mimikatz se ejecutó en el controlador de dominio.
Alertas: Alta De 80 a 89 Vulneración activa de un solo extremo o entidad. Debería recibir una revisión inmediata. Servidor de producción que llama a un C2 conocido y reciente
Alertas: Media De 50 a 79 Posible problema de seguridad que requiere investigación. No se confirmó ningún ataque, pero es posible derivar el caso. Una credencial expuesta, sin indicios de uso inadecuado.
Sin alertas: Baja De 20 a 49 Es un evento de seguridad de bajo impacto que, cuando se combina con otros indicadores u observaciones, podría provocar un incidente más significativo. Por lo general, no se necesita una revisión y se puede combinar con otras detecciones a través de reglas compuestas para crear una alerta. Análisis de puertos internos.
Observaciones que no generan alertas 1 - 19 Por lo general, son detecciones basadas en información que tienen como objetivo generar un conocimiento de la situación de una amenaza. Por lo general, no requiere revisión; se puede combinar con otras detecciones a través de reglas compuestas para generar alertas. Un evento de acceso, sin indicios de uso inadecuado.

Debido a que risk_score es una variable de resultado, tus reglas pueden expresar matices según factores como la inteligencia contra amenazas o algunas otras condiciones simultáneas.

Las puntuaciones de riesgo de las entidades se pueden usar para generar alertas basadas en el riesgo casi en tiempo real. Para obtener más información, consulta la descripción general de las estadísticas de riesgo.

Variable de resultado risk_entity_to_score

De forma predeterminada, Google SecOps asigna una puntuación de riesgo de detección a todas las entidades de los eventos de muestra. También asigna la puntuación a todas las entidades capturadas en las secciones match y outcome de la regla. Para asignar la puntuación de riesgo a entidades específicas, especifica la variable de resultado risk_entity_to_score además de risk_score. La puntuación de riesgo admite las entidades user y asset. No admite los tipos de entidades RESOURCE ni GROUP.

Puedes crear varias variables risk_entity_to_score agregando una cadena única a la variable y asignar la puntuación de riesgo a entidades específicas. Por ejemplo:

$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid

Estas variables de resultado asignan el risk_score especificado en la sección outcome de la regla a las entidades $e.principal.asset.hostname y $e.target.user.userid.

Ejemplo: La regla detecta accesos a cuentas de administrador

Esta regla detecta los accesos exitosos a cuentas de administrador con privilegios elevados. Usa la palabra clave risk_entity_to_score para orientar de forma explícita al usuario específico que accede. Con esta variable, la detección garantiza que la puntuación de riesgo calculada se aplique solo a ese usuario y no a otras entidades involucradas en el evento, como la dirección IP de origen.

Para obtener detalles sobre cómo escribir una regla de varios eventos, consulta Regla de varios eventos.

rule suspicious_admin_privilege_escalation {
 // This rule matches single events. Rules can also match multiple events within
 // the same time window.

 meta:
   // Allows for storage of arbitrary key-value pairs of rule details, such as 
   // who wrote it, what it detects on, and version control.
   // The "author" and "severity" fields are special, since they are used as
   // columns on the rules dashboard. To sort based on these fields on the 
   // dashboard, add them here.
   // Severity value should be "Low", "Medium", or "High"
   author = "analyst123"
   description = "Detects suspicious login to critical admin accounts."
   severity = "HIGH"

 events:
   $e.metadata.event_type = "USER_LOGIN"
   $e.target.user.attribute.roles.name = "ADMIN"
   $e.security_result.summary = "Successful login with high-privilege access"

 outcome:
   // Multi-event rules require an aggregation function
   // For example, risk_score = max(0)
   // See https://docs.cloud.google.com/chronicle/docs/yara-l/yara-l-2-0-examples#outcome_conditionals_example_rule
   $risk_score = 80
   $risk_entity_to_score = $e.target.user.userid
   $source_ip = array_distinct($e.principal.ip)

 condition:
   $e
}

Ejemplo: La regla supervisa las conexiones de red internas

Esta regla verifica el movimiento lateral identificando las conexiones de red entre los segmentos de red internos. Usa $risk_entity_to_score prefix para asignar riesgo a varias entidades dentro de una sola detección. Se actualizan las puntuaciones de riesgo del host que inicia la acción ($risk_entity_to_score_source_asset) y del usuario objetivo ($risk_entity_to_score_targeted_user). El motor de riesgo registra otras variables de resultado que no usan este prefijo específico para el contexto, pero las ignora (sus puntuaciones de riesgo siguen siendo las mismas).

Para obtener detalles sobre cómo escribir una regla de varios eventos, consulta Regla de varios eventos y Regla de ejemplo de condicionales de resultado.

rule lateral_movement_network_connection {
 // This rule matches single events. You can also match multiple events within
 // the same time window.

 meta:
   // Allows for storage of arbitrary key-value pairs of rule details (for 
   // example, who wrote it, what it detects on, and version control).
   // The "author" and "severity" fields are special, since they are used as
   // columns on the rules dashboard. To sort based on these fields on the 
   // dashboard, add them here. Severity value should be "Low", "Medium" or "High"
   author = "analyst123"
   description = "Detects lateral movement attempts between internal segments."
   severity = "MEDIUM"

 events:
   $e.metadata.event_type = "NETWORK_CONNECTION"
   $e.principal.asset.hostname != ""
   $e.target.user.userid != ""
   // Can also use: $e.target.ip = /10\..*/
   net.ip_in_range_cidr($e.target.ip, "10.0.0.0/8")

 outcome:
   // Multi-event rules require an aggregation function
   // for example, risk_score = max(0)
   // See https://docs.cloud.google.com/chronicle/docs/yara-l/yara-l-2-0-examples#outcome-conditionals-example-rule
   $risk_score = 50
   $risk_entity_to_score_source_asset = $e.principal.asset.hostname
   $risk_entity_to_score_targeted_user = $e.target.user.userid
   $target_ip_info = array_distinct($e.target.ip)

 condition:
   $e
}

Tipos de datos de las variables de resultado

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

  • integer
  • floats
  • cadena
  • listas de números enteros
  • listas de números de punto flotante
  • 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, devuelve THEN_CLAUSE; de lo contrario, devuelve ELSE_CLAUSE".

BOOL_CLAUSE debe evaluarse como un valor booleano. Una expresión BOOL_CLAUSE adopta 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)

  • Es la variable de marcador de posición que se definió 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)

  • Busca en una lista de referencia:

    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)

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 la ELSE_CLAUSE si el tipo de datos es un número entero o un número de punto flotante. Si se omite, la 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 una cadena 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 el tipo de datos de número entero o de número de punto 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 cálculo de ejemplo 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 y cuando cada operando y toda la expresión aritmética se agreguen correctamente (consulta Agregaciones):

  • Campos de eventos numéricos
  • Variables de marcador de posición numéricas definidas en la sección events
  • Variables de resultado numéricas definidas en la sección outcome
  • Funciones que devuelven ints o floats
  • Agregaciones que devuelven ints o floats

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

Los literales de números enteros estándar se establecen de forma predeterminada en números enteros de 64 bits con firma (INT64), que son incompatibles con los campos de UDM de números enteros de 64 bits sin firma (UINT64), como network.received_bytes, network.sent_bytes y principal.file.size. Combinar estos tipos en operaciones aritméticas (+, -, *) o de módulo (%) puede causar un error de tiempo de ejecución en la sección outcome. Para resolver este problema, usa cast.as_int() o cast.as_uint() para que coincidan con los tipos de números enteros. Se requiere una conversión explícita para el operador %. Para las operaciones aritméticas, también puedes forzar que las constantes de números enteros se comporten como números de punto flotante con literales de punto flotante, como 2.0 o 100.0, o coerción de división, como (2/1), en expresiones sin otros operadores / en la misma línea. Para obtener más información, consulta Aritmética con campos de eventos sin firma.

Variables de marcador 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 consulta. En este ejemplo, supongamos que $email_sent_bytes se definió en la sección de eventos de la regla:

Ejemplo: Evento único sin sección de coincidencia

// 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: Evento múltiple con sección de coincidencia

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.0
    + $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 derivar otras variables de resultado, de manera similar 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 variable de resultado 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 consulta. Cuando se usan en una expresión de asignación, las variables de resultado no se deben agregar (consulta Agregaciones).

En el siguiente ejemplo, la variable de resultado $risk_score deriva 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 en el lado derecho de una asignación de resultado, excepto en las siguientes expresiones:

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

Agregaciones

Los campos de eventos recurrentes son valores no escalares. Es decir, una sola variable apunta a múltiples 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. Mientras que la variable de campo de evento $e.principal.hostname no es un campo repetido y solo tiene 1 valor (es decir, un valor escalar).

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

Ejemplo: Agrupa eventos con una sección de coincidencia y un campo no repetido

La siguiente consulta agrupa los eventos con 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 período de 5 minutos en el que se ejecute la consulta puede contener cero, uno o muchos eventos. La sección de resultados opera en todos los eventos de una ventana de coincidencia. 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. 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.

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 producir un solo valor escalar. En una sección de resultados, los siguientes son valores no escalares y se deben agregar:

  • Campos de eventos (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 eventos recurrentes cuando la consulta no usa una sección match
  • Marcadores de posición de eventos recurrentes 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 unir 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 unido, lo que las hace innecesarias. Una excepción es la agregación array(), que puedes usar para convertir de forma explícita un valor escalar en un array.

Las variables de resultado se tratan como agregaciones: no se deben volver a agregar cuando se hace 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 punto flotante.
min() Muestra el valor mínimo de todos los valores posibles. Solo funciona con números enteros y de punto flotante.
sum() Genera la suma de todos los valores posibles. Solo funciona con números enteros y de punto flotante.
count_distinct() Recopila todos los valores posibles y, luego, genera el recuento de valores posibles distintos.
count() Se comporta como `count_distinct()`, pero devuelve un recuento no distinto de los valores posibles.
array_distinct() Recopila todos los valores distintos posibles y, luego, genera una lista de estos valores. Primero se aplica la anulación de duplicación para producir una lista distinta y, luego, se aplica el truncamiento. En la Búsqueda, la lista se trunca a un máximo de 1,000 elementos aleatorios. En Paneles y Reglas, la lista se trunca a un máximo de 25 elementos aleatorios.
array() Se comporta como array_distinct(), pero devuelve una lista de valores no distintos. En la Búsqueda, la lista se trunca a un máximo de 1,000 elementos aleatorios. En Paneles y Reglas, la lista se trunca a un máximo de 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.

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

Dado que la sección "condition" 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"]

Limitaciones

  • La sección outcome no puede hacer referencia a una nueva variable de marcador de posición 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.

  • La sección outcome 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 de evento ya se definió en la sección events.

  • La sección outcome solo puede correlacionar variables de eventos que ya se hayan correlacionado en la sección events. Las correlaciones se producen cuando se igualan dos campos de eventos de diferentes variables de eventos.

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

Consulta Crea estadísticas adaptadas al contexto para obtener detalles sobre la anulación de duplicación de detecciones con la sección outcome.

¿Qué sigue?

Información adicional

¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.