Atividade 3: Kusto Query Language 101

Aqui é onde queremos que você abra o Scoreboard e o visualizador ADX em janelas separadas para completar os próximos exercícios. Se você não puder ou não quiser usar o Scoreboard, todas as perguntas desta seção estão listadas abaixo.

Lembre-se: qualquer página com vídeo repete a lição tanto em vídeo quanto em texto. Você pode seguir o que preferir, dependendo de como aprende melhor.

KQL 101

[Certifique-se de usar o banco de dados SecurityLogs para este exercício.]

Digite a consulta abaixo no workspace para ver as primeiras linhas da tabela Employees. Pressione “run” ou “shift + enter” para executar a consulta. Todos os blocos de código KQL deste workshop estarão destacados em cinza como o exemplo abaixo.

Employees
|   take 10

Esta consulta tem algumas partes. Vamos entender cada uma delas:

“KQL1” “KQL2”

O operador take é uma ferramenta poderosa para explorar linhas de uma tabela e, assim, entender melhor que tipo de dados estão guardados ali.

🎯Dica – O que fazer quando não sabe por onde começar: Sempre que você encontrar uma tabela de banco de dados desconhecida, a primeira coisa a fazer é amostrar suas linhas usando o operador take. Assim, você descobre quais campos estão disponíveis para consulta e pode imaginar que tipo de informação pode extrair da fonte de dados.

A tabela Employees contém informações sobre todos os funcionários da nossa organização. Neste caso, vemos que a organização se chama “Envolve Labs” e o domínio é “envolvelabs.com”.

Você pode escrever várias consultas na mesma aba do workspace. Para isso, separe cada consulta por uma linha em branco. Veja abaixo como as consultas para Employees, Email e OutboundBrowsing estão separadas por linhas em branco nas linhas 3 e 6.

“KQL3”

Quando há várias consultas, é importante dizer ao ADX qual delas você quer rodar. Para escolher, basta clicar em qualquer linha que faça parte da consulta. Assim que selecionar, ela ficará destacada em azul, como nas linhas 4 e 5 acima.

Descobrindo “Quantos”: O operador ‘count’

Podemos usar count para ver quantas linhas há em uma tabela. Isso mostra quanto dado está guardado ali.

Employees
|   count

Filtrando Dados com o operador ‘where’

Até agora, rodamos consultas que olham todo o conteúdo da tabela. Muitas vezes, na análise de cibersegurança, queremos ver só os dados que atendem a certos critérios. Para isso, aplicamos filtros em colunas específicas.

Podemos usar o operador where no KQL para filtrar um campo específico. Por exemplo, podemos encontrar todos os funcionários com o nome “Linda” filtrando pela coluna name na tabela Employees.

Comandos where seguem uma estrutura específica. Use o quadro abaixo para entender como montar um comando where.

“KQL4”
Employees
|   where name has "Linda"

O operador has é útil aqui porque estamos procurando uma correspondência parcial. Se quisermos buscar um funcionário com nome e sobrenome exatos, usamos o operador ==:

Employees
|   where name == "Linda Holbert"

No dia a dia, os funcionários da Envolve Labs enviam e recebem e-mails. Um registro de cada e-mail é guardado na tabela Email.

🎯Dica – Privacidade do Usuário e Metadados: Como você pode imaginar, alguns e-mails são muito sensíveis. Em vez de guardar o conteúdo completo de cada e-mail enviado e recebido em um banco de dados que pode ser acessado por analistas de segurança, capturamos apenas os metadados dos e-mails.

Metadados de e-mail incluem informações como: hora do envio, remetente, destinatário, assunto e links que o e-mail pode conter. Guardar só os metadados, e não o conteúdo completo, ajuda a proteger a privacidade dos funcionários e garante que os analistas possam nos manter seguros. Às vezes, até metadados podem revelar informações sensíveis, então é importante não comentar sobre dados de logs com outros funcionários fora do SOC.

Podemos encontrar informações sobre e-mails enviados ou recebidos por um usuário procurando o endereço de e-mail dele nos campos de remetente e destinatário da tabela Email. Por exemplo, podemos usar a consulta abaixo para ver todos os e-mails enviados por “Michael Montello”:

Email
|   where sender == "michael_montello@envolvelabs.com"

Fácil como 1, 2, 3… Consultas Compostas e o operador distinct

Podemos usar o operador distinct para encontrar valores únicos em uma coluna. Com a consulta abaixo, descobrimos quantos usuários da organização enviaram e-mails.

“KQL5”

Esta é a primeira vez que usamos uma consulta de várias linhas com múltiplos operadores, então vamos entender:

Na linha 2, pegamos a tabela Email e filtramos para encontrar só as linhas com “envolvelabs” na coluna sender.

Na linha 3, adicionamos outro pipe ( | ) e usamos o operador distinct para encontrar todos os remetentes únicos. Aqui, não estamos achando todos os remetentes únicos, mas só os que sobraram depois do filtro.

Por fim, na linha 4, adicionamos outro pipe ( | ) e usamos o operador count para contar os resultados das linhas 1-3 da consulta.

Rastreando um Clique: Dados de OutboundBrowsing

Quando funcionários da Envolve Labs acessam um site pela rede da empresa, essa atividade é registrada. Isso fica guardado na tabela OutboundBrowsing, que tem registros dos sites acessados por cada usuário. Sempre que alguém visita um site, um registro é salvo na tabela. Porém, o nome do usuário não é guardado, só o endereço IP. Existe uma relação 1:1 entre usuários e seus IPs, então podemos consultar a tabela Employees para descobrir quem acessou determinado site.

Se quisermos saber quais sites Annie Jackson visitou, podemos encontrar o IP dela na tabela Employees.

Employees
|   where name == "Annie Jackson"

A consulta acima mostra que o IP dela é “192.168.3.168”. Podemos pegar esse IP e procurar na tabela OutboundBrowsing para saber quais sites ela visitou.

OutboundBrowsing
| where src_ip == "192.168.3.168"

O que tem em um nome? Tudo sobre dados de DNS passivo

Embora nomes de domínio como “google.com” sejam fáceis para humanos lembrarem, os computadores não sabem lidar com eles. Então, eles convertem para endereços IP que as máquinas entendem. Assim como o endereço da sua casa diz aos amigos como te encontrar, um endereço IP diz ao computador onde encontrar uma página ou serviço na internet.

🎯Dica – Pratique o bom OPSEC: Se quisermos descobrir para qual IP um domínio resolve, poderíamos simplesmente acessá-lo. Mas, se o domínio for malicioso, você pode baixar arquivos perigosos ou avisar os atacantes que você sabe da infraestrutura deles. Como analistas de cibersegurança, precisamos seguir procedimentos e cuidados para proteger nossa capacidade de rastrear ameaças. Essas práticas são chamadas de segurança operacional, ou OPSEC.

Para não precisar resolver ativamente (ou seja, acessar ou interagir diretamente com um domínio para descobrir seu IP) cada domínio que nos interessa, podemos usar dados de DNS passivo. Eles permitem explorar com segurança as relações entre domínio e IP, respondendo perguntas como:

Essas relações estão guardadas na tabela PassiveDns.

🤯Comandos let – facilitando sua vida:

Às vezes, precisamos usar o resultado de uma consulta como entrada para outra. O jeito mais simples é digitar manualmente o resultado na próxima consulta.

“KQL6”

Depois, você pode copiar e colar esses IPs em uma consulta na tabela OutboundBrowsing. Note que podemos usar o operador in para escolher todas as linhas que têm um valor igual a qualquer valor da lista. Ou seja, o operador == procura uma correspondência exata, enquanto o operador in verifica se está na lista.

“KQL7”

Embora isso funcione, não é muito prático se você tiver 100 ou 1000 funcionários chamados “Linda”.

Podemos fazer isso de forma mais elegante usando um comando let , que permite dar um nome para uma expressão ou função. Podemos usar o comando let aqui para salvar e nomear o resultado da primeira consulta, assim podemos reutilizar os valores depois. Isso evita digitar ou copiar e colar os resultados várias vezes.

“KQL8”

À esquerda do comando let está o nome da variável (“linda_ips” neste caso). O nome pode ser o que você quiser, mas é bom escolher algo que ajude a lembrar o que está guardando.

“KQL9”

À direita do comando let está a expressão que você está guardando. Neste caso, usamos o operador distinct para selecionar valores de uma coluna só – assim eles ficam em um array ou lista de valores.

“KQL10”

O comando let termina com ponto e vírgula.

Depois de guardar o valor de uma consulta em uma variável usando let, podemos usá-la quantas vezes quisermos no resto da consulta. A consulta guardada não mostra nenhum resultado. Lembre-se, porém, que sua consulta KQL precisa ter um comando tabular – ou seja, você precisa ter outra consulta depois do comando let.

🎯Dica – Pivotando: Parte de ser um bom analista de cibersegurança é aprender a usar várias fontes de dados para contar uma história mais completa sobre o que um atacante fez. Chamamos isso de “pivotar”. Você pivota ao pegar um dado conhecido em um conjunto de dados e procurar em outro conjunto para descobrir algo novo. Você praticou isso aqui quando começou na tabela Employees e usou o que aprendeu para achar dados relacionados em outra fonte – OutboundBrowsing.