Sintaxe da linguagem YARA-L 2.0

Esta seção descreve os principais elementos da sintaxe YARA-L. Consulte também Visão geral da linguagem YARA-L 2.0.

Estrutura da regra

Para YARA-L 2.0, você deve especificar declarações de variáveis, definições e usos na seguinte ordem:

  1. meta
  2. events
  3. correspondência (opcional)
  4. resultado (opcional)
  5. condição
  6. opções (opcional)

Confira a seguir a estrutura genérica de uma regra:

rule <rule Name>
{
    meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  outcome:
    // Additional information extracted from each detection.

  condition:
    // Condition to check events and the variables used to find matches.

  options:
    // Options to turn on or off while executing this rule.
}

Sintaxe de metaseção

A metaseção é composta por várias linhas, onde cada uma delas define um par de chave-valor. Uma parte da chave precisa ser uma string sem aspas e uma parte do valor precisa estar entre aspas:

<key> = "<value>"

Este é um exemplo de uma linha de seção meta válida: none meta: author = "Chronicle" severity = "HIGH"

Sintaxe da seção "Eventos"

Na seção events, liste os predicados para especificar o seguinte:

  • Declarações de variáveis
  • Filtros de variáveis do evento
  • Mesclagens de variáveis de evento

Declarações de variáveis

Para declarações de variáveis, use esta sintaxe:

  • <EVENT_FIELD> = <VAR>
  • <VAR> = <EVENT_FIELD>

Ambos são equivalentes, conforme mostrado nos exemplos a seguir:

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

Essa declaração indica que a variável representa o campo especificado para a variável do evento. Quando o campo do evento é repetido, a variável de correspondência pode representar qualquer valor na matriz. Também é possível atribuir vários campos de evento a uma única correspondência ou variável de marcador. Esta é uma condição de mesclagem transitiva.

Por exemplo, os seguintes URLs:

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

São equivalentes a:

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

Quando uma variável é usada, ela precisa ser declarada por meio da declaração de variável. Se uma variável é usada sem declaração, ela é considerada um erro de compilação.

Filtros de variáveis do evento

Uma expressão booleana que atua sobre uma única variável de evento é considerada um filtro.

Mesclagens de variáveis de evento

Todas as variáveis de evento usadas na regra precisam ser unidas a todas as outras variáveis de evento de uma das seguintes maneiras:

  • Diretamente por uma comparação de igualdade entre campos de evento das duas variáveis de evento unidas, por exemplo: $e1.field = $e2.field A expressão não pode incluir aritmética.

  • Indiretamente, por meio de uma mesclagem transitiva envolvendo apenas um campo de evento. Consulte a declaração de variável para conferir uma definição de "mesclagem transitiva". A expressão não pode incluir aritmética.

Por exemplo, supondo que $e1, $e2 e $e3 sejam usados na regra, as seções events a seguir são válidas.

events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
  $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
  // $e1 joins with $e2 via function to event comparison
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
  // $e1 joins with $e2 via an `or` expression
  $e1.principal.hostname = $e2.src.hostname
  or $e1.principal.hostname = $e2.target.hostname
  or $e1.principal.hostname = $e2.principal.hostname
events:
  // all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  // $e1 and $e2 are transitively joined via function to event comparison
  re.capture($e2.principal.application, ".*") = $app
  $e1.principal.hostname = $app

No entanto, veja a seguir exemplos de seções events inválidas.

events:
  // Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.port = $e2.src.port + 1
events:
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
  $e1.src.port = $port

  // Arithmetic to placeholder comparison is an invalid transitive join condition.
  $e2.principal.port + 800 = $port

Corresponder sintaxe da seção

Na seção match, liste as variáveis de correspondência dos eventos do grupo antes de verificar as condições de correspondência. Esses campos são retornados com cada correspondência.

  • Especifique o que cada variável de correspondência representa na seção events.
  • Especifique o tempo a ser usado para correlacionar eventos após a palavra-chave over. Eventos fora desse período são ignorados.
  • Use a seguinte sintaxe para especificar a duração: <number><m/h/d>

    Em que m/h/d significa minutos, horas e dias, respectivamente.

  • O tempo mínimo que você pode especificar é 1 minuto.

  • O tempo máximo que você pode especificar é 48 horas.

Veja a seguir um exemplo de um match válido:

$var1, $var2 over 5m

Essa instrução retorna $var1 e $var2 (definidos na seção events) quando a regra encontra uma correspondência. O tempo especificado é de 5 minutos. Eventos com mais de cinco minutos de diferença não são correlacionados e, portanto, são ignorados pela regra.

Aqui está outro exemplo de uma seção match válida:

$user over 1h

Essa instrução retorna $user quando a regra encontra uma correspondência. A janela de tempo especificada é de 1 hora. Os eventos com mais de uma hora de diferença não são correlacionados. A regra não os considera uma detecção.

Aqui está outro exemplo de uma seção match válida:

$source_ip, $target_ip, $hostname over 2m

Essa instrução retorna $source_ip, $target_ip e $hostname quando a regra encontra uma correspondência. A janela de tempo especificada é de dois minutos. Os eventos com mais de dois minutos de diferença não são correlacionados. A regra não os considera uma detecção.

Os exemplos a seguir ilustram seções match inválidas:

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

Processamento de valor zero na seção de correspondência

O Rules Engine filtra implicitamente os valores zero para todos os marcadores de posição usados na seção de correspondência ("" para string, 0 para números, false para booleanos, o valor na posição 0 para tipos enumerados). O exemplo a seguir ilustra as regras que filtram os valores zero.

rule ZeroValuePlaceholderExample {
  meta:
  events:
    // Because $host is used in the match section, the rule behaves
    // as if the following predicate was added to the events section:
    // $host != ""
    $host = $e.principal.hostname

    // Because $otherPlaceholder was not used in the match section,
    // there is no implicit filtering of zero values for $otherPlaceholder.
    $otherPlaceholder = $e.principal.ip

  match:
    $host over 5m

  condition:
    $e
}

No entanto, se um marcador for atribuído a uma função, as regras não filtram implicitamente os valores zero dos marcadores de posição usados na seção de correspondência. O exemplo a seguir ilustra as regras que filtram os valores zero:

rule ZeroValueFunctionPlaceholder {
  meta:
  events:
    // Even though $ph is used in the match section, there is no
    // implicit filtering of zero values for $ph, because $ph is assigned to a function.
    $ph = re.capture($e.principal.hostname, "some-regex")

  match:
    $ph over 5m

  condition:
    $e
}

Para desativar a filtragem implícita de valores zero, use a opção allow_zero_values na seção de opções.

Janela de salto

Por padrão, as regras YARA-L 2.0 com uma seção de correspondência são avaliadas usando janelas de salto. O período de execução da regra é dividido em um conjunto de janelas de salto sobrepostas, cada uma com a duração especificada na seção match. Em seguida, os eventos são correlacionados dentro de cada janela de salto.

Por exemplo, para uma regra executada no período [1:00, 2:00], com uma seção match em 30m, um possível conjunto de janelas de salto sobrepostas que podem ser geradas é [1:00, 1:30], [1:03, 1:33] e [1:06, 1:36]. Essas janelas são usadas para correlacionar vários eventos.

Janela deslizante

O uso de janelas de salto não é uma maneira eficaz de pesquisar eventos que ocorrem em uma ordem específica (por exemplo, e1 acontece até dois minutos após e2). Uma ocorrência do evento e1 e uma ocorrência do evento e2 são correlacionadas somente se estiverem na mesma janela de salto gerada.

Uma forma mais eficaz de pesquisar essas sequências de eventos é usar janelas deslizantes. Janelas deslizantes com a duração especificada na seção match são geradas ao começar ou terminar com uma variável de evento dinâmico especificada. Os eventos são, então, correlacionados dentro de cada janela deslizante. Isso possibilita pesquisar eventos que ocorrem em uma ordem específica (por exemplo, e1 acontece dentro de dois minutos de e2). Uma ocorrência do evento e1 e uma ocorrência do evento e2 serão correlacionadas se o evento e1 ocorrer dentro da duração da janela deslizante após o evento e2.

Especifique janelas deslizantes na seção match de uma regra desta maneira:

<match-var-1>, <match-var-2>, ... over <duration> before|after <pivot-event-var>

A variável do evento dinâmico é a variável do evento em que as janelas deslizantes são baseadas. Se você usar a palavra-chave before, janelas deslizantes serão geradas, terminando com cada ocorrência do evento dinâmico. Se a palavra-chave after for usada, as janelas deslizantes serão geradas começando com cada ocorrência do evento dinâmico.

Confira a seguir exemplos de usos válidos de janelas deslizantes:

  • $var1, $var2 over 5m after $e1
  • $user over 1h before $e2

Veja um exemplo de regra de janela deslizante.

O Google recomenda não usar janelas deslizantes para regras de evento único, porque as janelas deslizantes foram projetadas para detectar vários eventos. Se uma das suas regras se enquadra nessa categoria, o Google recomenda uma das seguintes soluções alternativas:

  • Converta a regra para usar várias variáveis de evento e atualize a seção de condição se a regra exigir mais de uma ocorrência do evento.
    • Outra opção é adicionar filtros de carimbo de data/hora em vez de usar uma janela deslizante. Por exemplo, $permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds.
  • Remova a janela deslizante.

Sintaxe da seção de resultados

Na seção outcome, é possível definir até 20 variáveis de resultado, com nomes arbitrários. Esses resultados serão armazenados nas detecções geradas pela regra. Cada detecção pode ter valores diferentes para os resultados.

O nome do resultado, $risk_score, é especial. Opcionalmente, você pode definir um resultado com esse nome e, se fizer isso, ele precisa ser um número inteiro ou tipo flutuante. Se preenchido, o risk_score será mostrado na visualização do Enterprise Insights para alertas provenientes de detecções de regras.

Se você não incluir uma variável $risk_score na seção de resultado de uma regra, um dos valores padrão a seguir será definido:

  • Se a regra estiver configurada para gerar um alerta, $risk_score será definido como 40.
  • Se a regra não estiver configurada para gerar um alerta, $risk_score será definido como 15.

O valor de $risk_score é armazenado no campo security_result.risk_score UDM.

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 calculá-la. Oferecemos suporte aos seguintes tipos de dados de resultados:

  • integer
  • flutuantes
  • string
  • listas de números inteiros
  • listas de pontos flutuantes
  • listas de strings

Lógica condicional

Use a lógica condicional para calcular o valor de um resultado. As condicionais são especificadas usando este 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 avaliado como um valor booleano. Uma expressão BOOL_CLAUSE assume uma forma semelhante às expressões na seção events. Por exemplo, ele pode conter:

  • Nomes de campos de UDM com operador de comparação, por exemplo:

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

  • variável de marcador de posição que foi definida na seção events, por exemplo:

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

  • outra variável de resultado definida na seção outcome, por exemplo:

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

  • funções que retornam um booleano, por exemplo:

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

  • procure em uma lista de referências, por exemplo:

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

  • comparação de agregação, por exemplo:

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

THEN_CLAUSE e ELSE_CLAUSE precisam ser do mesmo tipo de dados. Aceitamos números inteiros, pontos flutuantes e strings.

É possível omitir ELSE_CLAUSE se o tipo de dados for inteiro ou um ponto flutuante. Se omitido, o ELSE_CLAUSE será avaliado como 0. Exemplo:

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

Forneça ELSE_CLAUSE se o tipo de dados for string ou THEN_CLAUSE for uma variável de marcador ou de resultado.

Operações matemáticas

É possível usar operações matemáticas para calcular números inteiros ou tipos de dados flutuantes nas seções outcome e events de uma regra. O Chronicle oferece suporte a 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 tipos de operandos abaixo, desde que cada operando e toda a expressão aritmética sejam agregadas corretamente (consulte Agregações):

  • Campos de eventos numéricos
  • Variáveis numéricas de marcador de posição definidas na seção events
  • Variáveis de resultado numéricas definidas na seção outcome
  • Funções que retornam ints ou floats
  • Agregações que retornam ints ou flutuações

Módulos não são permitidos em flutuações.

Variáveis de marcador nos resultados

Ao calcular variáveis de resultado, use variáveis de marcador de posição que foram definidas na seção de eventos da sua regra. Neste exemplo, suponha que $email_sent_bytes tenha sido definido na seção de eventos da regra:

Exemplo de evento único:

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

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 de vários eventos:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Use placeholder directly in an aggregation function.
  $max_email_size = max($email_sent_bytes)

  // Use placeholder in a mathematical computation.
  $total_bytes_exfiltrated = sum(
    1024
    + $email_sent_bytes
    + $file_event.principal.file.size
  )

condition:
  $email_event and $file_event

Variáveis de resultado em expressões de atribuição de resultados

As variáveis de resultado podem ser usadas para derivar outras, 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 regra. Quando usadas em uma expressão de atribuição, as variáveis de resultado não podem ser agregadas. Consulte Agregações.

No exemplo abaixo, a variável de resultado $risk_score deriva o valor da variável de resultado $event_count:

Exemplo de vários eventos:

match:
  // This is a multi event rule 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 above 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 any ou all

Agregações

Campos de eventos repetidos são valores não escalares. Ou seja, uma única variável aponta para diversos valores. Por exemplo, a variável do campo de evento $e.target.ip é um campo repetido e pode ter zero, um ou muitos valores de IP. É um valor não escalar. Já a variável de campo do 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 eventos não repetidos e repetidos usados na seção de resultados de uma regra com uma janela de correspondência são valores não escalares. Por exemplo, a regra a seguir agrupa eventos usando uma seção de correspondência e se refere a um campo de evento não repetido na seção de resultado:

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

Qualquer janela de cinco minutos em que a regra for executada pode conter zero, um ou vários eventos. A seção de resultados opera em todos os eventos em uma janela de correspondência. Qualquer variável de campo do evento mencionada na seção de resultado pode apontar para zero, um ou muitos valores do campo em cada evento na janela de correspondência. Na regra anterior, se uma janela de cinco minutos contiver cinco eventos $e, $e.principal.hostname na seção de resultados vai apontar para cinco nomes de host diferentes. A variável do campo de evento $e.principal.hostname é, portanto, um valor não escalar na seção de resultado dessa regra.

Como as variáveis de resultado precisam sempre produzir um único valor escalar, qualquer valor não escalar de que uma atribuição de resultado depende precisa ser agregado para produzir um único valor escalar. Em uma seção de resultados, os valores não escalares abaixo precisam ser agregados:

  • Campos de evento (repetidos ou não repetidos) quando a regra usa uma seção de correspondência
  • Marcadores de eventos (repetidos ou não) quando a regra usa uma seção de correspondência
  • Campos de eventos repetidos quando a regra não usa uma seção de correspondência
  • Marcadores de eventos repetidos quando a regra não usa uma seção de correspondência

Campos de eventos escalares, marcadores de eventos escalares e constantes podem ser agrupados em uma agregação em uma regra que não usa uma seção de correspondência. No entanto, a maioria das agregações vai gerar o valor agrupado e, portanto, é desnecessária. A exceção é a agregação array(), que pode ser usada para converter um valor escalar em uma matriz.

As variáveis de resultado são tratadas como agregações: não podem ser agregadas novamente quando referidas em outra atribuição de resultado.

Você pode usar as seguintes funções de agregação:

  • max(): gera o máximo sobre todos os valores possíveis. Funciona apenas com números inteiros e flutuantes.
  • min(): gera o mínimo entre todos os valores possíveis. Funciona apenas com números inteiros e flutuantes.
  • sum(): gera a soma de todos os valores possíveis. Funciona apenas com números inteiros e flutuantes.
  • count_distinct(): coleta todos os valores possíveis e gera a contagem distinta de valores possíveis.
  • count(): se comporta 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 desses valores. Ela truncará a lista de valores distintos para 25 elementos aleatórios. A eliminação de duplicação para uma lista distinta é aplicada primeiro e, depois, o truncamento.
  • array(): se comporta como array_distinct(), mas retorna uma lista não distinta de valores. Ela também trunca a lista de valores para 25 elementos aleatórios.

A função agregada é importante quando uma regra inclui uma seção condition que especifica a existência de vários eventos, porque a função agregada operará em todos os eventos que geraram a detecção.

Por exemplo, se as seções outcome e condition contiverem:

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 de condição exige que haja mais de um event para cada detecção, as funções de agregação operam em vários eventos. Suponha que os seguintes eventos tenham gerado uma detecção:

event:
  // UDM event 1
  asset_id="asset-a"

event:
  // UDM event 2
  asset_id="asset-b"

event:
  // UDM event 3
  asset_id="asset-b"

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"]

O que você precisa saber ao usar a seção de resultados:

Outras observações e restrições:

  • A seção outcome não pode referenciar uma nova variável de marcador de posição que ainda não foi definida na seção events ou na seção outcome.
  • A seção outcome não pode usar variáveis de evento que não foram definidas na seção events.
  • A seção outcome pode usar um campo de evento que não foi usado na seção events, já que a variável a que o campo do evento pertence já foi definida na seção events.
  • A seção outcome só pode correlacionar variáveis de evento que já foram correlacionadas na seção events. As correlações acontecem quando dois campos de evento de diferentes variáveis de evento são igualados.

É possível encontrar um exemplo usando a seção de resultados em Visão geral do YARA-L 2.0. Consulte Criar análises com reconhecimento de contexto para detalhes sobre como eliminar a duplicação da detecção com a seção de resultados.

Sintaxe da seção de condição

  • especificar uma condição de correspondência em eventos e marcadores de posição definidos na seção events. Consulte a seção a seguir, Condicionais de evento e marcador de posição, para mais detalhes.
  • (opcional) use a palavra-chave and para especificar uma condição de correspondência usando variáveis de resultado definidas na seção outcome. Consulte a seção a seguir, Condicionais de resultado, para saber mais detalhes.

Contar caractere

O caractere # é especial na seção condition. Se for usado antes de qualquer nome de variável de marcador ou evento, ele representa o número de eventos ou valores distintos que atendem a todas as condições da seção events.

Por exemplo, #c > 1 significa que a variável c precisa ocorrer mais de uma vez.

Caractere de valor

O caractere $ é especial na seção condition. Se for usado antes de qualquer nome de variável de resultado, ele representará o valor desse resultado.

Se for usado antes de qualquer nome de variável de marcador ou evento (por exemplo, $event), ele representará #event > 0.

Condicionais de evento e marcador de posição

Liste os predicados de condição para eventos e variáveis de marcador aqui, unidos às palavras-chave and ou or. A palavra-chave and pode ser usada entre qualquer condição, mas or só pode ser usada quando a regra tem apenas uma única variável de evento.

Um exemplo válido de uso de or entre dois marcadores de posição no mesmo evento:

rule ValidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"

      // Note that all placeholders use the same event variable.
      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.
      $ph2 = $e.principal.ip  // Define a second placeholder variable to put in condition section.
      $ph3 = $e.principal.hostname  // Define a third placeholder variable to put in condition section.

  match:
    $ph over 5m

  condition:
    $ph2 or $ph3
}

Um exemplo inválido de uso de or entre duas condições em eventos diferentes:

rule InvalidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"
      $e2.graph.metadata.entity_type = "FILE"
      $e2.graph.entity.hostname  = $e.principal.hostname

      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.

  match:
    $ph over 5m

  condition:
    $e or $e2 // This line will cause an error because there is an or between events.
}

Condições limitadas e ilimitadas

As condições a seguir são limitadas. Eles forçam a variável do evento associada a existir, o que significa que pelo menos uma ocorrência do evento precisa aparecer em qualquer detecção.

  • $var // equivalent to #var > 0
  • #var > n // where n >= 0
  • #var >= m // where m > 0

As condições a seguir são ilimitadas. Eles permitem que a variável de evento associada não exista, o que significa que é possível que nenhuma ocorrência do evento apareça em uma detecção e qualquer referência a campos na variável de evento produza um valor zero. Condições ilimitadas podem ser usadas para detectar a ausência de um evento durante um período. Por exemplo, um evento de ameaça sem um evento de mitigação em uma janela de 10 minutos. As regras que usam condições ilimitadas são chamadas de regras de não existência.

  • !$var // equivalent to #var = 0
  • #var >= 0
  • #var < n // where n > 0
  • #var <= m // where m >= 0

Requisitos para não existência

Para que uma regra inexistente seja compilada, ela precisa atender aos seguintes requisitos:

  1. Pelo menos um evento de UDM precisa ter uma condição limitada, ou seja, precisa existir pelo menos um evento de UDM.
  2. Se um marcador tiver uma condição ilimitada, ele precisará estar associado a pelo menos um evento UDM limitado.
  3. Se uma entidade tem uma condição ilimitada, ela precisa estar associada a pelo menos um evento UDM limitado.

Considere a seguinte regra com a seção de condição omitida:

rule NonexistenceExample {
  meta:
  events:
      $u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
      $u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
      $e1.graph.metadata.entity_type = "FILE"        // $e1 is an Entity.
      $e2.graph.metadata.entity_type = "FILE"        // $e2 is an Entity.

      $user = $u1.principal.user.userid // Match variable is required for Multi-Event Rule.

      // Placeholder Associations:
      //   u1        u2
      //   |  \    /
      // port   ip
      //   |       \
      //   e1        e2
      $u1.target.port = $port
      $e1.graph.entity.port = $port
      $u1.principal.ip = $ip
      $u2.target.ip = $ip
      $e2.graph.entity.ip = $ip

      // UDM-Entity Associations:
      // u1 - u2
      // |  \  |
      // e1   e2
      $u1.metadata.event_type = $u2.metadata.event_type
      $e1.graph.entity.hostname = $u1.principal.hostname
      $e2.graph.entity.hostname = $u1.target.hostname
      $e2.graph.entity.hostname = $u2.principal.hostname

  match:
    $user over 5m

  condition:
      <condition_section>
}

Confira a seguir exemplos válidos para o <condition_section>:

  • $u1 and !$u2 and $e1 and $e2
    • Todos os eventos e entidades de UDM estão presentes na seção de condição.
    • Pelo menos um evento de UDM é limitado.
  • $u1 and !$u2 and $e1 and !$e2
    • $e2 é ilimitado, o que é permitido porque está associado à $u1, que é limitada. Se $e2 não estivesse associado a $u1, ele seria inválido.
  • #port > 50 and #ip = 0
    • Não há eventos e entidades de UDM na seção de condição. No entanto, os marcadores de posição presentes abrangem todos os eventos e entidades de UDM.
    • $ip está atribuído a $u1 e $u2, e #ip = 0 é uma condição ilimitada. No entanto, as condições limitadas são mais fortes que as ilimitadas. Como $port é atribuído a $u1 e #port > 50 é uma condição limitada, $u1 ainda está limitado.

Confira abaixo exemplos inválidos para <condition_section>:

  • $u1 and $e1
    • Cada evento e entidade do UDM que aparece na seção "Eventos" precisa aparecer na seção "Condição" ou ter um marcador atribuído a eles na seção "Condição".
  • $u1, $u2, $e1, $u2, #port > 50
    • Não são permitidas vírgulas como separadores de condição.
  • !$u1 and !$u2 and $e1 and $e2
    • Viola o primeiro requisito de que pelo menos um evento de UDM seja limitado.
  • ($u1 or #port < 50) and $u2 and $e1 and $e2
    • A palavra-chave or não é compatível com condições ilimitadas.
  • ($u1 or $u2) and $e1 and $e2
    • A palavra-chave or não tem suporte entre diferentes variáveis de evento.
  • not $u1 and $u2 and $e1 and $e2
    • A palavra-chave not não é permitida para condições de evento e marcador de posição.
  • #port < 50 and #ip = 0
    • Os marcadores presentes abrangem todos os eventos e entidades de UDM. No entanto, todas as condições são ilimitadas. Isso significa que nenhum dos eventos do UDM é limitado, fazendo com que a regra não seja compilada.

Condicionais de resultado

Liste os predicados de condição para as variáveis de resultado aqui, unidos com a palavra-chave and ou or ou precedidos pela palavra-chave not.

Especifique os condicionais de resultado de maneira diferente dependendo do tipo da variável:

  • integer: compara com um literal de número inteiro com os operadores =, >, >=, <, <=, !=, por exemplo:

    $risk_score > 10

  • float: compara com um literal flutuante com operadores =, >, >=, <, <=, !=, por exemplo:

    $risk_score <= 5.5

  • string: compara com um literal de string com = ou !=, por exemplo:

    $severity = "HIGH"

  • lista de números inteiros ou matrizes: especifique a condição usando a função arrays.contains, por exemplo:

    arrays.contains($event_ids, "id_1234")

Classificação de regras

Especificar uma condição de resultado em uma regra que tenha uma seção de correspondência significa que ela será classificada como uma regra de vários eventos para a cota de regras. Consulte regra de evento único e regra de vários eventos para mais informações sobre as classificações de um ou vários eventos.

Sintaxe da seção de opções

Na seção options, especifique as opções para a regra. Confira um exemplo de como especificar a seção de opções:

rule RuleOptionsExample {
  // Other rule sections

  options:
    allow_zero_values = true
}

Você pode especificar opções usando a sintaxe key = value, em que key precisa ser um nome predefinido de opção e value precisa ser um valor válido para a opção, conforme especificado para as seguintes opções:

allow_zero_values

Os valores válidos para essa opção são true e false, que determinam se ela será ativada ou não. O valor padrão é false. Essa opção será desativada se não for especificada na regra.

Para ativar essa configuração, adicione o seguinte à seção de opções da sua regra: allow_zero_values = true. Isso vai evitar que a regra filtre implicitamente os valores zero dos marcadores de posição usados na seção de correspondência, conforme descrito em Processamento de valor zero na seção de correspondência.

Expressões booleanas

As expressões booleanas são expressões com um tipo booleano.

Comparações

Para uma expressão binária simples usar como condição, use a seguinte sintaxe:

  • <EXPR> <OP> <EXPR>

A expressão pode ser um campo de evento, uma variável, um literal ou uma expressão de função.

Exemplo:

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port
  • $e1.source.hostname != $e2.target.hostname
  • $e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
  • $port >= 25
  • $host = $e2.target.hostname
  • "google-test" = strings.concat($e.principal.hostname, "-test")
  • "email@google.org" = re.replace($e.network.email.from, "com", "org")

Se ambos os lados forem literais, isso será considerado um erro de compilação.

Funções

Algumas expressões de função retornam um valor booleano, que pode ser usado como um predicado individual na seção events. Essas funções são:

  • re.regex()
  • net.ip_in_range_cidr()

Exemplo:

  • re.regex($e.principal.hostname, `.*\.google\.com`)
  • net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

Expressões de lista de referência

Você pode usar listas de referência na seção de eventos. Consulte a seção sobre Listas de referência para mais detalhes.

Expressões lógicas

É possível usar os operadores lógicos and e or na seção events, conforme mostrado nos exemplos a seguir:

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

Por padrão, a ordem de precedência da maior para a menor é not, and, or.

Por exemplo, "a ou b e c" é avaliado como "a ou (b e c)" quando os operadores or e and são definidos explicitamente na expressão.

Na seção events, os predicados serão mesclados usando o operador and se um operador não for definido explicitamente.

A ordem de avaliação poderá ser diferente se o operador and estiver implícito na expressão.

Por exemplo, considere as seguintes expressões de comparação em que or é definido explicitamente. O operador and está implícito.

$e1.field = "bat"
or $e1.field = "baz"
$e2.field = "bar"

Este exemplo é interpretado da seguinte maneira:

($e1.field = "bat" or $e1.field = "baz")
and ($e2.field = "bar")

Como or é definido explicitamente, os predicados em torno de or são agrupados e avaliados primeiro. O último predicado, $e2.field = "bar", é mesclado implicitamente usando and. O resultado é essa ordem das mudanças de avaliação.

Tipos enumerados

Você pode usar os operadores com tipos enumerados. Ele pode ser aplicado a regras para simplificar e otimizar o desempenho (use o operador em vez de listas de referência).

No exemplo a seguir, "USER_UNCATEGORIZED" e "USER_RESOURCE_DELETION" correspondem a 15.000 e 15.014, então a regra vai procurar todos os eventos listados:

$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"

Lista de eventos:

  • USER_RESOURCE_DELETION
  • USER_RESOURCE_UPDATE_CONTENT
  • USER_RESOURCE_UPDATE_PERMISSIONS
  • USER_STATS
  • USER_UNCATEGORIZED

Modificador sem uso de maiúsculas

Quando você tem uma expressão de comparação entre valores de string ou uma expressão regular, pode acrescentar nenhum caso no final da expressão para ignorar a capitalização.

  • $e.principal.hostname != "http-server" nocase
  • $e1.principal.hostname = $e2.target.hostname nocase
  • $e.principal.hostname = /dns-server-[0-9]+/ nocase
  • re.regex($e.target.hostname, `client-[0-9]+`) nocase

Não pode ser usado quando um tipo de campo é um valor enumerado. Os exemplos abaixo são inválidos e vão gerar erros de compilação:

  • $e.metadata.event_type = "NETWORK_DNS" nocase
  • $e.network.ip_protocol = "TCP" nocase

Campos repetidos

No modelo de dados unificado (UDM, na sigla em inglês), alguns campos são rotulados como repetidos, o que indica que são listas de valores ou outros tipos de mensagens.

Campos repetidos e expressões booleanas

Há dois tipos de expressões booleanas que atuam em campos repetidos:

  1. Modificado
  2. Não modificado

Considere o seguinte evento:

event_original {
  principal {
    // ip is a repeated field
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "host"
  }
}

Expressões modificadas

As seções abaixo descrevem a finalidade e como usar os modificadores any e all em expressões.

qualquer um

Se qualquer elemento do campo repetido satisfizer a condição, o evento como um todo atende à condição.

  • event_original atende a any $e.principal.ip = "192.0.2.1".
  • event_original falha any $e.repeated_field.field_a = "9.9.9.9.
todas

Se todos os elementos do campo repetido satisfizerem a condição, o evento como um todo atenderá à condição.

  • event_original atende a net.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8").
  • event_original falha all $e.principal.ip = "192.0.2.2".

Ao gravar uma condição com any ou all, esteja ciente de que negar a condição com not pode não ter o mesmo significado que usar o operador negado.

Exemplo:

  • not all $e.principal.ip = "192.168.12.16" verifica se nem todos os endereços IP correspondem a 192.168.12.16, o que significa que a regra está verificando se pelo menos um endereço IP não corresponde a 192.168.12.16.
  • all $e.principal.ip != "192.168.12.16" verifica se todos os endereços IP não correspondem a 192.168.12.16, o que significa que a regra está verificando se nenhum endereço IP corresponde a 192.168.12.16.

Limitações:

  • Os operadores any e all são compatíveis apenas com campos repetidos (não campos escalares).
  • any e all não podem ser usados para mesclar dois campos repetidos. Por exemplo, any $e1.principal.ip = $e2.principal.ip não é válido.
  • Os operadores any e all não são compatíveis com a expressão da lista de referência.

Expressões não modificadas

Com expressões não modificadas, cada elemento no campo repetido é tratado individualmente. Se o campo repetido de um evento tiver n elementos, a regra será aplicada a n cópias do evento, em que cada cópia tiver um dos elementos do campo repetido. Essas cópias são temporárias e não são armazenadas.

A regra é aplicada nas seguintes cópias:

texto do evento principal.ip principal.hostname
event_copy_1 "192.0.2.1" "host"
event_copy_2 "192.0.2.2" "host"
event_copy_3 "192.0.2.3" "host"

Se qualquer cópia de evento satisfizer todas as condições não modificadas no campo repetido, o evento como um todo atende a todas as condições. Isso significa que, se você tiver várias condições em um campo repetido, a cópia do evento precisará satisfazer a todas elas. Os exemplos de regras a seguir usam o conjunto de dados de exemplo anterior para demonstrar esse comportamento.

A regra a seguir retorna uma correspondência quando executada no conjunto de dados de exemplo event_original, porque event_copy_1 satisfaz todos os predicados de eventos:

rule repeated_field_1 {
  meta:
  events:
    net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/8") // Checks if IP address matches 192.x.x.x
    $e.principal.ip = "192.0.2.1"
  condition:
    $e
}

A regra a seguir não retorna uma correspondência quando executada no conjunto de dados de exemplo event_original, porque não há cópia de evento em $e.principal.ip que satisfaça todos os predicados de evento.

rule repeated_field_2 {
  meta:
  events:
    $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.2"
  condition:
    $e
}

As expressões modificadas em campos repetidos são compatíveis com expressões não modificadas em campos repetidos porque a lista de elementos é a mesma para cada cópia de evento. Considere a seguinte regra:

rule repeated_field_3 {
  meta:
  events:
    any $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.3"
  condition:
    $e
}

A regra é aplicada nas seguintes cópias:

texto do evento principal.ip qualquer $e.principal.ip
event_copy_1 "192.0.2.1" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_2 "192.0.2.2" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_3 "192.0.2.3" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]

Nesse caso, todas as cópias satisfazem any $e.principal.ip = "192.0.2.1", mas apenas event_copy_3 atende a $e.principal.ip = "192.0.2.3". Como resultado, o evento como um todo seria correspondente.

Outra maneira de pensar sobre esses tipos de expressão é:

  • As expressões em campos repetidos que usam any ou all operam na lista em event_original.
  • As expressões em campos repetidos que não usam any ou all operam em eventos event_copy_n individuais.

Campos repetidos e marcadores de posição

Os campos repetidos funcionam com atribuições de marcador de posição. Semelhante às expressões não modificadas em campos repetidos, uma cópia do evento é feita para cada elemento. Usando o mesmo exemplo de event_copy, o marcador usa o valor do campo repetido de event_copy_n para cada cópia de evento, em que n é o número da cópia do evento. Se o marcador for usado na seção de correspondência, isso poderá resultar em várias correspondências.

O exemplo a seguir gera uma correspondência. O marcador $ip é igual a 192.0.2.1 para event_copy_1, o que satisfaz os predicados na regra. As amostras de eventos de correspondência contêm um único elemento, event_original.

// Generates 1 match.
rule repeated_field_placeholder1 {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1"
    $host = $e.principal.hostname

  match:
    $host over 5m

  condition:
    $e
}

O exemplo a seguir gera três correspondências. O marcador $ip é igual a valores diferentes, para cada uma das cópias event_copy_n diferentes. O agrupamento é feito em $ip, já que está na seção de correspondência. Portanto, você tem três correspondências em que cada uma tem um valor diferente para a variável de correspondência $ip. Cada correspondência tem a mesma amostra de evento: um único elemento, event_original.

// Generates 3 matches.
rule repeated_field_placeholder2 {
  meta:
  events:
    $ip = $e.principal.ip
    net.ip_in_range_cidr($ip, "192.0.2.0/8") // Checks if IP matches 192.x.x.x

  match:
    $ip over 5m

  condition:
    $e
}

Resultados usando marcadores de posição atribuídos a campos repetidos

Os marcadores de posição são atribuídos a cada elemento de cada campo repetido, não à lista inteira. Assim, quando usados na seção de resultados, o resultado é calculado usando apenas os elementos que atenderam às seções anteriores.

Considere a seguinte regra:

rule outcome_repeated_field_placeholder {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1" or $ip = "192.0.2.2"
    $host = $e.principal.hostname

  match:
    $host over 5m

  outcome:
    $o = array_distinct($ip)

  condition:
    $e
}

Há quatro etapas de execução para essa regra. A primeira etapa é a cópia de eventos:

texto do evento $ip $host $e
event_copy_1 "192.0.2.1" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id
event_copy_3 "192.0.2.3" "host" event_id

A seção de eventos filtra as linhas que não correspondem aos filtros:

texto do evento $ip $host $e
event_copy_1 "192.0.2.1" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id

event_copy_3 foi filtrado porque "192.0.2.3" não atende a $ip = "192.0.2.1" or $ip = "192.0.2.2".

A seção de correspondência agrupa por variáveis de correspondência, e a seção de resultados agrega informações em cada grupo:

$host $o $e
"host" ["192.0.2.1", "192.0.2.2"] event_id

$o = array_distinct($ip) é calculado usando $ip do estágio anterior, e não da etapa de cópia de eventos.

Por fim, a seção de condição filtra cada grupo. Como essa regra apenas verifica a existência de $e, a linha anterior produzirá uma única detecção.

$o não contém todos os elementos de $e.principal.ip porque nem todos os elementos atendem a todas as condições na seção de eventos. No entanto, todos os elementos de e.principal.ip aparecerão na amostra de evento porque ela usa event_original.

Indexação de matriz

É possível realizar a indexação da matriz em campos repetidos. Para acessar o enésimo elemento de campo repetido, use a sintaxe de lista padrão (os elementos são indexados em 0). Um elemento fora dos limites retorna o valor padrão.

  • $e.principal.ip[0] = "192.168.12.16"
  • $e.principal.ip[999] = "" Se houver menos de 1.000 elementos, será avaliado como true.

Limitações:

  • Um índice precisa ser um literal inteiro não negativo. Por exemplo, $e.principal.ip[-1] não é válido.
  • Valores que têm um tipo int (por exemplo, um marcador definido como int) não contam.
  • A indexação de matrizes não pode ser combinada com any ou all. Por exemplo, any $e.intermediary.ip[0] não é válido.
  • A indexação de matrizes não pode ser combinada com a sintaxe do mapa. Por exemplo, $e.additional.fields[0]["key"] não é válido.
  • Se o caminho do campo tiver vários campos repetidos, todos eles precisarão usar a indexação de matriz. Por exemplo, $e.intermediary.ip[0] não é válido porque intermediary e ip são campos repetidos, mas há apenas um índice para ip.

Mensagens repetidas

Quando um campo message é repetido, um efeito indesejado é reduzir a probabilidade de uma correspondência. Isso é ilustrado nos exemplos a seguir.

Considere o seguinte evento:

event_repeated_message {
  // about is a repeated message field.
  about {
    // ip is a repeated string field.
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "alice"
  }
  about {
    hostname: "bob"
  }
}

Como indicado para expressões não modificadas em campos repetidos, uma cópia temporária do evento é feita para cada elemento do campo repetido. Considere a seguinte regra:

rule repeated_message_1 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about.hostname = "bob"
  condition:
    $e
}

A regra é aplicada nas seguintes cópias:

texto do evento about.ip about.hostname
event_copy_1 "192.0.2.1" “alice”
event_copy_2 "192.0.2.2" “alice”
event_copy_3 "192.0.2.3" “alice”
event_copy_4 "" “bob”

O evento não corresponde à regra porque não existe uma cópia do evento que satisfaça a todas as expressões.

Mensagens repetidas e indexação de matriz

Outro comportamento inesperado pode ocorrer ao usar a indexação de matriz com expressões não modificadas em campos de mensagens repetidos. Considere a seguinte regra de exemplo que usa indexação de matriz:

rule repeated_message_2 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about[1].hostname = "bob"
  condition:
    $e
}

A regra é aplicada às seguintes cópias:

texto do evento about.ip sobre[1].nomedohost
event_copy_1 "192.0.2.1" “bob”
event_copy_2 "192.0.2.2" “bob”
event_copy_3 "192.0.2.3" “bob”
event_copy_4 "" “bob”

Como event_copy_1 atende a todas as expressões em repeated_message_2, o evento corresponde à regra.

Isso pode causar um comportamento inesperado, porque a regra repeated_message_1 não tinha indexação de matriz e não produziu correspondências, enquanto a regra repeated_message_2 usou a indexação de matriz e produziu uma correspondência.

Comentários

Defina comentários com dois caracteres de barra (// comment) ou de várias linhas separados usando caracteres de barra asterisco (/* comment */), como você faria em C.

Literais

São aceitos literais, números inteiros e flutuantes não negativos, strings, booleanos e expressões regulares.

Literais de strings e expressões regulares

Você pode usar qualquer um dos seguintes caracteres de aspas para delimitar strings em YARA-L 2.0. No entanto, o texto citado é interpretado de maneira diferente dependendo de qual você usar.

  1. Aspas duplas (") — use para strings normais. É necessário incluir caracteres de escape.
    Por exemplo: "hello\tworld" —\t é interpretado como uma tabulação

  2. aspas curvas (`): use para interpretar todos os caracteres literalmente.
    Por exemplo: "hello\tworld" —\t não é interpretado como uma tabulação

Para expressões regulares, você tem duas opções.

Se você quiser usar expressões regulares diretamente sem a função re.regex(), use /regex/ para os literais de expressão regular.

Também é possível usar literais de string como literais de expressão regular com a função re.regex(). Observe que, para literais de string de aspas duplas, é preciso escapar caracteres de barra invertida com caracteres de barra invertida, que podem parecer estranhos.

Por exemplo, as expressões regulares a seguir são equivalentes:

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

O Google recomenda usar caracteres de aspas para strings em expressões regulares para facilitar a leitura.

Operadores

Você pode usar os seguintes operadores em YARA-L:

Operador Descrição
= igual/declaração
!= diferente
< menor que
<= menor que ou igual a
> maior que
>= maior ou igual a

Variáveis.

No YARA-L 2.0, todas as variáveis são representadas como $<variable name>.

Você pode definir os seguintes tipos de variáveis:

  • Variáveis de evento: representam grupos de eventos em formato normalizado (UDM, na sigla em inglês) ou eventos de entidade. Especifique as condições das variáveis de evento na seção events. Para identificar as variáveis, use um nome, uma fonte e campos de eventos. As origens permitidas são udm (para eventos normalizados) e graph (para eventos de entidade). Se a fonte for omitida, udm será definida como a fonte padrão. Os campos de evento são representados como uma cadeia de .<nome do campo> (por exemplo, $e.field1.field2). As cadeias de campos de evento sempre começam na origem de nível superior (UDM ou Entity).

  • Corresponda variáveis: declare na seção match. As variáveis de correspondência se tornam campos de agrupamento da consulta, já que uma linha é retornada para cada conjunto exclusivo de variáveis de correspondência (e para cada janela de tempo). Quando a regra encontra uma correspondência, os valores das variáveis de correspondência são retornados. Especifique o que cada variável de correspondência representa na seção events.

  • Variáveis de marcador de posição: declare e defina na seção events. As variáveis de marcador de posição são semelhantes às variáveis de correspondência. No entanto, é possível usar variáveis de marcador na seção condition para especificar as condições de correspondência.

Use as variáveis de correspondência e de marcador para declarar as relações entre os campos de evento por meio de condições de mesclagem transitiva (consulte Sintaxe da seção Eventos para mais detalhes).

Keywords

As palavras-chave em YARA-L 2.0 não diferenciam maiúsculas de minúsculas. Por exemplo, and ou AND são equivalentes. Os nomes das variáveis não podem entrar em conflito com as palavras-chave. Por exemplo, $AND ou $outcome é inválido.

As seguintes palavras-chave são para as regras de detecção de mecanismo: rule, meta, match, over, events, condition, outcome, options, and, or, not, nocase, in, regex, cidr, before, after, all, any, if, max, min, sum, array, array_distinct, count, count_distinct, is, e null.

Mapas

O YARA-L oferece suporte ao acesso ao mapa para structs e rótulos.

Estruturas e identificadores

Alguns campos do UDM usam o tipo de dados Struct ou Label.

Para pesquisar um par específico de chave-valor em Struct e Label, use a sintaxe de mapa padrão:

// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

O acesso ao mapa sempre retorna uma string.

Casos aceitos

Seção de eventos e resultados
// Using a Struct field in the events section
events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"

// Using a Label field in the outcome section
outcome:
  $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
Como atribuir um valor de mapa a um marcador de posição
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
Como usar um campo de mapa em uma condição de mesclagem
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]

Casos incompatíveis

Mapas não são aceitos nos casos a seguir.

Combinar palavras-chave any ou all com um mapa

Por exemplo, não há suporte para o seguinte: all $e.udm.additional.fields["pod_name"] = "kube-scheduler"

Outros tipos de valores

A sintaxe do mapa só pode retornar um valor de string. No caso dos tipos de dados Struct, a sintaxe do mapa só pode acessar chaves com valores que sejam strings. Não é possível acessar chaves com valores que sejam de outros tipos primitivos, como números inteiros.

Processamento de valores duplicados

Os acessos ao mapa sempre retornam um único valor. No caso extremo incomum de o acesso ao mapa se referir a vários valores, o acesso ao mapa retorna deterministicamente o primeiro valor.

Isso pode acontecer em um dos seguintes casos:

  • Um rótulo tem uma chave duplicada.

    A estrutura do rótulo representa um mapa, mas não impõe a exclusividade da chave. Por convenção, um mapa precisa ter chaves exclusivas. Portanto, o Chronicle não recomenda preencher um marcador com chaves duplicadas.

    O texto da regra $e.metadata.ingestion_labels["dupe-key"] retornaria o primeiro valor possível, val1, se executado no seguinte exemplo de dados:

    // Disrecommended usage of label with a duplicate key:
    event {
      metadata{
        ingestion_labels{
          key: "dupe-key"
          value: "val1" // This is the first possible value for "dupe-key"
        }
        ingestion_labels{
          key: "dupe-key"
          value: "val2"
        }
      }
    }
    
  • Um rótulo tem um campo repetido ancestral.

    Um campo repetido pode conter um rótulo como campo filho. Duas entradas diferentes no campo repetido de nível superior podem conter rótulos com a mesma chave. O texto da regra $e.security_result.rule_labels["key"] retornaria o primeiro valor possível, val3, se executado no seguinte exemplo de dados:

    event {
      // security_result is a repeated field.
      security_result {
        threat_name: "threat1"
        rule_labels {
          key: "key"
          value: "val3" // This is the first possible value for "key"
        }
      }
      security_result {
        threat_name: "threat2"
        rule_labels {
          key: "key"
          value: "val4"
        }
      }
    }
    

Funções

Esta seção descreve as funções do YARA-L 2.0 compatíveis com o Chronicle no mecanismo de detecção.

Essas funções podem ser usadas nas seguintes áreas em uma regra:

arrays.length

arrays.length(repeatedField)

Descrição

Retorna o número de elementos de campo repetidos.

Tipos de dados de parâmetro

LIST

Tipo de retorno

NUMBER

Exemplos de código

Exemplo 1

Retorna o número de elementos de campo repetidos.

arrays.length($e.principal.ip) = 2
Exemplo 2

Se vários campos repetidos estiverem ao longo do caminho, retorna o número total de elementos de campo repetidos.

arrays.length($e.intermediary.ip) = 3

math.abs

math.abs(numericExpression)

Descrição

Retorna o valor absoluto de um número inteiro ou expressão flutuante.

Tipos de dados de parâmetro

NUMBER

Tipo de retorno

NUMBER

Exemplos de código

Exemplo 1

Este exemplo retornará "True" se o evento tiver ocorrido mais de cinco minutos do horário especificado (em segundos a partir da época Unix), independentemente de o evento ter chegado antes ou depois do horário especificado. Uma chamada para math.abs não pode depender de várias variáveis ou marcadores. Por exemplo, não é possível substituir o valor de tempo fixado no código de 1643687343 no exemplo a seguir por $e2.metadata.event_timestamp.seconds.

300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)

metrics

As funções de métricas podem agregar grandes quantidades de dados históricos. Use isso na sua regra com metrics.functionName() na seção de resultados.

Para mais informações, consulte Métricas YARA-L.

net.ip_in_range_cidr

net.ip_in_range_cidr(ipAddress, subnetworkRange)

Descrição

Retorna true quando o endereço IP fornecido está dentro da sub-rede especificada.

É possível usar YARA-L para pesquisar eventos de UDM em todos os endereços IP de uma sub-rede usando a instrução net.ip_in_range_cidr(). IPv4 e IPv6 são aceitos.

Para pesquisar em um intervalo de endereços IP, especifique um campo de UDM de IP e um intervalo de CIDR. YARA-L pode lidar com campos de endereço IP singulares e repetidos.

Para pesquisar em vários endereços IP, especifique um campo de UDM ip e um intervalo de roteamento entre domínios sem classe (CIDR). YARA-L pode lidar com campos de endereço IP singulares e repetidos.

Tipos de dados de parâmetro

STRING, STRING

Tipo de retorno

BOOL

Amostras de código

Exemplo 1

Exemplo de IPv4:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
Exemplo 2

Exemplo de IPv6:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

Para uma regra de exemplo que usa a instrução net.ip_in_range_cidr(), consulte a regra de exemplo em Evento único dentro do intervalo de endereços IP.

re.regex

Você pode definir a correspondência de expressão regular em YARA-L 2.0 usando uma das seguintes sintaxes:

  • Usar a sintaxe YARA : relacionado a eventos. Confira a seguir uma representação genérica dessa sintaxe: none $e.field = /regex/
  • Usando a sintaxe YARA-L: como uma função que aceita os seguintes parâmetros:
    • Campo ao qual a expressão regular é aplicada.
    • Expressão regular especificada como string. É possível usar o modificador nocase depois de strings para indicar que a pesquisa precisa ignorar as letras maiúsculas. Confira a seguir uma representação genérica dessa sintaxe: none re.regex($e.field, `regex`)

Descrição

Essa função retornará true se a string tiver uma substring que corresponda à expressão regular fornecida. Não é necessário adicionar .* ao início ou ao final da expressão regular.

Observações
  • Para corresponder à string exata ou apenas a um prefixo ou sufixo, inclua os caracteres âncora ^ (início) e $ (final) na expressão regular. Por exemplo, /^full$/ corresponde exatamente a "full", enquanto /full/ pode corresponder a "fullest", "lawfull" e "joyfully".
  • Se o campo do UDM incluir caracteres de nova linha, o regexp corresponderá apenas à primeira linha dele. Para aplicar a correspondência completa de campos de UDM, adicione um (?s) à expressão regular. Por exemplo, substitua /.*allUDM.*/ por /(?s).*allUDM.*/.

Tipos de dados de parâmetro

STRING, STRING

Tipos de expressão de parâmetro

ANY, ANY

Tipo de retorno

BOOL

Exemplos de código

Exemplo 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")

re.capture

re.capture(stringText, regex)

Descrição

Captura (extrai) dados de uma string usando o padrão de expressão regular fornecido no argumento.

Essa função usa dois argumentos:

  • stringText: a string original a ser pesquisada.
  • regex: a expressão regular que indica o padrão a ser pesquisado.

A expressão regular pode conter 0 ou 1 grupo de captura entre parênteses. Se a expressão regular não contiver grupos de captura, a função retornará a primeira substring inteira correspondente. Se a expressão regular contiver um grupo de captura, ela retornará a primeira substring correspondente. Definir dois ou mais grupos de captura retorna um erro do compilador.

Tipos de dados de parâmetro

STRING, STRING

Tipo de retorno

STRING

Exemplos de código

Exemplo 1

Neste exemplo, se $e.principal.hostname contiver "aaa1bbaa2", o seguinte seria verdadeiro, porque a função retorna a primeira instância. Este exemplo não tem grupos de captura.

"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")
Exemplo 2

Este exemplo captura tudo após o símbolo @ em um e-mail. Se o campo $e.network.email.from for test@google.com, o exemplo retornará google.com. O exemplo a seguir contém um grupo de captura.

"google.com" = re.capture($e.network.email.from , "@(.*)")
Exemplo 3

Se a expressão regular não corresponder a nenhuma substring no texto, a função retornará uma string vazia. É possível omitir eventos em que nenhuma correspondência ocorre excluindo a string vazia, o que é ainda mais importante quando você usa re.capture() com uma desigualdade:

// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")

// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")

re.replace

re.replace(stringText, replaceRegex, replacementText)

Descrição

Executa uma substituição de expressão regular.

Essa função usa três argumentos:

  • stringText: a string original.
  • replaceRegex: a expressão regular que indica o padrão a ser pesquisado.
  • replacementText: o texto a ser inserido em cada correspondência.

Retorna uma nova string derivada do stringText original, em que todas as substrings que correspondem ao padrão em replaceRegex são substituídas pelo valor em replacementText. Você pode usar dígitos de escape de barra invertida (de \1 a \9) em replacementText para inserir um texto correspondente ao grupo entre parênteses correspondente no padrão replaceRegex. Use \0 para se referir ao texto correspondente inteiro.

A função substitui correspondências não sobrepostas e priorizará a primeira ocorrência encontrada. Por exemplo, re.replace("banana", "ana", "111") retorna a string "b111na".

Tipos de dados de parâmetro

STRING, STRING e STRING

Tipo de retorno

STRING

Exemplos de código

Exemplo 1

Este exemplo captura tudo após o símbolo @ em um e-mail, substitui com por org e retorna o resultado. Observe o uso de funções aninhadas.

"email@google.org" = re.replace($e.network.email.from, "com", "org")
Exemplo 2

Esse exemplo usa dígitos de escape de barra invertida no argumento replacementText para fazer referência a correspondências ao padrão replaceRegex.

"test1.com.google" = re.replace(
                       $e.principal.hostname, // holds "test1.test2.google.com"
                       "test2\.([a-z]*)\.([a-z]*)",
                       "\\2.\\1"  // \\1 holds "google", \\2 holds "com"
                     )
Exemplo 3

Observe os seguintes casos ao lidar com strings vazias e re.replace():

Usando string vazia como replaceRegex:

// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")

Para substituir uma string vazia, use "^$" como replaceRegex:

// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")

strings.base64_decode

strings.base64_decode(encodedString)

Descrição

Retorna uma string contendo a versão decodificada base64 da string codificada.

Essa função usa uma string codificada em base64 como argumento. Se encodedString não for uma string codificada em base64 válida, a função retornará encodedString inalterada.

Tipos de dados de parâmetro

STRING

Tipo de retorno

STRING

Exemplos de código

Exemplo 1
"test" = strings.base64_decode($e.principal.domain.name)

strings.coalesce

strings.coalesce(a, b, c, ...)

Descrição

Essa função usa um número ilimitado de argumentos e retorna o valor da primeira expressão que não é avaliada como uma string vazia (por exemplo, "valor diferente de zero"). Se todos os argumentos forem avaliados como uma string vazia, a chamada de função retornará uma string vazia.

Os argumentos podem ser literais, campos de evento ou chamadas de função. Todos os argumentos precisam ser do tipo STRING. Se algum argumento for um campo de evento, os atributos precisarão ser do mesmo evento.

Tipos de dados de parâmetro

STRING

Tipo de retorno

STRING

Exemplos de código

Exemplo 1

O exemplo a seguir inclui variáveis de string como argumentos. A condição é avaliada como verdadeira quando (1) $e.network.email.from é suspicious@gmail.com ou (2) $e.network.email.from está vazio e $e.network.email.to é suspicious@gmail.com.

"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
Exemplo 2

O exemplo a seguir chama a função coalesce com mais de dois argumentos. Essa condição compara o primeiro endereço IP não nulo do evento $e com os valores na lista de referência ip_watchlist. A ordem em que os argumentos são agrupados nessa chamada é a mesma em que eles são enumerados na condição da regra:

  1. $e.principal.ip é avaliado primeiro.
  2. $e.src.ip é avaliado em seguida.
  3. $e.target.ip é avaliado em seguida.
  4. Por fim, a string "Sem IP" vai ser retornada como um valor padrão se os campos ip anteriores não estiverem definidos.
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
Exemplo 3

O exemplo a seguir tenta unir principal.hostname do evento $e1 e $e2. Ele retornará um erro do compilador porque os argumentos são variáveis de evento diferentes.

// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)

strings.concat

strings.concat(a, b, c, ...)

Descrição

Retorna a concatenação de um número ilimitado de itens, cada um dos quais pode ser uma string, um número inteiro ou um valor flutuante.

Se algum argumento for um campo de evento, os atributos precisarão ser do mesmo evento.

Tipos de dados de parâmetro

STRING, FLOAT, INT

Tipo de retorno

STRING

Exemplos de código

Exemplo 1

O exemplo a seguir inclui uma variável de string e uma variável de número inteiro como argumentos. Tanto principal.hostname quanto principal.port são do mesmo evento $e e são concatenados para retornar uma string.

"google:80" = strings.concat($e.principal.hostname, ":", $e.principal.port)
Exemplo 2

O exemplo a seguir inclui uma variável de string e um literal de string como argumentos.

"google-test" = strings.concat($e.principal.hostname, "-test") // Matches the event when $e.principal.hostname = "google"
Exemplo 3

O exemplo a seguir inclui uma variável de string e um literal flutuante como argumentos. Quando representados como strings, os pontos flutuantes que são números inteiros são formatados sem o ponto decimal. Por exemplo, 1.0 é representado como "1". Além disso, os pontos flutuantes que excedem 16 dígitos decimais são truncados até a décima sexta casa decimal.

"google2.5" = strings.concat($e.principal.hostname, 2.5)
Exemplo 4

O exemplo a seguir inclui uma variável de string, um literal de string, uma variável de número inteiro e um literal flutuante como argumentos. Todas as variáveis são do mesmo evento, $e, e são concatenadas com os literais para retornar uma string.

"google-test802.5" = strings.concat($e.principal.hostname, "-test", $e.principal.port, 2.5)
Example 5

O exemplo a seguir tenta concatenar principal.port do evento $e1, com principal.hostname do evento $e2. Ele retornará um erro do compilador porque os argumentos são variáveis de evento diferentes.

// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

strings.to_lower

strings.to_lower(stringText)

Descrição

Essa função usa uma string de entrada e retorna uma string depois de mudar todos os caracteres para minúsculas

Tipos de dados de parâmetro

STRING

Tipo de retorno

STRING

Exemplos de código

Exemplo 1

O exemplo a seguir retorna true.

"test@google.com" = strings.to_lower($e.network.email.to)

strings.to_upper

strings.to_upper(stringText)

Descrição

Essa função usa uma string de entrada e retorna uma depois de mudar todos os caracteres para maiúsculas.

Tipos de dados de parâmetro

STRING

Tipo de retorno

STRING

Exemplos de código

Exemplo 1

O exemplo a seguir retorna true.

"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)

timestamp.current_seconds

timestamp.current_seconds()

Descrição

Retorna um número inteiro que representa o horário atual em segundos do Unix. Ele é aproximadamente igual ao carimbo de data/hora de detecção e se baseia no momento em que a regra é executada.

Tipos de dados de parâmetro

NONE

Tipo de retorno

INT

Exemplos de código

Exemplo 1

O exemplo a seguir retornará true se o certificado tiver expirado há mais de 24 horas. Ela calcula a diferença de tempo subtraindo os segundos Unix atuais e comparando usando um operador "maior que".

86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after

timestamp.get_date

timestamp.get_date(unix_seconds [, time_zone])

Descrição

Essa função retorna uma string no formato YYYY-MM-DD, representando o dia em que um carimbo de data/hora se encontra.

  • unix_seconds é um número inteiro que representa o número de segundos após a época do Unix, como $e.metadata.event_timestamp.seconds, ou um marcador que contém esse valor.
  • time_zone é opcional e é uma string que representa um fuso horário. Se omitido, o padrão é "GMT". É possível especificar fusos horários usando literais de string. As opções são:
    • O nome do banco de dados TZ, por exemplo, "America/Los_Angeles". Para mais informações, consulte a coluna "Nome do banco de dados TZ" desta página
    • A diferença de fuso horário de UTC, no formato (+|-)H[H][:M[M]], por exemplo: "-08:00".

Confira abaixo exemplos de especificadores time_zone válidos, que podem ser transmitidos como o segundo argumento para funções de extração de tempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de dados de parâmetro

INT, STRING

Tipo de retorno

STRING

Exemplos de código

Exemplo 1

Neste exemplo, o argumento time_zone é omitido, por isso, o padrão é "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts) = "2024-02-19"
Exemplo 2

Este exemplo usa um literal de string para definir o time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts, "America/Los_Angeles") = "2024-02-20"

timestamp.get_minute

timestamp.get_minute(unix_seconds [, time_zone])

Descrição

Essa função retorna um número inteiro no intervalo [0, 59] que representa o minuto.

  • unix_seconds é um número inteiro que representa o número de segundos após a época do Unix, como $e.metadata.event_timestamp.seconds, ou um marcador que contém esse valor.
  • time_zone é opcional e é uma string que representa um fuso horário. Se omitido, o padrão é "GMT". É possível especificar fusos horários usando literais de string. As opções são:
    • O nome do banco de dados TZ, por exemplo, "America/Los_Angeles". Para mais informações, consulte a coluna "Nome do banco de dados TZ" desta página
    • A diferença de fuso horário de UTC, no formato (+|-)H[H][:M[M]], por exemplo: "-08:00".

Confira abaixo exemplos de especificadores time_zone válidos, que podem ser transmitidos como o segundo argumento para funções de extração de tempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de dados de parâmetro

INT, STRING

Tipo de retorno

INT

Exemplos de código

Exemplo 1

Neste exemplo, o argumento time_zone é omitido, por isso, o padrão é "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Exemplo 2

Este exemplo usa um literal de string para definir o time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_hour

timestamp.get_hour(unix_seconds [, time_zone])

Descrição

Essa função retorna um número inteiro no intervalo [0, 23] que representa a hora.

  • unix_seconds é um número inteiro que representa o número de segundos após a época do Unix, como $e.metadata.event_timestamp.seconds, ou um marcador que contém esse valor.
  • time_zone é opcional e é uma string que representa um fuso horário. Se omitido, o padrão é "GMT". É possível especificar fusos horários usando literais de string. As opções são:
    • O nome do banco de dados TZ, por exemplo, "America/Los_Angeles". Para mais informações, consulte a coluna "Nome do banco de dados TZ" desta página
    • A diferença de fuso horário de UTC, no formato (+|-)H[H][:M[M]], por exemplo: "-08:00".

Confira abaixo exemplos de especificadores time_zone válidos, que podem ser transmitidos como o segundo argumento para funções de extração de tempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de dados de parâmetro

INT, STRING

Tipo de retorno

INT

Exemplos de código

Exemplo 1

Neste exemplo, o argumento time_zone é omitido, por isso, o padrão é "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Exemplo 2

Este exemplo usa um literal de string para definir o time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_day_of_week

timestamp.get_day_of_week(unix_seconds [, time_zone])

Descrição

Essa função retorna um número inteiro no intervalo [1, 7], que representa o dia da semana que começa com domingo. Por exemplo, 1 = domingo e 2 = segunda-feira.

  • unix_seconds é um número inteiro que representa o número de segundos após a época do Unix, como $e.metadata.event_timestamp.seconds, ou um marcador que contém esse valor.
  • time_zone é opcional e é uma string que representa um fuso horário. Se omitido, o padrão é "GMT". É possível especificar fusos horários usando literais de string. As opções são:
    • O nome do banco de dados TZ, por exemplo, "America/Los_Angeles". Para mais informações, consulte a coluna "Nome do banco de dados TZ" desta página
    • A diferença de fuso horário de UTC, no formato (+|-)H[H][:M[M]], por exemplo: "-08:00".

Confira abaixo exemplos de especificadores time_zone válidos, que podem ser transmitidos como o segundo argumento para funções de extração de tempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de dados de parâmetro

INT, STRING

Tipo de retorno

INT

Exemplos de código

Exemplo 1

Neste exemplo, o argumento time_zone é omitido, por isso, o padrão é "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts) = 6
Exemplo 2

Este exemplo usa um literal de string para definir o time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6

timestamp.get_week

timestamp.get_week(unix_seconds [, time_zone])

Descrição

Essa função retorna um número inteiro no intervalo [0, 53] que representa a semana do ano. As semanas começam no domingo. As datas antes do primeiro domingo do ano estão na semana 0.

  • unix_seconds é um número inteiro que representa o número de segundos após a época do Unix, como $e.metadata.event_timestamp.seconds, ou um marcador que contém esse valor.
  • time_zone é opcional e é uma string que representa um fuso horário. Se omitido, o padrão é "GMT". É possível especificar fusos horários usando literais de string. As opções são:
    • O nome do banco de dados TZ, por exemplo, "America/Los_Angeles". Para mais informações, consulte a coluna "Nome do banco de dados TZ" desta página
    • A diferença de fuso horário de UTC, no formato (+|-)H[H][:M[M]], por exemplo: "-08:00".

Confira abaixo exemplos de especificadores time_zone válidos, que podem ser transmitidos como o segundo argumento para funções de extração de tempo:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Tipos de dados de parâmetro

INT, STRING

Tipo de retorno

INT

Exemplos de código

Exemplo 1

Neste exemplo, o argumento time_zone é omitido, por isso, o padrão é "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts) = 0
Exemplo 2

Este exemplo usa um literal de string para definir o time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts, "America/Los_Angeles") = 0

Função para atribuição de marcador de posição

Você pode atribuir o resultado de uma chamada de função a um marcador na seção events. Exemplo:

$placeholder = strings.concat($e.principal.hostname, "my-string").

Você pode usar as variáveis de marcador de posição nas seções match, condition e outcome. No entanto, existem duas limitações com a atribuição de funções para marcadores de posição:

  1. Cada marcador de posição na função para atribuição de marcador deve ser atribuído a uma expressão que contenha um campo de evento. Por exemplo, os seguintes exemplos são válidos:

    $ph1 = $e.principal.hostname
    $ph2 = $e.src.hostname
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.concat($ph2, ".com")
    
    $ph1 = $e.network.email.from
    $ph2 = strings.concat($e.principal.hostname, "@gmail.com")
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.to_lower($ph2)
    

    No entanto, o exemplo a seguir é inválido:

    $ph1 = strings.concat($e.principal.hostname, "foo")
    $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
    
  2. A chamada de função precisa depender de um e exatamente um evento. No entanto, mais de um campo do mesmo evento pode ser usado em argumentos de chamada de função. Por exemplo, o seguinte é válido:

    $ph = strings.concat($event.principal.hostname, "string2")

    $ph = strings.concat($event.principal.hostname, $event.src.hostname)

    No entanto, o seguinte é inválido:

    $ph = strings.concat("string1", "string2")

    $ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)

Sintaxe das listas de referência

Consulte nossa página sobre Listas de referência para mais informações sobre o comportamento e a sintaxe delas.

Use listas de referência nas seções events ou outcome. Veja a sintaxe para usar vários tipos de listas de referência em uma regra:

// STRING reference list
$e.principal.hostname in %string_reference_list

// REGEX reference list
$e.principal.hostname in regex %regex_reference_list

// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list

Você também pode usar o operador not e o operador nocase com listas de referência, conforme mostrado aqui: ```none // Excluir eventos com nomes de host correspondentes a substrings em my_regex_list. não $e.principal.hostname na regex %my_regex_list

// Os nomes do host do evento devem corresponder a pelo menos uma string em my_string_list (não diferencia maiúsculas de minúsculas). $e.principal.hostname em %my_string_list nocase ```

O operador nocase é compatível com listas STRING e REGEX.

Por motivos de desempenho, o mecanismo de detecção restringe o uso da lista de referências.

  • Máximo de instruções in em uma regra, com ou sem operadores especiais: 7
  • Máximo de instruções in com o operador regex: 4
  • Máximo de instruções in com o operador cidr: 2

Verificação de tipo

O Chronicle faz a verificação de tipos em relação à sintaxe YARA-L à medida que você cria regras na interface. Os erros de verificação de tipo exibidos ajudam você a revisar a regra para garantir que ela funcione conforme o esperado.

Veja a seguir exemplos de predicados inválidos:

// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"

// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"

Amostragem de eventos de detecção

As detecções de regras de vários eventos contêm amostras de eventos para fornecer contexto sobre os eventos que causaram a detecção. Há um limite de até 10 amostras de eventos para cada variável de evento definida na regra. Por exemplo, se uma regra definir duas variáveis de evento, cada detecção poderá ter até 20 amostras de eventos. O limite é aplicado a cada variável de evento separadamente. Se uma variável de evento tiver dois eventos aplicáveis nessa detecção e a outra variável tiver 15 eventos aplicáveis, a detecção resultante terá 12 amostras de eventos (2 + 10).

As amostras de eventos acima do limite são omitidas da detecção.

Se você quiser mais informações sobre os eventos que causaram a detecção, use agregações na seção de resultados para gerar mais informações.

Se você estiver visualizando detecções na UI, poderá fazer o download de todas as amostras de eventos para uma detecção. Para mais informações, consulte Fazer o download dos eventos.