Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Sentinel-Queries — KQL 查询集合 | Kitploit
工具/GitHubGitHub/reprise99/sentinel-queries
防御工具威胁情报学习与教育精选资源异常检测日志分析
GitHubreprise99/sentinel-queries

Sentinel-Queries

KQL 查询集合

查看仓库
1.6k382168个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

KQL for Microsoft Sentinel

一些使用 KQL for Microsoft Sentinel 的技巧、示例和实例。

  1. 简介
  2. KQL 查询的结构
  3. 基础知识
    1. 时间基础
    2. Where 基础
    3. Project 基础
    4. Summarize 基础
    5. Render 基础
    6. Parse 与 Split 基础

简介

Kusto 查询语言是一种用于 Azure Monitor、Azure Data Explorer 和 Azure Log Analytics(Microsoft Sentinel 底层使用的语言)的语言。我一直觉得下面这张关于 KQL 的图非常有用——

KQL 可视化

我们想要使用 KQL 创建准确、高效的查询,以便从更大的数据集中发现威胁、检测、模式和异常。

KQL 查询的结构

以下面的查询为例```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

当我们运行这样的查询时,第一行告诉 Microsoft Sentinel 要在哪个表中查找数据,所以在这种情况下,我们要搜索 SigninLogs 表,这是 Azure AD 登录数据被发送到的地方。你可以[在此处](https://docs.microsoft.com/en-us/azure/sentinel/data-source-schema-reference)查看表列表。

然后 Microsoft Sentinel 会按顺序运行你的查询,也就是说,它会一行一行地执行,直到到达末尾或出现错误。所以下面我们逐行分解这个查询。```kql
SigninLogs

因此,首先我们选择了我们的 SigninLogs 表。```kql SigninLogs | where TimeGenerated > ago(14d)

接下来,我们让 Sentinel 回溯查看此表中过去 14 天的数据。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

接下来,我们要求 Sentinel 仅查找 UserPrincipalName 等于 "[email protected]" 的日志。```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0"

然后,我们只查找 `ResultType == 0` 的日志,这些日志表示成功登录 Azure AD。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| where AppDisplayName == "Microsoft Teams"

接下来,我们只查找登录 Microsoft Teams 的情况。```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

Our last line uses the project operator, to return only 4 fields from our logs, so we will only see the TimeGenerated, Location, IPAddress and UserAgent returned from our SigninLogs data.

That is how you build queries, now the basics.

## 基础知识

### 时间基础

Microsoft Sentinel 和 KQL 针对时间筛选进行了高度优化,因此如果你知道要搜索的数据的时间段,应该立即筛选时间范围。例如,检索最近 14 天的日志,然后搜索一个用户名,如下面的查询 -```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

比先搜索用户名再搜索时间段要高效得多,就像这样 -```kql SigninLogs | where UserPrincipalName == "[email protected]" | where TimeGenerated > ago(14d)

KQL 有许多选项可用于查询特定时间段。```kql
SigninLogs
| where TimeGenerated > ago(14d)

如第一个示例所示,这将搜索最近14天。```kql SigninLogs | where TimeGenerated > ago(14h)

你也可以按小时进行。```kql
SigninLogs
| where TimeGenerated > ago(14m)

And minutes.

KQL also supports querying between time ranges -```kql SigninLogs | where TimeGenerated between (ago(14d) .. ago(7d))

这将查找14天前至7天前之间的SigninLogs数据。```kql
SigninLogs
| where TimeGenerated between (ago(14h) .. ago(7h))

在14小时前到7小时前之间。```kql SigninLogs | where TimeGenerated between (ago(14m) .. ago(7m))

And between 14 minutes and 7 minutes ago.

### Where 基础

Where 是一个运算符,你基本上在编写的每个查询中都会使用它。这就是你告诉 Microsoft Sentinel 搜索特定数据的方式。对于 where 运算符来说,语法非常重要。如果我们使用之前相同的示例。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

这将搜索我们的 SigninLogs 表,在过去 14 天内,查找 UserPrincipalName 等于 [email protected] 的精确匹配。在 KQL 中,== 区分大小写,因此如果你搜索 [email protected] 而实际用户名是 [email protected],你将不会得到任何结果。不区分大小写的等效写法是 =```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName = "[email protected]"

这将查找 [email protected] 的任何匹配项,无论大小写如何。

除了 equals,我们也可以使用 contains。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName contains "reprise_99"

这将查找 UserPrincipalName 包含 reprise_99 的任何日志条目,如果您有 [email protected] 和 [email protected] 的数据,它将同时找到两者。contains 运算符不区分大小写,但您可以使用 contains_cs 使其区分大小写。

如果您正在搜索特定模式,可以使用 startswith 或 endswith。```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName startswith "reprise_99"

SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName endswith "testdomain.com"

startswith 和 endswith 均不区分大小写,但你可以使用 startswith_cs 或 endswith_cs 使其区分大小写。

如果你要搜索完整的单词(超过四个字符),在 KQL 中可以使用 has 运算符。使用 'has' 比 'contains' 更高效,因为数据已为你建立索引。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has "Teams"

这将查找应用程序显示名称中包含单词 Teams 的任何 SigninLogs,可能包括 "Microsoft Teams" 和 "Microsoft Teams Web Client",两者都满足该查询。

如果要搜索多个单词,可以使用 has_any 或 has_all。```kql SigninLogs | where TimeGenerated > ago(14d) | where AppDisplayName has_any ("Teams","Outlook")

这将返回应用程序显示名称包含 "Teams" 或 "Outlook" 的结果```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has_all ("Teams","Outlook")

这将返回应用程序显示名称包含“Teams”和“Outlook”的结果。

如果你不知道要在哪些字段中搜索,你也可以使用通配符,这样效率不高,但可能会帮你找到正确的方向。```kql SigninLogs | where TimeGenerated > ago(14d) | where * contains "reprise_99"

这将在 SigninLogs 表中搜索任何包含 reprise_99 的字段。

其中许多选项还支持使用 `!` 来反转查询,以查找条件不成立的结果。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName != "[email protected]"

此查询将查找所有 UserPrincipalName 不等于 [email protected] 的 SigninLogs```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName !contains "reprise_99"

此查询将查找所有 UserPrincipalName 不包含 reprise_99 的 SigninLogs```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName !has "Teams"

此查询将查找应用程序显示名称不包含"Teams"的 SigninLogs。

Project 基础

Project 允许我们选择在查询中返回哪些列以及它们的顺序。```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

此查询搜索过去 14 天的 SigninLogs 数据,其中 UserPrincipalname 等于 [email protected],ResultType 为 0,应用程序显示名称等于 "Microsoft Teams",然后对于该查询的每个匹配项,返回 TimeGenerated、Location、IPAddress 和 UserAgent。

我们可以在同一个函数中重命名列。```kql
| project LogTime=TimeGenerated, SigninLocation=Location, IP=IPAddress, Agent=UserAgent

这将返回相同的数据,但将列重命名为 LogTime、SigninLocation、IP 和 Agent。

我们甚至可以借助 project 运算符对输出进行内联操作。```kql | project LocalTime=TimeGenerated+5h, Location, IPAddress, UserAgent

这会返回相同的数据,但会将 TimeGenerated 名称更改为 LocalTime,如果你在该时区工作,则转换为 +5h 时区。

project-away 与 project 相反,将从查询中移除列。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| project-away UserAgent
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| where AppDisplayName == "Microsoft Teams"

在此查询中,我们移除了 UserAgent。请记住,如果你移除了某一列,之后在查询中就无法再访问它了。

Summarize 基础

Summarize 生成一个表,用于聚合你查询中的内容。Summarize 具有许多底层的聚合函数。如果我们再次使用示例查询,就可以通过 summarize 以各种方式操作结果。```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize count() by AppDisplayName

此查询将查找 SigninLogs 表中过去 14 天内与 [email protected] 匹配的所有事件,其中结果为成功(ResultType == 0),然后按应用程序显示名称汇总这些事件。

您可以选择为结果列命名。```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize AppCount=count() by AppDisplayName

这会返回相同的数据,但会将返回列的名称更新为 AppCount。

除了总计数之外,你还可以对去重计数进行汇总。```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize DistinctAppCount=dcount(AppDisplayName) by AppDisplayName

这将针对 [email protected] 登录过的每个不同应用程序返回一条记录。
下载工具