安全加载库:利用LoadLibraryEx API防范DLL劫持攻击

本文详细探讨了Windows系统中动态加载库的安全风险,介绍了LoadLibraryEx API的安全使用方式、DLL搜索顺序控制方法,以及如何通过数据文件加载和AppLocker策略防范DLL劫持攻击。

安全加载库 | MSRC博客

动态加载库到应用程序中如果未正确保护可能导致漏洞。在本博客文章中,我们讨论使用LoadLibraryEx() API加载库,并利用其选项确保安全。

了解默认设置

传递给LoadLibrary() / LoadLibraryEx()调用的库文件名不需要包含扩展名。如果未指定扩展名,则使用默认库文件扩展名.DLL。由于此特性,如果传递null作为库名称,它会尝试加载“.DLL”,这可能被通过在搜索路径中放置“.DLL”文件来利用。

传递给LoadLibrary()/ LoadLibraryEx()调用的库文件名不需要指定目录路径。如果指定了路径,则仅从指定路径加载库。否则,使用以下默认DLL搜索顺序:

  1. 当前进程映像文件目录,应用程序目录
  2. 系统目录
  3. 16位系统目录
  4. Windows目录
  5. 当前工作目录
  6. PATH环境变量中列出的目录

Windows维护一个已知DLL列表,这些基本上是系统DLL集合,当指定绝对名称时,始终保证从系统目录加载。

加载库到内存后,会调用已加载库中的DllMain()函数。

控制DLL搜索顺序

有多种选项可以修改加载库时的搜索顺序,与提供绝对名称时的默认搜索顺序不同。

以下是一些可以通过LoadLibraryEx()影响DLL搜索顺序/路径的API:

  • SetDllDirectory():将目录添加到用于定位应用程序DLL的搜索路径中
  • SetDefaultDllDirectories():将目录添加到进程DLL搜索路径
  • AddDllDirectory():将目录添加到进程DLL搜索路径
  • RemoveDllDirectory():移除通过AddDllDirectory()添加到进程DLL搜索路径的目录
  • SearchPath():在指定路径中搜索指定文件
  • SetSearchPathMode():设置SearchPath()函数在定位文件时使用的每进程模式
  • SetCurrentDirectory():更改当前进程的当前目录
  • DefaultDllImportSearchPathsAttribute:对于托管应用程序,使用此属性指定平台调用期间搜索DLL的路径

LoadLibraryEx()提供了许多可用于更改默认搜索顺序的标志。下表列出了大多数标志,并描述了每个标志遵循的DLL搜索顺序。某些选项甚至考虑了使用上述API设置的路径。

以非可执行方式加载库

并不总是需要将库作为可执行映像加载。LoadLibraryEx()可以使其作为数据文件或图像资源加载。为此,它支持以下不同选项:

  • LOAD_LIBRARY_AS_DATAFILE
  • LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
  • LOAD_LIBRARY_AS_IMAGE_RESOURCE
  • DONT_RESOLVE_DLL_REFERENCES

这些选项有助于将文件视为普通数据文件而不是可执行模块。使用此选项加载不会调用DLLMain(),并且加载的DLL数据的内存空间都不会标记为可执行。

阻止库加载

有时可能需要阻止库或非法库加载到应用程序中。查看以下设施来帮助实现:

AppLocker

AppLocker是一种基于策略的机制,用于阻止DLL加载到应用程序中。这些策略可以通过组策略推送。AppLocker可以控制可执行文件、脚本和安装程序。

当新DLL加载时,会向AppLocker发送通知以验证是否允许加载该DLL。AppLocker调用应用程序标识组件来计算文件属性。它复制现有的进程令牌,并用加载的DLL的属性替换复制的令牌中的那些应用程序标识属性。AppLocker然后评估此DLL的策略,并丢弃复制的令牌。根据此检查的结果,系统要么继续加载DLL,要么停止进程。

AppLocker可以根据路径、发布者或文件哈希阻止DLL。

代码签名

Microsoft Authenticode技术可用于对DLL进行签名,即将数字签名附加到DLL以保证其真实性和完整性。

总结讨论

为确保安全加载库:

  • 使用适当的DLL搜索顺序
  • 当库位置固定时,始终指定完全限定路径
  • 需要时作为数据文件加载
  • 利用代码签名基础设施或AppLocker

我们常见的一些攻击向量:

  • 应用程序目录攻击,特别是从临时互联网或下载文件夹的角度。特别是当应用程序是安装程序时,人们通常会将安装程序下载到默认目录并从那里执行。考虑到攻击者可以在默认目录中放置恶意文件,可以利用应用程序目录加载DLL。在这种情况下也可以使用清单和.local重定向。

  • 从内存加载DLL以及PowerShell DLL注入。恶意软件可以使用这些方法来避免检测恶意DLL的加载。

  • 从远程位置加载库时的TOCTOU攻击。

  • Swamy Shivaganga Nagaraju,MSRC工程团队

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计