Sintaxe da seção de resultados
A seção outcome de uma consulta YARA-L define variáveis de resultado que especificam a saída de uma consulta de pesquisa e de painel, além de contexto e informações adicionais para uma detecção quando uma regra é acionada. Essas variáveis podem ser usadas para vários fins, como exibir dados relevantes em painéis e criar pontuações de risco.
Definir seção de resultados
Use o caractere $, seguido por um nome de variável, para definir uma variável de resultado na seção outcome de uma única consulta. É possível definir até 20 variáveis de resultado. Os nomes das variáveis são arbitrários. Para regras, os valores de resultado são calculados e agregados com base em cada detecção.
Cada variável de resultado recebe um valor usando uma expressão.
Esta regra pesquisa logins com falha em um novo local:
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
}
A seção outcome realiza agregações nas variáveis de evento e de marcador de posição: conta os logins com falha, conta os IPs distintos e recebe o horário em que a falha ocorreu.
outcome:
$failed_login_count = count($e.metadata.id)
$first_fail_time = min($e.metadata.event_timestamp.seconds)
Se você incluir e preencher a variável de resultado especial $risk_score, o valor dela (número inteiro ou flutuante) será exibido na página Alertas e IoCs para alertas gerados pela consulta.
Se você não incluir uma variável $risk_score na seção outcome de uma consulta, um dos seguintes valores padrão será definido:
Se a consulta estiver configurada para gerar um alerta,
$risk_scoreserá definido como 40.Se a consulta não estiver configurada para gerar um alerta,
$risk_scoreserá definido como 15.
O valor de $risk_score é armazenado no campo de UDM security_result.risk_score.
variável de resultado risk_score
O Google SecOps Risk Analytics associa automaticamente detecções
e alertas a entidades relacionadas a essa detecção ou alerta. A variável de resultado risk_score é usada para atribuir um valor de risco. Se esse valor não for definido,
o valor padrão de detecção ou alerta será usado. É possível configurar valores padrão
em "Configurações".
Para garantir a consistência em toda a plataforma, recomendamos usar os seguintes
intervalos de pontuação ao atribuir um risk_score às detecções personalizadas. Esse
alinhamento ajuda a padronizar os fluxos de trabalho de priorização e resposta de alertas.
| Gravidade | Intervalo de pontuação | Descrição | Exemplo |
|---|---|---|---|
| Alerta: crítico | 90 - 100 | Comprometimento ativo com potencial de impacto além de uma única conta de usuário ou endpoint. Requer revisão imediata. | Mimikatz executado no controlador do domínio. |
| Alerta: alto | 80 - 89 | Comprometimento ativo de um único endpoint ou entidade. Devem ser revisados imediatamente. | Servidor de Production chamando um C2 recente e conhecido. |
| Alertas: médio | 50 - 79 | Possível problema de segurança que requer investigação. Nenhum comprometimento confirmado, mas o encaminhamento é possível. | Uma credencial exposta, sem sinais de uso indevido. |
| Sem alertas: baixo | 20 - 49 | Ocorrência de segurança de baixo impacto que, quando combinada com outros indicadores ou observações, pode levar a um incidente mais significativo. Geralmente, não é necessária uma análise, mas pode ser combinada com outras detecções usando regras compostas para criar um alerta. | Verificação de porta interna. |
| Observações que não geram alertas | 1 - 19 | Em geral, detecções baseadas em informações destinadas a criar consciência situacional de uma ameaça. Geralmente não requer revisão. Pode ser combinada com outras detecções por meio de regras compostas para gerar alertas. | Um evento de login, sem sinais de uso indevido. |
Como risk_score é uma variável de resultado, suas regras podem expressar nuances
dependendo de fatores como inteligência contra ameaças ou outras condições simultâneas.
As pontuações de risco de entidades podem ser usadas para gerar alertas baseados em risco quase em tempo real. Para mais informações, consulte Visão geral da análise de risco.
Variável de resultado risk_entity_to_score
Por padrão, o Google SecOps atribui uma pontuação de risco de detecção a todas as entidades nos eventos de amostra. Ele também atribui a pontuação a todas as entidades
capturadas nas seções match e outcome da regra. Para atribuir a pontuação de risco a entidades específicas, especifique a variável de resultado risk_entity_to_score além de risk_score. A pontuação de riscos é compatível com entidades user e asset. Ele não é compatível com os tipos de entidade RESOURCE ou GROUP.
É possível criar várias variáveis risk_entity_to_score anexando uma string exclusiva
à variável e atribuindo a pontuação de risco a entidades específicas. Exemplo:
$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid
Essas variáveis de resultado atribuem o risk_score especificado na seção outcome da regra às entidades $e.principal.asset.hostname e $e.target.user.userid.
Exemplo: a regra detecta logins em contas de administrador
Essa regra detecta logins bem-sucedidos em contas de administrador com privilégios elevados. Ele
usa a palavra-chave risk_entity_to_score para segmentar explicitamente o usuário específico
que está fazendo login. Usando essa variável, a detecção garante que a pontuação de risco calculada se aplique apenas a esse usuário, e não a outras entidades envolvidas no evento, como o endereço IP de origem.
Para saber como escrever uma regra de vários eventos, consulte Regra de vários 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
}
Exemplo: a regra monitora conexões de rede internas
Essa regra verifica se há movimento lateral identificando conexões de rede entre
segmentos de rede internos. Ele usa $risk_entity_to_score prefix para atribuir risco
a várias entidades em uma única detecção. As pontuações de risco do host iniciador ($risk_entity_to_score_source_asset) e do usuário de destino ($risk_entity_to_score_targeted_user) são atualizadas. O mecanismo de risco registra outras variáveis de resultado que não usam esse prefixo específico para contexto, mas as ignora (as pontuações de risco permanecem as mesmas).
Para saber como escrever uma regra de vários eventos, consulte Regra de vários eventos e Exemplo de regra de condicionais 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 dados de variáveis de resultado
Cada variável de resultado pode ter um tipo de dado diferente, que é determinado pela expressão usada para calculá-la. Os seguintes tipos de dados de resultado são compatíveis com o Google SecOps:
- integer
- floats
- string
- listas de números inteiros
- listas de números de ponto flutuante
- listas de strings
Lógica condicional
É possível usar a lógica condicional para calcular o valor de um resultado. As condicionais são especificadas usando o seguinte padrão de sintaxe:
if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)
É possível ler uma expressão condicional como "se BOOL_CLAUSE for verdadeiro, retorne THEN_CLAUSE, caso contrário, retorne ELSE_CLAUSE".
BOOL_CLAUSE precisa ser avaliada como um valor booleano. Uma expressão BOOL_CLAUSE tem um formato semelhante às expressões na seção events. Por exemplo, ele pode conter:
Nomes de campo de UDM com operador de comparação:
if($context.graph.entity.user.title = "Vendor", 100, 0)Variável de marcador de posição que foi definida na seção
events:if($severity = "HIGH", 100, 0)Outra variável de resultado definida na seção
outcome:if($risk_score > 20, "HIGH", "LOW")Funções que retornam um booleano:
if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)Pesquise em uma lista de referência:
if($u.principal.hostname in %my_reference_list_name, 100, 0)Comparação de agregação:
if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)
THEN_CLAUSE e ELSE_CLAUSE precisam ser do mesmo tipo de dados. Oferecemos suporte a números inteiros, flutuantes e strings.
É possível omitir ELSE_CLAUSE se o tipo de dados for um número inteiro ou um ponto flutuante. Se omitida, a ELSE_CLAUSE será avaliada como 0. Exemplo:
`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`
É necessário fornecer a ELSE_CLAUSE se o tipo de dados for string ou se a THEN_CLAUSE for uma variável de marcador de posição ou de resultado.
Operações matemáticas
É possível usar operações matemáticas para calcular tipos de dados inteiros ou flutuantes nas seções outcome e events de uma consulta. O Google Security Operations aceita adição, subtração, multiplicação, divisão e módulo como operadores de nível superior em um cálculo.
O snippet a seguir é um exemplo de cálculo na seção outcome:
outcome:
$risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))
Operações matemáticas são permitidas nos seguintes tipos de operandos, desde que cada operando e toda a expressão aritmética sejam agregados corretamente (consulte Agregações):
- Campos de evento numéricos
- Variáveis de marcador de posição numéricas definidas na seção
events - Variáveis de resultado numéricas definidas na seção
outcome - Funções que retornam ints ou floats
- Agregações que retornam ints ou floats
O módulo não é permitido em números de ponto flutuante.
Os literais inteiros padrão usam como padrão inteiros de 64 bits assinados (INT64), que são
incompatíveis com campos de UDM de inteiros de 64 bits não assinados (UINT64), como
network.received_bytes, network.sent_bytes e principal.file.size.
Combinar esses tipos em operações aritméticas (+, -, *) ou de módulo (%)
pode causar um erro de tempo de execução na seção outcome. Para resolver esse problema, use
cast.as_int() ou cast.as_uint() para corresponder aos tipos de números inteiros. A conversão explícita é
necessária para o operador %. Para operações aritméticas, também é possível forçar
constantes inteiras a se comportarem como pontos flutuantes usando literais de ponto flutuante, como
2.0 ou 100.0, ou coerção de divisão, como (2/1), em expressões sem
outros operadores / na mesma linha. Para mais informações, consulte
Aritmética com campos de evento não assinados.
Variáveis de marcador de posição em resultados
Ao calcular variáveis de resultado, é possível usar variáveis de marcador de posição que foram definidas na seção de eventos da consulta. Neste exemplo, suponha que
$email_sent_bytes foi definido na seção de eventos da regra:
Exemplo: evento único sem seção de correspondência
// 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
Exemplo: vários eventos com seção de correspondência
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_eventVariáveis de resultado em expressões de atribuição de resultado
As variáveis de resultado podem ser usadas para derivar outras variáveis de resultado, de forma semelhante às variáveis de marcador de posição definidas na seção events. É possível se referir a uma variável de resultado
na atribuição de outra variável de resultado com um token $ seguido
pelo nome da variável. As variáveis de resultado precisam ser definidas antes de serem referenciadas no texto da consulta. Quando usadas em uma expressão de atribuição, as variáveis de resultado não podem ser agregadas (consulte Agregações).
No exemplo a seguir, a variável de resultado $risk_score deriva o valor da variável de resultado $event_count:
Exemplo: variável de resultado derivada de outra variável 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
As variáveis de resultado podem ser usadas em qualquer tipo de expressão no lado direito de uma atribuição de resultado, exceto nas seguintes expressões:
- Agregações
Arrays.length()chamadas de funções- Com modificadores
anyouall
Agregações
Os campos de evento recorrente são valores não escalares. Ou seja, uma única variável aponta para
vários valores. Por exemplo, a variável de campo de evento $e.target.ip é um campo repetido
e pode ter zero, um ou muitos valores de IP. É um valor não escalar. Já a variável de campo de evento
$e.principal.hostname não é um campo repetido e tem apenas um valor (ou seja, um valor escalar).
Da mesma forma, os campos de evento não repetidos e campos de evento recorrente usados na seção outcome de uma consulta com uma janela de correspondência são valores não escalares.
Exemplo: agrupar eventos com seção de correspondência e campo não repetido
A consulta a seguir agrupa eventos usando uma seção "match" e se refere a um campo de evento não repetido na seção "outcome":
rule OutcomeAndMatchWindow{
...
match:
$userid over 5m
outcome:
$hostnames = array($e.principal.hostname)
...
}Qualquer janela de 5 minutos em que a consulta é executada pode conter zero, um ou muitos eventos. A seção de resultados
opera em todos os eventos em uma janela de correspondência. Qualquer variável de campo de evento mencionada na seção de resultado pode apontar para zero, um ou muitos valores do campo em cada evento na janela de correspondência.
Por exemplo, se uma janela de 5 minutos tiver 5 eventos $e, $e.principal.hostname
na seção de resultados vai apontar para cinco nomes de host diferentes. A variável de campo de evento
$e.principal.hostname é tratada como um valor não escalar na seção outcome dessa consulta.
Como as variáveis de resultado precisam sempre gerar um único valor escalar, qualquer valor não escalar de que uma atribuição de resultado dependa precisa ser agregado para gerar um único valor escalar. Em uma seção de resultado, os seguintes valores não são escalares e precisam ser agregados:
- Campos de evento (repetidos ou não) quando a consulta usa uma seção
match - Marcadores de posição de evento (repetidos ou não) quando a consulta usa uma seção
match - Campos de evento recorrente quando a consulta não usa uma seção
match - Marcadores de posição de eventos recorrentes quando a consulta não usa uma seção
match
Campos de eventos escalares, marcadores de posição de eventos escalares e constantes podem ser agrupados em
funções de agregação em consultas que não incluem uma seção match. No entanto, na maioria dos casos, essas agregações retornam o valor encapsulado, tornando-as desnecessárias.
Uma exceção é a agregação array(), que pode ser usada para converter explicitamente
um valor escalar em uma matriz.
As variáveis de resultado são tratadas como agregações: elas não podem ser reagregadas quando referenciadas em outra atribuição de resultado.
É possível usar as seguintes funções de agregação:
| Função de agregação | Descrição |
|---|---|
max() |
Mostra o máximo de todos os valores possíveis. Funciona apenas com números inteiros e flutuantes. |
min() |
Mostra o mínimo de todos os valores possíveis. Funciona apenas com números inteiros e flutuantes. |
sum() |
Mostra a soma de todos os valores possíveis. Funciona apenas com números inteiros e flutuantes. |
count_distinct() |
Coleta todos os valores possíveis e gera a contagem distinta de valores possíveis. |
count() |
Comporta-se como "count_distinct()", mas retorna uma contagem não distinta de valores possíveis. |
array_distinct() |
Coleta todos os valores distintos possíveis e gera uma lista deles. A eliminação de duplicação para produzir uma lista distinta é aplicada primeiro, seguida pelo truncamento. Na Pesquisa, a lista é truncada para no máximo 1.000 elementos aleatórios. Em "Painéis" e "Regras", a lista é truncada para um máximo de 25 elementos aleatórios. |
array() |
Comporta-se como array_distinct(), mas retorna uma lista de valores não distintos. Na Pesquisa, a lista é truncada para no máximo 1.000 elementos aleatórios. Em "Painéis" e "Regras", a lista é truncada para um máximo de 25 elementos aleatórios. |
A função de agregação é importante quando uma regra inclui uma seção condition
que especifica que vários eventos precisam existir, porque a função de agregação vai
operar em todos os eventos que geraram a detecção.
Exemplo: condição para vários eventos
Veja a seguir um exemplo de condição para vários eventos. Se a seção de resultado e condição tiver:
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 a seção "condition" exige que haja mais de um "event" para cada detecção, as funções de agregação vão operar em vários eventos. Suponha que os seguintes eventos tenham gerado uma detecção:
event: // UDM event 1 asset_id="asset-a" event: // UDM event 2 asset_id="asset-b" event: // UDM event 3 asset_id="asset-b"
Então, os valores dos resultados serão:
- $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"]
Limitações
A seção
outcomenão pode fazer referência a uma nova variável de marcador de posição que ainda não tenha sido definida na seçãoeventsououtcome.A seção
outcomenão pode usar variáveis de evento que não foram definidas na seçãoevents.A seção
outcomepode usar um campo de evento que não foi usado na seçãoevents, desde que a variável de evento a que o campo pertence já tenha sido definida na seçãoevents.A seção
outcomesó pode correlacionar variáveis de evento que já foram correlacionadas na seçãoevents. As correlações acontecem quando dois campos de evento de variáveis de evento diferentes são igualados.
Consulte Visão geral do YARA-L 2.0 para ver exemplos da seção outcome.
Consulte Criar análises sensíveis ao contexto para detalhes sobre a eliminação de duplicação de detecção com a seção outcome.
A seguir
Informações adicionais
- Expressões, operadores e construções usados na YARA-L 2.0
- Funções no YARA-L 2.0
- Criar regras de detecção compostas
- Exemplos: consultas YARA-L 2.0
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.