追踪无文件恶意软件
我最近阅读了Manuel Arrieta关于在Windows注册表中追踪无文件恶意软件的文章,发现这是一篇非常有趣的读物。
首先我要说明,“无文件恶意软件"这个术语对我来说就像指甲刮过黑板一样刺耳。部分原因来自于DarkWatchman的分析报告,作者声称恶意软件的某些部分”…写入注册表以避免写入磁盘"。这种区分方式一直让我感到不适。然而,无论我们如何称呼它,我确实理解这种表达方式背后的概念,以及为什么人们倾向于认为这类恶意软件比实际写入磁盘的恶意软件更难检测。
我不确定他们为什么会有这种感觉…也许是因为下载恶意软件并将其直接注入内存的代码(在某些情况下)可以驻留在系统的任何位置,以及任何注册表值中。然而,关键在于这种代码需要保持持久性,这限制了用于启动下载、访问shellcode或执行其他初始化功能的代码位置数量。
检测方法
在Manuel的文章中,他讨论了使用LOLBins向注册表写入信息的方法,以及如何利用这一点进行检测。他提到了几个LOLBins,我们需要记住的是,这些检测方法往往比表面看起来更加复杂。例如,如果在您的基础设施中不常使用PowerShell创建注册表值,那么仅凭PowerShell的这种使用方式就值得进行深入调查,甚至可以作为良好的检测机会。对于其他LOLBins也是如此,包括reg.exe、rundll32.exe等。如果这些在您的基础设施中不常见,那么出现的任何实例都需要进行调查。
Manuel的文章讨论了许多有趣的方法,用于为写入注册表的"无文件"恶意软件创建检测规则。任何从事检测工程的人都应该认真阅读这篇文章,看看如何将其应用到自己的环境中。
补充检测方法
我想借此机会对Manuel的工作进行补充,从事件响应或"死盒"分析的角度提出检测此类恶意软件的方法。例如,Manuel提到了寻找写入可疑长度注册表值的LOLBins。我很喜欢这种方法,因为我在2015年最初编写RegRipper的sizes.pl插件时就采用了类似的方法。该插件会遍历注册表配置单元,查找所有超过特定$min_size的值,该值设置为5000字节(您可以通过在记事本中打开插件并更改大小值来轻松修改)。当然,您会发现包含大量数据的合法注册表值,这是可以预期的正常情况。但是,扩展这种方法的一个途径是查看基于实际事件数据的公开威胁情报,了解不同威胁行为者会在注册表值中放置什么内容,从而定制您的检测方法。
大约两年前,我宣布找到了将Yara集成到RegRipper v4.0中的方法,因此任何在文件中查找"无文件"恶意软件或shellcode迹象的Yara规则都可以通过RegRipper对注册表值运行。这可能包括查找base64编码字符串的规则,或者以某种"powershell"变体开头的规则(例如,大小写混合、字母间插入脱字符等)。
实际案例
findexes.pl插件会在注册表值中查找以"MZ"开头的字符串,该插件最初编写于2009年,基于Don Weber在IBM ISS X-Force ERS团队工作时处理的一个案例。Don发现,在该事件中,威胁行为者将PE文件写入注册表值,然后不是从网络资源下载恶意软件,而是直接从注册表值中提取。当时我觉得这非常有趣,因为在几年前,在为军方进行网络利用研究时,我曾理论化过类似的情况,并实际创建了一个可工作的演示。几年后,Don向我展示了这种方法实际上已经在野外被使用。这个findexes.pl插件是一种方法,使用Yara规则是另一种方法。
示例
以下是注册表中持久性机制的一个示例,指向包含base64编码字符串的值。
这是来自Splunk的示例;向下滚动到"通过注册表进行无文件执行"部分;这个示例创建了一个Run键值,该值会创建运行calc.exe的Javascript代码,因此它本身显然不是"无文件"的,但它可以作为一个无害的示例,用于测试死盒检测。
这里还有一些来自Securonix的实际示例;不幸的是,其中一些示例是屏幕截图,因此您无法获取具体细节,例如值数据的长度,但您可以使用这些示例来完善您的检测方法。