Elastic para Analistas de Segurança. Parte 1: Pesquisa de Strings.
Índice:
Propósito:
Com o Elastic aumentando sua presença na área de cibersegurança através da velocidade e escalabilidade de sua solução, esperamos mais novos usuários do Elastic. Estes usuários se aproximarão do Elastic armados com uma intuição formada a partir da experiência com outras plataformas e SIEMs. Muitas vezes, essa intuição será desafiada diretamente após algumas buscas no Elastic. O propósito desta série é familiarizar os analistas de segurança com a singularidade do Elastic. Este post fornece aos leitores um guia para construir buscas adequadas contra dados de string no Elastic.Não compreender como os tipos de dados analisados Texto e não analisados Palavra-chave afetam a busca de dados baseados em string resultará em resultados enganadores. Ao ler este post, você estará melhor equipado para realizar buscas contra strings que correspondem às suas intenções analíticas.
Resumo:
- Antes de Começarmos
- Qual Tipo de Dados Você Está Usando?
- Resumo das Diferenças
- Diferença 1: Tokenização e Termos
- Diferença 2: Sensibilidade a Maiúsculas
- Diferença 3: Correspondência de Símbolos
Antes de Começarmos:
Lucene
Este post do blog usa o Lucene. O KQL ainda não suporta expressões regulares e nós precisamos delas.
Termos: Tipos de Dados, Mapeamentos e Analisadores:
Ao discutir como os dados são armazenados nos índices do Elastic, é necessário estar familiarizado com os termos Mapeamentos, Tipos de Dados e Analisadores.
- Tipo de Dados – O “tipo”, “o tipo de dados” ou “tipo de dado” que um valor é armazenado/indexado. Exemplos de tipos de dados são: String, Booleano, Inteiro e IP. Strings são armazenadas/indexadas como um “Texto” ou “Palavra-chave” tipo de dado.
- Mapeamento – Esta é a configuração que atribui (mapeia) cada campo a um tipo de dado. Acessível através da API de obtenção de mapeamento. Quando você “obtém o mapeamento”, é retornado o campo ao qual o tipo de dado é mapeado.
- Analisador – antes de os dados de string serem armazenados/indexados, o valor é pré-processado para otimizar o armazenamento e a busca. Analisadores ajudam a tornar as buscas contra strings rápidas.
Como Strings são Armazenadas:
Existem dois principais tipos de dados para strings: Palavra-chave and Texto.
- Palavra-chave – strings do tipo Palavra-chave são armazenadas como seu valor bruto. Nenhum analisador é aplicado.
- Texto – strings do tipo Texto são analisadas. O analisador padrão e mais comum é o analisador padrão (texto). Neste post, quando nos referimos ao tipo de dado “Texto” estamos nos referindo ao tipo de dado com o analisador padrão. Existem outros analisadores, e analisadores personalizados são possíveis. Texto datatype with the standard analyzer. There are other analyzers, and custom analyzers are possible.
Qual Tipo de Dados Você Está Usando?
É altamente provável que a sua instância do Elastic esteja usando ambos os tipos de dados para strings. No entanto, o Elastic Common Schema (ECS) Texto and Palavra-chave datatypes for strings. However, the Elastic Common Schema (ECS) e Winlogbeat usam principalmente o tipo de dado Palavra-chave .
Mesmo que você esteja usando o ECS, os administradores podem personalizar mapeamentos! Para saber com certeza como um campo está mapeado, você deve consultar sua instância do Elastic. Para fazer isso, você pode usar a API de mapeamento de campo ou a API de obtenção de mapeamento. É uma boa prática se manter atualizado sobre os mapeamentos mais recentes para os campos que você pesquisa regularmente ou nos quais construiu conteúdos. Mapeamentos podem mudar, enquanto nomes de campos podem permanecer os mesmos. Reafirmando, o campo Palavra-chave de hoje pode ser um campo Texto de amanhã.
As diferenças notáveis entre Palavra-chave and Texto são detalhadas na seção abaixo. Adicionalmente, cada diferença que afetará os resultados de busca será explorada em sua própria seção.
Resumo das Diferenças
Não esperamos que você olhe para esta seção e imediatamente entenda por que os tipos correspondem quando o fazem. Cada uma das diferenças é expandida em sua seção própria. Cada um dos exemplos nas tabelas também é colocado em uma tabela dentro da seção que explica o comportamento.
Diferenças
A tabela a seguir fornece uma visão geral breve das principais diferenças nos tipos de dados.
Diferença | Padrão (texto) | Palavra-chave |
Tokenizado | Dividido em termos (tokenizado), valor original perdido, mas é mais rápido | Não tokenizado, valor original mantido |
Sensibilidade a Maiúsculas | Insensível a maiúsculas, consultas sensíveis a maiúsculas não são possíveis | Sensível a maiúsculas, consultas insensíveis a maiúsculas possíveis via regex |
Símbolos | Geralmente, caracteres não alfanuméricos não são armazenados. Mas, retém caracteres não alfanuméricos em certos contextos | Retém caracteres não alfanuméricos / Retém símbolos |
Diferenças no Comportamento
A tabela a seguir fornece exemplos do mundo real de como os tipos afetam o comportamento de busca.
Valor de Exemplo | Consulta | Correspondência de Texto | Correspondência de Palavra-chave |
Powershell.exe –encoded TvqQAAMA | process.args:encoded | Yes | No |
Powershell.exe –encoded TvqQAAMA | process.args:/.*[Ee][Nn][Cc][Oo][Dd][Ee][Dd].*/ | Yes | Yes |
Powershell.exe –encoded TvqQAAMA | process.args:*Powershell.exe*Tvq* | No | Yes |
TVqQAAMA | process.args:*TVqQAAMA* | Yes | Yes |
TVqQAAMA | process.args:*tvqqaama* | Yes | No |
cmd.exe | process.name:cmd.exe | Yes | Yes |
CmD.ExE | process.name:cmd.exe | Yes | No |
CmD.ExE | process.name:/[Cc][Mm][Dd].[Ee][Xx][Ee]/ | Yes | Yes |
\*$* | process.args:*\\*$* | No | Yes |
\C$WindowsSystem32 | process.args:*C$\* | Yes | Yes |
_
Diferença 1: Analisador, Tokenização e Termos
Diferença
Diferença | Texto (analisador padrão) | Palavra-chave |
Tokenizado | Dividido em termos (tokenizado) | Não Analisado, Não Tokenizado. Valor original mantido. |
Por quê…?
The Texto o tipo de dado / analisador padrão usa tokenização, que divide uma string em pedaços (tokens). Esses tokens são baseados em limites de palavras (ou seja, um espaço), pontuação e mais.
Como exemplo, se tokenizarmos a seguinte string com o analisador padrão:“buscando coisas com o Elastic é direto”Os termos resultantes seriam:“buscando” | “coisas” | “com” | “o” | “elastic” | “é” | “direto”Perceba que tudo foi tokenizado em espaços (limites de palavras), está agora em letras minúsculas, e o “s” foi removido de coisas.
A tokenização permite correspondência em termos únicos sem usar contains ou curingas. Por exemplo, se realizarmos uma busca por “Elastic” the Texto uma string de tipo de dado contendo “buscando coisas com o Elastic é direto” seria correspondente. Isso é diferente de outros SIEMs que dependem fortemente de curingas ou lógica de ‘contains’.
No entanto, a tokenização quebra em curingas entre termos. Por exemplo, “*buscando*Elastic*” não corresponderia à string analisada padrão “buscando com o Elastic é direto”.Nota: Você pode contornar isso com proximidade, mas a ordem não é mantida. Por exemplo, “buscando Elastic”~1 corresponderia “buscando com Elastic” e “Elastic com buscando”.
Muitas vezes na segurança precisamos de correspondência exata e a capacidade de usar curingas entre os termos. Esta é uma razão pela qual o tipo de dado Palavra-chave se tornou o tipo de dado padrão no ECS. Pelo que você perde em velocidade você ganha na capacidade de realizar buscas mais precisas.
Exemplos
Valor de Exemplo | Consulta | Correspondência de Texto | Correspondência de Palavra-chave |
Powershell.exe –encoded | process.args:”Powershell.exe –encoded” | Yes | Yes |
Powershell.exe –encoded TvqQAAMA | process.args:/.*[Ee][Nn][Cc][Oo][Dd][Ee][Dd].*/ | Yes | Yes |
Powershell.exe –encoded TvqQAAMA | process.args:encoded | Yes | No |
Powershell.exe –encoded TvqQAAMA | process.args:*Powershell.exe*encoded* | No | Yes |
_
Diferença 2: Sensibilidade a Maiúsculas
Diferença
Diferença | Texto (analisador padrão) | Palavra-chave |
Sensibilidade a Maiúsculas | Armazenado inteiramente em letras minúsculas e, portanto, insensível a maiúsculas. Consultas sensíveis a maiúsculas não são possíveis. | Sensível a maiúsculas. Consultas insensíveis a maiúsculas possíveis usando expressões regulares. |
Por quê…?
Questões de sensibilidade a maiúsculas são uma das principais causas de confusão no comportamento do Elastic como analista de segurança. Isso é especialmente verdadeiro para o Palavra-chave tipo de dado (olá pessoal do ECS). Um único caractere fora de maiúscula em um log pode evitar uma consulta construída de forma inadequada contra os campos Palavra-chave . Quando um atacante controla partes dos dados que entram no Palavras-chave (pense em eventos do Windows 4688 & 4104) você deve usar expressões regulares para garantir a insensibilidade a maiúsculas!Além disso, o Elastic não o alertará se um documento foi praticamente perdido por causa de um único caractere fora de maiúscula. Portanto, resultados ausentes ou obter mais resultados do que o pretendido é uma das causas principais de confusão como analista de segurança.
Aqui está um exemplo básico combinando-se com “PoWeRsHeLl”. Veja como basta apenas um caractere fora de maiúscula para impedir que a consulta seja correspondida.
Valor de Exemplo | Consulta | Correspondência de Texto | Correspondência de Palavra-chave |
PoWeRsHeLl | process.args:PoWeRsHell | Yes | No |
PoWeRsHeLl | process.args:PoWeRsHeLl | yes | yes |
PoWeRsHeLl | process.args:/[Pp][Oo][Ww][Ee][Rr][Ss][Hh][Ee][Ll][Ll]/ | yes | Sim (combina todos os casos) |
Para um exemplo real no Kibana. Na imagem abaixo, o campo de tipo “process.args” é consultado para a string “windows”. Para um analista desavisado isso pode parecer bom o suficiente… 42 resultados foram retornados. Bem, se eles esperavam obter qualquer documento contendo “windows” estariam errados. Como a busca é sensível a maiúsculas, portanto, “Windows” não corresponderia. Palavra-chave type field “process.args” is queried for the string “windows”. To an unsuspecting analyst this may seem good enough… 42 results were returned. Well if they were hoping to obtain any document containing “windows” they would be wrong. As the search is case sensitive, therefore “Windows” would not match.
Resultados limitados de busca sensível a maiúsculas
Na consulta abaixo, usando uma expressão regular para buscar “windows” retornam-se 567 resultados que estavam anteriormente “faltando”!
Resultados máximos
Esperamos que agora esteja claro que, se estamos buscando usando o tipo Palavra-chave e não estamos usando uma expressão regular, então perderemos variações de “powershell” além de uma correspondência exata. Tenha cuidado ao usar KQL (que não suporta regex) para buscar dados que o atacante controla.Nota: Existem casos de uso em que você desejará combinações sensíveis a maiúsculas em campos de tipo Palavra-chave, como com base64.Você pode tornar qualquer consulta insensível a maiúsculas usando conjuntos de caracteres regex. Aqui estão exemplos:
encoded | /[Ee][Nn][Cc][Oo][Dd][Ee][Dd]/ |
cmd.exe | /[Cc][Mm][Dd].[Ee][Xx][Ee]/ |
C:windowssystem32* | /[Cc]:\[Ww][Ii][Nn][Dd][Oo][Ww][Ss]\[Ss][Yy][Ss][Tt][Ee][Mm]32\.*/ |
Exemplos
Valor de Exemplo | Consulta | Correspondência de Texto | Correspondência de Palavra-chave |
TVqQAAMA | process.args::*TVqQAAMA* | Yes | Yes |
TVqQAAMA | process.args: *tvqqaama* | Yes | No |
cmd.exe | process.name:cmd.exe | Yes | Yes |
CmD.ExE | process.name:cmd.exe | Yes | No |
CmD.ExE | process.name:/[Cc][Mm][Dd].[Ee][Xx][Ee]/ | Yes | Yes |
_
Diferença 3: Correspondência de Símbolos
Diferença
Diferença | Texto (analisador padrão) | Palavra-chave |
Símbolos | Geralmente, caracteres não alfanuméricos não são armazenados. Mas, retém caracteres não alfanuméricos em certos contextos | Retém caracteres não alfanuméricos / Retém símbolos |
Por quê?
Todos os símbolos são mantidos pelo tipo Palavra-chave pois o campo inteiro é mantido exatamente como os dados são inseridos (veja a nota). No entanto, para o analisador padrão, uma regra geral a seguir é que símbolos não serão mantidos. Isso porque o analisador foi feito para combinar palavras inteiras e símbolos não são palavras. Reafirmando, símbolos são (na maior parte) não armazenados no analisador padrão. Então, Se você pretende combinar símbolos é melhor usar o tipo de dados Palavra-chave , se você tem apenas um campo de texto e precisa combinar um grupo de símbolos, você está sem sorte. No entanto, existem contextos em que símbolos serão mantidos no analisador padrão. Por exemplo, pontos serão mantidos em termos como “cmd.exe”. Os autores descobriram que a maneira mais fácil de entender quando símbolos serão mantidos no analisador padrão é simplesmente executar dados de teste na API de análise.
Exemplos
Valor de Exemplo | Consulta | Correspondência de Texto | Correspondência de Palavra-chave |
\*$* | process.args:*\\*$* | No | Yes |
\C$WindowsSystem32 | process.args:*C$\* | Yes | Yes |
cmd.exe | process.name:cmd.exe | Yes | Yes |
_
Conclusão
Elastic é uma ferramenta poderosa. No entanto, também pode ser enganadora. Esperamos que tenhamos armado você com um pouco mais de conhecimento e o poder para buscar com confiança contra dados baseados em strings.
Se você sente que precisa de ajuda escrevendo conteúdo para Elastic, o Threat Detection Marketplace da SOC Prime está repleto de conteúdo de detecção que funciona com nossa configuração sugerida do Elastic.
Posts Futuros
Fique atento a mais posts do blog explorando os fundamentos e nem tão fundamentos de usar o Elastic como analista de segurança.
Recursos Adicionais para Busca:
Esta série foca nos pontos comuns de dor para analistas ao invés de se aprofundar no tópico de sintaxe. Elastic fornece documentação detalhada sobre sua sintaxe Lucene. Além disso, existem várias folhas de dicas da comunidade de qualidade: notavelmente as de McAndre’s and Florian Roth e Thomas Patzke’s.
Meta:
Publicado – Março de 2020
Última Atualização – 12 de Março
Autores – Adam Swan (@acalarch) com a ajuda de Nate Guagenti (@neu5ron)
Versão do Elastic Usada: 7.5.2
Logs Usados Nos Exemplos: https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES