Microsoft Sentinel自定义定时分析规则未触发及延迟问题咨询
问题描述
我在自定义定时分析规则中运行以下KQL查询,目的是识别所有全局管理员,并验证他们过去24小时内的登录活动(测试时已让全局管理员在24小时内完成登录)。
- 查询在Logs面板运行正常,能返回记录,但激活为定时分析规则后无结果返回
- 分析规则的查询频率和回溯时长已设置为1天,与查询逻辑、日志 ingestion 延迟匹配
- 诡异的是,在分析规则中测试KQL时,首次模拟无结果,多次点击测试后却能返回记录
想知道延迟原因是什么,以及如何确保查询正确触发、返回记录并生成事件。
对应的KQL查询代码:
let PrivilgedRoles = dynamic(["Global Administrator"]); let PrivilegedIdentities = IdentityInfo | summarize arg_max(TimeGenerated, *) by AccountObjectId | mv-expand AssignedRoles | where AssignedRoles in~ (PrivilgedRoles) | extend lc_AccountUPN = tolower(AccountUPN) | summarize AssignedRoles=make_set(AssignedRoles) by AccountObjectId, AccountSID, lc_AccountUPN, AccountDisplayName, JobTitle, Department; SigninLogs | where TimeGenerated > ago (1d) | extend lc_UserPrincipalName = tolower(UserPrincipalName) | join kind=inner PrivilegedIdentities on $left.lc_UserPrincipalName == $right.lc_AccountUPN | project TimeGenerated, AccountDisplayName, AccountObjectId, lc_AccountUPN, lc_UserPrincipalName, AppDisplayName, ResultType, ResultDescription, IPAddress, LocationDetails
问题分析与解决办法
延迟/无结果的可能原因
- IdentityInfo日志同步延迟:IdentityInfo表的角色分配数据更新存在延迟,首次测试时最新的管理员角色信息还未同步到该表,导致无法关联登录日志;多次测试后数据完成同步,查询即可返回结果。
- 时间窗口边界偏差:定时分析规则的时间窗口基于规则触发时间计算
ago(1d),而Logs面板测试时基于当前时间,两者时间范围存在细微偏差,加上日志入库延迟,首次触发时部分登录日志还未完成入库。 - 内连接的局限性:如果规则触发时PrivilegedIdentities集合为空(比如IdentityInfo未同步完成),内连接会直接返回空结果。
确保查询正常触发的优化措施
- 限制IdentityInfo的时间范围:在PrivilegedIdentities查询中增加时间过滤,只取最近更新的角色数据,降低延迟影响:
let PrivilegedIdentities = IdentityInfo | where TimeGenerated > ago(7d) // 取最近7天的角色更新记录,覆盖可能的延迟 | summarize arg_max(TimeGenerated, *) by AccountObjectId | mv-expand AssignedRoles | where AssignedRoles in~ (PrivilgedRoles) | extend lc_AccountUPN = tolower(AccountUPN) | summarize AssignedRoles=make_set(AssignedRoles) by AccountObjectId, AccountSID, lc_AccountUPN, AccountDisplayName, JobTitle, Department; - 替换内连接为左连接+过滤:避免因IdentityInfo延迟导致的空结果,同时保留登录日志与管理员的关联:
SigninLogs | where TimeGenerated > ago(1d) | extend lc_UserPrincipalName = tolower(UserPrincipalName) | join kind=leftouter PrivilegedIdentities on $left.lc_UserPrincipalName == $right.lc_AccountUPN | where isnotempty(AccountObjectId) // 过滤出匹配到全局管理员的记录 | project ... // 保持原project字段 - 调整回溯时长:考虑日志入库延迟,把回溯时长设置为25小时(1天+1小时),确保覆盖所有可能延迟入库的登录日志:
- 查询频率:1天
- 回溯时长:1.04天(或直接设置25小时)
- 启用查询延迟偏移:在分析规则的高级设置中,设置30分钟到1小时的查询延迟偏移,给日志足够的时间完成入库和同步。
- 测试时使用固定时间范围:在分析规则测试时,选择与规则触发时间一致的固定时间窗口,而非"最近24小时",更贴近实际触发场景,避免时间偏差导致测试结果不一致。
优化后的完整KQL查询
let PrivilgedRoles = dynamic(["Global Administrator"]); let PrivilegedIdentities = IdentityInfo | where TimeGenerated > ago(7d) | summarize arg_max(TimeGenerated, *) by AccountObjectId | mv-expand AssignedRoles | where AssignedRoles in~ (PrivilgedRoles) | extend lc_AccountUPN = tolower(AccountUPN) | summarize AssignedRoles=make_set(AssignedRoles) by AccountObjectId, AccountSID, lc_AccountUPN, AccountDisplayName, JobTitle, Department; SigninLogs | where TimeGenerated > ago(1d + 1h) // 增加1小时回溯覆盖延迟 | extend lc_UserPrincipalName = tolower(UserPrincipalName) | join kind=leftouter PrivilegedIdentities on $left.lc_UserPrincipalName == $right.lc_AccountUPN | where isnotempty(AccountObjectId) | project TimeGenerated, AccountDisplayName, AccountObjectId, lc_AccountUPN, lc_UserPrincipalName, AppDisplayName, ResultType, ResultDescription, IPAddress, LocationDetails
内容的提问来源于stack exchange,提问作者Jason Smyth
相关产品推荐
相关产品推荐

