使用Anomalize进行异常检测与威胁狩猎
在十月份和十一月份的工具文章中,我基于“R语言中为调查员提供更深层次功能”(DFIR)的前提重新定义了DFIR,当时我发现这只是“冰山一角”。因此,我想通过一个额外的发现和机会重新探讨这个概念。实际上,这是在原始且最重要的DFIR(数字取证/事件响应)通用实践中的一个DFIR案例。
正如之前讨论的,我们这些从事DFIR实践以及蓝队整体工作的人,都被数据和规模所淹没。成功确实需要算法方法。如果您还没有投入到这里,我有一个立即适用的案例研究,介绍如何使用anomalize进行整洁的异常检测。
首先,我要完全归功于以下工作。我所讨论和提供的一切都直接源自Business Science(@bizScienc),特别是Matt Dancho(@mdancho84)。他创建了anomalize,“一个基于时间(构建在tibbletime之上)的整洁异常检测算法,可以从一个时间序列扩展到多个时间序列”,当时一个客户要求Business Science构建一个满足他们需求的开源异常检测算法。我认为他回应得非常漂亮,当他的博客文章通过R-Bloggers进入我的视野时,它在我浏览器中作为一个打开的标签页存在了一个多月,直到生成了这篇工具文章。请将Matt的文章视为此过程的第一步必读内容。在转换上下文之前,我将特别引用Matt的话:“我们的客户有一个具有挑战性的问题:在大规模日常或每周数据的时间序列中检测异常。异常表示异常事件,可能是营销领域网络流量的增加,或IT领域服务器故障。无论如何,标记这些不寻常的事件以确保业务平稳运行非常重要。其中一个挑战是客户处理的不是一个时间序列,而是数千个需要分析这些极端事件的时间序列。”
关键要点:在大规模日常或每周数据的时间序列中检测异常。异常表示异常事件。
现在,与我一起转换上下文到特定安全事件和事故,因为它们涉及安全监控、事件响应和威胁狩猎。在我2017年11月的文章中,记得我讨论了使用Holt-Winters方法的时间序列回归,重点关注季节性和趋势。不幸的是,我无法分享我们如何应用TSR的代码,但指出了替代方法,包括使用Loess的季节和趋势分解(STL):
- 处理任何类型的季节性~可以随时间变化
- 趋势周期的平滑度也可以由用户控制
- 对异常值具有鲁棒性
现在,Matt创建了一种方法,可以立即应用STL方法以及Twitter方法(参考页面),作为他的time_decompose()
函数的一部分,这是anomalize包特有的三个函数之一。除了将时间序列分解为季节性、趋势和剩余组件的time_decompose()
之外,anomalize还包括:
anomalize()
:将异常检测方法应用于剩余组件。time_recompose()
:计算将“正常”数据与异常分离的限制。
anomalize()
中使用的方法,包括IQR和GESD,在Matt的参考页面中有描述。Matt最终着手构建Twitter的AnomalyDetection包的可扩展适配,以解决客户在处理不是一个而是数千个需要分析极端事件的时间序列的挑战。您会注意到,Matt使用从CRAN下载的15个tidyverse包的日常下载计数数据集来描述anomalize,这很相关,因为他利用了tidyverse包。我最初尝试调整Matt的演示,以模拟从CRAN下载特定安全R包(是的,有这些东西)的情况,包括RAppArmor、net.security、securitytxt和cymuservices,后两个由我们亲爱的数据驱动安全:分析、可视化和仪表板的Bob Rudis(@hrbrmstr)提供。唉,这只是一个简单的复制和替换,并没有真正展示anomalize在值得的、多样化的、真正特定安全上下文中的使用。也就是说,我能够立即生成结果,如图1所示。
我想针对真实的安全数据场景运行anomalize,所以我回到了原始DFIR文章中的数据集,其中我使用了给定服务器上每个用户每天的4624事件ID计数。正如最初使用的那样,我仅代表了一个设备和用户的结果,但这就是anomalize的美妙之处。我们可以在多个时间序列(多个系统/用户)上快速获得结果。这个前提只是许多可以将时间序列分析和季节性应用于安全数据的场景之一。
我最初尝试将log.csv中的日志数据直接写入anomalize.R脚本,使用logs = read_csv("log.csv")
到一个tibble(准备好您的tibbles笑话),但解析不准确,特别是时间属性。为了纠正这一点,我从Matt的Github获取了tidyverse_cran_downloads.R
,并修改如下:
这要归功于tibbletime包,它“是一个允许创建时间感知tibble的扩展。一些直接优势包括:能够在tibble上执行基于时间的子设置,快速按时间段总结和聚合结果。猜猜看,Matt也写了tibbletime。:-)
然后,我按照Matt在Business Science上发布的序列,但将我的日志定义为Security_Access_Logs_Function.R
中的一个函数。接下来,我将给您代码片段,如从Matt的示例修订而来,然后是它们各自的结果,特定于处理我的事件ID 4624日常计数日志。
首先,让我们总结三个月内三个服务器的日常登录计数。
结果在图2中显而易见。
接下来,让我们使用Matt的三个主要函数time_decompose()
、anomalize()
和time_recompose()
,以及可视化函数plot_anomalies()
,确定哪些日常下载登录是异常的,跨越三个月内的三个服务器。
结果在图3中揭示。
遵循Matt使用Twitter的AnomalyDetection包的方法,结合time_decompose(method = "twitter")
和anomalize(method = "gesd")
,同时调整trend = "4 months"
以调整中位数跨度,我们将仅关注SERVER-549521。
在图4中,您会注意到SERVER-549521在六月有异常的登录计数。
我们可以比较Twitter(time_decompose
)和GESD(anomalize
)方法与STL(time_decompose
)和IQR(anomalize
)方法,它们使用不同的分解和异常检测方法。
再次,我们注意到六月的异常,如图5所示。
显然,结果非常相似,正如人们所希望的那样。最后,让我们使用Matt的plot_anomaly_decomposition()
来可视化算法如何检测SERVER-549521剩余部分中的异常的内部工作。
结果是一个四部分的可视化,包括观察值、季节、趋势和剩余部分,如图6所示。
我真的很期待在更大规模、更广泛的事件日志数据集上使用这些方法。我坚定地断言,蓝队在对抗自动化对手策略和纯粹规模问题方面已经远远落后,所以…很多…数据。只有通过像Matt的anomalize这样的策略,以及其他类似的方法,防御者才能有望成功。请务必观看Matt关于anomalize的YouTube视频,Business Science正在构建一系列视频,所以请密切关注那里和他们的GitHub,以获取更多我们可以应用于蓝队/防御者上下文的伟大工作。
所有代码片段都在我的GitHubGist这里,示例日志文件、单个R脚本和Jupyter Notebook都可以在我的GitHub上的toolsmith_r中找到。我希望您发现anomalize像我一样令人兴奋和有用,Matt做了伟大的工作,期待看到Business Science的下一步。
干杯…直到下次。