Este artigo é a terceira e última parte da série Sysmon Threat Analysis. Todas as outras partes da série:
Parte 1. Apresentando a análise de registro do Sysmon
Parte 2. Usando dados de eventos do Sysmon para detectar ameaças
Parte 3. Análise avançada de ameaças do Sysmon usando gráficos (estamos aqui)
Encontrando Subgráficos Não Padrão com Dados de Evento Sysmon (Exemplo Simples)
Antes de olharmos para um exemplo de identificação de anomalias em subgráficos que indicam uma ameaça potencial (e se essas palavras não despertam o nerd em você, então nada o despertará!), Vamos fazer uma pequena digressão.
Neste ponto, devo emitir um aviso: este post, junto com o código no GitHub, não pode substituir uma solução de nível empresarial. Ele pode ajudar a identificar ameaças em uma escala menor, mas meu nobre missão é ajudar os profissionais de segurança de entender e apreciar soluções de proteção contra ameaças do mundo real. E uma maneira de conseguir isso é criar sua própria solução (com a minha ajuda).
Os experimentos em casa ajudarão você a entender como é difícil dimensionar o software de detecção de ameaças DIY. Você terá que trabalhar com conjuntos de big data e tudo relacionado a eles: limpeza (que é uma tarefa extremamente difícil), processamento eficiente (encontrar as estruturas de dados necessárias, algoritmos, etc.) e fornecer resultados com um baixo número de falsos positivos para que seu os mesmos colegas não subiram em você com os punhos. Com isso em mente, você pode querer considerar uma solução de detecção de ameaças pronta ... mas somente depois de concluir nossa série de artigos e conduzir seus próprios experimentos.
Definindo pesos gráficos
Uma maneira fácil de construir uma solução de proteção contra ameaças que não dependa de assinaturas de malware é usar o gráfico de ameaças da parte anterior .
Esse gráfico conecta os nós de processo com base nas entradas do log de eventos Sysmon.
Observação: não separei cada evento de início de processo (ID de evento 1 em eventos Sysmon) em um vértice separado. Em vez disso, criei um gráfico mais abstrato que mostra, digamos, o vértice do PowerShell tem um link para qualquer aplicativo que ele inicia de qualquer usuário - um link para o Excel, um para o navegador e assim por diante.
A visualização em árvore PSQuickGraph do meu gráfico de ameaças Sysmon. Preste atenção à ramificação anômala em cmd.exe.
No entanto, ainda queremos controlar a frequência dos processos em execução. Por exemplo, se o PowerShell lançou "whoami" 1 vez e o editor do Windows desatualizado "Notepad.exe" 10 vezes, as arestas do gráfico que vão do vértice do PowerShell devem ser marcadas com os "pesos" correspondentes de 1 e 10, respectivamente. Isso é lógico?
Em muitos dos algoritmos de detecção de ameaças mais simples, esse peso se torna uma métrica para comparar as regiões do gráfico. O ponto principal é que um subgrafo com peso médio inferior em relação ao peso médio geral é suspeito.
Não é? O cume raramente visitado é uma zona anômala. Portanto, se as ações do usuário na análise de ameaças potenciais vão para um subgrafo raramente usado, você deve aumentar o nível de alarme para amarelo.
A abordagem que descrevo e os scripts do PowerShell abaixo não devem ser usados para fins práticos em grandes infraestruturas. Mas para um servidor separado, a solução pode funcionar, ou pelo menos fornecer verificação independente das soluções corporativas que você usa.
Eu mencionei que os algoritmos do PowerShell de Doug Finke para estruturas de dados são ferramentas excelentes e poderosas? Sem seu trabalho, eu não teria alcançado nada no meu projeto de gráfico de anomalias. Obrigado novamente, Doug!
Com a ajuda de sua biblioteca PowerShell de lindas funções de gráfico, posso calcular facilmente o peso do meu gráfico de ameaça Sysmon com apenas algumas linhas PS e também descobrir o peso médio do vértice de todo o gráfico. À medida que atravessa o gráfico, o código também atribui a cada vértice o peso de todas as suas arestas de saída:
$AW=0 #average weight
$GW=0 #total weight
$mset = [System.Collections.ArrayList]@() #master set of subraphs
#calculate total weight by summing up the frequencies or weights of the edges
foreach ($e in $g.getAllEdges() ) {
$GW = $GW + $e.weight
}
write-host "Weight of Graph: " $GW
$AW = $GW / $g.vertices.count
write-host "Average weight per vertex: " $AW
#assign weight of edges to vertice
for ($i=0; $i -lt $g.vertices.count; $i++) {
$w=0
$v=$g.vertices[$i]
foreach($e in $v.getEdges()) {
if($e -eq $null) {continue}
$w=$w + $e.weight
}
$v.value.Weight = $w
}
O código acima faz os cálculos de que precisamos. Nesse caso, cada vértice pode ser considerado como a frequência de visitas, dependendo das arestas de saída.
A parte mais difícil do meu script de gráfico de anomalia do PowerShell - que mostrarei em breve - é encontrar as regiões do gráfico com menor probabilidade de ocorrer e, em seguida, encontrar o maior subgráfico que as contém . Você pode precisar folhear um antigo livro de ciência da computação para concluir esta tarefa. Mas na verdade não é tão difícil de escrever!
Usei a pesquisa de largura clássica para meu gráfico visitando cada vértice e, em seguida, expandindo-o às custas dos vértices vizinhos até que meu subgrafo alcance um certo limite, dependendo do peso médio do vértice. Como isso:
function extend-subgraph($v, $t) {
$vertexQueue = New-Object Queue
#initialize
$vertexQueue.enqueue($v)
$h=$v.value.Weight
$s=@() #subgraph
$s+=$v
$extend=$false
while (!$vertexQueue.isEmpty()) { #bfs
$currentVertex = $vertexQueue.dequeue()
$es= $currentVertex.getEdges()
foreach($e in $es) {
$ev= $e.endVertex
if ((($h + $ev.value.Weight)/($s.count+1) -lt $th) {
#extend the sub-graph
$s+=$ev
$h =$h + $ev.value.weight
#queue it up
$vertexQueue.enqueue($ev)
}
}
Uma nota rápida para os entusiastas do faça você mesmo: use o tipo arraylist para criar uma série de arrays e você evitará muitas dores de cabeça.
Ameaças e subgráficos de baixo peso
Existem muitos algoritmos diferentes para gráficos anômalos. O que usei é baseado em um determinado graphBAD que encontrei na Internet - e darei um link assim que o encontrar novamente.
Em geral, o principal problema na detecção prática de ameaças é encontrar um bom conjunto de dados para formar uma linha de base. Como blogueiro em tempo integral e especialista em detecção de ameaças em festas, nunca consegui criar um log do Sysmon interessante o suficiente contendo muitos aplicativos diferentes. Foi muito difícil gerar subgráficos anômalos porque eu não tinha uma distribuição grande o suficiente nos pesos. De uma forma ou de outra, ao usar um servidor real, você pode acabar com um conjunto de dados muito melhor do que o uso ocasional de uma instância do Windows AWS, como no meu caso.
O script PS de gráficos anômalos que escrevi era perfeitamente capaz de produzir subgráficos suspeitos com pesos médios baixos. E até consegui pegar alguns ambientes interessantes (veja abaixo).
Algoritmo de pesos subgráficos em ação: um ambiente interessante com pesos baixos do subgrafo 7
Como mencionei anteriormente, existem outros algoritmos para detectar anomalias em gráficos com métricas diferentes de pesos simples que vale a pena aprender. Um deles procura grupos de vértices "semelhantes" e percebe conexões ou conexões entre ambientes diferentes. Nesse caso, a anomalia está no usuário ou processo que conecta os ambientes por meio de alguma outra característica. Faz sentido, não é?
Se o seu nerd interior é forte em você, você pode conferir SCAN(Structural Clustering Algorithm for Networks), que faz o acima. Junto com os algoritmos PowerShell de Doug Finke, você pode até usá-lo. Eu mesmo quero assumir este projeto e colocá-lo em breve no meu GitHub .
Encontre anomalias por meio de caminhadas aleatórias
Vamos terminar esta seção com outra maneira de encontrar anomalias no gráfico de ameaças. Eu me referi a essa abordagem no final da parte anterior . Para mim, como uma pessoa com matemática no "você", ele é mais intuitivo. E os fãs do antigo programa de TV numb3rs reconhecerão imediatamente o conceito de cadeias de Markov [limpar a garganta].
Para todos os outros, você pode pensar nisso como um "passeio aleatório" pelo gráfico. Em cada um dos vértices, jogamos um dado e selecionamos uma aresta do gráfico dependendo de seu peso: quanto maior o peso da aresta, maior a chance de segui-la. Você precisa dividir o gráfico em duas partes - chamado de gráfico bipartido na teoria dos grafos - com usuários em uma parte e aplicativos na outra.
Em seguida, você classificatodos os aplicativos de vértices que podem ser alcançados pelo usuário com base na probabilidade de alcançar um determinado vértice. Para analisar a ameaça, você pesquisará os aplicativos em execução e, se algum deles tiver uma probabilidade muito baixa de alcançá-los, é possível que você tenha encontrado uma ameaça real!
Mais um carma para alguém que o vinculou ao algoritmo PageRank do Google . Descreverei isso com mais detalhes na próxima seção, mas os interessados podem pesquisar no Google a frase passeio aleatório com reiniciar .
Teoria Random Traversal e Prática EQL
Vamos fazer outra digressão e analisar o que estamos tentando alcançar com o log do Sysmon, que é uma ótima ferramenta para detectar ameaças e conduzir investigações pós-incidente.
- , Sysmon. Sysmon , .
- 2 Sysmon , , .
- Na terceira parte, investigamos uma visão geral de um algoritmo simples que considera as conexões de borda como pesos. Seções de um gráfico pesando menos (em termos de bordas) do que o peso médio total em todo o gráfico podem ser uma ameaça potencial. Vou carregar os scripts do PowerShell dos algoritmos desta seção para meu GitHub (depois de passar o mouse sobre eles).
A vantagem desses métodos é que eles não dependem de comandos específicos ou nomes de processos que os invasores mudam ou mascaram constantemente.
Além disso, existe outro método baseado em probabilidade para encontrar vulnerabilidades. Vamos dar uma olhada nisso.
Traversal aleatório de um gráfico de vulnerabilidades de dados com base em eventos Sysmon
Em vez de analisar a estrutura do gráfico em si, podemos pensar nos links como um caminho ou roteiro, no qual cada aplicativo é uma parada separada ao longo do caminho. A partir dos dados de log do Sysmon, podemos obter a frequência com que cada aplicativo inicia de seu pai.
Se você olhar meu script de gráfico de ameaças no GitHub, verá que essa frequência é armazenada em cada objeto de borda usando os maravilhosos algoritmos PowerShell de Doug Finke.
Podemos considerar a frequência de cruzamento de cada uma das arestas do gráfico de vulnerabilidade como uma probabilidade!
A próxima etapa é usar essas informações para encontrar a probabilidade de, digamos, uma inicialização do PowerShell de taskmgr.exe, Windows Process Analyzer, Notepad ou hostname.exe.
Aonde estou querendo chegar?
Resumindo: posso criar uma matriz de transição de probabilidade, tão amada pelos seguidores de Markove comumente usado em sistemas de modelagem. Na verdade, lançar os dados, ir para a próxima aplicação no gráfico e repetir essas ações é uma travessia aleatória do gráfico. Em última análise, esse método matemático classifica cada vértice do gráfico de acordo com a probabilidade de chegar lá desde o ponto inicial. E você descobrirá que, digamos, lançar planilhas no Windows Explorer é um processo extremamente comum e o Windows Script Host Engine é teoricamente extremamente fora do padrão e, portanto, potencialmente um indicador de ameaça.
Este método é conhecido como Random Walk With Restart (doravante - RWWR, random walk with restart) e é uma variação do agora lendário algoritmo de classificação do Google PageRank .
Vamos dar uma olhada em um pedaço de script que escrevi para calcular essas classificações:
#lets build a row
$row= @(0)*$g.vertices.count
$w=0
foreach($e in $start.getEdges()) { #calculate total frequency
$w+=$e.weight
}
if ($w -eq 0) { #make it connected
$row[$ix] =1
}
else { #we assign probabilitys
#now create transition probability
foreach($e in $start.getEdges()) {
$ev = $e.endVertex
$p = $e.weight
$jx = v-index $ev.value.Key
$row[$jx]= $p/$w #normalize by dividing by total
}
}
$P[$ix] = $row #yay! One row added to transition matrix
Para cada vértice, calculo a frequência resultante de todos os vizinhos e, em seguida, atribuo a probabilidade de cada transição por meio da normalização pelo total. Portanto, se o PowerShell.exe tiver 20 visitas a todos os seus vizinhos, mas o nc.exe tiver sido visitado apenas uma vez do topo do PowerShell.exe, a probabilidade de ir será de 1/20 ou 0,05. Isso é lógico?
A dificuldade está em calcular a matriz utilizada no RWWR, mas para quem participou de aulas de modelagem probabilística, esse procedimento não será difícil. Há um bom artigo de revisão sobre o assunto no site do Medium .
Meu script, que eu chamo de avaliador aleatório , classifica e produz os 10 menoresvalores da lista. Assim, você pode obter aplicativos que têm a menor probabilidade de serem iniciados, a partir de um determinado vértice do gráfico de ameaças. Aqui está o resultado ao usar PowerShell.exe como ponto de partida:
O algoritmo Random Walk With Restart pode produzir uma classificação de ameaças semelhante ao google. Hmmm, whoami é o menos provável de ser executado.
Como uma nota prática e um aviso, é importante notar que PWWR será um problema de big data em um sistema real. Mesmo no caso do meu pequeno log Sysmon, o atraso de cálculo foi bastante perceptível devido ao grande número de operações de ponto flutuante.
Event Query Language (EQL) para análise de ameaças
Por enquanto, vale a pena observar que os fornecedores que usam abordagens mais sofisticadas para detectar ameaças em seus produtos vão muito além do que você ou eu podemos fazer por conta própria. E, definitivamente, com uma precisão muito maior.
Para aqueles que desejam se aprofundar no tópico de detecção de ameaças, mas não querem trabalhar com meus scripts - eu entendo! - existe Event Query Language , ou EQL . Este é um projeto open source para aplicar o Sysmon Log Query Language, que você pode aprender mais sobre no extremamente abrangente pós... EQL não é ótimo apenas para investigar incidentes, mas também pode ser usado como uma ferramenta, desde que você tenha uma cópia nova do log do Sysmon.
O pacote EQL fornece um manipulador de eventos que converte o log em JSON legível por humanos. Você pode verificar uma cópia do meu branch no GitHub. Ao contrário do meu script PS estático do caminho da ameaça de exibição, o EQL permite que você faça consultas em tempo real.
Digamos que eu esteja interessado em todos os shells cmd.exe que foram iniciados em nome de scvhost.exe - isso pode ser um sinal de que o invasor está usando psexec.exe ou smb.exe. A solicitação será semelhante a esta:
Usando EQL para localizar shells cmd.exe iniciados a partir de svchost.exe. A propósito, jq é um utilitário Linux para exibir dados JSON.
Há uma maneira ainda mais legal e poderosa de obter esse resultado usando o modificador filho. Esta consulta EQL permite pesquisar todos os processos com um ancestral especificado, em qualquer lugar na hierarquia. Por exemplo, você pode pesquisar aplicativos que, digamos, tiveram o processo regsvr32.exe como ancestral e podem ter explorado uma vulnerabilidade conhecida que descrevi aqui .
Há muito a dizer sobre EQL neste post já longo, então prefiro publicar um artigo separado sobre os detalhes das habilidades de EQL para encontrar vulnerabilidades.
Considerações finais sobre soluções de detecção de ameaças DIY
Prometi baixar o repositório Sysmon com todos os scripts de detecção de ameaças descritos neste artigo. Volte no meu GitHub periodicamente, pois adicionarei novas ferramentas de detecção de ameaças baseadas em gráficos ao longo do tempo, junto com documentação adicional - muita coisa para cobrir em um artigo.
Você chegou a este lugar, parabéns!
Experimente meus scripts ou use-os como base para desenvolver suas próprias ideias de detecção de ameaças. O PowerShell é adequado para algoritmos complexos. Para mim, que cresci na linguagem shell do Linux, foi uma agradável surpresa trabalhar com uma linguagem de script madura. E eu aconselho você a conferir a Galeria do PowerShell, outro grande recurso para scripts de batalha prontos: você não precisa reinventar a roda no mundo do PowerShell.
Outra conclusão mais importante de todo o artigo será a compreensão de que os fornecedores de soluções de nível empresarial não apenas usam tecnologias de detecção de ameaças muito mais sofisticadas do que aquelas que um desenvolvedor de TI pode escrever em seu tempo livre, mas também a adaptabilidade dessas soluções para trabalhar com o nível de tráfego grande organização. Obviamente, usar soluções DIY para analisar um servidor subutilizado ou validação adicional de produtos corporativos é uma boa ideia. Mas a inteligência e a identificação de ameaças são de fato um problema de big data e, obviamente, não um desafio que o PowerShell pode resolver.
Se você está interessado na oportunidade de aprender mais sobre como a Varonis lida com a tarefa de analisar e detectar ameaças, você pode sempre solicitar uma demonstração pessoal .