Visão geral da linguagem YARA-L 2.0

YARA-L 2.0 é uma linguagem de computador usada para criar regras para pesquisar dados de registro empresarial à medida que são ingeridos na sua conta do Chronicle. A sintaxe YARA-L é derivada da linguagem YARA desenvolvida pelo VirusTotal. A linguagem funciona em conjunto com o Chronicle Detection Engine e permite que você procure ameaças e outros eventos em grandes volumes de dados. Veja também Sintaxe de linguagem YARA-L 2.0.

Exemplos de regras YARA-L 2.0

Os exemplos a seguir mostram regras escritas em YARA-L 2.0. Cada um demonstra como correlacionar eventos dentro da linguagem de regra.

Logins de diferentes cidades

A regra a seguir procura usuários que fizeram login na empresa em duas ou mais cidades em menos de cinco minutos:

rule DifferentCityLogin {
  meta:

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

  match:
    $user over 5m

  condition:
    $udm and #city > 1
}

Variável de correspondência: $user

Variável de evento:$udm

Variável de marcador: $city e $user

Veja a seguir como essa regra funciona:

  • Agrupa eventos com nome de usuário ($user) e os retorna ($user) quando uma correspondência é encontrada.
  • O intervalo de tempo é de cinco minutos, o que significa que apenas eventos com menos de cinco minutos estão correlacionados.
  • Pesquisando um grupo de eventos ($udm) com o tipo de evento USER_LOGIN.
  • Para esse grupo de eventos, a regra chama o ID do usuário como $user e a cidade de login como $city.
  • Retornará uma correspondência se o número distinto de valores $city for maior que um no grupo de eventos ($udm) no período de cinco minutos.

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

A regra a seguir procura usuários que foram criados e excluídos em até quatro horas:

rule UserCreationThenDeletion {
  meta:

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

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

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

  match:
    $user over 4h

  condition:
    $create and $delete
}

Variáveis de evento:$create e $delete

Variável de correspondência: $user

Variável de marcador: N/A

Veja a seguir como essa regra funciona:

  • Agrupa eventos com nome de usuário ($user) e os retorna ($user) quando uma correspondência é encontrada.
  • A janela de tempo é de quatro horas, o que significa que somente os eventos separados por menos de quatro horas são correlacionados.
  • Pesquisa dois grupos de eventos ($create e $delete, em que $create é equivalente a #create >= 1).
  • $create corresponde a eventos USER_CREATION e chama o ID do usuário como $user.
  • $user é usado para unir os dois grupos de eventos juntos.
  • $delete corresponde a eventos USER_DELETION e chama o ID do usuário como $user. Esta regra procura uma correspondência em que o identificador do usuário nos dois grupos de eventos seja o mesmo.
  • Esta regra procura casos em que o evento de $delete acontece depois do evento de $create, retornando uma correspondência quando descoberto.

Evento único x vários eventos

As regras de exemplo a seguir mostram como criar uma regra para pesquisar um único evento e modificá-la para pesquisar vários eventos.

Esta é a versão de evento único da regra:

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

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

  condition:
    $e
}

Essa regra simplesmente pesquisa um evento de login do usuário e retorna o primeiro que encontrar nos dados da empresa armazenados na sua conta do Chronicle.

Esta é uma versão de vários eventos da regra:

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

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

  match:
    $user over 10m

  condition:
    #e >= 10
}

A regra procura um usuário que tenha feito login pelo menos 10 vezes em menos de 10 minutos.

Evento único no intervalo de endereços IP

O exemplo a seguir mostra uma única regra de evento que procura uma correspondência entre dois usuários específicos e um intervalo específico de endereços IP:

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

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

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

  condition:
    $e
}

exemplo de regra "all and all"

A regra a seguir procura eventos de login em que todos os endereços IP de origem não correspondam a um endereço IP conhecido como seguro dentro de cinco minutos.

rule SuspiciousIPLogins {
  meta:
    author = "noone@google.com"

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

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

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

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

    $e.principal.ip = $ip

  match:
    $ip over 5m

  condition:
    $e
}

Expressões regulares em uma regra

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

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

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

  match:
    $host over 10m

  condition:
    #e > 10
}

Exemplo de regra de janela deslizante

O seguinte exemplo de janela deslizante YARA-L 2.0 pesquisa a ausência de eventos firewall_2 após firewall_1. A palavra-chave after é usada com a variável de evento dinâmica $e1 para especificar que apenas 10 minutos após cada evento firewall_1 precisam ser verificados ao correlacionar eventos.

rule SlidingWindowRuleExample {
  meta:
    author = "noone@google.com"

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

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

  match:
    $host over 10m after $e1

  condition:
    $e1 and !$e2
}

Exemplo de exclusão de valor zero

Se a regra não especificar opções de allow_zero_values, nenhum valor será retornado dos valores da variável de correspondência. No entanto, nos outros campos de evento referenciados, os valores zero não são excluídos, a menos que você especifique explicitamente essas condições. Consulte este link para ver mais detalhes.

rule ExcludeZeroValues {
  meta:
    "author" = "noone@google.com"

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

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

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

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

  match:
    // $hostname cannot be empty string.
    $hostname over 1h

  condition:
    $e1 and $e2
}

Exemplo de regra com seção de resultados

É possível adicionar a seção opcional outcome na regra YARA-L 2.0 para extrair mais informações de cada detecção. Consulte a sintaxe e a visão geral desta seção sobre como usá-la.

rule DetectionWithOutcomeSectionAndConditionalsAndAddition {
    meta:
    events:
      $u.udm.principal.hostname = $hostname
      $asset_context.graph.entity.hostname = $hostname

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

    match:
      $hostname over 5m

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