Windows注册表运行键安全攻防指南
2022-2-7 09:30:0 Author: mp.weixin.qq.com(查看原文) 阅读量:13 收藏

文章来源 :嘶吼专业版

Windows注册表是一个庞大而复杂的话题,因此,我们根本不可能通过一篇文章讲清楚。然而,从安全的角度来看,一个特别值得关注的领域是注册表运行键。在这篇文章中,我们将探讨谁在使用运行键,如何发现该键的滥用情况,以及如何根除系统中的恶意运行键。

什么是注册表运行键?运行键是注册表的一种开机运行机制:当用户登录或机器启动时,在Windows系统上执行一些程序。

由于运行键很容易引发安全问题,所以,它自然会成为攻击者的研究对象。例如,Fancy Bear(也被称为APT28)、TA456和Group 123都喜欢用运行键来实现对被攻击网络的权限维持。同时,运行键还可以包含各种形式的恶意内容——从简单的可执行文件到充满宏代码的电子表格。

MITRE ATT&CK将这种特殊的权限维持战术记为子技术T1547.001。在入侵活动中,虽然这种技术并不常见,然而它却可以实现权限维持——因此,我们更有理由进一步探索这种“默默无闻”的技术。

虽然高级攻击者偶尔会利用运行键,但我发现,关于这种机制的探讨却非常少见。实际上,之所以很少有文章讨论这种注册表功能,并不是因为整个信息安全社区的技术差距。相反,运行键是Windows注册表“配置数据库”的一个不太引人注目的可执行组件。这意味着与更强大、更知名的攻击技术和操作系统组件相比,它们往往没有得到同等程度的关注。然而,我最近在信息安全社交圈中看到了下面的讨论:

在我们介绍如何检测恶意运行键之前,让我们先来简单聊一下Windows注册表。

Windows注册表是一个迷宫般的系统。从表面上看,它是一个集中式数据库,用于存储与用户和机器设置有关的信息。不过现实情况却是,它更像是一个由古怪和奇妙的功能组成的系统;尽管这些功能具有破坏性的潜力,但是,微软对这些功能的说明并不详尽。

我可以花几个小时的时间,来讲述关于Windows注册表的不一致性和反复无常。同时,试图了解其潜力的限制和参数确实会令人抓狂。但是,注册表的杂乱无章的特性,貌似对攻击者特别有利,因为这便于藏匿其权限维护机制,并在网络外潜伏,直到蓝队转移视线。

通常情况下,要想区分windows注册表中哪些是良性的,哪些是恶性的,通常是不可能的,特别是在安全事件发生时。

我希望到目前为止,我已经讲清楚了驯服注册表是多么的困难。更糟糕的是,微软对运行键的功能的介绍,也是少的令人发指,因为他们只用了六段话来描述运行键。

运行键存在于注册表中。它们是可配置的,当用户登录或开机时,允许一个程序执行。“但是等一下!”,我听到你愤怒地喊道,“Windows已经有一个任务调度器,这就是你安排任务的方式!!!”

不过,与Windows的任务调度器相比,运行键还是有一些重要的区别的,或者说它的功能更加有限。

与Windows任务调度器相比,注册表运行键具有下列特点:

运行键只能存储少于280个字符的命令。因此,攻击者的one-liner命令的字符数不能超过这个限制。我希望微软并不是想以此作为一种底层的防御机制,因为脚本小子的许多反向shell的长度都少于50个字符。

此外,如果编译恶意可执行文件并通过运行键执行的话,只需用到很少的字符,却能达到最大的效果。因此,尽管与其他系统防御机制相比,字符限制是独特的,但其作用是微不足道的。

运行键的另一个特性是,特殊字符可以改变被调度命令的行为,尤其是感叹号(!)和星号/通配符(*)。在默认情况下,运行键在执行后会自我删除——无论任务的执行是否成功。这两个特殊字符可以用来改变这一行为。

当您将来处理事件响应时,如果看到一个感叹号,说明很可能遇到了一个运行键:它将持续存在,直到运行完指定的命令。如果由于某种原因,这个邪恶的命令没有运行,感叹号能够确保它不会删除自己,直到它运行成功为止。

我们可以通过在安全模式下引导计算机来消除运行键的前缀感叹号。为了确保无论启动模式如何都能执行运行键,攻击者可以利用星号/通配符强制命令运行。

默认情况下,运行键被配置为在运行后自行擦除,这意味着除非您仔细检查日志记录,否则这些恶意活动很可能会被忽视。

这是您现在的表情吗?反正这是我第一次遇到运行键时的表情。说实话,这种表情一直持续至今。

虽然运行键可能看起来很复杂和晦涩,但我向你保证它们并不复杂。它们非常引用检测和监控,而且当攻击者操纵它们的值时,它们会在SIEM中显示得非常清楚,这一点会在下面看到。

有许多地方可以部署恶意的运行键。我们只是要关注前四个位置,但如果你阅读一些红队的文档,就会发现还有更多的注册表位置可以实现运行键的持久性。

总之,在Windows注册表中,只需在HKey Local Machine和Current User目录下寻找,只需越过几个目录,就能找到Run和RunOnce。 

"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"

"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"

"HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"

"HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"

目录在这里很重要,因为运行键的行为取决于它所在的注册表位置:

如果被写入到HKLM:\的话,这意味着这是作为一个高权限用户(很可能是管理员)或SYSTEM写入的。

写在这里的运行键可以在机器启动时执行。

如果被写入到HKCU:\中的话,这意味着这只是作为一个普通用户写入的。

写在这里的运行键只有在用户登录时才会执行。

如果被写入到\RunOnce的话,它将在执行后被删除。

如果被写入到\Run的话,它在执行后并不会被删除。

这些都会因为我们已经讨论过的特殊字符行为而变得愈加复杂。

在现实生活中,我们必须从注册表过滤掉一些噪音后,才能看到运行键的内容。下面我们举例说明,第一个例子是没有经过PowerShell的过滤,第二个例子则通过PowerShell进行了相应的过滤。

看看这一团糟。这到底是什么?我们根本就不需要红框中的东西,那些只是噪音。事后看,我们知道这里表示“HKLM”驱动器和“Run”ChildName,但是,乍一看,的确是一言难尽……

下面,让我们利用PowerShell过滤掉这些噪音:

Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" | select -property * -exclude PS* | fl

看看这有多优雅。想象一下,如果能够通过类似方式让数以千计的端点以这种清晰、无噪音的方式返回信息,这简直就是蓝队的梦想。这种用于过滤的PowerShell非常适合在企业范围内运行,以识别网络中标准构建之外的异常。

如果看一下运行键,就会发现条目的名称和附带的命令。不过,运行键的合法内容可能有所不同,我们需要了解企业中什么东西是正常的,因为这样才能知道哪些东西是不正常的。

在进行安全审计时,有时需要过滤掉注册表运行键中合法的启动项目。这其实很容易做到。为此,只需使用与上述相同的PowerShell,不过这次需要加上-exclude

标志,然后是需要排除的PS*,后面加上一个逗号,以及其他不想看到的运行键名称。

Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" | select -property * -exclude PS*, Vmware*,bginfo*  | fl

下面,让我们模仿一下攻击者的一些行为。我们将在一个运行键中插入一些恶意的东西,同时,我将向您展示:

第一,如何通过循环方式自动找到它。

第二,如何在不破坏其他合法运行键的情况下将其从机器上清除。

假设我们已经入侵了一台机器,并希望在这台机器上面维持相应的权限。为此,我们编译了evilcommand.exe,它能够绕过人类已知的所有反病毒软件,并向我们一个反向shell。我们可以命令其中一个运行键来执行我们的恶意程序:

Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name '!Delete After Running' -Value "evilcommand.exe"

如果我们能够在单行Powershell命令的末尾加上-whatif,它就不会真正运行你的命令。相反,它将向您显示如果您运行它会产生什么效果。

当您想真正运行一些命令时,请使用-verbose标签。

这就是我们强制运行键为我们做的事情:创建了一个名为“Delete_After_Running”的运行键,其执行值为“evilcommand.exe”。注意前面这个感叹号,正如我们已经讨论过的,它将确保程序在自我删除之前运行,以欢迎我们再次光顾这台被入侵的机器。

任务调度器不会注意到这一点。它不会也无法识别这个运行键已被调度。如果我是微软,我可能会在任务调度器中加入这一功能……

利用Powershell的for循环,我们可以收集上述四个注册表位置的内容。

在构思这个脚本时,我设法通过确保代码产生的输出被预先过滤并添加颜色,以便于辨认是否存在异常的东西及其所在的位置。

如果我们看得足够仔细,就会发现一些异常情况。一旦我们取得可执行文件并对其进行逆向分析,我们就可以确定它是否是来自攻击者的恶意可执行文件。

如果发现恶意的运行键,那么就需要将它从机器上删除,具体方法将在后面介绍。

让我们从检测和监控的角度讨论一下恶意运行键的行为。

在这里,我们将使用内置的Windows事件查看器,并为Sysmon和Florian Roth配置相应的规则来检测恶意的运行键。然后,你可以将这些Sysmon日志数据输入SIEM,并监控数十万个端点的运行键恶意行为(以及其他东西)。

这里有大量的信息需要考察:

蓝色的箭头:事件信息

事件ID 13涉及注册表值的修改,这个ID在任何环境下都是一致的。

EventType和Task Category也准确地指出了这里发生的事情:一个注册表值正在被设置。

红色箭头:具体信息

TargetObject显示了我们正在改变的运行键注册表的完整路径。它还显示了我们给它起的名字,并包括改变行为的特殊字符

Details部分显示了运行键强制执行的命令/可执行文件

粉红色的箭头:MITRE ATT&CK参考

这个可能不是在每个symon配置中都有。然而,Florian Roth将MITRE ATT&CK战术编号列入了某个事件中。

与其为每个Event 13生成攻击警报,我建议你去了解一下环境中的运行键通常做什么。

在整个企业中,它们是否有一致的内容?

还是财务部门运行的软件合法地改变了运行键?

你是否能够以这个为基准,然后为财务部门的工作站的任何新的、不一致的运行键变化创建一个小警报?

这比从一百万个事件中抓住一个流氓Event 13更有价值。

如果您想获得更多的交互式检测体验,我会推荐使用Michael Cohen博士的Velociraptor这样的工具。

Velocitaptor是一个非常棒的工具,但是,我们这里只做简单的介绍。总的来说,Velociraptor就是一个端点响应代理,我们可以把它安装到企业中的所有端点上,并通过运行在服务器上的Web应用对其进行协调。这种分布式工具使我们能够同时查询成千上万的机器。

Velociraptor内置了一个搜索功能,专门查询每台Windows机器的启动过程,而这个搜索功能的一部分就包括查询运行键。正如你所看到的,这个搜索功能的目标就是一些注册表的运行键。此外,Velociraptor的目标还有另外几个运行键,以及其他一些启动位置。

如果我们启动了这个启动检测搜索,我们将得到一个格式优美的结果表。在真实的生产环境中,你会发现噪音会更多一些,所以请注意!现在,看看我们检测到了什么:域中的一台机器正在运行C:\evil.exe,这个名字真是太吓人了。

幸运的是,现在我们已经找到了恶意的运行键,不仅如此,我们还可以从主机中删除它。

现在,是时候铲除恶意的运行键了。

下面,我们开始外科手术。如果使用的命令不够精确,则会意外地删除合法的运行键。重要的是,这里也要用-verbose完成删除操作,并仔细检查它是否已经消失,以确保删除对象的确已经被清除了。

在PowerShell的for语句的后面,复制并粘贴前面检测到的恶意运行键的完整路径,并再次检查确认。

Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" | select -property * -exclude PS*| fl

然后,选择要删除的运行键的确切名称,然后复制粘贴该名称。注意,这里必须包括相应的特殊字符,但是,不要复制冒号后面的可执行文件的详细数据。

Remove-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "*Run Safe Mode too" -verbose

这样,就会返回详尽的消息,以确认删除的的确是我们的目标运行键。

然后,让我们再检查一下,以确认它的确已经被清除。如果这里还有恶意运行键的话,请仔细检查复制和粘贴的内容是否正确,因为发生误操作也不是不可能的事情。

Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" | select -property * -exclude PS*| fl

运行键是一种非常晦涩难懂的权限维持机制。但我希望这篇文章能让我们对监视、检测、控制和清除涉及运行键的任何恶意活动有所帮助。

作为一个防御者,许多时候我们的角色与入侵者相比一直处于劣势。他们可以利用zero-day漏洞,他们可以欺骗用户,他们可以用更大的预算跨时区运行。所以,这就要求我们进行全方位的防护,但对他们来说,只需要拿下一个突破口就行了。所有这些都是真实不虚的,但我发现有时我们可以把这种观点颠倒一下,把重点放在我们与攻击者相比所拥有的优势上。

环境是我们的,注册表是我们的,运行键也是我们的。同时,我们知道这一切是如何运作的,我们应该在这里等待对手在我们的领域里打喷嚏。虽然这是我们的地盘,但我们并不天真,我们有时候的确会被攻陷。但是,我们会抓住入侵者,把他们踢出去,并提高入侵难度。

了解您的环境中什么是正常的,这样您就可以知道注册表运行键操作何时不合适,并培植一个对抗性的网络,让攻击者寸步难行。

当然,还有许多其他古怪的注册表项,它们可以通过运行键做一些奇怪的事情。例如,我们没有提到整个文件夹是如何通过注册表运行键实现权限维护的!。

侵权请私聊公众号删文



文章来源: http://mp.weixin.qq.com/s?__biz=MzAxMjE3ODU3MQ==&mid=2650533081&idx=2&sn=2391f09bdfe1d0b44b9d4b4a7d795234&chksm=83ba893db4cd002b819893f9886e6474f03dcc29869be0c1a7953c451562562d5b567b3d258e#rd
如有侵权请联系:admin#unsafe.sh