
Coleção de consultas KQL
Algumas dicas, truques e exemplos para usar KQL com Microsoft Sentinel.
Kusto Query Language é a linguagem usada no Azure Monitor, no Azure Data Explorer e no Azure Log Analytics (o que o Microsoft Sentinel usa internamente). Sempre achei esta visualização sobre KQL útil -

Queremos usar o KQL para criar consultas precisas e eficientes para encontrar ameaças, detecções, padrões e anomalias dentro do nosso conjunto de dados maior.
Tome a consulta abaixo como exemplo```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent
Quando executamos uma consulta como essa, a primeira linha informa ao Microsoft Sentinel em qual tabela procurar os dados. Nesse caso, queremos pesquisar na tabela SigninLogs, que é onde os dados de entrada do Azure AD são enviados. Você pode ver uma lista de tabelas [aqui](https://docs.microsoft.com/en-us/azure/sentinel/data-source-schema-reference).
O Microsoft Sentinel executará sua consulta sequencialmente, ou seja, executará cada linha uma a uma até chegar ao final ou até você ter um erro. Então, para detalhar nossa consulta linha por linha.```kql
SigninLogs
Então, primeiro escolhemos a nossa tabela SigninLogs.```kql SigninLogs | where TimeGenerated > ago(14d)
Em seguida, instruímos o Sentinel a examinar os últimos 14 dias de dados nesta tabela.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
Em seguida, pedimos ao Sentinel para encontrar apenas logs onde UserPrincipalName é igual a "[email protected]"```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0"
Em seguida, procuramos apenas logs onde o ResultType == 0, que é um logon bem-sucedido no Azure AD.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| where AppDisplayName == "Microsoft Teams"
Em seguida, procuramos apenas logins no Microsoft Teams.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent
Nossa última linha usa o operador project, para retornar apenas 4 campos dos nossos logs, então veremos apenas TimeGenerated, Location, IPAddress e UserAgent retornados dos dados de SigninLogs.
É assim que você cria consultas, agora o básico.
## O Básico
### Noções Básicas de Tempo
O Microsoft Sentinel e o KQL são altamente otimizados para filtros de tempo, portanto, se você souber o período dos dados que deseja pesquisar, deve filtrar o intervalo de tempo imediatamente. Recuperando os últimos 14 dias de logs e depois pesquisando um nome de usuário como na consulta abaixo -```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
É muito mais eficiente do que pesquisar primeiro por um nome de usuário e depois pesquisar pelo período de tempo assim -```kql SigninLogs | where UserPrincipalName == "[email protected]" | where TimeGenerated > ago(14d)
KQL tem muitas opções para consultar períodos de tempo específicos.```kql
SigninLogs
| where TimeGenerated > ago(14d)
Conforme o primeiro exemplo, isso irá pesquisar pelos últimos 14 dias.```kql SigninLogs | where TimeGenerated > ago(14h)
Você também pode definir horas.```kql
SigninLogs
| where TimeGenerated > ago(14m)
E minutos.
O KQL também suporta consultas entre intervalos de tempo -```kql SigninLogs | where TimeGenerated between (ago(14d) .. ago(7d))
Isso encontrará dados de SigninLogs entre 14 dias e 7 dias atrás.```kql
SigninLogs
| where TimeGenerated between (ago(14h) .. ago(7h))
Entre 14 horas e 7 horas atrás.```kql SigninLogs | where TimeGenerated between (ago(14m) .. ago(7m))
E entre 14 minutos e 7 minutos atrás.
### Noções básicas do Where
Where é um operador que você usará em basicamente todas as consultas que escrever. É assim que você diz ao Microsoft Sentinel para caçar dados específicos. A sintaxe é muito importante com o operador where. Se usarmos nosso mesmo exemplo.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
Isto irá pesquisar a nossa tabela SigninLogs, nos últimos 14 dias, por correspondências exatas em que o nosso UserPrincipalName seja igual a [email protected]. Em KQL, == é sensível a maiúsculas e minúsculas, por isso, se pesquisar por [email protected] e o nome de utilizador for, na verdade, [email protected], não obterá quaisquer resultados. O equivalente sem sensibilidade a maiúsculas e minúsculas é =```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName = "[email protected]"
This will find any matches for [email protected] regardless of case sensitivity.
Instead of equals, we can also use contains.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName contains "reprise_99"
Isso encontrará quaisquer entradas de log onde o UserPrincipalName contém reprise_99; se você tivesse dados de [email protected] e [email protected], encontraria ambos. O operador contains não diferencia maiúsculas de minúsculas, mas você pode usar contains_cs para torná-lo sensível a maiúsculas e minúsculas.
Você pode usar startswith ou endswith se estiver procurando por padrões específicos.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName startswith "reprise_99"
SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName endswith "testdomain.com"
Tanto startswith quanto endswith não diferenciam maiúsculas de minúsculas, mas você pode usar startswith_cs ou endswith_cs para torná-los sensíveis a maiúsculas e minúsculas.
Se você estiver procurando por palavras completas (com mais de quatro caracteres), em KQL você pode usar o operador has. Usar 'has' é mais eficiente do que 'contains', pois os dados são indexados para você.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has "Teams"
This will find any SigninLogs where the application display name has the word Teams in it, that could include "Microsoft Teams" and "Microsoft Teams Web Client", both satisfy the query.
If you are searching for multiple words you can use has_any or has_all.```kql SigninLogs | where TimeGenerated > ago(14d) | where AppDisplayName has_any ("Teams","Outlook")
Isso retornará resultados em que o nome de exibição do aplicativo contém "Teams" ou "Outlook"```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has_all ("Teams","Outlook")
Isso retornará resultados onde o nome de exibição do aplicativo tenha "Teams" e "Outlook".
Se você não souber em quais campos pesquisar, também pode usar curingas; é ineficiente, mas pode colocá-lo no caminho certo para encontrar o que deseja.```kql SigninLogs | where TimeGenerated > ago(14d) | where * contains "reprise_99"
Isso irá pesquisar a tabela SigninLogs por qualquer campo que contenha reprise_99.