Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Sintaxe da linguagem YARA-L 2.0

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

Estrutura da regra

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

  1. Meta
  2. events
  3. match (opcional)
  4. result (opcional)
  5. condição
  6. opções (opcional)

Veja 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.
}

Comentários

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

Literais

Há suporte para números inteiros não negativos (sem pontos decimais), literais de string, booleanos e regex.

Literais de string e regex

É possível usar um dos caracteres de aspas a seguir para colocar strings em YARA-L 2.0. No entanto, o texto das aspas é interpretado de maneiras diferentes dependendo do que você usa.

  1. Aspas duplas (") — use para strings normais. Precisa incluir caracteres de escape.
    Por exemplo: "hello\tworld" —\t é interpretado como uma guia

  2. Aspas (`) — Use para interpretar todos os caracteres literalmente.
    Por exemplo: "hello\tworld" —\t não é interpretado como uma guia

Há duas opções para expressões regulares.

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 regex ao utilizar a função re.regex(). Para literais de string de aspas duplas, é necessário inserir caracteres de barra invertida com os caracteres de barra invertida, que podem parecer estranhos.

Por exemplo, as seguintes expressões regulares 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 o uso de caracteres de aspas duplas para strings em expressões regulares para facilitar a legibilidade.

Operadores

É possível usar os seguintes operadores em YARA-L:

Operador Descrição
= igual/declaração
!= diferente
< menor que
<= menor 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>.

É possível definir os seguintes tipos de variável:

  • Variáveis de evento: representam grupos de eventos no 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. Identifique variáveis de evento usando um nome, uma origem e campos de evento. As origens permitidas são udm (para eventos normalizados) e graph (para eventos de entidade). Se a fonte for omitida, udm será definido como padrão. Os campos de evento são representados como uma cadeia de .<field name> (por exemplo, $e.field1.field2). As cadeias de campos de eventos sempre começam na fonte de nível superior (UDM ou Entity).

  • Variáveis de correspondência: declare na seção match. As variáveis de correspondência se tornam campos de agrupamento para a 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 são retornados. Especifique o que cada variável de correspondência representa na seção events.

  • Variáveis de marcador: 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 variáveis de correspondência e marcadores de posição para declarar relações entre campos de eventos usando condições de mesclagem transitivas. Consulte a Sintaxe da seção de eventos para mais detalhes.

Mapas

Estruturas e rótulos

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

Para pesquisar um par de chave-valor específico 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"

Casos suportados

Seção "Eventos" e "Resultado"
// 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"])
Atribuir um valor de mapa a um marcador de posição
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
Como usar um campo do 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 não aceitos

Combinar palavras-chave any ou all com um mapa

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

Funções

Esta seção descreve as funções YARA-L 2.0 compatíveis com o Chronicle no Detection Engine.

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

Funções de string

O Chronicle é compatível com as seguintes funções de manipulação de strings:

  • strings.concat(a, b)
  • strings.to_low(stringText)
  • strings.to_upper(stringText)
  • strings.base64_decode(encodedString)

Veja nas próximas seções como usar cada um deles.

Concatenar strings ou números inteiros

Retorna a concatenação de duas strings, dois números inteiros ou uma combinação dos dois.

strings.concat(a, b)

Essa função usa dois argumentos, que podem ser strings ou números inteiros, e retorna os dois valores concatenados como uma string. Números inteiros são convertidos em uma string antes da concatenação. Os argumentos podem ser literais ou campos de evento. Se ambos os argumentos forem campos, os dois atributos precisarão ser do mesmo evento.

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

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

"google80" = strings.concat($e.principal.hostname, $e.principal.port)

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 eventos diferentes.

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

Converter string em maiúsculas ou minúsculas

Essas funções retornam o texto da string depois de mudar todos os caracteres para maiúsculas ou minúsculas.

  • strings.to_low(stringText)
  • strings.to_upper(stringText)
"test@google.com" = strings.to_lower($e.network.email.from)
"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)

Decodificar uma string em Base64

Retorna uma string que contém a versão decodificada em base64 da string codificada.

strings.base64_decode(encodedString)

Essa função usa uma string codificada em base64 como argumento. Se codificadaString não é uma string codificada em base64 válida, a função retorna codificadaString como está.

Este exemplo retorna "True" se principal.domain.name for "dGVzdA==", que é uma codificação em base64 para a string "test".

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

Funções RegExp

O Chronicle é compatível com as seguintes funções de expressão regular:

  • re.regex(stringText, regex)
  • re.capture(stringText, regex)
  • re.replace(stringText, replaceRegex, replaceText)

Correspondência RegExp

É possível definir a correspondência de expressão regular em YARA-L 2.0 usando uma das seguintes sintaxes:

  • Uso da sintaxe YARA: relacionado a eventos. Veja a seguir uma representação genérica dessa sintaxe: $e.field = /regex/
  • Uso da sintaxe YARA-L: como uma função que aceita os seguintes parâmetros:
    • Campo a que a expressão regular é aplicada.
    • Expressão regular especificada como uma string. É possível usar o modificador nocase após strings para indicar que a pesquisa deve ignorar o uso de letras maiúsculas. Veja a seguir uma representação genérica dessa sintaxe: re.regex($e.field, `regex`)

Esteja ciente do seguinte ao definir expressões regulares em YARA-L 2.0:

  • Em ambos os casos, o predicado é verdadeiro se a string contém uma substring que corresponde à expressão regular fornecida. Não é necessário adicionar .* ao início ou ao final da expressão regular.
  • Para corresponder à string exata ou apenas a um prefixo ou sufixo, inclua os caracteres de â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 UDM incluir caracteres de nova linha, o regexp corresponderá apenas à primeira linha do campo UDM. Para aplicar a correspondência completa do campo UDM, adicione um (?s) à expressão regular. Por exemplo, substitua /.*allUDM.*/ por /(?s).*allUDM.*/.

Captura RegExp

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

re.capture(stringText, regex)

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 contiver 0 grupos de captura, a função retornará a primeira substring correspondente. Se a expressão regular contiver um grupo de captura, ele retorna a primeira substring correspondente para o grupo de captura. Definir dois ou mais grupos de captura retorna um erro do compilador.

Neste exemplo, se $e.principal.hostname contiver "aaa1bbaa2", o valor será 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]")

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. Este exemplo contém um grupo de captura.

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

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 é especialmente importante quando você está usando 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 , "@(.*)")

Substituição de RegExp

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

re.replace(stringText, replaceRegex, replacementText)

Essa função usa três argumentos:

  • stringText: a string original.
  • replaceRegex: a expressão regular que indica o padrão a ser pesquisado.
  • replaceText: 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. É possível usar dígitos com escape de barra invertida (\1 a \9) em replacementText para inserir texto correspondente ao grupo entre parênteses no padrão replaceRegex. Use \0 para indicar o texto correspondente inteiro.

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

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

Este exemplo usa dígitos com escape de barra invertida no argumento replaceText para referenciar correspondências para o 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"
                     )

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

Usando uma 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")

Funções de data

O Chronicle é compatível com as seguintes funções relacionadas à data:

  • timestamp.get_minute(unix_seconds [, time_zone])
  • timestamp.get_hour(unix_seconds [, time_zone])
  • timestamp.get_day_of_week(unix_seconds [, time_zone])
  • timestamp.get_week(unix_seconds [, time_zone])
  • timestamp.current_seconds()

O Chronicle é compatível com números inteiros negativos como o argumento unix_seconds. Números inteiros negativos representam períodos antes da época Unix. Se você fornecer um número inteiro inválido, por exemplo, um valor que resulta em um estouro, a função retornará -1. Esse é um cenário incomum.

Como a YARA-L 2 não oferece suporte a literais de números inteiros negativos, verifique essa condição usando o operador "menor ou maior que". Exemplo:

0 > timestamp.get_hour(123)

Extração de data/hora

Retorna um número inteiro no intervalo [0, 59].

timestamp.get_minute(unix_seconds [, time_zone])

A função a seguir retorna um número inteiro no intervalo [0, 23], representando a hora do dia.

timestamp.get_hour(unix_seconds [, time_zone])

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

timestamp.get_day_of_week(unix_seconds [, time_zone])

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

timestamp.get_week(unix_seconds [, time_zone])

Essas funções de extração de tempo têm os mesmos argumentos.

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

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

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15

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

$ts = $e.metadata.collected_timestamp.seconds

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

Veja alguns exemplos de outros especificadores de time_zone, que podem ser transmitidos como o segundo argumento para funções de extração de tempo:

  • "America/Los_Angeles" ou "-08:00". ("PST" não é compatível)
  • "America/New_York" ou "-05:00". ("EST" não é compatível)
  • "Europe/London"
  • "UTC"
  • "GMT"

Carimbo de data/hora atual

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

timestamp.current_seconds()

O exemplo a seguir retornará "True" se o certificado tiver expirado por mais de 24 horas. Para calcular a diferença de horário, subtraia os segundos Unix atuais e faça a comparação usando um operador "maior que".

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

Funções matemáticas

Valor absoluto

Retorna o valor absoluto de uma expressão de número inteiro.

math.abs(intExpression)

Este exemplo retorna "Verdadeiro" se os eventos tiverem mais de cinco minutos de diferença, independentemente de qual tenha ocorrido primeiro. Observe como o exemplo usa funções aninhadas.

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

Funções de rede

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

net.ip_in_range_cidr(ipAddress, subnetworkRange)

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

Para pesquisar em um intervalo de endereços IP, especifique um campo de UDM de IP e um intervalo de roteamento entre domínios sem classe (CIDR). A YARA-L aceita campos de endereços IP únicos e repetidos.

Exemplo de IPv4:

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

Exemplo de IPv6:

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

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

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

É possível 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").

Em seguida, use as variáveis de marcador nas seções match, condition e outcome. No entanto, existem duas limitações com a função para a atribuição de marcadores:

  1. Cada marcador de posição na função para a atribuição de marcador de posição precisa ser atribuído a uma expressão contendo um campo de evento. Por exemplo, os exemplos a seguir 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 abaixo é 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ências para mais informações sobre o comportamento das listas de referências e a sintaxe delas.

Você pode usar listas de referência nas seções events ou outcome. Esta é 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

Também é possível usar o operador not com listas de referência, como mostrado aqui: not $e.principal.hostname in regex %my_regex_list.

Por motivos de desempenho, o mecanismo de detecção restringe o uso da lista de referência. É possível usar até sete instruções in em uma regra, e é possível usar vários tipos de instruções in na mesma regra. No máximo, duas das sete instruções in podem usar os operadores especiais regex ou cidr.

O operador nocase não está funcionando com listas de referência. Colocar nocase após uma chamada de lista de referência não tem efeito e não é recomendado.

Sintaxe da seção Meta

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

<key> = "<value>"

Veja a seguir um exemplo de linha de seção meta válida: meta: author = "Chronicle" severity = "HIGH"

Sintaxe da seção "Eventos"

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

  • O que cada correspondência ou variável de marcador representa
  • Expressões binárias simples como condições
  • Expressões de função como condições
  • Expressões de lista de referência como condições
  • Operadores lógicos

Declarações de variáveis

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

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

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

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

Essa declaração indica que essa variável representa o campo especificado para a variável do evento. Quando o campo de evento é um campo 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 variável de correspondência ou marcador de posição. 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 usando uma declaração. Se uma variável for usada sem uma declaração, ela será considerada um erro de compilação.

Expressões binárias simples como condiçõ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, eles serão considerados um erro de compilação.

Expressões de função como condiçõ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 como condições

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

Operadores lógicos

É 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 or b and c" é avaliado como "a or (b and c)". É possível usar parênteses para alterar a precedência, se necessário.

Na seção events, todos os predicados são considerados and juntos por padrão.

Operadores em eventos

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

No exemplo a seguir, "USER_UNCATEGORIZED" e "USER_RESOURCE_DELETION" correspondem a 15000 e 15014, portanto, a regra 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
  • ESTATÍSTICAS DO USUÁRIO
  • USER_UNCATEGORIZED

Modificadores

mala

Quando você tem uma expressão de comparação entre valores de string ou uma expressão regex, pode acrescentar um maiúsculo no final da expressão para ignorar letras maiúsculas.

  • $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

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

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

Campos repetidos

todos, todos

No UDM e no Entity, alguns campos são marcados como repetidos, o que indica que são listas de valores ou outros tipos de mensagens. Em YARA-L, cada elemento no campo repetido é tratado individualmente. Isso significa que, se o campo repetido for usado, vamos avaliar a regra de cada elemento no campo. Isso pode causar um comportamento inesperado. Por exemplo, se uma regra tiver $e.principal.ip = "1.2.3.4" e $e.principal.ip = "5.6.7.8" na seção events, a regra nunca gerará correspondências, mesmo que "1.2.3.4" e "5.6.7.8" estejam em principal.ip.

Para avaliar o campo repetido como um todo, use os operadores any e all. Quando any é usado, o predicado é avaliado como verdadeiro se qualquer valor no campo repetido atender à condição. Quando all é usado, o predicado é avaliado como verdadeiro se todos os valores no campo repetido atenderem à condição.

  • any $e.target.ip = "127.0.0.1"
  • all $e.target.ip != "127.0.0.1"
  • re.regex(any $e.about.hostname, `server-[0-9]+`)
  • net.ip_in_range_cidr(all $e.principal.ip, "10.0.0.0/8")

Os operadores any e all só podem ser usados com campos repetidos. Além disso, eles não podem ser usados ao atribuir um campo repetido a uma variável de marcador ou a um campo de outro evento.

Por exemplo, any $e.principal.ip = $ip e any $e1.principal.ip = $e2.principal.ip não são sintaxes válidas. Para corresponder ou participar de um campo repetido, use $e.principal.ip = $ip. Haverá um valor de variável correspondente ou mesclagem para cada elemento do campo repetido.

Ao gravar uma condição com any ou all, lembre-se 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 verifica se algum 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".

Requisitos de participação de variáveis de evento

Todas as variáveis de evento usadas na regra precisam ser mescladas a todas as outras variáveis de evento de uma destas maneiras:

  • diretamente por uma comparação de igualdade entre os campos de evento das duas variáveis de evento mescladas, por exemplo: $e1.field = $e2.field. A expressão não pode incluir chamadas aritméticas ou de função.

  • indiretamente por uma junção transitiva que envolve apenas um campo de evento. Consulte a declaração de variáveis para uma definição de "junção transitiva". A expressão não pode incluir chamadas aritméticas ou de função.

Por exemplo, supondo que $e1, $e2 e $e3 sejam usados na regra, as seguintes seções de events 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:
  // 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.principal.hostname = $e2.src.hostname // $e1 joins with $e2

  // Function to event comparison is not a valid join condition for $e1 and $e2,
  // but the whole events section is valid because we have a valid join condition in the first line.
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname

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

events:
  // Event to function comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.hostname = re.capture($e2.principal.application, ".*")
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.ip = $ip

  // Function to placeholder comparison is an invalid transitive join condition.
  re.capture($e2.target.ip, ".*") = $ip
events:
  $e1.src.port = $port

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

Sintaxe da seção de correspondência

Na seção match, liste as variáveis de correspondência para os eventos do grupo antes de verificar as condições. 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 período a ser usado para correlacionar eventos após a palavra-chave over. Os eventos fora do período são ignorados.
  • Use a seguinte sintaxe para especificar o intervalo de tempo: <number><s/m/h/d>, em que s/m/h/d significa segundos, minutos, horas e dias, respectivamente.
  • O tempo mínimo que você pode especificar é de um minuto.
  • O tempo máximo especificado é de 48 horas.

Veja a seguir um exemplo de match válido:

$var1, $var2 over 5m

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

Veja outro exemplo de um match válido:

$user over 1h

Essa instrução retorna $user quando a regra encontra uma correspondência. O período especificado é de uma hora. Os eventos com mais de uma hora de intervalo não são correlacionados. A regra não os considera uma detecção.

Veja outro exemplo de um match válido:

$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. Eventos com mais de dois minutos de diferença não estão correlacionados. A regra não os considera uma detecção.

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

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

Janela deslizante

Por padrão, as regras YARA-L 2.0 são avaliadas usando janelas de salto. Um intervalo de tempo de dados de eventos empresariais é dividido em um conjunto de janelas de salto sobrepostas, cada uma com a duração especificada na seção match. Os eventos são correlacionados em cada janela de salto. Com as janelas de salto, é impossível pesquisar eventos que acontecem 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 estão correlacionadas, desde que estejam dentro da duração da janela de salto uma da outra.

As regras também podem ser avaliadas com janelas deslizantes. As janelas deslizantes com a duração especificada na seção match são geradas ao iniciar ou terminar com uma variável de evento dinâmico especificada. Os eventos são correlacionados em cada janela deslizante. Isso possibilita a pesquisa de eventos que acontecem 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 sã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 da seguinte maneira:

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

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

Veja a seguir exemplos de usos válidos da janela deslizante:

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

Sintaxe da seção de resultados

Na seção outcome, é possível definir até 10 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. Também é possível definir um resultado com esse nome. Caso você faça isso, ele precisará ser um tipo de número inteiro. Se preenchido, o risk_score será exibido na visualização do Enterprise Insights para alertas provenientes de detecções de regras.

Tipos de dados da variável "Resultado"

Cada variável de resultado pode ter um tipo de dado diferente, que é determinado pela expressão usada para fazer o cálculo. Aceitamos os seguintes tipos de dados de resultado:

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

Lógica condicional

É possível usar a lógica condicional para calcular o valor de um resultado. Os condicionais são especificados usando o seguinte padrão de sintaxe:

if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)

Você pode ler uma expressão condicional como "if BOOL_CLAUSE is true, retorna THEN_CLAUSE, caso contrário, retornará ELSE_CLAUSE".

BOOL_CLAUSE precisa avaliar um valor booleano. Uma expressão BOOL_CLAUSE assume uma forma semelhante às expressões na seção events. Por exemplo, ela pode conter:

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

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

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

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

  • 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ência, por exemplo:

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

O THEN_CLAUSE e o ELSE_CLAUSE precisam ser do mesmo tipo de dados. Aceitamos números inteiros e strings.

Você poderá omitir ELSE_CLAUSE se o tipo de dados for inteiro. Se omitido, ELSE_CLAUSE será avaliado como 0. Exemplo:

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

Informe ELSE_CLAUSE se o tipo de dados for string.

Operações matemáticas

É possível usar operações matemáticas para calcular resultados com tipos de dados inteiros. Aceitamos adição e subtração, mas não multiplicação, divisão ou módulo. Exemplo:

outcome:
  $risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))

Variáveis de marcador nos resultados

Ao calcular variáveis de resultado, é possível usar variáveis de marcador que foram definidas na seção de eventos da 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

Agregações

A seção de resultados pode ser usada em regras de vários eventos (regras que contêm uma seção de correspondência) e em regras de evento único (regras que não contêm uma seção de correspondência). Os requisitos para agregações são os seguintes:

  • Regras de vários eventos (com a seção correspondente)

    • A expressão para calcular resultados é avaliada em todos os eventos que geraram uma detecção específica.
    • A expressão precisa ser encapsulada em uma função agregada.
      • Exemplo: $max_email_size = max($e.network.sent_bytes)
      • Se a expressão contiver um campo repetido, o agregado operará em todos os elementos no campo repetido em todos os eventos que geraram a detecção.
  • Regras de evento único (sem seção de correspondência)

    • A expressão para calcular resultados é avaliada sobre o único evento que gerou uma detecção específica.
    • É preciso usar a função agregada para expressões que envolvem pelo menos um campo repetido.
      • Exemplo: $suspicious_ips = array($e.principal.ip)
      • O agregador opera em todos os elementos no campo repetido
    • Não é possível usar uma função agregada para expressões que não envolvem um campo repetido.
      • Exemplo: $threat_status = if($e.principal.file.size > 1024, "SEVERE", "MODERATE")

É possível usar as seguintes funções de agregação:

  • max(): gera o máximo de todos os valores possíveis. Só funciona com o número inteiro.
  • min(): gera o mínimo sobre todos os valores possíveis. Só funciona com o número inteiro.
  • sum(): gera a soma de todos os valores possíveis. Só funciona com o número inteiro.
  • 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 possíveis e gera uma lista desses valores. Ele truncará a lista de valores para 25 elementos aleatórios.
  • array(): se comporta como array_distinct(), mas retorna uma lista não distinta de valores. Ele 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 funcionará em todos os eventos que geraram a detecção.

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

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 funcionam em vários eventos. Suponha que os seguintes eventos tenham gerado uma detecção:

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

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

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

Então, os valores dos resultados serão:

  • $asset_id_count = 3
  • $asset_id_distinct_count = 2
  • $asset_id_list = ["asset-a", "asset-b", "asset-b"]
  • $asset_id_distinct_list = ["asset-a", "asset-b"]

Informações importantes ao usar a seção de resultados:

Outras observações e restrições:

  • A seção outcome não pode fazer referência a uma nova variável de marcador que ainda não foi definida na seção events.
  • 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 de evento a que o campo 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 equitados.

Veja um exemplo usando a seção de resultados em Visão geral do YARA-L 2.0. Consulte Criar análises com base no contexto para ver detalhes sobre a detecção de detecção com a seção de resultados.

Sintaxe da seção de condições

Na seção condition, é possível:

  • especifique uma condição de correspondência para eventos e marcadores de posição definidos na seção events. Consulte a seção a seguir, Condicionais de eventos e marcadores de posição para mais detalhes.
  • (Opcional) Use a palavra-chave and para especificar uma condição de correspondência usando as variáveis de resultado definidas na seção outcome. Consulte a seção a seguir, Condicionais de resultados, para mais detalhes.

Os seguintes padrões de condição são válidos:

condition:
  <event/placeholder conditionals>
condition:
  <event/placeholder conditionals> and <outcome conditionals>

Condicionais de eventos e marcadores de posição

Liste os predicados de condições para variáveis e variáveis de marcador aqui, unidos com a palavra-chave and ou or.

As condições a seguir são condições delimitadoras. Eles forçam a variável de 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 abaixo não são limitadas. 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. Isso permite a criação de regras de não existência, que pesquisam a ausência de uma variável em vez da presença de uma variável.

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

No exemplo a seguir, o caractere especial # em uma variável (variável de evento ou de marcador) representa a contagem de eventos ou valores distintos dessa variável.

$e and #port > 50 or #event1 > 2 or #event2 > 1 or #event3 > 0

O exemplo não existente a seguir também é válido e será considerado verdadeiro se houver mais de dois eventos distintos do $event1 e nenhum evento do $event2.

#event1 > 2 and !$event2

Veja a seguir exemplos de predicados inválidos:

  • $e, #port > 50 // incorrect keyword usage
  • $e or #port < 50 // or keyword not supported with non-bounding conditions
  • not $e // not keyword is not allowed for event and placeholder conditions

Condicionais dos resultados

Aqui, os predicados de condições para variáveis de resultado são unidos pela palavra-chave and ou or ou precedidos pela palavra-chave not.

Especifique os condicionais de resultados de forma diferente, dependendo do tipo da variável:

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

    $risk_score > 10

  • string: compare com um literal de string usando = 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 condicional condicional de resultados em uma regra que tem uma seção de correspondência significa que a regra 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 eventos únicos e múltiplos.

Contagem de caracteres (#)

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

Caractere de valor ($)

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

Se ele for usado antes de qualquer nome de variável de evento ou marcador de posição (por exemplo, $event), é uma abreviação de #event > 0.

Sintaxe da seção "Opções"

Na seção options, é possível especificar as opções para a regra. A sintaxe da seção options é semelhante à da seção meta. No entanto, uma chave precisa ser um dos nomes de opções predefinidos, e o valor não é restrito ao tipo de string.

Atualmente, a única opção disponível é allow_zero_values.

  • allow_zero_value: se definido como verdadeiro, as correspondências geradas pela regra poderão ter valores zero como valores de variável correspondentes. Os valores zero são fornecidos aos campos de evento quando não são preenchidos. Essa opção é definida como falsa por padrão.

Veja a seguir a linha de seção válida de options:

  • allow_zero_values = true

Verificação de tipo

O Chronicle realiza a verificação de tipo na 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"