Sintaxe da seção de resultado
A seção outcome de uma consulta YARA-L define variáveis de resultado que especificam a saída de uma pesquisa e uma consulta 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árias finalidades, como mostrar dados relevantes em painéis e criar pontuações de risco.
Definir seção de resultado
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 procura falhas de login 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 marcador de posição: conta os logins com falha, os IPs distintos e 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 (inteiro ou ponto 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 security_result.risk_score do UDM.
Variável de resultado da pontuação de risco
A análise de risco do Google SecOps associa automaticamente detecções e alertas a entidades relacionadas a eles. 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 suas detecções personalizadas. Esse alinhamento ajuda a padronizar a priorização de alertas e os fluxos de trabalho de resposta.
| Gravidade | Intervalo de pontuação | Descrição | Exemplo |
|---|---|---|---|
| Alertas - 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 de domínio. |
| Alertas: alto | 80 - 89 | Comprometimento ativo de um único endpoint ou entidade. Precisa de revisão imediata. | Servidor de Production chamando um C2 conhecido e recente. |
| Alertas: média | 50 - 79 | Possível problema de segurança que exige investigação. Nenhum comprometimento confirmado, mas o encaminhamento é possível. | Uma credencial exposta, sem sinais de uso indevido. |
| Não alerta: baixo | 20 - 49 | Ocorrência de segurança de baixo impacto que, quando combinado com outros indicadores ou observações, pode levar a um incidente mais significativo. Geralmente não é necessária uma revisão. Pode ser combinado com outras detecções por regras compostas para criar um alerta. | Verificação de porta interna. |
| Observações sem alerta | 1 a 19 | Em geral, detecções baseadas em informações destinadas a criar uma percepção situacional de uma ameaça. Geralmente não requer revisão. Pode ser combinado com outras detecções por 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 de ameaças ou outras condições simultâneas.
As pontuações de risco da entidade podem ser usadas para gerar alertas com base no risco quase em tempo real. Para mais informações, consulte Visão geral da análise de risco.
Tipos de dados da variável de resultado
Cada variável de resultado pode ter um tipo de dados diferente, que é determinado pela expressão usada para calcular. Os seguintes tipos de dados de resultado são compatíveis com o Google SecOps:
- integer
- ponto flutuante
- 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 condições são especificadas usando o seguinte padrão de sintaxe:
if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)
Você pode 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 uma forma semelhante às expressões na seção events. Por exemplo, ele pode conter:
Nomes de campos da UDM com operador de comparação:
if($context.graph.entity.user.title = "Vendor", 100, 0)Variável de marcador de posição 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)Pesquisar em uma lista de referências:
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)
As cláusulas THEN_CLAUSE e ELSE_CLAUSE precisam ser do mesmo tipo de dados. Aceitamos números inteiros, números de ponto flutuante e strings.
É possível omitir a ELSE_CLAUSE se o tipo de dados for um número inteiro ou um ponto flutuante. Se for omitida, a ELSE_CLAUSE será avaliada como 0. Exemplo:
`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`
Você precisa 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 o tipo de dados inteiro ou de ponto flutuante 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))
As 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 números inteiros ou de ponto flutuante
- Agregações que retornam números inteiros ou de ponto flutuante
O módulo não é permitido em números de ponto flutuante.
Variáveis de marcador de posição em resultados
Ao calcular variáveis de resultado, você pode usar variáveis de marcador de posição 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
+ $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, semelhantes à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
Campos de evento repetidos não são valores 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 vários 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 repetidos 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 cinco minutos em que a consulta é executada pode conter zero, um ou vários eventos. A seção de resultado opera em todos os eventos de uma janela de correspondência. Qualquer variável de campo de evento referida na seção de resultado pode apontar para zero, um ou vários valores do campo em cada evento na janela de correspondência.
Por exemplo, se uma janela de 5 minutos contiver 5 eventos $e, $e.principal.hostname na seção de resultados 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 desta consulta.
Como as variáveis de resultado sempre precisam 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 repetidos) quando a consulta usa uma seção
match - Substitutos de eventos (repetidos ou não repetidos) quando a consulta usa uma seção
match - Campos de evento repetidos quando a consulta não usa uma seção
match - Marcadores de posição de eventos repetidos 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 envolvidos 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, o que as torna 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 são mencionadas em outra atribuição de resultado.
É possível usar as seguintes funções de agregação:
| Função de agregação | Descrição |
|---|---|
max() |
Retorna o máximo em todos os valores possíveis. Só funciona com números inteiros e de ponto flutuante. |
min() |
Mostra o mínimo em todos os valores possíveis. Só funciona com números inteiros e de ponto flutuante. |
sum() |
Mostra a soma de todos os valores possíveis. Só funciona com números inteiros e de ponto flutuante. |
count_distinct() |
Coleta todos os valores possíveis e gera a contagem distinta deles. |
count() |
Funciona 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. Ela trunca a lista de valores distintos em 1.000 elementos aleatórios. Primeiro, a deduplicação é aplicada para gerar uma lista distinta e, em seguida, o truncamento. |
array() |
Funciona como array_distinct(), mas retorna uma lista de valores não distintos. Ela também trunca a lista de valores para 1.000 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 ela opera em todos os eventos que geraram a detecção.
Exemplo: condição para vários eventos
Confira a seguir um exemplo de condição para vários eventos. Se a seção de resultado e condição contiver:
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 mais de um "event" para cada detecção, as funções agregadas operam em vários eventos. Suponha que os eventos a seguir geraram 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 foi 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 eventos de variáveis de eventos diferentes são igualados.
Consulte Visão geral do YARA-L 2.0 para exemplos da seção outcome.
Consulte Criar análises contextuais para mais detalhes sobre a remoçã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 na YARA-L 2.0
- Criar regras de detecção compostas
- Exemplos: consultas da YARA-L 2.0
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.