我花了很多时间专注于更高层次的威胁检测策略,但今天我要换一个方向,从更具体的战术层面来谈谈如何创建能够抵抗SIEM常见问题(如摄入延迟和查询故障)的检测机制。今天我要谈一些常见问题,并分享一些好的做法,使检测更可靠,希望这能帮你以后少踩坑!
好不容易构建了一个完美的检测系统,但在关键时刻却出了问题,导致事件未能及时被发现,这种感觉非常令人沮丧。所以让我们来谈谈如何构建更具有韧性的系统,以及我们通常会遇到的一些故障类型。
延迟适应性这是最常见且最容易解决的问题,所以这是一个不错的起点!顺便提一下,我不是第一个讨论这个问题的人(链接1)(链接2)(链接3)(链接4),但在检测工程师社区中对该问题的认识似乎还不够高,我找到的大多数在线解决方案都只能部分解决问题。因此,我会再多写一点,希望能提高大家对此问题的认识,并提供一个更好的解决办法。
我们先来定义一些术语和概念,怎么样?
- 摄入延迟是指事件实际发生时间和记录该事件的日志被摄入到您的SIEM中的时间之间的差异。
- 每个我见过的自动化检测平台都涉及定期运行查询,并定义每个查询执行将检查的时间段,即回溯时段。通常,查询通常每小时或每30分钟运行一次,并回溯相同的时间长度。这种滑动窗口确保每个日志都被依次检查,而不会出现重叠(这可能会导致重复警报)。回溯窗口可以是即时回溯(时间窗口从查询时间开始,回溯X分钟),或延迟回溯(时间窗口从查询时间减去某个预设时间段开始,回溯X分钟)。
- 每当一条记录被摄入到数据库或文档存储中时,你应该了解两个时间戳:事件时间是事件实际发生的时间点,摄入时间是记录该事件的日志被摄入到数据库的时间点。在安全领域,几乎所有查询都限定在一个特定的时间范围内,事件时间几乎总是被使用。(我见过的大多数开箱即用的检测和SIEM系统都采用事件时间。)
每30分钟运行一次的查询,并且有一个30分钟的即时回溯窗口(即事件时间窗口),看起来会是这样。
查询过去30分钟内的30分钟日程安排
当你的检测查询查找日志时,如果日志不在SIEM中,就会出现摄入延迟的问题。假设你有一个每30分钟运行一次的查询,但你需要检测的日志却延迟了30分钟。当你的查询运行并回溯30分钟时,日志没有出现在SIEM里,所以你没有收到警报。但是,当30分钟后下一次查询运行时,回溯窗口向前移动,不再包含事件发生的时间段!虽然你的检测可以100%检测到恶意活动,但由于摄入延迟,你还是错过了它。
因加载延迟而错过的事件
我从未遇到过真正实时的SIEM,所以一些数据摄入延迟总是存在。如果你用事件时间作为查询的时间戳,并且使用了即时回溯窗口,你很可能有一个盲点。 有些事件会落在你的查询窗口内,但还未被摄入。你的盲点大小取决于日志源的摄入延迟时间和回溯窗口的长度,但几乎可以肯定,至少会有一个小的盲点存在!如果关键事件恰好出现在盲点内,你就错过了它。
这里是如何找出你的盲区有多大:在你的SIEM中运行一个典型的检测查询,使用你的典型检测查询时间范围,并统计每个2分钟窗口内的记录数量。我们来画一个图表,这样更容易看出。你会发现图中有一个开始下降的点。这个下坡趋势,加上任何完全没有记录的区间,就是你的检测盲区,也就是所谓的摄入延迟盲区。
一小时内回溯时间窗的图表,该日志来源的平均处理延迟为半小时。
如果你的日志源图形看起来像这样,并且你使用事件时间作为检测查询的时间戳,那么你就有一个盲点。虽然这些日志会最终被摄入,但它们永远不会重新落入查询的滑动时间窗口中!每次查询执行都会有自己的盲点,从而降低检测找到特定日志的概率。
即使是延迟时间非常短的日志,仍然会有盲区。
一张具有3分钟平均延迟的一小时回溯窗口图表。
那么,在最坏的情况下,如果数据摄入延迟几乎和你的回溯时间窗口一样长,你的盲点可能会变得几乎完全看不见了!
这是一个显示30分钟回溯窗口的图表,该窗口的数据源平均延迟时间为30分钟。
希望你已经熟悉了你所使用的SIEM系统的正常数据摄入延迟时间,并且已经对此做好了计划。一种解决办法是使用一个延迟回溯窗口,这个窗口比你预期的最长摄入延迟时间(而不是平均延迟时间!)还要长。这样可以确保在你查询特定时间窗口之前,事件应该已经被摄入。
进行一个带有30分钟延迟回顾窗口的查询
这种方法的权衡是,你的“检测时间”(从恶意事件发生到你知道它发生的这段时间)也会被延迟。在上面的例子中,延迟的回溯提供了对摄入延迟长达30分钟的缓冲,但对恶意事件的警报也会延迟30分钟,无论当前实际的摄入延迟有多长。但至少你不会错过任何异常,因此你可以确信你会及时收到警报。
真正的挑战在于出现意外的激增。 当摄入延迟突然增加到两到四小时,甚至更长时,几乎肯定会超过任何延迟回溯的范围,导致可能遗漏的检测。如果摄入完全停止了六个小时,而工程团队在查找并修复问题期间,查询时间窗口已经过去,您将错失在停机期间本应触发的所有警报。
应对摄入延迟的最好解决办法是,在检测查询中使用摄入时间而非事件时间。 使用基于摄入时间戳的方法意味着,所有事件都会在它们被摄入后的下一个查询中被检测查询检查,无论你正在经历多大的摄入延迟。即使SIEM系统停机整整一天,只要延迟的日志最终被摄入,它们也会被检查,在接下来的查询执行中。不会有遗漏的警报,只会有延迟的警报。使用摄入时间戳还意味着你不必使用延迟回溯窗口,因此不会有内置的检测延迟。无论当前摄入延迟有多大,你都可以达到最短的检测时间。这就是所谓的韧性!
在您的SIEM中利用时间戳注意:更容易检测输入延迟盲点,文章末尾附有一个简单的 PowerShell 脚本文件。
据我观察,大多数SIEM系统将事件时间作为主要时间戳(如果采用摄入时间作为主要时间戳,可能会对其他搜索场景造成影响)。而且,其自动查询默认使用的是主要时间戳。因此,使用默认设置时,你可能至少有一个较小的摄入延迟盲点。不过,希望你的SIEM允许你使用摄入时间戳。以下是我曾经使用过的几个例子:
- Azure Data eXplorer (ADX,我越来越喜欢它了!)使你能够很容易地使用摄取时间。ADX API 没有定义单独的查询时间参数,这些参数需要在查询本身中提供。因此,你完全控制着时间参数,只需要使用摄取时间(ingestion_time())函数就可以完成!当然,ADX 并不会提供自动查询,所以你需要自己来解决这部分问题。
- Sentinel 的分析规则和 Splunk 的警报都会自动基于事件时间进行查询,但有一些变通方法可用。微软提供了一个 有限的变通方法(仅在预期的摄取延迟内具有弹性,超过这个时间将会错过事件),而 Splunk 提供了一个 更好的方法(但这仍然是一个需要你知道如何使用的变通方法)。Splunk 的解决方案适用于两个平台,所以我会在这里总结一下。在查询中添加一个子句,选择摄取时间:在 Splunk 中使用 _index_earliest 和 _index_latest 字段,在 Sentinel 中使用 ingestion_time() 函数。你可以看到示例在上面的链接中。确保你动态定义时间:Splunk 中使用 -1h,Sentinel 中使用 ago(1h)。然后将查询回溯设置为平台允许的最大值(Splunk 中为“所有时间”,Sentinel 中为最近的 14 天)。这意味着基于事件时间的选择条件将不起主要作用,所以你的摄取时间子句将成为主要的时间过滤器。
- 如果你直接使用 ElasticSearch 的 API,可以在查询的范围语句中指定任何时间戳。你需要在摄取管道中 添加摄取时间字段,因为默认情况下不会添加。在 Elastic 公共架构(ECS)中,摄取时间应该命名为 event.ingested,所以使用这个并设置好即可。
- 我从未使用过 Splunk Enterprise Security 或 Elastic Security(Splunk 和 Elastic 的 SIEM 解决方案),如果你知道如何在这两个平台上使用摄取时间进行自动查询,欢迎在下面留言分享你的知识。我认为你可能可以将 Splunk 的变通方法应用到任一平台上。
你将需要根据你的SIEM和数据摄入的延迟(别忘了考虑正常的延迟和潜在的峰值流量!)找出最适合你环境的解决方案。如果你的SIEM不支持使用摄入时间进行自动化的查询,是时候向你的SIEM团队提出功能请求了!此外,在本文的末尾,有脚本可帮助你验证你的解决方案是否有效。
- 让我澄清一下我在多篇文章中看到的一个观点:认为将最大回溯窗口设置为较短的时间会减少查询效率。这是一个误解。摄入时间窗口限制了查询的记录数量,与事件时间窗口限制记录的方式也是一样的;如果你在这两种情况下使用相同的回溯窗口长度,那么效率应该是相同的。你可以在Splunk中亲自验证这一点,运行一个搜索“index=whatever | stats count”并设置时间选择器为“最近60分钟”。然后检查作业并记录扫描到的记录数。接下来,运行搜索“index=whatever _index_earliest=-60m _index_latest=now | stats count”,并将时间选择器设置为“所有时间”,然后检查作业。扫描的记录数和所花费的时间不会有太大差别。通过将事件时间回溯窗口设置得较短(如微软解决方案中所做的),你只是在限制你的摄入延迟容错性:一旦摄入延迟超过你的事件时间回溯窗口,你就会开始错过这些事件。当你正确使用摄入时间戳时,摄入延迟容错性和查询效率之间实际上并不存在权衡。
另一个检测遗漏的来源是查询平台故障。可能失败的情况取决于具体平台,但任何平台都可能由于诸如API限流、网络故障或平台维护等原因导致运行失败。如果不幸让恶意事件正好发生在查询窗口失败的时间段内,那么这个事件就会被忽略。
查询失败,事件未记录。
有三种方法可以处理查询失败的问题。不幸的是,但是最好的方法需要您的检测自动化平台的支持。如果您的平台不支持这些方法中的任何一个,现在是时候向平台提出功能请求了。
选项1:健康监控和手动或自动重新提交
对于此选项,你需要配置任何失败查询的通知配置,然后重新运行任何失败的查询以确保没有遗漏任何恶意活动。这可以手动或自动完成,但自动重新提交无疑更优越。如果你有数百或数千个检测,手动重新运行所有检测可能会非常困难。理想情况下,解决方案应该自动化,这样失败的查询会被自动重新提交以覆盖遗漏的时间段。更理想的是,这种自动失败检测和重新提交功能应该由你的检测自动化平台来实现,这样你就完全不用担心这个了!
选项二:重叠回看窗口
你可以通过配置查询使用重叠的回溯窗口来构建一定的容错能力。这样一来,即使一个查询失败了,后续查询也会覆盖失败的查询窗口,从而不会错过任何事件。你的容错能力将等于重叠窗口的数量,但连续的查询失败会导致漏掉警报。例如,你可以使用每30分钟运行一次且带有1小时回溯窗口的查询,这将提供对单次失败的容错。连续两次失败将会留下一个未被覆盖的时间窗口。
查询一个30分钟的安排,带有1小时重叠回顾窗口。
这种方法需要一种去重告警的机制,因为在正常情况下,给定的恶意事件会在检测查询的多次执行中被检查,因此,相同的恶意事件可能会被多次识别。它还可能导致事件分组时的一些问题:如果你在分组事件之后进行去重,那么后续的查询执行可能会找到一组略有不同的事件(因为其中一些事件可能落在新的回溯窗口之外而不会被包含在当前的查询范围内),从而可能导致重复的告警。总的来说,这种解决方案可以运作,但它确实会带来不少麻烦。我更偏好选项1和3。
由于在不同的窗口上事件组引起的重复的报警信息。
调整查询时间范围
此选项需要您的自动化检测平台支持,但它是一个简单的解决方案。在该方案中,自动化平台会为每次执行记录查询时间窗口。当某个查询运行时,使查询窗口覆盖从上次成功执行到当前的时间段。因此每次查询只针对一个时间段,无需重复查询,所以无需进行去重处理。
查询因为调整了回溯时间窗口而失败了,这个窗口用于执行后续查询。
结论部分希望这篇文章给你一些有用的建议,让你的检测尽可能坚不可摧,这样它们无论是好时候还是坏时候都能发挥作用(可能只是稍微晚一点)。
如果你有任何想法,可以在评论区留言哦!
测量您摄入延迟盲区的脚本如果你担心自己存在摄入延迟盲区,这里有一个简单的PowerShell脚本可以帮助量化这种情况。该脚本将在一小时内每5分钟启动一个带有唯一命令行的cmd.exe进程,共持续一小时,总共启动12次。要使用它,请在你的自动化平台上设置一个检测规则,用于查找命令行中包含字符串“IngestDelayTestCommand”的进程。将其设置为以你通常的频率执行,并使用你常用的回溯窗口。然后在一台已将日志记录到SIEM的机器上运行此脚本,并核对总共收到了多少个警报,理论上应该是12个。然后自己评估可以容忍多少漏报情况。(我知道,我知道……我这是在引导你。 😁)
#此脚本帮助测试数据摄取延迟盲点
#使用说明:在自动化平台上创建一个检测规则,在进程命令行中查找"IngestDelayTestCommand"。
#然后在向您的SIEM系统上传数据的资产上运行此脚本。脚本会每5分钟运行一次cmd.exe进程,输出预设字符串,持续一小时,期间每五分钟一次。未接收到的告警数量即为您的数据摄取延迟盲点,可能有12次。
for ($i=1; $i -le 12; $i++) {
$currenttime = Get-Date -Format "HH:mm:ss"
$command = 'echo {0} IngestDelayTestCommand - 测试项 #{1}' -f $currenttime, $i
& cmd.exe /c $command
Start-Sleep -seconds 300
}
这里将显示:
07:33:38 数据摄入延迟测试命令 - 测试一
命令行看起来会是这样的:
"C:\WINDOWS\system32\cmd.exe" /c "echo 09:13:06 IngestDelayTestCommand - 测试#1"
共同学习,写下你的评论
评论加载中...
作者其他优质文章