导语:以前,我在博客中介绍了一种DCOM横向移动的技术,该技术​利用了Windows 2008/2012主机上的注册表类标识符(CLSID)子键值中引用的不存在的丢失文件。在看到该技术的影响后,COM和键值路径劫持的整个概念对我来说变得更加迷人。因此,我决

TL; DR

· 一些供应商因在其产品中包括或遗留了可能被攻击者用来进行横向移动、规避杀软查杀、绕过和持久性的注册表而臭名昭着。

· 可以枚举CLSID子项(LocalServer32和InprocServer32)来发现遗留的没有用的二进制引用。

· 有趣的是,可以使用以下命令调用('调用')CLSID:

rundll32.exe -sta {CLSID}

· 防御性建议:删除后清除一些软件配置项(例如unregister),监视可疑事件(例如rundll32.exe的使用情况),并实施强大的应用程序白名单(AWL)策略规则。

背景

以前,我在博客中介绍了一种DCOM横向移动的技术,该技术利用了Windows 2008/2012主机上的注册表类标识符(CLSID)子键值中引用的不存在的丢失文件。在看到该技术的影响后,COM(组件对象模型)和键值路径劫持的整个概念对我来说变得更加迷人。因此,我决定重新研究CSLID,LocalServer32和InprocServer32,希望能发现更有趣的东西。

在这篇文章中,我们将讨论:

· CLSID,LocalServer32和InprocServer32的用途

· 枚举LocalServer32和InprocServer32键以及缺少键引用的略微改进的方法

· DCOM横向运动方法

· Rundll32和CLSID滥用

· 几个防御性建议

让我们进一步深入……

CLSID,LocalServer32和InprocServer32上的快速入门

大多数COM类都在操作系统中注册,并由表示注册表中的类标识符(CLSID)的GUID标识(通常在HKCR \ CLSID或HKCU \ Software \ Classes \ CLSID下)。在COM类的实现背后是在CLSID下的注册表项中引用的“服务器”(某些二进制文件)。LocalServer32键表示可执行(exe)文件的路径,InprocServer32键表示动态链接库(DLL)文件的路径。

在注册表中,CLSID结构看起来像下图这样:

LocalServer32

clsid_2.png

InprocServer32的

clsid_1.png

*参考:CyberReason的Philip Tsukerman(@PhilipTsukerman)滥用DCOM技术新横向移动技术

枚举LocalServer32 / InprocServer32键值并查找废弃的二进制引用

在Windows 操作系统中,有许多COM类,并且在LocalServer32 / InprocServer32的数据字段中废弃的二进制路径的引用的数量是由以下几个因素造成的:

· 操作系统版本,家族和功能

· 第三方软件(安装后/卸载后)

· (之前的)DLL / COM注册

要找到这些废弃的引用路径,请考虑以下几个常规的步骤:

· 枚举所有LocalServer32和InprocServer32的值找到引用二进制文件的路径

· 格式化二进制文件的路径并删除参数和开关(如果适用)

· 验证二进制文件的路径是否存在并找到相应的废弃文件

LocalServer32

让我们使用以下PowerShell代码段枚举所有LocalServer32键值:

$inproc = gwmi Win32_COMSetting | ?{ $_.LocalServer32 -ne $null }
$inproc | ForEach {$_.LocalServer32} > values.txt

在这种情况下(在Win2k12 R2机器上),我们将输出内容重定向到文件(values.txt)中,这样可以方便的编辑命令参数和开关。

localserver_file1.png

格式化文件后,我们可以使用以下代码段找到可能缺失的值:

$paths = gc .\values.txt
foreach ($p in $paths){$p;cmd /c dir $p > $null}

在我们的测试用例中,我们可以看到以下结果有一些与上一篇文章中看起来很熟悉的内容

localserver_file2.png

InprocServer32

你可能会发现更多具有InprocServer32键的Registry CLSID类。从System32目录,我们可以运行以下代码片段而不必担心格式化后的枚举结果(由很多输出):

$inproc = gwmi Win32_COMSetting | ?{ $_.InprocServer32 -ne $null }
$paths = $inproc | ForEach {$_.InprocServer32}
foreach ($p in $paths){$p;cmd /c dir $p > $null}

*注意:在运行上述代码时你可能需要喝一杯咖啡,因为这可能需要几分钟时间。另外,请考虑将此输出重定向到文件以便于后续的分析。

inprocserver32_01.png

在我的一个Win10虚拟机上,这个缺失的引用看起来很有趣:

vmware_clsid.png

除了Windows本身的一些文件之外,我们还可以看到一些(可信的)供应商软件也留下了一些缺失的文件路径也就不足为奇了。这些废弃的注册表元素不一定表示在非特权用户上下文中存在漏洞(例如,由于目录结构上的ACL),但这些文件可能为攻击者利用其他方式(例如COM Hijacks)“入侵”并影响注册表结构创造机会。

重新审视DCOM横向运动技术

在Windows 2008和Windows 2012的基准安装中,C947D50F-378E-4FF6-8835-FCB50305244D的COM CLSID结构具有指向%SystemRoot%\system32\mobsync.exe的LocalServer32子项。

dcom_06.png

遵循上面的枚举方法,枚举文件路径,并且在文件位置显然不存在引用的二进制文件。由于这个COM对象可以远程实例化(当没有锁定时),因此很明显可以滥用于DCOM横向移动。

dcom_08.png

dcom_09.png

dcom_10.png

更多信息可以在这篇博文中找到 – 又一种横向运动技术——滥用DCOM。

滥用注册表COM CSLID与Rundll32

如果你在Twitter上关注了我,你可能已经了解这种技术:-)。但是,这个博客是一个更好的记录它的地方。在枚举Windows 10计算机上的LocalServer32键时,我遇到了这个非常有趣的CLSID和LocalServer32键值:

%SystemRoot%\system32\rundll32.exe /sta {fcc2867c-69ea-4d85-8058-7c214e611c97}

clsid_sta.png

-sta(/ sta)开关是指“单线程单元”,它是COM线程体系结构的一部分。除了有关COM的微软官方文档之外,我在rundll32.exe中找不到有关-sta开关的更多信息。有趣的是,powershell.exe有一个-sta开关,用一个单线程单元启动powershell(在默认情况下,是在版本2之后)。当使用相应的CLSID(或ProgID,如果可用)调用时,rundll32.exe中的此开关通过LocalServer32或InprocServer32加载('调用')引用二进制文件。我对这块的技术背景的理解仍然不够,但它对于滥用COM有一些有趣的含义。

规避DLL加载

正如在枚举部分中所提到的,我发现VMware Workstation中的注册表工件是从机器卸载软件后遗留下来的。有趣的是,以下CLSID和目录结构仍然存在:

vmware_dll.png

文件夹结构也没有软件二进制文件和相关的依赖项。以下ACL条目对此文件夹有效:

vmware_acl.png

幸运的是,没有特权的用户不具有写入此目录的能力。但是,我们仍然可以通过将名为'vmnetbridge.dll'的恶意DLL复制到目录中来影响InprocServer32的加载来证明特权用户可以尝试“攻击”:

vmnet_dir1.png

让我们使用以下命令加载我们的DLL有效载荷与相应的CLSID:

rundll32.exe -sta {3d09c1ca-2bcc-40b7-b9bb-3f3ec143a87b}

vmnet_dll.png

当然,此示例在特权上下文中加载,但如果普通用户可以影响“已废弃”注册表CLSID的路径元素,则含义可能会变得非常有趣。

通常,这也可以通过Run key或Scheduled Task 实现可行的持久性机制。

利用AWL绕过传统的COM劫持

使用合法的CLSID引用和注册的程序ID(ProgID),我们可以在非特权用户的上下文中简单的劫持已注册的COM结构。在这个例子中,让我们加载调用远程COM 脚本的Casey Smith(@subTee)“scripting.dictionary”COM Hijack reg文件。这为我们设置了“ squiblydoo” 的AppLocker绕过规则(使用默认规则):

reg_import.png

很明显,此劫持方式很有效,因为HKCU中的CLSID值优先于HKLM中的CLSID值(*感谢@KyleHanslovan提醒!)。

现在,让我们运行以下rundll32.exe命令来调用有影响力的COM CLSID并执行Jscript代码:

rundll32.exe -sta {00000001-0000-0000-0000-0000FEEDACDC}

rundll32_sta (1).png

更新:

在与@PhilipTsukerman讨论有关引导和加载COM类的其他方法之后,有一点值得注意,如果有相应的键值,ProgID可以调用该命令。在这种情况下,“scripting.dictionary”会被劫持,所以下面的命令也有效:

rundll32.exe -sta "scripting.dictionary"

progid_rundll32.png

防御需要考虑的因素

1.供应商应在卸载实用程序软件时删除(例如取消注册)COM注册表配置项(和磁盘文件)。此外,供应商不应创建一个指向不存在的二进制文件的CLSID二进制路径注册表键值。

2.网络防御者应该监视一些可疑的主机活动,尤其是对于rundll32.exe的使用。 请注意,'sta'开关可以使用后缀(例如'stagggg'或'stagggggggggggggggggg')与CLSID一起成功调用。

3.企业组织应实施强大的应用程序白名单(AWL)策略并且需要比默认规则更未严格。

结论

感谢你抽出宝贵时间阅读这篇文章!我希望对于相关主题的后续内容能有更有深度的探讨!

源链接

Hacking more

...