利用Splunk查找表加速检测工程:高效实现基于字符串的威胁检测

本文介绍如何利用Splunk查找表快速实现基于字符串的检测规则,减少传统检测规则部署时间。通过实际SPL搜索示例和三种方法对比,提升检测工程效率并降低管理复杂度。

利用Splunk查找表加速检测工程

概述

本文探讨如何利用Splunk中的查找表(Lookups)功能,显著缩短基于简单字符串检测的新规则实施时间。例如,检测到dump /service:krbtgt时立即触发告警。

虽然检测即代码(detection-as-code)的部署可能减少对此类方法的需求,但实际经验表明,基于字符串搜索的新规则部署时间仍然过长。

背景

新规则开发的常见流程包括:阅读报告、识别TTP(战术、技术和程序)的独特实现、创建或获取规则(例如从Sigma搜索引擎、detection.fyi或SigmaHQ的GitHub仓库获取Sigma规则)。

即使采用检测即代码,这仍可能是一个漫长的过程,并可能导致管理数百个检测规则,每个规则都有自己的管理开销,而这些规则本质上可能只是字符串指示器。

解决方案——使用查找表!

在Splunk中,查找表本质上是一个CSV表格,用于存储我们要查找的数据。

简化的现有IOC威胁匹配在Splunk中使用查找表/kv存储。我们只是将该概念扩展到包含字符串片段,如*mimikatz*,并添加我们想要查看的字段(如command)。

Sigma规则示例

以查找命令行参数的Sigma规则为例:

示例Sigma规则中所有感兴趣的内容只是出现在CommandLine中的字符串。我们希望将此类简单Sigma规则的主题转换为CSV结构。

上述示例显示,它查找多个命令行片段中的任何一个。这确实说明了基于查找表的方法的局限性:如果我们不想承担分割分隔字段的开销,则所有内容都必须放在单独的行上,这对某些规则可能相当“凌乱”。

示例查找表文件

以下示例查找表存储我们最感兴趣的信息,例如:

  • l_field:要查找值的字段
  • l_value:要查找的值(注意周围的通配符)
  • l_description/l_name:名称和描述
  • l_references:任何有用的调查参考
  • l_severity:可能触发的严重性(可用作RBA计算中的风险因素)

在Splunk搜索中使用查找表

有几种方法可以在Splunk搜索中使用此查找表,每种方法的效率各不相同。总体思路是指向索引,指定我们关心的字段,然后进行查找。

重要步骤:

  1. 确保为查找表定义了查找定义
  2. 确保在查找定义中将搜索的字段启用为通配符字段(参考Splunk文档)
  3. 所有搜索项应保存为带有周围通配符*的形式

示例SPL:方法1——首先使用inputlookup子搜索的Tstats

1
2
3
4
5
| tstats summariesonly=true c from datamodel="Endpoint.Processes" where `rule_tuning_macro` [|inputlookup string_indicator_lookup | rename l_value as Processes.process | fields Processes.process] by _time Processes.process Processes.user host
| rename Proceses.* as *
| eval lookup_field="command"
| eval lookup_value=process
| lookup string_indicator_lookup l_field as lookup_field l_value as lookup_value

这里使用加速数据模型,内部搜索是inputlookup,重命名后仅将字符串输出到我们关心的字段(此处为processes.process)。我们可以针对此较小数据集进行搜索,并直接使用查找表丰富任何发现。

与编写规则的良好实践一样,我们包含一个调优宏,其中包含误报等,包括使用原始数据中其他字段进行调优。

缺点: 随着查找表文件的增长,由于inputlookup命令在Splunk索引器上的工作方式,这可能相当慢。搜索需要定期运行且时间窗口较小。

示例SPL:方法2——使用Tstats提取所有数据然后进行查找

1
2
3
4
5
| tstats summariesonly=true c from datamodel="Endpoint.Processes" where `rule_tuning_macro` by _time Processes.process Processes.user host
| rename Proceses.* as *
| eval lookup_field="command"
| eval lookup_value=process
| lookup string_indicator_lookup l_field as lookup_field l_value as lookup_value

在此示例中,查看加速端点数据模型中的所有命令(Processes.process),然后对每个命令进行查找,允许我们看到查找表中的所有字段(如Description或References)。同样使用调优宏。

缺点: 这可能相当慢,因为它首先将所有命令拉入内存,因此应在短时间范围内运行,尽管查找表增长的影响可能较小。

示例SPL:方法3——在非数据模型数据上,使用inputlookup和lookup

1
2
3
4
5
{{YOUR DATA}}
| eval lookup_field="command"
| eval lookup_value=command
| search[|inputlookup string_indicator_lookup | eval search=l_value |fields search | format ]
| lookup string_indicator_lookup l_field as lookup_field l_value as lookup_value

这里不使用加速数据模型,但为加速使用两次传递。第一次inputlookup在原始数据中查找我们关心的字符串——此时它可能出现在任何字段中,但应大大减少后续查找的数据集。随后进行查找,确保在正确字段上匹配并用查找表的上下文丰富它。

进一步探索

这些搜索相当基础,因此有一些想法值得探索:

  • 使用分隔符减少重复/多行——涉及的解析可能严重影响搜索时间,尤其是无法进行简单查找时。但希望进一步调查。
  • 附加字段,如parent_process——仅当两者都满足时
  • 查找表中的逻辑——在查找表中存储Sigma逻辑并在SPL搜索中使用,如“ANY”、“ALL”
  • 在摄取/实时执行——希望在原始日志进入Splunk时进行简单模式匹配,类似IDS。想看看在摄取时进行此类查找的可行性。

结论

诚然,可能存在某个点,使用查找表效率低于拥有多个规则。但目标是从阅读报告时的“嘿,我们可能可以查找那个”到实际有规则查找它,大幅降低复杂性和所需时间。

如果有任何反馈,请告诉我!(我喜欢重新发明完美的好轮子,所以如果有更好的方法,请告诉我!)

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计