Vista geral da linguagem YARA-L 2.0
O YARA-L 2.0 é uma linguagem informática usada para criar regras para pesquisar através dos dados de registo da sua empresa à medida que são carregados na sua instância do Google Security Operations. A sintaxe YARA-L deriva da linguagem YARA desenvolvida pelo VirusTotal. A linguagem funciona em conjunto com o motor de deteção do Google SecOps e permite-lhe procurar ameaças e outros eventos em grandes volumes de dados.
Para mais informações, consulte o seguinte:
Regras de exemplo do YARA-L 2.0
Os exemplos seguintes mostram regras escritas em YARA-L 2.0. Cada um demonstra como correlacionar eventos na linguagem de regras.
Regras e otimização
A regra seguinte verifica a existência de padrões específicos nos dados de eventos e cria uma deteção
se encontrar os padrões. Esta regra inclui uma variável $e1
para acompanhar o tipo de evento e o campo metadata.event_type
UDM. A regra verifica ocorrências específicas de correspondências de expressões regulares com e1
. Quando o evento $e1
ocorre, é criada uma deteção.
É incluída uma condição not
na regra para excluir determinados caminhos não maliciosos.
Pode adicionar not
condições 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
}
Inícios de sessão a partir de cidades diferentes
A regra seguinte procura utilizadores que tenham iniciado sessão na sua empresa a partir de duas ou mais cidades em menos de 5 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 do marcador de posição: $city
e $user
A descrição seguinte explica como funciona esta regra:
- Agrupa eventos com o nome de utilizador (
$user
) e devolve-o ($user
) quando é encontrada uma correspondência. - O intervalo de tempo é de 5 minutos, o que significa que apenas os eventos com uma diferença inferior a 5 minutos são correlacionados.
- Pesquisar um grupo de eventos (
$udm
) cujo tipo de evento seja USER_LOGIN. - Para esse grupo de eventos, a regra chama o User-ID como
$user
e a cidade de início de sessão como$city.
- Devolve uma correspondência se o número distinto de valores
city
(indicado por#city
) for superior a 1 no grupo de eventos ($udm
) no intervalo de tempo de 5 minutos.
Criação e eliminação rápidas de utilizadores
A regra seguinte procura utilizadores que foram criados e, em seguida, eliminados no prazo de 4 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 eventos:$create
e $delete
Variável de correspondência: $user
Variável do marcador de posição: N/A
A descrição seguinte explica como funciona esta regra:
- Agrupa eventos com o nome de utilizador (
$user
) e devolve-o ($user
) quando é encontrada uma correspondência. - O período é de 4 horas, o que significa que apenas os 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 a eventosUSER_CREATION
e chama o ID do utilizador como$user
.$user
é usado para juntar os dois grupos de eventos.$delete
corresponde a eventosUSER_DELETION
e chama o ID do utilizador como$user
. Esta regra procura uma correspondência em que o identificador do utilizador nos dois grupos de eventos seja o mesmo.- Esta regra procura casos em que o evento de
$delete
ocorre mais tarde do que o evento de$create
, devolvendo uma correspondência quando é detetada.
Regra de evento único
As regras de evento único são regras que estabelecem correlações com base num único evento. Uma única regra de evento pode ser:
- Qualquer regra sem uma secção de correspondência.
- Regra com uma secção
match
e uma secçãocondition
que verifica apenas a existência de 1 evento (por exemplo, "$e", "#e > 0", "#e >= 1", "1 <= #e", "0 < #e").
Por exemplo, a seguinte regra procura um evento de início de sessão do utilizador e devolve o primeiro que encontrar nos dados empresariais armazenados na sua conta do Google SecOps:
rule SingleEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
Segue-se outro exemplo de uma regra de evento única com uma secção de correspondência. Esta regra procura um utilizador que tenha iniciado sessão, pelo menos, uma vez em menos de 5 minutos. Verifica a existência simples de um evento de início de sessão do utilizador.
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 eventos para agrupar muitos eventos num período especificado e tentar encontrar correlações entre eventos. Uma regra de vários eventos típica tem o seguinte:
- Uma secção
match
que especifica o intervalo de tempo durante o qual os eventos têm de ser agrupados. - Uma secção
condition
que especifica a condição que deve acionar a deteção e a verificação da existência de vários eventos.
Por exemplo, a regra seguinte procura um utilizador que tenha iniciado sessão, 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 seguinte mostra uma única regra de evento que procura correspondências entre dois nomes de anfitrião 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 de qualquer tipo
A regra seguinte procura eventos de início de sessão em que todos os endereços IP de origem não correspondem a um endereço IP conhecido como seguro num intervalo 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 numa regra
O exemplo de expressão regular YARA-L 2.0 seguinte pesquisa eventos com emails recebidos do domínio altostrat.com. Uma vez que nocase
foi adicionado à comparação da variável $host
regex
e à função regex
, ambas as comparações não são sensíveis a maiúsculas e 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
}
Exemplos de regras compostas
As deteções compostas melhoram a deteção de ameaças através da utilização de regras compostas. Estas regras compostas usam deteções de outras regras como entrada. Isto permite a deteção de ameaças complexas que as regras individuais podem não detetar. Para mais informações, consulte o artigo Vista geral das deteções compostas.
Deteções de cabo de tropeço
As deteções compostas de armadilhas são a forma mais simples de deteção composta que opera em campos nas conclusões de deteção, como variáveis de resultado ou metadados de regras. Ajudam a filtrar deteções de condições que podem indicar um risco mais elevado, como um utilizador administrador ou um ambiente de produção.
rule composite_admin_detection {
meta:
rule_name = "Detection with Admin User"
author = "Google Cloud Security"
description = "Composite rule that looks for any detections where the actor is an admin user"
severity = "Medium"
events:
$rule_name = $d.detection.detection.rule_name
$principal_user = $d.detection.detection.outcomes["principal_users"]
$principal_user = /admin|root/ nocase
match:
$principal_user over 1h
outcome:
$risk_score = 75
$upstream_rules = array_distinct($rule_name)
condition:
$d
}
Deteções de limite e agregação
As regras de deteção compostas de agregação permitem agrupar as conclusões de deteção com base em atributos partilhados, como um nome de anfitrião ou um nome de utilizador, e analisar os dados agregados. Seguem-se alguns exemplos de utilização comuns:
- Identificar utilizadores que geram um volume elevado de alertas de segurança ou risco agregado.
- Detetar anfitriões com padrões de atividade invulgares agregando deteções relacionadas.
Exemplo de agregação de riscos:
rule composite_risk_aggregation {
meta:
rule_name = "Risk Aggregation Composite"
author = "Google Cloud Security"
description = "Composite detection that aggregates risk of a user over 48 hours"
severity = "High"
events:
$rule_name = $d.detection.detection.rule_name
$principal_user = $d.detection.detection.outcomes["principal_users"]
$risk = $d.detection.detection.risk_score
match:
$principal_user over 48h
outcome:
$risk_score = 90
$cumulative_risk = sum($risk)
$principal_users = array_distinct($principal_users)
$upstream_rules = array_distinct($rule_name)
condition:
$d and $cumulative_risk > 500
}
Exemplo de agregação de táticas:
rule composite_tactic_aggregation {
meta:
rule_name = "MITRE Tactic Aggregation Composite"
author = "Google Cloud Security"
description = "Composite detection that detects if a user has triggered detections over multiple mitre tactics."
severity = "Medium"
events:
$principal_user = $d.detection.detection.outcomes["principal_users"]
$tactic = $d.detection.detection.rule_labels["tactic"]
$rule_name = $d.detection.detection.rule_name
match:
$principal_user over 48h
outcome:
$mitre_tactics_count = count_distinct($tactic)
$mitre_tactics = array_distinct($d.detection.rule_labels["tactic"])
$risk_score = min(100, (50+15*$mitre_tactics_count))
$upstream_rules = array_distinct($rule_name)
condition:
$d and $mitre_tactics_count > 1
}
Deteções compostas sequenciais
As deteções compostas sequenciais identificam padrões de eventos relacionados em que a sequência de deteções é importante, como uma deteção de tentativa de início de sessão por força bruta, seguida de um início de sessão bem-sucedido. Estes padrões podem envolver várias deteções base ou uma combinação de deteções base e eventos.
rule composite_bruteforce_login {
meta:
rule_name = "Bruteforce Login Composite"
author = "Google Cloud Security"
description = "Detects when an IP address associated with a Workspace brute force attempt successfully logs in"
severity = "High"
events:
$bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
$bruteforce_ip = $d.detection.detection.outcomes["principal_ips"]
$login_event.metadata.product_name = "login"
$login_event.metadata.product_event_type = "login_success"
$login_event.metadata.vendor_name = "Google Workspace"
$login_ip = $login_event.principal.ip
// Ensure the brute force detection and successful login occurred from the same IP
$login_ip = $bruteforce_ip
$target_account = $login_event.target.user.email_addresses
// Ensure the brute force detection occurred before the successful login
$bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds
match:
$bruteforce_ip over 24h
outcome:
$risk_score = 90
$principal_users = array_distinct($target_account)
condition:
$bruteforce_detection and $login_event
}
Deteções sensíveis ao contexto
As deteções compostas sensíveis ao contexto enriquecem as deteções com contexto adicional, como endereços IP encontrados em feeds de ameaças.
rule composite_tor_enrichment {
meta:
rule_name = "Detection with IP from TOR Feed"
author = "Google Cloud Security"
description = "Adds additional context from the TOR intel feed to detections"
severity = "High"
events:
$detection_ip = $d.detection.detection.outcomes["principal_ips"]
$gcti.graph.metadata.entity_type = "IP_ADDRESS"
$gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
$gcti_feed.graph.metadata.source_type = "GLOBAL_CONTEXT"
$gcti.graph.metadata.product_name = "GCTI Feed"
$gcti.graph.metadata.threat.threat_feed_name = "Tor Exit Nodes"
$detection_ip = $gcti.graph.entity.ip
$rule_name = $d.detection.detection.rule_name
$risk = $d.detection.detection.outcomes["risk_score"]
match:
$detection_ip, $rule_name over 1h
outcome:
$risk_score = 80
$upstream_rule = array_distinct($rule_name)
condition:
$d and $gcti
}
Deteções de ocorrência simultânea
As deteções compostas de ocorrência conjunta são uma forma de agregação que pode detetar uma combinação de eventos relacionados, como uma combinação de deteções de escalada de privilégios e exfiltração de dados acionadas por um utilizador.
rule composite_privesc_exfil_sequential {
meta:
rule_name = "Privilege Escalation and Exfiltration Composite"
author = "Google Cloud Security"
description = "Looks for a detection sequence of privilege escalation followed by exfiltration."
severity = "High"
events:
$privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
$exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"
$pe_user = $privilege_escalation.detection.detection.outcomes["principal_users"]
$ex_user = $exfiltration.detection.detection.outcomes["principal_users"]
$pe_user = $ex_user
match:
$pe_user over 48h
outcome:
$risk_score = 75
$privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
$exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)
condition:
$privilege_escalation and $exfiltration
}
Exemplo de regra de janela deslizante
O seguinte exemplo de janela deslizante YARA-L 2.0 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 tabela dinâmica $e1
para especificar que só devem ser verificados os períodos de 10 minutos após cada evento firewall_1
quando 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 motor de regras filtra implicitamente os valores zero para todos os marcadores de posição usados na secção match
.
Para mais informações, consulte o processamento de valores zero na secção match
.
Pode desativar esta opção através da opção allow_zero_values
, conforme descrito em allow_zero_values.
No entanto, para outros campos de eventos referenciados, os valores zero não são excluídos, a menos que 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
}
Exemplo de regra com a secção outcome
Pode adicionar a secção outcome
opcional numa regra YARA-L 2.0 para extrair informações adicionais de cada deteção. Na secção de condições, também pode especificar condições nas variáveis de resultados. Pode usar a secção outcome
de uma regra de deteção para definir variáveis para consumo a jusante. Por exemplo, pode definir uma classificação de gravidade com base nos dados dos eventos que estão a ser analisados.
Para mais informações, consulte o seguinte:
Regra de vários eventos com secção de resultado:
A seguinte regra analisa dois eventos para obter o valor de
$hostname
. Se o valor de $hostname
corresponder durante um período de 5 minutos,
é aplicada uma classificação de gravidade. Quando inclui um período na secção match
, a regra verifica o 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 secçã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
}
Refatorar uma regra de resultado de vários eventos numa regra de resultado de um único evento.
Pode usar a secção outcome
para regras de evento único (regras sem uma secção match
) e regras de vários eventos (regras com uma secção match
).
Se criou anteriormente uma regra com vários eventos apenas para poder usar a secção de resultados, pode, opcionalmente, refatorar essas regras eliminando a secção match
para melhorar o desempenho. Tenha em atenção que, como a sua regra já não tem uma secção match
que aplique o agrupamento, pode receber mais deteções. Esta refatoração só é possível para regras que usam uma variável de evento, conforme mostrado no exemplo seguinte.
Regra de resultado com vários eventos que usa apenas uma variável de evento (um bom candidato para uma 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
}
Pode refatorar a regra eliminando a secção match
. Tenha em atenção que também tem de remover a agregação na secção outcome
, uma vez que a regra passa a ser de evento único. 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 marcador de posição para função
Pode atribuir uma variável de marcador de posição ao resultado de uma chamada de função e
pode usar a variável de marcador de posição noutras secções da regra, como a secção
match
, a secção outcome
ou a secção condition
. Veja o exemplo seguinte:
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 condições de resultados
Na secção condition
, pode usar variáveis de resultados que foram definidas na secção outcome
. O exemplo seguinte demonstra como filtrar as pontuações de risco para reduzir o ruído nas deteções através de condições de resultados.
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
}
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais da Google SecOps.