Regras de evento único e múltiplo

Compatível com:

Este documento mostra consultas escritas em YARA-L 2.0. Cada exemplo demonstra como correlacionar eventos na linguagem de regra de consulta para identificar ameaças à segurança, monitorar o comportamento de entidades e enriquecer as detecções com lógica de negócios.

Use os exemplos como blocos de construção da YARA-L 2.0, incluindo detecção de evento único, correspondência de expressão regular e filtragem de intervalo de rede. Esses exemplos são organizados em categorias funcionais para ajudar você a progredir da lógica básica para correlações avançadas de vários eventos e detecções compostas.

Sintaxe fundamental e básica

Os exemplos nesta seção demonstram como correlacionar eventos da UDM e estruturar consultas na linguagem de regras de maneira eficaz.

Tópico Exemplos
Consulta de evento único Pesquisa de login inicial do usuário; Detecção de login de 5 minutos
Consultas e ajustes Detecção de processos com base em exclusão
Intervalo e lógica de rede Correspondência de evento único (intervalo de IP)
Expressões regulares em consultas Filtragem de e-mails; Expressão regular de nome do host; Pesquisa de registro bruto
Campos repetidos com condições universais Validação de IP de login suspeito

Consulta de evento único

Caso de uso: detecção básica de um tipo de evento específico (por exemplo, USER_LOGIN) sem precisar correlacionar em uma janela de tempo.

Lógica principal: usa apenas as seções de eventos e condição para identificar uma única ocorrência. Uma regra de evento único pode ser:

  • Qualquer regra sem uma seção match.
  • Regra com uma seção match e uma seção condition que verifica apenas a existência de um evento (por exemplo, $e, #e > 0, #e >= 1, 1 <= #e, 0 < #e).

Regra

O exemplo de regra a seguir procura um evento de login do usuário (USER_LOGIN) e retorna o primeiro que encontra nos dados corporativos armazenados na sua conta do Google SecOps:

rule SingleEventRule {
meta:
  author = "noone@altostrat.com"

events:
  $e.metadata.event_type = "USER_LOGIN"

condition:
  $e
}

Este exemplo de pesquisa não agregada gera eventos individuais diretamente. Como essa consulta não exige correlação de eventos, as variáveis de evento, como $e1, são omitidas.

metadata.event_type = "USER_LOGIN"

Painel

Como essa lógica de consulta se concentra em mostrar eventos específicos e não correlacionados no estado bruto, ela não usa as seções match ou outcome necessárias para visualizações de painel.

Exemplo: detecção de login em cinco minutos

Regra

O exemplo a seguir mostra uma regra de evento único que usa a seção match para encontrar qualquer usuário com pelo menos um evento de login em uma janela de tempo de 5 minutos (5m). Ele verifica a existência de um evento de login do usuário.

rule SingleEventRule {
meta:
  author = "alice@example.com"
  description = "windowed single event example rule"

events:
  $e.metadata.event_type = "USER_LOGIN"
  $e.principal.user.userid = $user

match:
  $user over 5m

condition:
  #e > 0
}

Pesquisar

Este exemplo de pesquisa estatística agrega a atividade em janelas rotativas de cinco minutos (5m), com saída de uma linha por usuário por janela. Como a consulta se concentra em contagens volumétricas por janela, as variáveis event e as seções condition são omitidas, porque os resultados incluem um ou mais eventos. Essa versão usa uma janela rotativa em vez de uma janela de salto para garantir que os resultados sejam renderizados corretamente na plataforma.

metadata.event_type = "USER_LOGIN"
principal.user.userid = $user

match:
  $user by 5m

Painel

O exemplo a seguir incorpora uma seção outcome para calcular a contagem total de eventos por usuário, o que ajuda a representar os dados como um valor estatístico ao longo do tempo. A consulta usa uma janela rotativa em vez de uma janela de salto para garantir que os pontos de dados sejam mapeados para intervalos discretos e não sobrepostos, além de fornecer uma visualização mais clara para a tendência do painel.

metadata.event_type = "USER_LOGIN"
principal.user.userid = $user

match:
  $user by 5m

outcome:
  $event_count = count(metadata.id)

Consultas e ajuste

Caso de uso: detectar svchost.exe do Windows iniciados em diretórios não padrão.

Lógica da chave: negação (not) combinada com correspondência de expressão regular.

Exemplo: detecção de processos com base em exclusão

Regra

A regra a seguir verifica padrões específicos nos dados de eventos e cria uma detecção se os encontra. Essa regra inclui uma variável $e1 para rastrear o tipo de evento e o campo metadata.event_type da UDM. A regra verifica ocorrências específicas de correspondências de expressões regulares com e1. Quando o evento $e1 ocorre, uma detecção é criada. Uma condição not é incluída na regra para excluir determinados caminhos não maliciosos. É possível adicionar condições not para evitar falsos positivos.

rule suspicious_unusual_location_svchost_execution
{
meta:
  author = "Google Cloud Security"
  description = "Windows 'svchost' executed from an unusual location"
  yara_version = "YL2.0"
  rule_version = "1.0"

events:
  $e1.metadata.event_type = "PROCESS_LAUNCH"
  re.regex($e1.principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
  not re.regex($e1.principal.process.command_line, `\\Windows\\System32\\`) nocase

condition:
  $e1
}

Pesquisar

Este exemplo realiza uma pesquisa não agregada para gerar eventos individuais. Como essa pesquisa não exige correlação de eventos em várias instâncias, variáveis de evento como $e1 são desnecessárias.

metadata.event_type = "PROCESS_LAUNCH"
re.regex(principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex(principal.process.command_line, `\\Windows\\System32\\`) nocase

Painel

Essa sintaxe incorpora as seções match e outcome para calcular o volume de eventos ao longo do tempo. A função timestamp.get_timestamp() agrupa os resultados por dia para visualizar tendências.

metadata.event_type = "PROCESS_LAUNCH"
re.regex(principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex(principal.process.command_line, `\\Windows\\System32\\`) nocase
$date = timestamp.get_timestamp(metadata.event_timestamp.seconds)

match:
  $date

outcome:
  $event_count = count(metadata.id)

Intervalo e lógica de rede

Caso de uso: filtrar a atividade com base em sub-redes IP específicas (CIDR) e fazer a correspondência com vários nomes de host possíveis.

Conceitos principais:

  • net.ip_in_range_cidr(): essa função verifica se um determinado endereço IP está contido em uma determinada sub-rede de roteamento entre domínios sem classe (CIDR) para correspondência de sub-rede e o operador "or" para matrizes de strings.
  • Operador lógico OR: usado para combinar várias condições. As condições na seção de eventos são combinadas implicitamente com AND. O operador OR verifica vários nomes de host possíveis.

Exemplo: correspondência de evento único (intervalo de IP)

Regra

O exemplo a seguir mostra uma regra de evento único que procura correspondências entre dois nomes de host específicos e um intervalo específico de endereços IP:

rule OrsAndNetworkRange {
meta:
  author = "noone@altostrat.com"

events:
  // Checks CIDR ranges.
  net.ip_in_range_cidr($e.principal.ip, "203.0.113.0/24")

  // Detection when the hostname field matches either value using or.
  $e.principal.hostname = /pbateman/ or $e.principal.hostname = /sspade/

condition:
  $e
}

Pesquisar

O exemplo de consulta a seguir identifica eventos em que um endereço IP específico está dentro de um intervalo CIDR definido e o nome do host corresponde a um padrão de usuário específico:

net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")

principal.hostname = /pbateman/ or principal.hostname = /sspade/

Como essa é uma consulta de pesquisa, não uma regra de detecção, todo o evento é retornado automaticamente se os filtros forem atendidos. Uma seção match agrupa dados por principal.ip e principal.hostname. Uma seção condition não é necessária, e as variáveis de evento ($e) são omitidas porque nenhuma correlação de evento é realizada.

Painel

A consulta de exemplo a seguir agrega resultados agrupando pares exclusivos de IP e nome do host:

net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")

principal.hostname = /pbateman/ or principal.hostname = /sspade/

match:
  principal.ip, principal.hostname

Expressões regulares em consultas

Caso de uso: pesquisa padrões de strings flexíveis (por exemplo, domínios específicos em e-mails) ignorando o uso de maiúsculas. Isso é mais usado com frequência na pesquisa e nas regras.

Lógica principal: usa /regex/ nocase para correspondências básicas e a função re.regex() para análise de campo complexa.

Exemplo: filtragem de e-mails

Regra

O exemplo de expressão regular da YARA-L 2.0 a seguir pesquisa eventos com e-mails recebidos do domínio altostrat.com. Como nocase foi adicionado à comparação de regex da variável $host e à função regex, essas comparações não diferenciam maiúsculas de minúsculas.

rule RegexRuleExample {
meta:
  author = "noone@altostrat.com"

events:
  $e.principal.hostname = $host
  $host = /.*HoSt.*/ nocase
  re.regex($e.network.email.from, `.*altostrat\.com`) nocase

match:
  $host over 10m

condition:
  #e > 10
}

Pesquisar

Na interface de pesquisa, essa lógica é usada para caça de ameaças de alta fidelidade e análise de dados. Em vez de esperar um alerta automatizado, os analistas podem consultar manualmente a UDM para descobrir instâncias específicas de nomes de host que correspondem a uma convenção de nomenclatura, além de domínios de e-mail segmentados. Esse é o principal método para validar o volume desses eventos antes de promovê-los a uma regra de detecção persistente.

principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase
match:
 $host over 10m
 ```

Painel

A lógica a seguir identifica padrões de interesse agregando a telemetria hostname e email em intervalos de 10 minutos (10m). Quando usada em um painel, essa lógica permite que os analistas visualizem a frequência de comunicação de recursos específicos (correspondentes a host) para o domínio altostrat.com. Essa visualização é essencial para monitorar tendências de movimentação de dados internos e identificar principais comunicadores em toda a infraestrutura crítica.

principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase

match:
  $host over 10m
  ```

Exemplo: expressão regular de nome de host

Regra

O exemplo a seguir identifica qualquer atividade de registro em que o principal hostname é identificado como um servidor da Web (webserver) ou de desenvolvimento (devserver). Ele usa uma expressão regular sem distinção entre maiúsculas e minúsculas para garantir que variações nas convenções de nomenclatura não resultem em detecções perdidas.

rule WebServerOrDevServerActivity {
meta:
 author = "Alex"
 description = "Detects events where the principal hostname is 'webserver' or 'devserver', ignoring case."
 severity = "Informational"

events:
 $e.principal.hostname = /webserver|devserver/ nocase

condition:
 $e
}

Pesquisar

No exemplo a seguir, principal.hostname = /webserver|devserver/ nocase corresponde a nomes de host como "WebServer01", "devserver-test" e "MyWebServers". Esse é um caso de uso comum para encontrar um evento específico.

// Use /regex/ followed by nocase for a case-insensitive match
principal.hostname = /webserver|devserver/ nocase

Painel

Embora esse exemplo específico não seja visualizado em um painel, essa regra oferece alertas ativos e detecção persistente. Ao contrário de um painel, que exige revisão manual, isso garante que todas as instâncias de atividade nesses servidores sejam sinalizadas e registradas automaticamente no mecanismo de detecção para pesquisa imediata.

Regra

Enquanto você usa a pesquisa manual para investigações pontuais, as regras de detecção fornecem monitoramento contínuo de telemetria 24 horas por dia, 7 dias por semana. É possível converter uma consulta de pesquisa bem-sucedida em uma regra YARA-L para automatizar o processo de alerta.

Principais benefícios das regras:

  • Alertas em tempo real: sinaliza automaticamente as correspondências à medida que elas entram no sistema.
  • Persistência: elimina a necessidade de reinserir manualmente os termos de pesquisa.
  • Ações de resultado: alimentam diretamente a visualização de detecção para triagem de analistas e resposta a incidentes.

Pesquisar

Os analistas de segurança usam com frequência o regex para pesquisar registros brutos e não analisados no Google SecOps. Essa ação permite a correspondência flexível de padrões para encontrar artefatos específicos, mesmo que eles não estejam totalmente estruturados ou indexados. A sintaxe usa barras:

raw = /host/

Essa consulta retorna qualquer linha de registro bruta em que a sequência de caracteres "host" aparece. Exemplos de conteúdo de registro bruto correspondente podem incluir "hostname": "myhost123".

Painel

Não há uma variante de painel dedicada para esse tipo de evento específico. Para visualizar essas detecções em grande escala, você pode:

  • Mapeie o metadata.event_type para um gráfico de barras ou de pizza no criador de painéis.
  • Acompanhe a frequência desses eventos em períodos de 7, 30 ou 90 dias para identificar anomalias no comportamento do usuário.

Campos repetidos com condições universais

Caso de uso: audite eventos que contêm listas de dados (campos repetidos) para garantir que não haja exceções confiáveis. Por exemplo, verifique se todos os endereços IP associados a um login estão fora de um intervalo seguro conhecido.

Lógica principal: usa o operador all para avaliar todos os elementos em um campo repetido em relação a uma condição específica e demonstra como atribuir um campo repetido a uma variável de marcador de posição (por exemplo, $ip) cria uma detecção distinta para cada valor único na lista.

Exemplo: validação de IP de login suspeito

Regra

A regra a seguir procura eventos de login em que todos os endereços IP de origem não correspondem a um endereço IP conhecido como seguro em um período de cinco minutos (5m).

rule SuspiciousIPLogins {
meta:
  author = "alice@example.com"

events:
  $e.metadata.event_type = "USER_LOGIN"

  // Detects if all source IP addresses in an event do not match "100.97.16.0"
  // For example, if an event has source IP addresses
  // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
  // it will be detected since "100.97.16.1", "100.97.16.2",
  // and "100.97.16.3" all do not match "100.97.16.0".

  all $e.principal.ip != "100.97.16.0"

  // Assigns placeholder variable $ip to the $e.principal.ip repeated field.
  // There will be one detection per source IP address.
  // For example, if an event has source IP addresses
  // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
  // there will be one detection per address.

  $e.principal.ip = $ip

match:
  $ip over 5m

condition:
  $e
}

Pesquisar

metadata.event_type = "USER_LOGIN"

// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".

all principal.ip != "100.97.16.0"

// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.

principal.ip = $ip

match:
  $ip over 5m

Painel

metadata.event_type = "USER_LOGIN"

// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".

all principal.ip != "100.97.16.0"

// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.

principal.ip = $ip

match:
  $ip over 5m

Janelas avançadas

Esta seção aborda padrões de vários estágios e detecções acionadas por atividades de outras regras.

Tópico Exemplos
Correlação de vários eventos Detecção de login em várias cidades; Criação e exclusão rápidas de usuários
Janela deslizante em consultas Detecção de eventos sequenciais ausentes
Consultas de vários eventos Detecção de login de alta frequência
Consultas de vários eventos com resultados calculados Força bruta seguida de login bem-sucedido; Correspondência de host com janela de tempo

Correlação de vários eventos

Esta seção mostra exemplos de como rastrear entidades (usuários ou hosts) em vários eventos ou períodos para identificar padrões de comportamento.

Caso de uso: detecta viagens impossíveis em que um único usuário faz login em duas ou mais cidades em menos de cinco (5m) minutos.

Lógica de chave: use a seção match para agrupar por $user e #city > 1 e encontrar valores de local distintos.

Exemplo: detecção de login em várias cidades

Regra

A regra a seguir procura usuários que fizeram login na sua empresa em duas ou mais cidades em menos de 5 (5m) minutos, em que $user é a variável match, $udm é a variável de evento, e $city e $user são as variáveis de marcador de posição:

rule DifferentCityLogin {
meta:

events:
  $udm.metadata.event_type = "USER_LOGIN"
  $udm.principal.user.userid = $user
  $udm.principal.location.city = $city

match:
  $user over 5m

condition:
  $udm and #city > 1
}

A explicação a seguir descreve como essa regra funciona:

  • Agrupa eventos com nome de usuário ($user) e o retorna ($user) quando uma correspondência é encontrada.
  • O período é de cinco minutos (5m), e somente eventos com menos de cinco minutos (5m) de intervalo são correlacionados.
  • Pesquisa um grupo de eventos ($udm) cujo tipo de evento é USER_LOGIN.
  • Para esse grupo de eventos, a regra chama o ID do usuário como $user e a cidade de login como $city.
  • Retorna uma correspondência se o número distinto de valores city (indicado por #city) for maior que 1 no grupo de eventos ($udm) dentro do período de 5 minutos (5m).

Pesquisar

A consulta de exemplo a seguir executa uma pesquisa estatística equivalente para identificar padrões de viagem impossível. Ele agrupa eventos USER_LOGIN por usuário em uma janela de cinco minutos (5m) e filtra os resultados para mostrar apenas instâncias em que várias cidades distintas são detectadas para uma única identidade.

events:
  metadata.event_type = "USER_LOGIN"
  principal.user.userid = $user
  principal.location.city = $city

match:
  $user over 5m

condition:
  #city > 1

Painel

A consulta de exemplo a seguir oferece uma visualização de painel equivalente para rastrear possíveis comprometimentos de conta. Ele agrega eventos USER_LOGIN por usuário em uma janela de cinco minutos (5m) e filtra instâncias em que uma única identidade está associada a mais de uma cidade distinta (#city), o que permite representar essas anomalias geográficas de alto risco ao longo do tempo.

events:
  metadata.event_type = "USER_LOGIN"
  principal.user.userid = $user
  principal.location.city = $city

match:
  $user over 5m

condition:
  #city > 1

Criação e exclusão rápida de usuários

  • Caso de uso: identifica e exclui contas descartáveis criadas em um período de quatro horas.

  • Lógica principal: une dois tipos de evento (USER_CREATION e USER_DELETION) em uma variável $user compartilhada e compara carimbos de data/hora.

Exemplo: criação e exclusão rápidas de usuários

Regra

O exemplo de regra a seguir pesquisa usuários que foram criados e excluídos em até 4 horas (4h), em que $create e $delete são as variáveis de evento, $user é a variável match e não há variáveis de marcador de posição:

rule UserCreationThenDeletion {
meta:

events:
  $create.target.user.userid = $user
  $create.metadata.event_type = "USER_CREATION"

  $delete.target.user.userid = $user
  $delete.metadata.event_type = "USER_DELETION"

  $create.metadata.event_timestamp.seconds <=
     $delete.metadata.event_timestamp.seconds

match:
  $user over 4h

condition:
  $create and $delete
}

Pesquisar

O exemplo a seguir demonstra uma pesquisa de estatísticas de vários eventos usada para identificar mudanças rápidas no ciclo de vida da conta. Essa consulta gera uma linha por usuário em um período de quatro horas, correlacionando a criação e a exclusão de identidades.

Como a pesquisa retorna por padrão qualquer janela que contenha os eventos especificados, uma seção condition não é necessária.

$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"

$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"

$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds

match:
  $user over 4h

Painel

O exemplo a seguir demonstra uma pesquisa de painel de vários eventos projetada para representar tendências do ciclo de vida da conta ao longo do tempo. Ao usar uma janela móvel (by 4h), os resultados são mapeados para intervalos de tempo discretos e não sobrepostos, o que é ideal para visualização.

Essa variação inclui uma seção outcome para calcular a contagem distinta de eventos de criação em cada janela. Ao contrário da pesquisa anterior, essa versão não exige que variáveis de evento específicas sejam retornadas, porque o foco está em valores estatísticos agregados, e não em linhas de registro individuais.

$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"

$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"

$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds

match:
  $user by 4h

outcome:
  $event_count = count_distinct($create.metadata.id)

Janela deslizante em consultas

Caso de uso: para detectar um possível problema de segurança em que um evento inicial (de firewall_1) não é seguido por um evento subsequente esperado (de firewall_2) no mesmo host em um período específico.

Lógica principal:

  • Evento principal: a regra se concentra em eventos de firewall_1, designados como $e1. Cada vez que um evento $e1 ocorre, ele funciona como um pivô.
  • Período: a seção match ($host over 10m after $e1) define um período de 10 minutos que começa imediatamente após cada evento $e1. Essa janela desliza com cada novo evento $e1.
  • Correlação: os eventos são agrupados por nome de host ($host).
  • Condição para detecção ($e1 e $e2): uma detecção é acionada para um determinado host se:
    • Um evento de firewall_1 ($e1) está presente.
    • AND, dentro da janela de 10 minutos após esse evento específico de $e1, o evento NO de firewall_2 ($e2) é encontrado para o mesmo host.

Exemplo: detecção de eventos sequenciais ausentes

Regra

O exemplo a seguir identifica instâncias em que um evento secundário não ocorre após um gatilho principal. Ao usar a condição !$e2 em uma janela de 10 minutos, essa regra sinaliza a falta de telemetria, especificamente quando um registro de firewall é visto em um local, mas não aparece no próximo salto esperado, o que indica uma possível falha de visibilidade ou queda de tráfego.

rule MissingSequentialEvent {
meta:
  author = "alice@example.com"

events:
  $e1.metadata.product_name = "firewall_1"
  $e1.principal.hostname = $host

  $e2.metadata.product_name = "firewall_2"
  $e2.principal.hostname = $host

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2
}

Pesquisar

O exemplo a seguir demonstra uma pesquisa sequencial usada para identificar lacunas na telemetria entre duas fontes. Ao usar $e1 como um pivô, a pesquisa procura um evento de firewall principal que não é seguido por um evento correspondente em um segundo firewall em 10 minutos. Essa é uma maneira altamente eficaz de procurar manualmente "buracos negros" no tráfego de rede ou falhas de registro durante uma investigação.

$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host

$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2

Painel

O exemplo a seguir oferece uma análise de lacuna de visibilidade projetada para uma visualização de painel. Ao agregar instâncias em que um evento secundário não segue um principal, é possível visualizar a confiabilidade do pipeline de geração de registros ao longo do tempo. Ao representar esses eventos "ausentes", é possível identificar zonas mortas persistentes na visibilidade da rede ou problemas de configuração em nomes de host específicos.

$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host

$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2

Consultas de vários eventos

  • Caso de uso: identifique atividades de alta frequência ou de força bruta rastreando uma única entidade (por exemplo, um usuário ou host) em várias ocorrências de um evento em um período específico.

  • Lógica principal: usa uma seção match para agrupar eventos por uma variável específica e uma seção condition para verificar uma contagem de limite (por exemplo, #e >= 10) no período definido.

Uma regra de vários eventos típica inclui:

  • Variáveis de evento para distinguir entre eventos.
  • Uma seção match que especifica o período em que os eventos precisam ser agrupados.
  • Uma seção condition que especifica qual condição deve acionar a detecção e verifica a existência de vários eventos.

Na Pesquisa, as consultas com vários eventos são definidas por mais de um evento em uma consulta. Para regras, há duas maneiras de definir isso:

  • Vários eventos: por exemplo, event1 = successful login, event2 = failed login.

  • Acionadores baseados em condição: a condição é declarada para ser acionada somente quando vários eventos atendem aos critérios (por exemplo, event1 > 10). Esse tipo de regra também precisa incluir uma seção outcome.

Exemplo: detecção de login de alta frequência

Regra

A regra a seguir procura um usuário que fez login pelo menos 10 vezes em menos de 10 minutos:

rule MultiEventRule {
meta:
  author = "noone@altostrat.com"

events:
  $e.metadata.event_type = "USER_LOGIN"
  $e.principal.user.userid = $user

match:
  $user over 10m

condition:
  #e >= 10
}

Pesquisar

O exemplo a seguir usa uma pesquisa de estatísticas de vários eventos para identificar atividades de login de alta frequência. Ele sinaliza qualquer instância em que um único usuário gera 10 ou mais eventos de login em uma janela de 10 minutos (10m).

$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user

match:
  $user by 10m

condition:
  #e >= 10

Painel

O exemplo a seguir usa uma pesquisa de vários eventos para monitorar possíveis comprometimentos de conta. Ao correlacionar tentativas de login em uma janela deslizante de 10 minutos, ele identifica instâncias em que um usuário e host específicos têm vários logins malsucedidos seguidos de um bem-sucedido, permitindo visualizar padrões de autenticação de alto risco em tempo real.

$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user

match:
  $user by 10m

condition:
  #e >= 10

Consultas de vários eventos com resultados calculados

  • Caso de uso: aplique a lógica condicional para definir um risk_score com base na gravidade do recurso ou no volume da rede.

  • Lógica principal: usa a seção outcome para calcular variáveis e a seção de condição para filtrar por essas variáveis.

Exemplo: força bruta seguida de login bem-sucedido

O exemplo a seguir usa a seção outcome para contar eventos em uma janela match. Essa consulta gera a mesma saída que a consulta padrão de vários eventos, mas demonstra como incorporar variáveis calculadas à lógica de detecção.

Regra

rule PossibleBruteForceThenSuccessfulLogin {
meta:
  author = "Alex"
  description = "Detects multiple failed login attempts followed by a successful login for the same user and host within a 10-minute window."
  severity = "High"
  tactic = "Credential Access"

events:
  // Define the first type of event: Failed Login
  // We use $failed to represent any event matching these criteria.
  $failed.metadata.event_type = "USER_LOGIN"
  $failed.security_result.action = "FAIL"
  // Extract common fields to correlate on
  $failed.target.user.userid = $user
  $failed.principal.hostname = $hostname

  // Define the second type of event: Successful Login
  // We use $success to represent any event matching these criteria.
  $success.metadata.event_type = "USER_LOGIN"
  $success.security_result.action = "ALLOW"
  // Correlate using the same user and hostname placeholders
  $success.target.user.userid = $user
  $success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a time window: by 10m.
  // The rule will evaluate all events matching $failed or $success that share the same $user and $hostname within any given 10-minute period.
  $user, $hostname by 10m

outcome:
  // Calculate aggregate values from the events within the match window.
  $failed_login_count = count($failed.metadata.id)
  $successful_login_count = count($success.metadata.id)

condition:
  // The conditions that must be met *within each matched group* ($user, $hostname over 10m).
  // - #failed >= 5: There must be 5 or more events matching the $failed criteria.
  // - #success >= 1: There must be at least 1 event matching the $success criteria.
  #failed >= 5 and #success >= 1
}

Pesquisar

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a sliding time window: over 10m.
  // The rule will evaluate all events matching $failed or $success that share
  // the same $user and $hostname within any given 10-minute period.
  $user, $hostname over 10m

Painel

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a sliding time window: over 10m.
  // The rule will evaluate all events matching $failed or $success that share
  // the same $user and $hostname within any given 10-minute period.
  $user, $hostname over 10m

Exemplo: correspondência de host com janela de tempo

Regra

A regra a seguir analisa dois eventos para receber o valor de $hostname. Se o valor de $hostname corresponder por um período de 5 minutos (5m), uma pontuação de gravidade será aplicada. Ao incluir um período na seção match, a regra verifica dentro do período especificado.

rule OutcomeRuleMultiEvent {
meta:
  author = "Google Cloud Security"
events:
  $u.udm.principal.hostname = $hostname
  $asset_context.graph.entity.hostname = $hostname

  $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $risk_score =
    max(
        100
      + if($hostname = "my-hostname", 100, 50)
      + if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
          "Empty asset id",
          $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

Pesquisar

 // Define the first type of event: Failed Login
 // We use $failed to represent any event matching these criteria.
 $failed.metadata.event_type = "USER_LOGIN"
 $failed.security_result.action = "FAIL"
 // Extract common fields to correlate on
 $failed.target.user.userid = $user
 $failed.principal.hostname = $hostname

 // Define the second type of event: Successful Login
 // We use $success to represent any event matching these criteria.
 $success.metadata.event_type = "USER_LOGIN"
 $success.security_result.action = "ALLOW"
 // Correlate using the same user and hostname placeholders
 $success.target.user.userid = $user
 $success.principal.hostname = $hostname

match:
 // This section is key for multi-event rules. It groups events:
 // - By the common placeholder variables: $user and $hostname.
 // - Within a sliding time window: over 10m.
 // The rule will evaluate all events matching $failed or $success that share
 // the same $user and $hostname within any given 10-minute period.
 $user, $hostname over 10m

outcome:
 // Calculate aggregate values from the events within the match window.
 $failed_login_count = count($failed.metadata.id)
 $successful_login_count = count($success.metadata.id)
 ```

Painel

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
 // This section is key for multi-event rules. It groups events:
 // - By the common placeholder variables: $user and $hostname.
 // - Within a sliding time window: over 10m.
 // The rule will evaluate all events matching $failed or $success that share
 // the same $user and $hostname within any given 10-minute period.
 $user, $hostname over 10m

outcome:
  // Calculate aggregate values from the events within the match window.
  $failed_login_count = count($failed.metadata.id)
  $successful_login_count = count($success.metadata.id)

Detecções compostas

As detecções compostas melhoram a detecção de ameaças usando regras compostas. Essas regras compostas usam detecções de outras regras como entrada. Isso permite a detecção de ameaças complexas que regras individuais não detectariam. Para mais informações, consulte Visão geral das detecções compostas.

Tópico Exemplos
Filtragem de alto risco Detecção de usuários administrativos
Agregação e definição de limites Agregação de riscos
Agregação de táticas Agregação de táticas do MITRE
Detecções compostas sequenciais Tentativa de força bruta seguida de login bem-sucedido
Detecções com base no contexto Enriquecimento de inteligência contra ameaças
Detecções de coocorrência Coocorrência de escalonamento de privilégios e exfiltração

Filtragem de alto risco

Caso de uso: filtre as detecções atuais para encontrar atributos de alto risco, como atividades envolvendo contas administrativas.

Lógica de chave: opera em resultados ou campos de metadados em descobertas atuais.

As detecções compostas de filtragem de alto risco são a forma mais simples de uma detecção composta que opera em campos dentro de descobertas de detecção, como variáveis de resultado ou metadados de regra. Eles ajudam a filtrar detecções de condições que podem indicar maior risco, como um usuário administrador ou um ambiente de produção.

Exemplo: detecção de usuários administrativos

Regra

A regra composta a seguir pesquisa detecções em que o ator é identificado como um usuário administrativo e aplica uma pontuação de risco padronizada.

rule composite_admin_detection {
meta:
  rule_name = "Detection with Admin User"
  author = "Google Cloud Security"
  description = "Composite rule that looks for any detections where the actor is an admin user"
  severity = "Medium"

events:
  $rule_name = $d.detection.detection.rule_name
  $principal_user = $d.detection.detection.variables["principal_users"]
  $principal_user = /admin|root/ nocase

match:
  $principal_user over 1h
outcome:
  $risk_score = 75
  $upstream_rules = array_distinct($rule_name)

condition:
  $d
}

Pesquisar

A pesquisa estatística a seguir identifica e agrega atividades de contas com privilégios elevados. Ele foi projetado para mostrar todos os nomes de regras exclusivas que acionaram detecções envolvendo usuários "administrador" ou "root".

Nesta consulta específica, a janela de tempo é removida para realizar uma única análise estatística em todas as detecções dentro do período selecionado. Além disso, como essa é uma pesquisa não agregada focada em dados de detecção atuais, as seções de eventos, variáveis de evento e condição não são necessárias.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase

match:
  $principal_user

outcome:
  $upstream_rules = array_distinct($rule_name)

Painel

Com essa consulta de painel, é possível visualizar quais regras específicas detectam atividades relacionadas ao administrador com mais frequência. Ele foi criado para oferecer uma visão geral de alto nível das tendências de detecção em todo o ambiente.

Observe a mudança na variável match e na agregação outcome em comparação com os exemplos anteriores. Essa consulta agrupa os resultados por nome da regra e calcula uma contagem dos usuários administradores detectados para cada um.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase

match:
  $rule_name

outcome:
  $admin_detections = count($principal_user)

Agregação e limiarização

Caso de uso: identifique usuários ou hosts que geram um grande volume de alertas ou acumulam pontuações de risco significativas ao longo do tempo.

Lógica principal: usa sum() ou count_distinct() para analisar dados agregados de detecção.

Com as regras de detecção agregadas, é possível agrupar descobertas com base em atributos compartilhados, como um nome de host ou de usuário, e analisar os dados agregados. Confira alguns casos de uso comuns:

  • Identificar usuários que geram um grande volume de alertas de segurança ou risco agregado.
  • Detectar hosts com padrões de atividade incomuns agregando detecções relacionadas.

Exemplo: agregação de risco

Regra

Essa regra agrega a pontuação de risco de um único usuário em um período de 48 horas. Ele identifica usuários cujo risco cumulativo em várias detecções excede um limite específico.

Nessa lógica atualizada, detection.detection.outcomes é substituído por variáveis de campo de mapa, que armazenam as variáveis match e outcome. Além disso, a variável de resultado $principal_users é removida porque cada detecção contém exatamente um valor de variável de correspondência, que já foi capturado.

rule composite_risk_aggregation {
meta:
  rule_name = "Risk Aggregation Composite"
  author = "Google Cloud Security"
  description = "Composite detection that aggregates risk of a user over 48 hours"
  severity = "High"

events:
  $rule_name = $d.detection.detection.rule_name
  $principal_user = $d.detection.detection.outcomes["principal_users"]
  $risk = $d.detection.detection.risk_score

match:
  $principal_user over 48h

outcome:
  $risk_score = 90
  $cumulative_risk = sum($risk)
  $upstream_rules = array_distinct($rule_name)

condition:
  $d and $cumulative_risk > 500
}

Pesquisar

Essa pesquisa estatística agrega dados de detecção para calcular o risco total de um usuário em um período de 48 horas. Ele gera uma linha por usuário principal para cada janela, fornecendo uma visão geral do risco da conta em vários tipos de detecção.

Nessa variação, as variáveis de evento não são necessárias. Embora o mecanismo de regras filtre automaticamente as detecções sem um usuário principal, essa pesquisa exige um filtro explícito ($principal_user != "") para garantir que os resultados incluam apenas dados preenchidos. Por padrão, a consulta retorna resultados apenas quando há uma ou mais detecções para um determinado usuário.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score

match:
  $principal_user over 48h

outcome:
  $risk_score = 90
  $cumulative_risk = sum($risk)
  $upstream_rules = array_distinct($rule_name)

condition:
  $cumulative_risk > 500

Painel

Essa variação foi criada especificamente para dashboards, com o objetivo de representar o risco do usuário e a atividade de detecção ao longo do tempo. Ele agrega dados em intervalos discretos, o que o torna ideal para visualizar tendências, como o volume de regras exclusivas acionadas ou a contagem total de detecções por usuário.

Nesta consulta, a janela é trocada de uma janela deslizante (hop) para uma janela rotativa (by 48h). Isso garante que os pontos de dados sejam mapeados para segmentos de tempo não sobrepostos, o que fornece uma visualização mais limpa para gráficos de série temporal. Assim como outras pesquisas não agregadas, as variáveis de evento não são obrigatórias, e a seção outcome é expandida para incluir contagens distintas de nomes de regras e IDs de detecção.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score

match:
  $principal_user by 48h

outcome:
  $cumulative_risk = sum($risk)
  $rule_count = count_distinct($rule_name)
  $detection_count = count_distinct(detection.id)

condition:
  $cumulative_risk > 500

Agregação de táticas

Caso de uso: identifique usuários cuja atividade tenha acionado detecções em várias táticas distintas do MITRE ATT&CK, sugerindo um ciclo de vida de ataque em andamento (por exemplo, mudando de Acesso inicial para Exfiltração).

Lógica principal: usa count_distinct($tactic) para acionar somente quando um usuário ultrapassa um limite específico de táticas diferentes em um período de 48 horas.

Exemplo: agregação de táticas do MITRE

Regra

rule composite_tactic_aggregation {
meta:
  rule_name = "MITRE Tactic Aggregation Composite"
  author = "Google Cloud Security"
  description = "Composite detection that detects if a user has triggered detections over multiple mitre tactics."
  severity = "Medium"

events:
  $principal_user = $d.detection.detection.outcomes["principal_users"]
  $tactic = $d.detection.detection.outcomes["mitre_tactic"]
  $rule_name = $d.detection.detection.rule_name

match:
  $principal_user over 48h

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $upstream_rules = array_distinct($rule_name)

condition:
  $d and $mitre_tactics_count > 1 }

Pesquisar

O exemplo a seguir demonstra uma variante de pesquisa projetada para desenvolvedores de segurança que precisam correlacionar detecções atuais e aplicar ponderação dinâmica de risco. Essa lógica de consulta extrai táticas do MITRE ATT&CK e informações do usuário da fonte de dados detection, agrupa a atividade pelo usuário principal e calcula uma pontuação de risco personalizada com base na diversidade das táticas observadas.

detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name

match:
  $principal_user

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $upstream_rules = array_distinct($rule_name)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $risk_score = if($calculated_risk > 100, 100,   $calculated_risk)

Painel

O exemplo a seguir ilustra uma variante de painéis da mesma lógica de análise de detecção. Quando usada nos painéis do Google SecOps, essa consulta permite que os desenvolvedores visualizem usuários de alto risco correlacionando resultados de detecção em diferentes regras. A lógica extrai o usuário principal e as táticas do MITRE, agrega as descobertas e aplica uma pontuação de risco limitada para ajudar a priorizar os esforços de investigação diretamente em um widget do painel.

detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name

match:
  $principal_user

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $upstream_rules = array_distinct($rule_name)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $risk_score = if($calculated_risk > 100, 100,   $calculated_risk)
  ```

Detecções compostas sequenciais

Caso de uso: identifique padrões de ataque críticos em que a ordem das operações é essencial. Por exemplo, detecte um login de conta bem-sucedido que ocorre somente após uma série de alertas de tentativa de força bruta do mesmo endereço IP.

Lógica principal: correlaciona uma detecção anterior com um evento UDM bruto subsequente unindo-os em uma variável comum (por exemplo, $bruteforce_ip) e usando uma comparação de carimbo de data/hora para garantir que os eventos ocorreram na sequência correta.

As detecções compostas sequenciais identificam padrões de eventos relacionados em que a sequência de detecções é importante, como uma tentativa de login por força bruta seguida de um login bem-sucedido. Esses padrões podem envolver várias detecções básicas ou uma combinação de detecções básicas e eventos.

Exemplo: tentativa de força bruta seguida de login bem-sucedido

Regra

A regra combinada a seguir identifica padrões de eventos relacionados em que a sequência é importante. Ele procura especificamente uma detecção de força bruta do Google Workspace seguida por um evento de login bem-sucedido do mesmo IP de origem em um período de 24 horas.

rule composite_bruteforce_login {
meta:
  rule_name = "Bruteforce Login Composite"
  author = "Google Cloud Security"
  description = "Detects when an IP address associated with a Workspace brute force attempt successfully logs in"
  severity = "High"

events:
  $bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
  $bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]

  $login_event.metadata.product_name = "login"
  $login_event.metadata.product_event_type = "login_success"
  $login_event.metadata.vendor_name = "Google Workspace"
  $login_ip = $login_event.principal.ip

  // Ensure the brute force detection and successful login occurred from the same IP
  $login_ip = $bruteforce_ip

  $target_account = $login_event.target.user.email_addresses

  // Ensure the brute force detection occurred before the successful login
  $bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds

match:
  $bruteforce_ip over 24h

outcome:
  $risk_score = 90
  $principal_users = array_distinct($target_account)

condition:
  $bruteforce_detection and $login_event
}

Pesquisar

$bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
$bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]

$login_event.metadata.product_name = "login"
$login_event.metadata.product_event_type = "login_success"
$login_event.metadata.vendor_name = "Google Workspace"
$login_ip = $login_event.principal.ip

// Ensure the brute force detection and successful login occurred from the same IP
$login_ip = $bruteforce_ip

$target_account = $login_event.target.user.email_addresses

// Ensure the brute force detection occurred before the successful login
$bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds

match:
  $bruteforce_ip over 24h

outcome:
  $principal_users = array_distinct($target_account)

condition:
  $bruteforce_detection and $login_event

Painel

Os painéis se concentram na visualização de dados de eventos brutos, enquanto a lógica de detecção composta correlaciona alertas de detecção atuais com eventos subsequentes. Essa análise multicamadas é otimizada para o mecanismo de detecção, e não para widgets de painel em tempo real.

Detecções com base no contexto

Caso de uso: enriqueça as detecções atuais com inteligência contra ameaças externa para verificar se um alerta envolve entidades maliciosas conhecidas. Por exemplo, verifique se um endereço IP sinalizado em uma detecção de segurança também está listado em um feed global de ameaças de nó de saída do TOR.

Lógica principal: usa regras compostas para unir descobertas de detecção com dados de gráfico GLOBAL_CONTEXT (por exemplo, feeds de inteligência de ameaças do Google Cloud) ao corresponder um atributo compartilhado, como um endereço IP.

As detecções compostas com reconhecimento de contexto enriquecem as detecções com mais contexto, como endereços IP encontrados em feeds de ameaças.

Exemplo: enriquecimento de inteligência contra ameaças

Regra

A regra composta a seguir adiciona automaticamente mais contexto do feed de inteligência do TOR às suas detecções atuais. Ele correlaciona um endereço IP encontrado em uma detecção anterior com o feed de nós de saída do TOR para aumentar a gravidade e a pontuação de risco da descoberta.

rule composite_tor_enrichment {
meta:
  rule_name = "Detection with IP from TOR Feed"
  author = "Google Cloud Security"
  description = "Adds additional context from the TOR intel feed to detections"
  severity = "High"

events:
  $rule_name = $d.detection.detection.rule_name

  $gcti.graph.metadata.entity_type = "IP_ADDRESS"
  $gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
  $gcti.graph.metadata.source_type = "GLOBAL_CONTEXT"
  $gcti.graph.metadata.product_name = "GCTI Feed"
  $gcti.graph.metadata.threat.threat_feed_name = "Tor Exit Nodes"

  $detection_ip = $d.detection.detection.variables["principal_ips"]
  $detection_ip = $gcti.graph.entity.ip

match:
  $detection_ip, $rule_name over 1h

outcome:
  $risk_score = 80

condition:
  $d and $gcti
}

Pesquisar

``` $rule_name = $d.detection.detection.rule_name

$gcti.graph.metadata.entity_type = "IP_ADDRESS" $gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence" $gcti.graph.metadata.source_type = "GLOBAL_CONTEXT" $gcti.graph.metadata.product_name = "GCTI Feed" $gcti.graph.metadata.threat.threat_feed_name = "Tor Exit Nodes"

$detection_ip = $d.detection.detection.variables["principal_ips"] $detection_ip = $gcti.graph.entity.ip

match: $detection_ip, $rule_name over 1h

condition: $d and $gcti ```

Painel

Detecções de coocorrência

Caso de uso: detecte uma combinação de táticas relacionadas acionadas pela mesma entidade em um período específico. Por exemplo, identifique um usuário que acionou uma detecção de escalonamento de privilégios e uma detecção de exfiltração de dados em 48 horas.

Lógica de chave: usa uma forma de agregação para correlacionar vários tipos de detecção distintos, unindo-os em uma variável de entidade compartilhada (por exemplo, $pe_user) na seção match.

As detecções compostas de coocorrência são uma forma de agregação que pode detectar uma combinação de eventos relacionados, como uma combinação de detecções de escalonamento de privilégios e exfiltração de dados acionadas por um usuário.

Exemplo: ocorrência simultânea de escalonamento de privilégios e exfiltração

Regra

A regra combinada a seguir procura uma sequência ou combinação específica de detecções (escalonamento de privilégios seguido de exfiltração) associadas ao mesmo usuário em um período de 48 horas.

rule composite_privesc_exfil_sequential {
meta:
  rule_name = "Privilege Escalation and Exfiltration Composite"
  author = "Google Cloud Security"
  description = "Looks for a detection sequence of privilege escalation followed by exfiltration."
  severity = "High"

events:
  $privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
  $exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"

  $privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
  $exfil_user = $exfiltration.detection.detection.variables["principal_users"]

  $privesc_user = $exfil_user

  $privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds

match:
  $privesc_user over 48h

outcome:
  $risk_score = 75
  $privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
  $exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)

condition:
  $privilege_escalation and $exfiltration
}

Pesquisar

$privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
$exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"

$privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
$exfil_user = $exfiltration.detection.detection.variables["principal_users"]

$privesc_user = $exfil_user

$privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds

match:
  $privesc_user over 48h

outcome:
  $privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
  $exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)

condition:
  $privilege_escalation and $exfiltration

Painel

Gerenciamento de resultados e variáveis

Esta seção mostra exemplos de como calcular o risco e normalizar os dados para consumo downstream.

Tópico Exemplos
Condicionais de resultado Filtrar por pontuação de risco calculada
Consulta de evento único com resultado Inclusão de tags de gravidade pontual
Pontuação de risco com base na rede Regra de pontuação de risco com base na rede
Refatorar a lógica de vários eventos (pré-refatoração) Refatoração de resultado (pré-refatoração)
Refatorar a lógica de vários eventos (pós-refatoração) Refatoração de resultado (pós-refatoração)
Atribuição de função a marcador de posição

Consultas com a seção outcome

É possível adicionar a seção opcional outcome em uma regra YARA-L 2.0 para extrair mais informações de cada detecção. Na seção condition, também é possível especificar condicionais em variáveis de resultado. Use a seção outcome de uma regra de detecção para definir variáveis para consumo downstream. Por exemplo, é possível definir uma pontuação de gravidade com base nos dados dos eventos analisados.

Para ver mais informações, consulte os seguintes tópicos:

Condicionais de resultado

Caso de uso: filtre detecções com base em pontuações de risco calculadas para reduzir o ruído e garantir que apenas eventos de alta confiança ou gravidade acionem alertas. Isso é útil para suprimir atividades de baixo risco que não atendem a um limite comercial específico.

Lógica principal: define variáveis na seção outcome usando matemática condicional (por exemplo, adicionando risco com base no tamanho do arquivo ou na hora do dia) e, em seguida, faz referência a essas variáveis na seção condition para restringir a detecção.

Exemplo: filtrar por pontuação de risco calculada

Regra

Na seção condition, é possível usar variáveis outcome definidas na seção outcome. O exemplo a seguir demonstra como filtrar pontuações de risco para reduzir o ruído nas detecções usando condicionais de resultado.

rule OutcomeConditionalRule {
meta:
  author = "alice@example.com"
  description = "Rule that uses outcome conditionals"

events:
  $u.metadata.event_type = "FILE_COPY"
  $u.principal.file.size = $file_size
  $u.principal.hostname = $hostname

  // 1 = Sunday, 7 = Saturday.
  $dayofweek = timestamp.get_day_of_week($u.metadata.collected_timestamp.seconds)

outcome:
  $risk_score =
      if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
      if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
      if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
      if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

condition:
  $u and $risk_score >= 10
}

Pesquisar

metadata.event_type = "FILE_COPY"
principal.file.size = $file_size
principal.hostname = $hostname

// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.collected_timestamp.seconds)

outcome:
  $risk_score =
      if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
      if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
      if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
      if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

Painel

Essa consulta adiciona a variável de resultado $hostname para mostrar quais hosts estão associados a cada pontuação de risco.

metadata.event_type = "FILE_COPY"
principal.file.size = $file_size
principal.hostname = $hostname

// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.collected_timestamp.seconds)

outcome:
  $host = $hostname
  $risk_score =
      if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
      if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
      if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
      if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

Consulta de evento único com resultado

Caso de uso: enriqueça as detecções pontuais com contexto imediato, como atribuir tags de gravidade com base em listas de usuários ou atributos de arquivo sem exigir uma janela de tempo ou correlação de eventos.

Lógica principal: usa a seção outcome em uma regra que não tem uma seção match. Isso permite extrair metadados e realizar lógica condicional (por exemplo, verificar um usuário em relação a uma lista de referência) para cada evento individual que atenda aos critérios.

Exemplo: inclusão de tags de gravidade pontual

Regra

O exemplo a seguir demonstra como usar a seção outcome em uma regra de evento único para definir variáveis para consumo downstream, como definir uma pontuação de gravidade com base no usuário específico e no tamanho do arquivo envolvidos em um evento de cópia de arquivo.

rule OutcomeRuleSingleEvent {
meta:
  author = "alice@example.com"
events:
  $u.metadata.event_type = "FILE_COPY"
  $u.principal.file.size = $file_size
  $u.principal.hostname = $hostname

outcome:
  $suspicious_host = $hostname
  $admin_severity = if($u.principal.user.userid in %admin_users, "SEVERE", "MODERATE")
  $severity_tag = if($file_size > 1024, $admin_severity, "LOW")

condition:
  $u
}

Pesquisar

O exemplo a seguir identifica eventos de criação de arquivos e usa a seção outcome para atribuir dinamicamente níveis de gravidade a cada resultado. Ao contrário das regras de vários eventos, essa pesquisa não agregada não exige variáveis de evento nem uma seção match. Em vez disso, ele processa cada registro individualmente para gerar 1 row per event, enriquecido com lógica personalizada com base no tamanho do arquivo e nas permissões do usuário.

metadata.event_type = "FILE_CREATION"
principal.file.size = $file_size
principal.hostname = $hostname

outcome:
  $suspicious_host = $hostname
  $admin_severity = if(principal.user.userid in %a1, "SEVERE", "MODERATE")
  $severity_tag = if($file_size > 1024, $admin_severity, "LOW")

Painel

Uma variante de painel não é aplicável a este exemplo, já que o objetivo principal é incluir tags e enriquecer eventos individuais. Embora um painel possa agregar esses eventos (por exemplo, calculando a contagem total de eventos por tag de gravidade), isso obscureceria o detalhe granular no nível da linha que essa pesquisa não agregada foi projetada para mostrar.

Pontuação de risco com base em rede

Caso de uso: identifique transferências de dados de alto risco calculando o volume cumulativo de tráfego de rede em um grupo de eventos. Isso permite identificar ameaças em que o limite mínimo de dados total excede um limite específico (por exemplo, 1024 bytes), considerando simultaneamente a gravidade da vulnerabilidade dos ativos envolvidos.

Lógica principal: usa a função de agregação sum() na seção outcome para combinar sent_bytes e received_bytes em todos os eventos em uma janela match. Para regras, a consulta usa uma instrução "if" para aplicar uma pontuação de risco mais alta se essa soma exceder um limite definido.

Exemplo: regra de pontuação de risco com base na rede

Regra

O exemplo a seguir demonstra como usar a seção outcome para calcular uma pontuação de risco dinâmica com base na atividade de rede. Ao somar o total de bytes transferidos em um grupo de eventos, a regra aplica uma prioridade maior a correspondências que excedem um limite mínimo de dados específico (1024 bytes), considerando simultaneamente a gravidade da vulnerabilidade do recurso envolvido.

rule OutcomeRuleMultiEvent {
meta:
  author = "alice@example.com"
events:
  $u.udm.principal.hostname = $hostname
  $asset_context.graph.entity.hostname = $hostname

  $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

  $risk_score = if($total_network_bytes > 1024, 100, 50) +
    max(
      if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
          "Empty asset id",
          $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

Pesquisar

O exemplo a seguir demonstra uma variante de pesquisa que correlaciona eventos de rede da UDM com o contexto de recursos do Grafo de contexto de entidade (ECG, na sigla em inglês). Ele usa uma janela de match minutos para agregar o tráfego de rede por nome de host, calcula uma pontuação de risco com base no volume de dados e na gravidade da vulnerabilidade e aplica um filtro condicional para excluir IDs de recursos específicos do conjunto de resultados final.

$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname

$severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

  $risk_score = if($total_network_bytes > 1024, 100, 50) +
    max(
      if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
        "Empty asset id",
        $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")

Painel

O exemplo a seguir ilustra uma variante dos painéis que enriquece a telemetria de rede em tempo real com dados de vulnerabilidade de recursos. Ao corresponder nomes de host em uma janela deslizante de cinco minutos, essa consulta permite que os desenvolvedores criem widgets de painel que visualizam os níveis de risco dos recursos. A lógica ajusta dinamicamente uma pontuação de riscos com base na capacidade de processamento da rede de computadores e na vulnerabilidade de maior gravidade encontrada no ativo, oferecendo uma visão priorizada de sistemas potencialmente comprometidos.

$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname

$severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

  $risk_score = if($total_network_bytes > 1024, 100, 50) +
    max(
      if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
        "Empty asset id",
        $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")

Refatorar uma regra outcome de vários eventos (pré-refatoração)

Caso de uso: melhore o desempenho do sistema e reduza a latência de processamento convertendo regras de vários eventos em regras de evento único. Isso é ideal para regras originalmente projetadas com uma seção de correspondência apenas para ativar a seção de resultado, mas que não exigem correlação entre vários eventos distintos.

Lógica principal: remove a seção match e todas as funções de agregação (por exemplo, max(), sum() ou count()) da seção outcome. Essa transição muda a regra de agrupar eventos ao longo do tempo para avaliar cada evento individualmente à medida que ele chega. match) e regras de vários eventos (regras com uma seção match).

É possível usar a seção outcome para regras de evento único (regras sem uma Se você projetou uma regra para ser de vários eventos apenas para usar a seção de resultado, é possível refatorar essas regras excluindo a seção match para melhorar o desempenho. Como sua regra não tem mais uma seção match que aplica o agrupamento, você pode receber mais detecções.

Exemplo: refatoração de resultado (pré-refatoração)

Regra

O exemplo a seguir mostra uma regra de resultado de vários eventos que usa apenas uma variável de evento. Como ele usa uma seção match, o mecanismo de regras precisa agrupar eventos em uma janela de cinco minutos antes de calcular o resultado, o que consome mais recursos do que uma avaliação de evento único.

rule OutcomeMultiEventPreRefactor {
meta:
  author = "alice@example.com"
  description = "Outcome refactor rule, before the refactor"

events:
  $u.udm.principal.hostname = $hostname

match:
  $hostname over 5m

outcome:
  $risk_score = max(if($hostname = "my-hostname", 100, 50))

condition:
  $u
}

Pesquisar

Equivalente de consulta de estatísticas

events:
  $u.udm.principal.hostname = $hostname

match:
  $hostname over 5m

outcome:
  $risk_score = max(if($hostname = "my-hostname", 100, 50))

condition:
  $u

Painel

events:
  $u.udm.principal.hostname = $hostname

match:
  $hostname over 5m

outcome:
  $risk_score = max(if($hostname = "my-hostname", 100, 50))

condition:
  $u

Refatorar uma regra de outcome de vários eventos (pós-refatoração)

Caso de uso: finalizar a otimização de uma consulta para melhorar a velocidade de processamento. Ao remover o requisito de agrupamento, a consulta agora aciona uma detecção imediatamente após a chegada de um único evento correspondente, o que é muito mais eficiente para o mecanismo de regras.

Lógica principal: exclui a seção match e remove a função aggregate (por exemplo, max()) da atribuição de variável outcome. A lógica na instrução "if" permanece a mesma, mas agora é aplicada a um único evento em vez de um grupo.

Para refatorar a consulta, exclua a seção match. Observação: você também precisa remover o agregado na seção outcome porque a consulta agora é de um único evento. Para mais informações sobre agregações, consulte agregações de resultados.

Exemplo: refatoração de resultado (: #outcome-post-refactor)

Regra

rule OutcomeSingleEventPostRefactor {
meta:
  author = "alice@example.com"
  description = "Outcome refactor rule, after the refactor"

events:
  $u.udm.principal.hostname = $hostname

// We deleted the match section.

outcome:
  // We removed the max() aggregate.
  $risk_score = if($hostname = "my-hostname", 100, 50)

condition:
  $u
}

Pesquisar

events:
  $u.udm.principal.hostname = $hostname

outcome:
  $risk_score = if($hostname = "my-hostname", 100, 50)

Painel

events:
  $u.udm.principal.hostname = $hostname

outcome:
  $risk_score = if($hostname = "my-hostname", 100, 50)

Atribuição de função a marcador de posição

Caso de uso: normalize os dados (por exemplo, padronize os domínios de e-mail) para verificar se o agrupamento na seção de correspondência está correto.

Lógica principal: atribui o resultado de re.capture() ou strings.concat() a uma variável de marcador de posição.

Exemplo: atribuição de variável de função a marcador de posição

Você pode atribuir uma variável de marcador de posição ao resultado de uma chamada de função e usar essa variável em outras seções da regra, como match, outcome ou condition.

Regra

rule FunctionToPlaceholderRule {
meta:
  author = "alice@example.com"
  description = "Rule that uses function to placeholder assignments"

events:
  $u.metadata.event_type = "EMAIL_TRANSACTION"

  // Use function-placeholder assignment to extract the
  // address from an email.
  // address@website.com -> address
  $email_to_address_only = re.capture($u.network.email.to , "(.*)@")

  // Use function-placeholder assignment to normalize an email:
  // address@-> address@company.com
  $email_from_normalized = strings.concat(
      re.capture($u.network.email.from , "(.*)@"),
      "@company.com"
  )

  // Use function-placeholder assignment to get the day of the week of the event.
  // 1 = Sunday, 7 = Saturday.
  $dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)

match:
  // Use placeholder (from function-placeholder assignment) in match section.
  // Group by the normalized from email, and expose it in the detection.
  $email_from_normalized over 5m

outcome:
  // Use placeholder (from function-placeholder assignment) in outcome section.
  // Assign more risk if the event happened on weekend.
  $risk_score = max(
      if($dayofweek = 1 or $dayofweek = 7, 10, 0)
  )

condition:
  // Use placeholder (from function-placeholder assignment) in condition section.
  // Match if an email was sent to multiple addresses.
  #email_to_address_only > 1
}

Pesquisar

metadata.event_type = "EMAIL_TRANSACTION"

// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture(network.email.from , "(.*)@")

// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
  re.capture(network.email.to , "(.*)@"),
  "@company.com"
  )

// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.event_timestamp.seconds)

match:
  // Use placeholder (from function-placeholder assignment) in match section.
  // Group by the normalized from email, and expose it in the detection.
  $email_from_normalized over 5m

outcome:
  // Use placeholder (from function-placeholder assignment) in outcome section.
  // Assign more risk if the event happened on weekend.
  $risk_score = max(
    if($dayofweek = 1 or $dayofweek = 7, 10, 0)
    )

condition:
  // Use placeholder (from function-placeholder assignment) in condition section.
  // Match if an email was sent to multiple addresses.
  #email_to_address_only > 1

Painel

O exemplo a seguir demonstra uma variante de painéis otimizada para visualização de séries temporais. Ao usar uma janela rotativa de um dia, em vez de granularidade no nível do minuto, essa consulta produz pontos de dados estáveis e não sobrepostos, ideais para representar graficamente as pontuações de risco por um período prolongado. A lógica normaliza as entidades de e-mail e aplica ponderações de risco mais altas às transações de fim de semana, fornecendo uma tendência diária clara de atividade de e-mail suspeita para monitoramento de longo prazo.

metadata.event_type = "EMAIL_TRANSACTION"

// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture(network.email.from , "(.*)@")

// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
re.capture(network.email.to , "(.*)@"),
"@company.com"
)

// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.event_timestamp.seconds)

match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m

outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
  if($dayofweek = 1 or $dayofweek = 7, 10, 0)
  )

condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1

Otimização e filtragem

A otimização eficaz de regras depende de uma filtragem de dados precisa para garantir que o mecanismo de detecção processe apenas informações significativas. Ao excluir dados "ruidosos" ou incompletos, você pode melhorar significativamente a performance das regras e garantir que os alertas gerados sejam úteis.

Tópico Exemplos
Exclusão de valor zero Exclusão explícita e implícita de valores zero

Exclusão de valor zero

Caso de uso: garanta a precisão das regras e reduza os falsos positivos filtrando explicitamente strings vazias, valores nulos ou contas de marcador de posição genéricas (por exemplo, "Convidado") que não fornecem dados de segurança úteis.

Lógica principal: usa a filtragem implícita de valores zero do mecanismo de regras para variáveis usadas na seção match, além de operadores de desigualdade explícitos (!= "") para outros campos de evento. Assim, apenas dados preenchidos acionam uma detecção.

O mecanismo de regras filtra implicitamente os valores zero de todos os marcadores de posição usados na seção match. Use a opção allow_zero_values para desativar. No entanto, para outros campos de evento referenciados, os valores zero não são excluídos, a menos que você especifique essas condições explicitamente. Para mais informações, consulte Valores zero na seção de correspondência.

Exemplo: exclusão explícita e implícita de valor zero

Regra

rule ExcludeZeroValues {
meta:
  author = "alice@example.com"

events:
  $e1.metadata.event_type = "NETWORK_DNS"
  $e1.principal.hostname = $hostname

  // $e1.principal.user.userid may be empty string.
  $e1.principal.user.userid != "Guest"

  $e2.metadata.event_type = "NETWORK_HTTP"
  $e2.principal.hostname = $hostname

  // $e2.target.asset_id cannot be empty string as explicitly specified.
  $e2.target.asset_id != ""

match:
  // $hostname cannot be empty string. The rule behaves as if the
  // predicate, `$hostname != ""` was added to the events section, because
  // `$hostname` is used in the match section.
  $hostname over 1h

condition:
  $e1 and $e2
}

Pesquisar

Você precisa declarar explicitamente que hostname não pode ser uma string vazia, já que não há um filtro de valor zero implícito para marcadores de posição na seção match.

$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname

// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"

$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname

// $e2.target.asset_id and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""

match:
  $hostname over 1h

Painel

Você precisa declarar explicitamente que hostname não pode ser uma string vazia, já que não há um filtro de valor zero implícito para marcadores de posição na seção match.

$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname

// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"

$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname

// $e2.target.asset_id and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""

match:
  $hostname over 1h

Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.