Visão geral da linguagem YARA-L 2.0
O YARA-L 2.0 é uma linguagem de computador usada para criar regras de pesquisa nos dados de registro da empresa conforme eles são ingeridos na instância do Chronicle. A sintaxe YARA-L é derivada da linguagem YARA desenvolvida pelo VirusTotal. A linguagem funciona em conjunto com o mecanismo de detecção do Chronicle e permite que você procure ameaças e outros eventos em grandes volumes de dados.
Para ver mais informações, consulte os seguintes tópicos:
Regras de exemplo do YARA-L 2.0
Os exemplos a seguir mostram regras escritas em YARA-L 2.0. Cada um demonstra como correlacionar eventos na linguagem das regras.
Regras e ajustes
A regra a seguir verifica se há padrões específicos nos dados de eventos e cria uma detecção
caso os padrões sejam encontrados. Essa regra inclui uma variável $e1
para o tipo de evento de rastreamento e o campo UDM metadata.event_type
. A regra verifica ocorrências específicas
de correspondências de expressão regular com e1
. Quando o evento $e1
ocorre, uma detecção é criada.
Uma condição not
é incluída na regra para excluir determinados caminhos não maliciosos.
É possível adicionar condições not
para evitar falsos positivos.
rule suspicious_unusual_location_svchost_execution
{
meta:
author = "Google Cloud Security"
description = "Windows 'svchost' executed from an unusual location"
yara_version = "YL2.0"
rule_version = "1.0"
events:
$e1.metadata.event_type = "PROCESS_LAUNCH"
re.regex($e1.principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex($e1.principal.process.command_line, `\\Windows\\System32\\`) nocase
condition:
$e1
}
Logins de diferentes cidades
A regra a seguir pesquisa usuários que fizeram login na sua 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 do evento:$udm
Variável de marcador: $city
e $user
Confira a seguir como essa regra funciona:
- Agrupa eventos com o nome de usuário (
$user
) e o retorna ($user
) quando é encontrada uma correspondência. - O período é de cinco minutos, o que significa que apenas os eventos com menos de cinco minutos de diferença são correlacionados.
- Pesquisar um grupo de eventos (
$udm
) com um tipo de evento USER_LOGIN. - Nesse 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
(indicados por#city
) for maior que 1 no grupo de eventos ($udm
) dentro do intervalo de tempo de 5 minutos.
Criação e exclusão rápidas de usuários
A regra a seguir pesquisa usuários que foram criados e excluídos no prazo de 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
Confira a seguir como essa regra funciona:
- Agrupa eventos com o nome de usuário (
$user
) e o retorna ($user
) quando é encontrada uma correspondência. - A janela de tempo é de quatro horas, o que significa que apenas 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 deUSER_CREATION
e chama o ID do usuário como$user
.$user
é usado para unir os dois grupos de eventos.$delete
corresponde a eventos deUSER_DELETION
e chama o ID do usuário como$user
. Essa 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
e retorna uma correspondência quando descoberto.
Regra de evento único
As regras de evento único são regras relacionadas a um único evento. Uma regra de evento único pode ser:
- Qualquer regra sem uma seção de correspondência.
- Regra com uma seção
match
e uma seçãocondition
que verifica apenas a existência de um evento (por exemplo, "$e", "#e > 0", "#e >= 1", "1 <= #e", "0 < #e").
Por exemplo, a regra a seguir pesquisa um evento de login de usuário e retornaria o primeiro que encontrar nos dados da empresa armazenados na sua conta do Chronicle:
rule SingleEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
Veja outro exemplo de uma regra de evento único com uma seção de correspondência. Esta regra pesquisa um usuário que fez login pelo menos uma vez em menos de 5 minutos. Ele verifica a existência simples de um evento de login do usuário.
rule SingleEventRule {
meta:
author = "alice@example.com"
description = "windowed single event example rule"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 5m
condition:
#e > 0
}
rule MultiEventRule{
meta:
author = "alice@example.com"
description = "Rule with outcome condition and simple existence condition on one event variable"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 10m
outcome:
$num_events_in_match_window = count($e.metadata.id)
condition:
#e > 0 and $num_events_in_match_window >= 10 // Could be rewritten as #e >= 10
}
Regra de vários eventos
Use várias regras de evento para agrupar muitos eventos em uma janela de tempo específica e tente encontrar correlações entre eventos. Uma regra de vários eventos típica terá o seguinte:
- Uma seção
match
que especifica o período em que os eventos precisam ser agrupados. - Uma seção
condition
especificando qual condição acionará a detecção e a verificação da existência de vários eventos.
Por exemplo, a regra a seguir pesquisa um usuário que fez login pelo menos 10 vezes em menos de 10 minutos:
rule MultiEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 10m
condition:
#e >= 10
}
Evento único dentro do intervalo de endereços IP
O exemplo a seguir mostra uma única regra de evento que pesquisa 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 "qualquer"
A regra a seguir pesquisa eventos de login em que todos os endereços IP de origem não correspondem a um endereço IP considerado seguro em um período de cinco minutos.
rule SuspiciousIPLogins {
meta:
author = "alice@example.com"
events:
$e.metadata.event_type = "USER_LOGIN"
// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".
all $e.principal.ip != "100.97.16.0"
// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.
$e.principal.ip = $ip
match:
$ip over 5m
condition:
$e
}
Expressões regulares em uma regra
O exemplo de expressão regular YARA-L 2.0 a seguir pesquisa eventos com e-mails recebidos do domínio altostrat.com. Como nocase
foi adicionado à comparação regex
da variável $host
e à função regex
, ambas as 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 exemplo de janela deslizante YARA-L 2.0 a seguir pesquisa a ausência de eventos firewall_2
após eventos firewall_1
. A palavra-chave after
é usada com
a variável de evento dinâmico $e1
para especificar que apenas janelas de 10 minutos após cada
evento firewall_1
precisam ser verificadas ao correlacionar eventos.
rule SlidingWindowRuleExample {
meta:
author = "alice@example.com"
events:
$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host
$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host
match:
$host over 10m after $e1
condition:
$e1 and !$e2
}
Exemplo de exclusão de valor zero
O Rules Engine filtra implicitamente os valores zero para todos os marcadores
usados na seção match
.
Para mais informações, consulte Processamento de valor zero na seção match
.
Isso pode ser desativado com a opção allow_zero_values
, conforme
descrito em allow_zero_values.
No entanto, para outros campos de evento referenciados, valores zero não serão excluídos, a menos que você especifique explicitamente essas condições.
rule ExcludeZeroValues {
meta:
author = "alice@example.com"
events:
$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname
// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"
$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname
// $e2.target.asset_id cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
match:
// $hostname cannot be empty string. The rule behaves as if the
// predicate, `$hostname != ""` was added to the events section, because
// `$hostname` is used in the match section.
$hostname over 1h
condition:
$e1 and $e2
}
Regra com exemplo de seção outcome
É possível adicionar a seção outcome
opcional na regra YARA-L 2.0 para extrair
mais informações de cada detecção. Na seção de condição, também é possível especificar
condicionais em variáveis de resultado. É possível usar a seção outcome
de uma regra de
detecção para definir variáveis para o consumo downstream. Por exemplo, é possível definir uma pontuação de gravidade com base nos dados dos eventos que estão sendo analisados.
Para ver mais informações, consulte os seguintes tópicos:
Regra de vários eventos com seção de resultados:
A regra a seguir analisa dois eventos para receber o valor de $hostname
. Se o valor de $hostname
corresponder a um período de cinco minutos,
uma pontuação de gravidade será aplicada. Quando inclui um período na seção match
,
a regra verifica dentro do período especificado.
rule OutcomeRuleMultiEvent {
meta:
author = "Google Cloud Security"
events:
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$risk_score =
max(
100
+ if($hostname = "my-hostname", 100, 50)
+ if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}
rule OutcomeRuleMultiEvent {
meta:
author = "alice@example.com"
events:
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)
$risk_score = if(total_network_bytes > 1024, 100, 50) +
max(
if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}
Regra de evento único com seção de resultados:
rule OutcomeRuleSingleEvent {
meta:
author = "alice@example.com"
events:
$u.metadata.event_type = "FILE_COPY"
$u.principal.file.size = $file_size
$u.principal.hostname = $hostname
outcome:
$suspicious_host = $hostname
$admin_severity = if($u.principal.userid in %admin_users, "SEVERE", "MODERATE")
$severity_tag = if($file_size > 1024, $admin_severity, "LOW")
condition:
$u
}
Refatoração de uma regra de resultado de vários eventos em uma regra de resultado de evento único.
É possível usar a seção outcome
para regras de evento único (regras sem uma seção match
) e regras de vários eventos (regras com uma seção match
).
Se você já tiver projetado uma regra para ser de múltiplos eventos apenas para poder usar a seção de resultados, poderá refatorar essas regras excluindo a seção match
para melhorar o desempenho. Esteja ciente de que, como sua regra não
tem mais uma seção match
que aplica o agrupamento,
talvez você receba mais detecções. Essa refatoração só é possível para regras que usam uma variável de evento, conforme mostrado no exemplo a seguir.
Regra de resultado de vários eventos que usa apenas uma variável de evento (um bom candidato para refatoração):
rule OutcomeMultiEventPreRefactor {
meta:
author = "alice@example.com"
description = "Outcome refactor rule, before the refactor"
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
}
É possível refatorar a regra excluindo a seção match
. Você também precisa remover a agregação na seção outcome
, já que a regra agora será de um único evento. Para saber mais sobre agregações, consulte agregações de resultados.
rule OutcomeSingleEventPostRefactor {
meta:
author = "alice@example.com"
description = "Outcome refactor rule, after the refactor"
events:
$u.udm.principal.hostname = $hostname
// We deleted the match section.
outcome:
// We removed the max() aggregate.
$risk_score = if($hostname = "my-hostname", 100, 50)
condition:
$u
}
Exemplo de regra de função para marcador de posição
É possível atribuir uma variável de marcador ao resultado de uma chamada de função e usar essa variável em outras seções da regra, como na seção match
, outcome
ou condition
. Veja o exemplo a seguir:
rule FunctionToPlaceholderRule {
meta:
author = "alice@example.com"
description = "Rule that uses function to placeholder assignments"
events:
$u.metadata.event_type = "EMAIL_TRANSACTION"
// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture($u.network.email.from , "(.*)@")
// Use function-placeholder assignment to normalize an email:
// uid@??? -> uid@company.com
$email_from_normalized = strings.concat(
re.capture($u.network.email.from , "(.*)@"),
"@company.com"
)
// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)
match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m
outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
if($dayofweek = 1, 10, 0) +
if($dayofweek = 7, 10, 0)
)
condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1
}
Regra de exemplo de condicionais de resultado
Na seção condition
, é possível usar variáveis de resultado que foram definidas
na seção outcome
. O exemplo a seguir demonstra como filtrar pontuações de risco para reduzir o ruído em detecções usando condicionais de resultado.
rule OutcomeConditionalRule {
meta:
author = "alice@example.com"
description = "Rule that uses outcome conditionals"
events:
$u.metadata.event_type = "FILE_COPY"
$u.principal.file.size = $file_size
$u.principal.hostname = $hostname
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week($u.metadata.collected_timestamp.seconds)
outcome:
$risk_score =
if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices
condition:
$u and $risk_score >= 10
}