Problemas conhecidos e limitações do YARA-L 2.0
Este documento é destinado a engenheiros de detecção que querem depurar a lógica de regras e otimizar a execução do YARA-L 2.0. Ele explica como lidar com comportamentos não padrão do mecanismo, como a descompactação de campos, a expansão do produto cartesiano em agregações e a consistência posterior do enriquecimento. Ao seguir esses métodos, você pode evitar erros lógicos que levam a valores de resultado inflacionados ou detecções perdidas.
O YARA-L 2.0 usa um modelo de execução específico em que os campos repetidos são expandidos em linhas de eventos individuais durante a avaliação. Como essa transformação acontece no nível do mecanismo, a referência a vários campos repetidos ou a execução de operações aritméticas em tipos de UDM não assinados exigem soluções alternativas de sintaxe específicas para evitar erros de compilador ou conjuntos de resultados incorretos. Este documento descreve essas restrições técnicas e os padrões lógicos necessários para resolvê-las.
Antes de começar
Verifique se sua conta tem os seguintes direitos técnicos antes de testar ou modificar as regras do YARA-L 2.0:
Papéis do IAM obrigatórios
roles/chronicle.viewer(Leitor de operações de segurança): para visualizar regras e metadados de detecção.roles/chronicle.editor(Editor de operações de segurança): para modificar a lógica de regras e salvar alterações.
Permissões necessárias
chronicle.rules.runTest: necessária para executar o recurso Executar teste em dados históricos.chronicle.detections.get: para inspecionar a saída de eventos descompactados no painel de detecção.
Terminologia importante
- UDM (modelo de dados unificado) : o esquema normalizado usado para estruturar toda a telemetria de segurança ingerida na plataforma.
- Descompactação:a expansão no nível do mecanismo de um único evento de UDM que contém um campo repetido (matriz) em várias linhas. Cada linha representa um elemento exclusivo da matriz, o que pode levar à multiplicação de linhas durante a avaliação de regras.
- T₀ (execução inicial) : a primeira execução de uma regra na telemetria recebida. Isso ocorre durante a fase de "streaming", geralmente antes que os processos de enriquecimento em segundo plano (como GeoIP ou ASN) sejam finalizados.
Agregações de resultados com descompactação de campos repetidos
Quando uma regra referencia um campo repetido em uma variável de evento com vários elementos, cada elemento é dividido em uma linha de evento separada.
Por exemplo, os dois endereços IP no campo repetido target.ip no evento $e são divididos em duas instâncias de $e, cada uma com um valor target.ip diferente.
rule outbound_ip_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$outbound_ip_count = count($e.target.ip) // yields 2.
condition:
$e
}
Registros de eventos: antes e depois da descompactação
As tabelas nesta seção demonstram como um único evento que contém uma matriz de endereços IP é transformado em dois registros distintos.
Antes da descompactação
A tabela a seguir mostra o registro de eventos antes da descompactação do campo repetido:
| metadata.id | principal.application | target.ip |
|---|---|---|
aaaaaaaaa |
Google SecOps |
[192.0.2.20, 192.0.2.28] |
Depois da descompactação
A tabela a seguir mostra o registro de eventos após a descompactação do campo repetido:
| metadata.id | principal.application | target.ip |
|---|---|---|
aaaaaaaaa |
Google SecOps |
192.0.2.20 |
aaaaaaaaa |
Google SecOps |
192.0.2.28 |
Campos repetidos aninhados (produto cartesiano)
Quando uma regra referencia um campo repetido aninhado em outro, como security_results.action, a descompactação ocorre nos dois níveis (pai e filho) simultaneamente. Isso resulta em um produto cartesiano de todos os elementos.
No exemplo a seguir, um evento $e com dois valores repetidos em security_results e dois valores repetidos em security_results.actions são descompactados em quatro instâncias.
rule security_action_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$security_action_count = count($e.security_results.actions) // yields 4.
condition:
$e
}
Registro de eventos antes da descompactação aninhada
O registro original armazena as ações em uma estrutura de matriz aninhada.
| metadata.id | principal.application | security_results |
|---|---|---|
aaaaaaaaa |
Google SecOps |
[ { actions: [ ALLOW, FAIL ] }, { actions: [ CHALLENGE, BLOCK ] } ] |
Registros de eventos após a descompactação aninhada
Após a expansão, cada ação exclusiva se torna uma linha própria, o que pode levar a contagens inesperadas em agregações não distintas.
| metadata.id | principal.application | security_results.actions |
|---|---|---|
aaaaaaaaa |
Google SecOps |
PERMITIR |
aaaaaaaaa |
Google SecOps |
REPROVADO |
aaaaaaaaa |
Google SecOps |
DESAFIO |
aaaaaaaaa |
Google SecOps |
BLOQUEAR |
Impacto em campos não relacionados
Esse comportamento de descompactação na avaliação de regras pode produzir agregações de resultados inesperadas quando a regra referencia um ou mais campos repetidos com um campo pai que também é um campo repetido. Agregações não distintas, como sum(), array() e count(), não podem considerar valores duplicados em outros campos no mesmo evento produzido pelo comportamento de descompactação.
No exemplo a seguir, o evento $e tem um único nome de host (google.com), mas o resultado (hostnames) agrega quatro instâncias descompactadas do mesmo evento $e, cada uma com um valor principal.hostname duplicado. Esse resultado gera quatro nomes de host (em vez de um) devido à descompactação de valores repetidos em security_results.actions.
rule security_action_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$hostnames = array($e.principal.hostname) // yields 4.
$security_action_count = count($e.security_results.action) // yields 4.
condition:
$e
}
Registro de eventos antes da descompactação com campos não relacionados
O nome do host é um valor único, mas fica ao lado dos resultados de segurança repetidos.
| metadata.id | principal.application | principal.hostname | security_results |
|---|---|---|---|
aaaaaaaaa |
Google SecOps |
google.com |
[ { action: [ ALLOW, FAIL ] }, { action: [ CHALLENGE, BLOCK ] } ] |
Registro de eventos após a descompactação com campos não relacionados
O nome do host agora é duplicado em quatro linhas, fazendo com que a função array() o selecione quatro vezes.
| metadata.id | principal.application | principal.hostname | security_results.action |
|---|---|---|---|
aaaaaaaaa |
Google SecOps |
google.com |
PERMITIR |
aaaaaaaaa |
Google SecOps |
google.com |
REPROVADO |
aaaaaaaaa |
Google SecOps |
google.com |
DESAFIO |
aaaaaaaaa |
Google SecOps |
google.com |
BLOQUEAR |
Solução alternativa para o comportamento de descompactação
Para garantir que os valores de resultado sejam precisos quando a descompactação ocorrer, use a versão distinta da agregação selecionada. As funções a seguir ignoram as linhas duplicadas criadas pela descompactação:
max()min()array_distinct()count_distinct()
Agregações de resultados com várias variáveis de evento
Se uma regra contiver várias variáveis de evento, haverá um item separado na agregação para cada combinação de eventos incluída na detecção. Por exemplo, se a seguinte regra de exemplo for executada nos eventos listados:
events:
$e1.field = $e2.field
$e2.somefield = $ph
match:
$ph over 1h
outcome:
$some_outcome = sum(if($e1.otherfield = "value", 1, 0))
condition:
$e1 and $e2
event1:
// UDM event 1
field="a"
somefield="d"
event2:
// UDM event 2
field="b"
somefield="d"
event3:
// UDM event 3
field="c"
somefield="d"
A soma é calculada em todas as combinações de eventos, permitindo que você use as duas variáveis de evento nos cálculos de valor de resultado. Os seguintes elementos são usados no cálculo:
1: $e1 = event1, $e2 = event2
2: $e1 = event1, $e2 = event3
3: $e1 = event2, $e2 = event1
4: $e1 = event2, $e2 = event3
5: $e1 = event3, $e2 = event1
5: $e1 = event3, $e2 = event2
Isso resulta em uma soma máxima potencial de 6, mesmo que $e2 só possa corresponder a 3 eventos distintos.
Isso afeta a soma, a contagem e a matriz. Para contagem e matriz, o uso de count_distinct ou array_distinct pode resolver o problema, mas não há solução alternativa para a soma.
Parênteses no início de uma expressão
Não é possível começar uma expressão com parênteses, e isso aciona um erro de análise no editor de regras.
Sintaxe inválida
parsing: error with token: ")"
invalid operator in events predicate
O exemplo a seguir gera esse tipo de erro:
($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1
Variações de sintaxe válidas
As seguintes variações de sintaxe retornam o mesmo resultado, mas com sintaxe válida:
$event.metadata.ingested_timestamp.seconds / 3600 -
$event.metadata.event_timestamp.seconds / 3600 > 1
1 / 3600 * ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) > 1
1 < ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600
A matriz de índice no resultado exige agregação
Não é permitido indexar diretamente uma matriz na seção outcome para campos repetidos. Ela exige uma variável de marcador temporário.
outcome:
$principal_user_dept = $suspicious.principal.user.department[0]
Alternativa
Capture o índice de matriz específico em uma variável de marcador na seção events e, em seguida, referencie esse marcador no resultado.
events:
$principal_user_dept = $suspicious.principal.user.department[0]
outcome:
$principal_user_department = $principal_user_dept
Condição OR com não existência
Se você aplicar uma condição OR entre duas variáveis de evento separadas e se a regra corresponder à não existência, a regra será compilada com sucesso, mas poderá produzir detecções de falsos positivos.
Por exemplo, a seguinte sintaxe de regra pode corresponder a eventos que têm $event_a.field = "something", mesmo que não deva:
events:
not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
$event_a and #event_b >= 0
Alternativa
Separe as verificações de não existência em blocos individuais para cada variável para manter a integridade lógica.
events:
not ($event_a.field = "something")
not ($event_b.field = "something")
condition:
$event_a and #event_b >= 0
Operações aritméticas com campos de eventos não assinados
Se você tentar usar uma constante inteira em uma operação aritmética com um campo de UDM cujo tipo seja um número inteiro não assinado, vai receber um erro. Por exemplo:
events:
$total_bytes = $e.network.received_bytes * 2
As constantes inteiras padrão são definidas como números inteiros assinados, que são incompatíveis com campos de UDM definidos como números inteiros não assinados, como network.received_bytes.
Alternativa
É possível ignorar esse erro forçando a constante inteira a se comportar como um float por meio de uma operação de divisão.
events:
$total_bytes = $e.network.received_bytes * (2/1)
Enriquecimento de GeoIP e consistência posterior
O sistema prioriza a velocidade em vez da precisão imediata nos estágios iniciais de enriquecimento (streaming e sensível à latência), o que pode levar à perda de dados e a possíveis falsos positivos. O sistema continua a enriquecer os dados em segundo plano, mas os dados podem não estar disponíveis quando a regra é executada. Isso faz parte do processo normal de consistência posterior.
Para evitar falsos positivos causados pelo atraso de enriquecimento, verifique explicitamente se o campo não está vazio antes de avaliar o valor dele.
Por exemplo, considere este evento de regra:
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
A regra depende do fato de que o evento precisa ter $e.principal.ip_geo_artifact.network.asn = "16509" E $e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom", que são campos enriquecidos. Se o enriquecimento não for concluído a tempo, a regra vai produzir um falso positivo.
Para evitar isso, uma verificação melhor para essa regra seria:
$e.principal.ip_geo_artifact.network.asn != "" AND
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region != "" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
Essa regra elimina a possibilidade de o evento ser acionado por IPs com o ASN 16509, mas localizados fora do Reino Unido. Isso melhora a precisão geral da regra.
Saiba como resolver problemas de atraso de enriquecimento.
Solução de problemas
Esta seção descreve as expectativas de desempenho e fornece correções de autoatendimento para problemas comuns em que o comportamento de detecção ao vivo difere dos resultados do teste.
Eventos futuros
As regras de vários eventos são projetadas para processar eventos em ordem cronológica em relação à ingestão. Se você especificar e ativar uma regra de vários eventos, ela não vai criar detecções para eventos com carimbos de data/hora futuros, por exemplo, quando o event.timestamp tiver uma data e hora definidas após o ingest.timestamp.
Atraso de enriquecimento
O Google SecOps prioriza a velocidade de ingestão para expor alertas iniciais o mais rápido possível. No entanto, os processos de enriquecimento em segundo plano, como a resolução de metadados GeoIP, ASN ou UDM, seguem um modelo de consistência posterior.
Execução inicial (T₀)
O mecanismo ativo pode avaliar uma regra antes que o enriquecimento em segundo plano seja concluído. Dependendo se a lógica depende de campos enriquecidos para detecções ou exclusões, isso pode levar às seguintes discrepâncias temporárias:
Falsos negativos (atraso de detecção): esse é um resultado comum. Se uma regra depender de um campo enriquecido para ser acionada (por exemplo,
target.user.department == "Finance") e esse campo fornull, a regra não vai corresponder durante a execução inicial.Falsos positivos (falha de exclusão): se a regra usar campos enriquecidos para filtrar atividades conhecidas (por exemplo,
NOT target.ip_geo_country == "US"), a regra poderá acionar um falso positivo porque os dados de "exclusão" ainda não foram aplicados.
Execuções de correção
Essas execuções em segundo plano reavaliam os dados após um atraso (por exemplo, 45 minutos ou 30 horas). Isso "corrige" os estados de detecção da seguinte maneira:
Detecções atrasadas: eventos que eram "falsos negativos" em T₀ agora produzem uma detecção quando o enriquecimento é finalizado.
Correção: todos os falsos positivos de T₀ permanecem no sistema, mas os dados totalmente enriquecidos ficam visíveis no visualizador de UDM para triagem manual.
Discrepância de teste de execução
A ferramenta Executar teste opera em dados históricos que já foram reconciliados. Como os dados são totalmente enriquecidos quando você executa um teste manual, é possível conferir os resultados da "correção" imediatamente. Isso significa que você não vai ver os falsos negativos de T₀ ou os falsos positivos baseados em exclusão que ocorreram durante a execução inicial ao vivo.
Correção de erros
Use a tabela a seguir para resolver discrepâncias entre alertas ativos e resultados de testes.
| Problema | Descrição | Correção acionável |
|---|---|---|
| Falha de exclusão | Uma regra é acionada apesar de uma exclusão (por exemplo, != "ASN_123") porque o campo era nulo durante a execução inicial. |
Adicione uma verificação não nula à seção de eventos para garantir que os dados sejam enriquecidos antes da avaliação, por exemplo:$e.principal.ip_geo_artifact.network.asn != ""
|
| Comparação entre correspondência ativa e de teste | As regras ativas acionam alertas, mas a execução do teste nos mesmos dados mostra "No Results". |
Adicione $e.field != "" que verifica todos os campos enriquecidos (GeoIP, ASN, File Path) para sincronizar o comportamento ativo e histórico. |
| Metadados ausentes | As detecções aparecem no painel com campos GeoIP ou File Path vazios. |
Isso é esperado para execuções T0. Para corrigir, inclua uma verificação field != "" ou aumente o deslocamento da primeira execução na programação para permitir mais tempo para a ingestão.
|
Validação e teste
Para verificar se uma regra está processando corretamente o enriquecimento atrasado, faça o seguinte:
Identifique o atraso:localize uma detecção que você acredita ser um falso positivo. Na coluna Tipo de detecção, procure o ícone
<span class="material-icons">lightbulb</span>. Os alertas sem esse ícone são da execução inicial em que o atraso de enriquecimento é mais comum.Atualize a lógica de regras: adicione uma verificação
field != ""para todos os pontos de dados enriquecidos usados na lógica.
Exemplo (caminho do arquivo):
$e.target.process.parent_process.file.full_path != ""Teste e verifique :
- Use o recurso Executar teste para garantir que a lógica ainda corresponda aos dados históricos pretendidos.
- Verifique se a regra agora só é acionada (ou excluída corretamente) durante as execuções de correção depois que os campos de enriquecimento são preenchidos.
Para mais detalhes, consulte Gerenciar a programação de execução de regras e Configurar programações personalizadas para regras.
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.