一、概述

当WindowsSide-by-Side(WinSxS)清单未明确说明程序正在加载的DLL的特征时,就会发生动态链接库(DLL)的侧加载。更简单地解释说,DLL侧加载可以使攻击者诱导程序加载恶意DLL。如果各位读者想了解有关DLL侧加载的工作原理,以及关于此类型攻击的更多信息,可以阅读我们发布的白皮书。

当攻击者能够利用Windows搜索和加载顺序,从而允许执行恶意DLL而非合法DLL时,就会发生DLL劫持的情况。

DLL侧加载和劫持的情况已经存在了多年。实际上,FireEyeMandiant最早在2010年就发现了DLL侧加载技术和DLL搜索顺序劫持。时至今日,该技术仍然是一种可行的方法,并且已经在现实世界的入侵攻击中利用。在应急响应期间,FireEyeMandiant仍然使用DLL滥用技术来识别和观察威胁参与者。目前,仍然有许多经过签名的可执行文件容易受到此攻击,我们的红方团队已经将DLL滥用技术武器化我们攻击方案的一部分。有关DLL滥用技术的检测和预防措施,我们将在后面详细说明。

目前,DLL滥用技术已经不再是新型或前沿的技术,本文将展示FireEyeMandiant红方团队如何使用FireEyeIntelligence来加速大规模确定易受攻击的可执行文件的研究工作。我们还会介绍如何发现存在DLL滥用风险的可执行文件,以及FireEyeMandiant红方团队如何在其DueDLLigence工具中将这些DLL滥用技术武器化。DueDLLigence工具最初是作为应用程序白名单绕过的框架发布的,但是考虑到其不受管理的导出的特点,它也可以用于DLL滥用技术之中。

二、收集和武器化FireEye情报

FireEyeMandiant红方团队成员的一大优势在于可以获得大量的威胁情报。在过去的十年中,我们在应急响应和情报分析过程中已经观察、记录和分析了攻击者几乎在所有严重漏洞利用中的行为。对于此项目,FireEyeMandiant红方团队要求FireEye技术运营和逆向工程高级实践团队利用FireEyeIntelligence,为我们提供攻击者利用的下述DLL滥用技术:

1、使用独立的PE文件(.exe文件)来调用恶意DLL;

2、.exe必须具有签名,并且证书在一年之内有效;

3、有关该技术的情报必须包含被调用的恶意DLL的名称。

在将结果提供给红方团队后,我们开始利用文章中描述的方法来实现武器化,具体包括:

1、识别容易受到DLL搜索顺序劫持的可执行文件;

2、识别可执行文件的库依赖关系;

3、确保API被正确导出。

2.1DLL搜索顺序劫持

在很多情况下,可以利用不安全的库引用,在合法的可移植可执行文件(PE)的上下文中执行代码。如果开发人员允许LoadLibrary动态解析库的路径,那么该PE还会在当前目录中查找库DLL。通过将合法的PE复制到该攻击者具有写入权限的目录中,就可以将这种行为用于恶意目的。如果攻击者创建了自定义的PayloadDLL,则应用程序将加载该DLL并执行攻击者的代码。这对于红方团队来说可能是有帮助的——此时的PE可能已经经过签名,这样会获得终端安全解决方案(AV/EDR)的信任,从而绕过应用程序白名单(AWL),并且可能会使调查过程出现混淆或阻碍。

在本节中,我们将看到一个示例,其中我们确定了劫持PE的条件,并在我们的PayloadDLL中满足了要求。针对这个测试用例,我们将使用有签名的二进制PotPlayerMini(MD5:f16903b2ff82689404f7d0820f461e5d)。之所以选择这个PE,原因在于攻击者在2016年曾经使用过它。

2.2识别库依赖

通过使用IDA或Ghidra之类的工具进行静态分析,我们可以确定PE需要哪些库和导出。例如,下图所示的屏幕截图显示了PotPlayerMini尝试加载名为"PotPlayer.dll"的DLL。

PotPlayerMini加载的DLL的静态分析:

在无法进行静态分析,或者不适合进行静态分析的地方,可以使用挂钩的框架(例如:APIMonitor或Frida)来分析应用程序的LoadLibrary/GetProcAddress行为。

在下图中,我们使用APIMonitor查看了相同的DLL加载行为。如我们所见,PotPlayerMini在其所在目录中查找PotPlayer.dll文件。至此,我们已经验证PotPlayerMini容易受到DLL搜索顺序劫持的影响。

PotPlayerMini加载的DLL的动态分析:

2.3满足导出要求

在确定潜在易受攻击的库模块之后,我们需要使用类似的方法来确定需要从模块PE导出哪些内容。下图展现了PotPlayerMini的反编译视图,其中突出展现了利用静态分析的方法,在GetProcAddress函数中寻找导出文件。下图展示了在PotPlayerMini应用程序中对导出进行相同的分析,但在这里使用了动态分析的方法。

PotPlayerMiniDLL中导出的静态分析:

PotPlayerMiniDLL中导出的动态分析:

在我们的示例中,Payload是使用UnmanagedExports的.NETDLL,因此我们必须满足二进制文件中的所有导出要求,如下图所示。原因在于,.NETUnmanagedExports库不支持DllMain,因为这是一个入口点,并且不会被导出。我们需要满足所有导出要求,以确保DLL具有导出的所有函数,程序可以通过GetProcAddress或导入地址表(IAT)访问这些函数。这些导出方法将与静态分析或动态分析中观察到的方法匹配。在此过程中,可能需要一些尝试,并且可能会出现一些错误,具体取决于二进制文件中的验证。

在.NETDLL中添加导出要求:

执行完二进制文件之后,我们可以看到它成功执行了我们的函数,如下图所示。

执行存在DLL滥用漏洞的二进制文件:

2.4未满足所有导出要求的DLL劫持

在C/C++中编写PayloadDLL时,可以劫持DllMain中的控制流。如果选择这种方式,就没有必要枚举并满足所有需要的导出。在某些情况下,DLL没有任何导出,只能通过DllMain入口点进行劫持。

可以使用WindowsMediaPlayer文件夹共享可执行文件wmpshare.exe来展示这个示例。我们可以将可执行文件复制到原始位置(C:ProgramFiles(x86)WindowsMediaPlayer)之外的目录中,并使用APIMonitor执行动态分析。在下图中,我们可以看到wmpshare.exe程序使用LoadLibraryW方法来加载wmp.dll文件,但未指定DLL的显式路径。发生这种功能情况时,LoadLibraryW方法将首先搜索在其中创建进程的目录(当前工作目录)。可以在LoadLibraryW文档和CreateProcess文档中找到有关使用搜索顺序的详细信息。

在wmpshare.exe中查看LoadLibrary调用:

由于它没有指定显式路径,因此可以通过创建一个名为"wmp.dll"的空白文件,并将其复制到与wmpshare.exe文件相同的目录中,来测试它是否容易受到DLL劫持的影响。现在,在APIMonitor中运行wmpshare可执行文件时,我们可以看到它首先在其所在目录中检查了wmp.dll文件,如下图所示。因此,可以使用这个二进制文件进行DLL劫持。

在存在虚拟dll的wmpshare.exe中查看LoadLibrary调用:

下图展示了以武器化方式,利用wmpshare可执行文件来使用C++创建的DLL利用DllMain入口点。

使用DllMain入口点:

三、发现存在DLL滥用漏洞的新可执行文件

除了将攻击者进行DLL滥用的可执行文件加入到FireEyeIntelligence之外,FireEyeMandiant红方团队还进行了研究,我们以Windows系统实用程序和第三方应用程序为目标,发现了容易被滥用的新可执行文件。

3.1Windows系统实用程序

FireEyeMandiant红方团队使用在上一章中描述的方法,来查看在C:WindowsSystem32目录中存在的容易受到DLL滥用技术影响的Windows系统实用程序。我们最终找到了一个系统实用程序——部署映像服务和管理(DISM)实用程序(Dism.exe)。在对该系统实用程序进行动态分析时,观察到它正在尝试在当前目录中加载DismCore.dll文件,如下图所示。

执行Dism实用程序的动态分析:

接下来,我们从其正常路径(C:WindowsSystem32)将DISM系统实用程序加载到APIMonitor中,以查看所需的导出,如下图所示。

DismCore.dll需要的导出:

下图中展示的代码已经添加到DueDLLigence中,以验证DLL是否易受攻击,以及是否可以使用DISM系统实用程序成功运行。

Dism导出方法已经添加到DueDLLigence:

3.2第三方应用程序

FireEyeMandiant红方团队还针对可能与DLL滥用有关的常见第三方应用程序相关的可执行文件进行分析。我们发现的一个可执行文件时TortoiseSVN实用程序(SubWCRev.exe)。在对该TortoiseSVN实用程序进行动态分析时,发现它会尝试在当前目录中加载crshhndl.dll。导出方法如下图所示。

执行SubWCRev.exe的动态分析:

下图中展示的代码已经添加到DueDLLigence中,以验证以验证DLL是否易受攻击,以及是否可以使用TortoiseSVN实用程序成功运行。

SubWCRev.exe导出方法已经添加到DueDLLigence:

四、红方团队的实际应用

在拥有独立的、受信任的可执行文件后,红方团队就可以将受信任的可执行文件和恶意DLL复制到受害计算机中,并绕过各种基于主机的安全控制,包括应用程序白名单。一旦受信任的可执行文件(容易受到DLL滥用)和恶意DLL都位于同一工作目录中,可执行文件便可以在相同目录中调用相应的DLL。这个方法可以在攻击生命周期的多个阶段中用于Payload植入,包括建立持久性阶段和横向移动阶段。

4.1建立持久性

在我们的示例中,我们将使用在"Windows系统实用程序"一节中找到的Windows系统实用程序Dism.exe作为可执行文件,并使用DueDLLigence与SharPersist共同生成的DLL,在目标系统上建立持久性。首先,将DISM系统实用程序和恶意DLL上传到目标系统,如下图所示。

上传Payload文件:

然后,我们使用SharPersist添加启动文件夹持久性,这里要使用到我们的DISM系统实用程序和关联的DLL,如下图所示。

将SharPersist添加到启动文件夹中以创建持久性:

在目标计算机重新启动,并且目标用户完成登录之后,下图显示了我们的CobaltStrikeC2服务器已经能够看到客户端上线,从而证明已经借助Dism.exe进程建立了持久性。

成功的持久化回调:

4.2横向移动

我们将继续使用相同的DISM系统实用程序和DLL文件进行横向移动。在这个示例中,HOGWARTSadumbledore用户具有对远程主机192.168.1.101的管理员访问权限。我们通过SMB协议,将DISM系统实用程序和关联的DLL文件传输到远程主机,如下图所示。

通过SMB将Payload文件传输到远程主机:

然后,我们在初始信标中设置一个SOCKS代理,然后使用Impacket的wmiexec.py通过WindowsManagementInstrumentation(WMI)协议执行Payload,如下图所示。

使用Impacket的wmiexec.py通过WMI执行Payload:

proxychainspythonwmiexec.py-nooutputDOMAIN/user:password:@x.x.x.xC:\Temp\Dism.exe

执行命令的输出结果:

通过WMI执行DISM系统实用程序后,我们从远程主机收到一个信标,如下图所示。

在远程主机上获取到信标:

五、检测和防范措施

在白皮书中,详细介绍了DLL侧加载的详细防范和检测方法,并且我们也在DLL滥用技术的概述中略有提及。在白皮书中,分为针对软件开发者的预防措施和针对终端用户的建议。白皮书中还存在没有提到的一些检测方法,具体包括:

1、检查网络连接异常的进程:如果我们已经建立了正常进程网络通信活动的基线,那么在发现特定进程的网络活动明显不同于基线时,证明该进程可能受到了攻击。

2、DLL白名单:跟踪系统上使用的DLL的哈希值,以发现潜在的差异。

这些检测方法难以大规模实施,但在理论上可以利用。而这也正是这种旧技术时至今日仍然有效,并且还在被红方团队和恶意组织利用的原因。之所以这些漏洞持续存在,实质上是与软件发行商有关。软件发布者需要了解DLL滥用技术,并掌握如何在开发的产品中规避此类漏洞风险(例如:应用白皮书中所讨论的缓解措施)。在实施这些建议后,可以减少攻击者绕过现代化检测技术的DLL滥用行为的可能性。

Microsoft提供了一些有关DLL安全性和针对DLL劫持漏洞进行分类的重要资源。

六、总结

将威胁情报应用到攻防研究中,并使用攻击者真实利用的攻击方式开展红蓝对抗,无疑为红方团队成员贡献了巨大的价值。通过跟踪真实攻击者的动向,红方团队可以得到关于武器库和TTP方面的灵感。

从防御的角度来看,在攻击生命周期的多个阶段(例如:持久性和横向移动),DLL滥用技术可能会有所帮助。我们后续将持续监测更多DLL滥用造成的影响,以及可以被专业安全人员和攻击者利用的可执行文件。

相关文章