Visão geral da linguagem YARA-L 2.0
A YARA-L 2.0 é uma linguagem de computador usada para criar regras de pesquisa nos dados de registros corporativos conforme eles são ingeridos na sua instância do Google Security Operations. A sintaxe YARA-L é derivada da linguagem YARA desenvolvida pelo VirusTotal. A linguagem funciona em conjunto com o mecanismo de detecção do Google Security Operations e permite detectar ameaças e outros eventos em grandes volumes de dados.
Para ver mais informações, consulte os seguintes tópicos:
Exemplos de regras da YARA-L 2.0
Os exemplos a seguir mostram regras escritas em YARA-L 2.0. Cada um demonstra como correlacionar eventos na linguagem de regras.
Regras e ajustes
A regra a seguir verifica padrões específicos nos dados de eventos e cria uma detecção
se encontrar os padrões. Essa regra inclui uma variável $e1
para rastrear o tipo de evento e o campo UDM metadata.event_type
. A regra verifica ocorrências específicas
de correspondências de expressões regulares com e1
. Quando o evento $e1
ocorre, uma detecção é criada.
Uma condição not
é incluída na regra para excluir determinados caminhos não maliciosos.
É possível adicionar condições not
para evitar falsos positivos.
rule suspicious_unusual_location_svchost_execution
{
meta:
author = "Google Cloud Security"
description = "Windows 'svchost' executed from an unusual location"
yara_version = "YL2.0"
rule_version = "1.0"
events:
$e1.metadata.event_type = "PROCESS_LAUNCH"
re.regex($e1.principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex($e1.principal.process.command_line, `\\Windows\\System32\\`) nocase
condition:
$e1
}
Logins de cidades diferentes
A regra a seguir procura usuários que fizeram login na sua empresa de 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 de posição: $city
e $user
Confira como essa regra funciona:
- Agrupa eventos com o nome de usuário (
$user
) e o retorna ($user
) quando uma correspondência é encontrada. - O período é de 5 minutos, o que significa que apenas eventos com menos de 5 minutos de diferença são correlacionados.
- Pesquisando um grupo de eventos (
$udm
) cujo tipo de evento é USER_LOGIN. - Para esse grupo de eventos, a regra chama o ID do usuário como
$user
e a cidade de login como$city.
- Retorna uma correspondência se o número distinto de valores
city
(indicado por#city
) for maior que 1 no grupo de eventos ($udm
) no período 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 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 de posição: N/A
Confira como essa regra funciona:
- Agrupa eventos com o nome de usuário (
$user
) e o retorna ($user
) quando uma correspondência é encontrada. - A janela de tempo é de 4 horas, o que significa que apenas eventos separados por menos de 4 horas são correlacionados.
- Pesquisa dois grupos de eventos (
$create
e$delete
, em que$create
é equivalente a#create >= 1
). $create
corresponde aos eventosUSER_CREATION
e chama o ID do usuário como$user
.$user
é usado para mesclar os dois grupos de eventos.$delete
corresponde aos eventosUSER_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 é o mesmo.- Essa regra procura casos em que o evento de
$delete
ocorre depois do evento de$create
, retornando uma correspondência quando descoberto.
Regra de evento único
As regras de eventos únicos são regras que se correlacionam com 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 procura um evento de login do usuário e retorna o primeiro que encontrar nos dados corporativos armazenados na sua conta do Google Security Operations:
rule SingleEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
Confira outro exemplo de uma regra de evento único com uma seção de correspondência. Essa regra procura 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 um período especificado e tentar encontrar correlações entre eles. Uma regra de vários eventos típica tem o seguinte:
- Uma seção
match
que especifica o período em que os eventos precisam ser agrupados. - Uma seção
condition
que especifica qual condição deve acionar a detecção e verificar a 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
}
Um único evento dentro do intervalo de endereços IP
O exemplo a seguir mostra uma regra de evento único 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
}
qualquer exemplo de regra
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 conhecido por ser seguro em um período de 5 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
, essas comparações não diferenciam maiúsculas de minúsculas.
rule RegexRuleExample {
meta:
author = "noone@altostrat.com"
events:
$e.principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex($e.network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
condition:
#e > 10
}
Exemplo de regra de janela deslizante
O exemplo de janela deslizante do YARA-L 2.0 a seguir procura a ausência de
eventos firewall_2
após eventos firewall_1
. A palavra-chave after
é usada com
a variável de evento de pivô $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 de todos os marcadores de posição
usados na seção match
.
Para mais informações, consulte Processamento de valor zero na seção match
.
Isso pode ser desativado usando a opção allow_zero_values
, conforme
descrito em allow_zero_values.
No entanto, para outros campos de evento referenciados, os valores zero não são excluídos, a menos que você especifique essas condições explicitamente.
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
}
Exemplo de regra com seção outcome
É possível adicionar a seção opcional outcome
na regra YARA-L 2.0 para extrair
mais informações de cada detecção. Na seção de condições, você também pode especificar condições em variáveis de resultado. É possível usar a seção outcome
de uma regra de detecção para definir variáveis para consumo downstream. Por exemplo, é possível definir uma pontuação de gravidade com base nos dados dos eventos analisados.
Para ver mais informações, consulte os seguintes tópicos:
Regra de vários eventos com a seção de resultado:
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 você inclui um período na seção match
,
a regra é verificada no 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 resultado:
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
}
Refazer uma regra de resultado de vários eventos em uma regra de resultado de um único evento.
É possível usar a seção outcome
para regras de eventos únicos (regras sem uma
seção match
) e para regras de eventos múltiplos (regras com uma seção match
).
Se você já criou uma regra para ser multievento apenas para usar a seção de resultados, é possível refatorar essas regras excluindo a seção match
para melhorar o desempenho. Como sua regra não
tem mais uma seção match
que aplica o agrupamento,
você pode receber mais detecções. Essa refatoração só é
possível para regras que usam uma variável de evento, conforme mostrado no
exemplo abaixo.
Regra de resultado de vários eventos que usa apenas uma variável de evento (um bom candidato para uma refatorizaçã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
}
Você pode refatorar a regra excluindo a seção match
. Você também precisa remover o agregado na seção outcome
, porque a regra agora será de um único evento. Para mais informações 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 de posição ao resultado de uma chamada de função e
usar a variável de marcador de posição em outras seções da regra, como a
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
}
Exemplo de regra de condicional de resultado
Na seção condition
, é possível usar variáveis de resultado definidas
na seção outcome
. O exemplo a seguir demonstra como filtrar as
pontuações de risco para reduzir o ruído nas detecções usando resultados condicionais.
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
}