修复DLL劫持的问题
因为最后面DLL劫持的修复方法水了篇文章
DLL劫持
对于DLL劫持简单来说既是:
DLL劫持是一种通过利用某些 Windows 应用程序搜索和加载动态链接库 (DLL) 的方式将恶意代码注入应用程序的方法。
现在DLL加载最常见的搜索顺序如下:
- The directory from which the application loaded.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The current directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
-- microsoft docs
具体加载顺序可以参考这里
所以将某些系统的DLL放置在可执行文件的同目录, 则会优先于原本需要加载的系统DLL搜索并加载.
系统缓解措施
大致分为三个阶段
在win xp sp2及以下
远古时期, 无缓解措施
在win7之前
添加了SafeDLLSearchMode
注册表,将进程中%cd%
这一当前目录的搜索优先级降级了. 本来是紧跟当前可执行文件所在目录后搜索, 如今变为了倒数第二位, 即%PATH%
之前搜索
如今
在NT命名空间中存储了KnownDLLs
这一列表, 其中所有的内容都仅能从%SystemRoot%\SYSTEM32
这一目录下搜索
该项可使用winobj查看, 或者在注册表中查看HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
的值作为参考
但是也有问题, 即KnownDLLs
项并不完整, 有些系统库反而不在该列表中. 如msimg32.DLL
,Version.DLL
等等
修复
分动态加载与静态加载两种情况. 以下所有方法绝大多数均需要修改源码, 唯一一个不需要源码的可以是manifest
的方法, 但是该方法需要patch相关的pe文件.
动态加载的修复
有多种方法
绝对路径加载
一目了然, 不言而喻.
1 | LoadLibraryA("/path/to/library.DLL"); |
设置搜索路径
使用SetDLLDirectory
函数设置一个路径, 若传入路径为空, 则在DLL搜索路径中删去进程中%cd%
这一当前目录.
实际上效果较低.
1 | SetDLLDirectory("") |
hash校验
在装载DLL前, 先对文件的hash进行校验, 确认文件未被修改.
使用函数设置搜索行为
使用SetDefaultDLLDirectories
函数来设置默认的行为, 其中若使用LOAD_LIBRARY_SEARCH_SYSTEM32这一参数, 则只搜索%SystemRoot%\SYSTEM32
这一目录.
1 | SetDefaultDLLDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32) |
使用函数加载DLL
低版本不支持此函数, 该函数的flag可指定仅搜索%SystemRoot%\SYSTEM32
这一目录.
1 | LoadLibraryEx("system_library.DLL", 0, LOAD_LIBRARY_SEARCH_SYSTEM32) |
导入表加载
搜索后得知也有多种方法, 已经在多个开源项目中使用. 这也是水这篇文章的原因. 😀
嵌入manifest文件
在exe嵌入的manifest文件中设置文件的路径. 这个仅作为记录, 未测试.
该项唯一可在github上参考的是这个链接, 看来对非csharp编写可执行文件的也起作用.
1 |
|
延迟加载
编辑link.exe的链接参数, 将所需DLL改为以参数/DELAYLOAD
的形式链接.
同时在代码初始化的地方设置SetDefaultDLLDirectories
, 这样延迟加载的DLL亦会收到前面所述函数的影响.
这里是某软件编译时使用延迟加载的方式去链接DLL
这里是同一软件初始化时使用SetDefaultDLLDirectories
函数来设置DLL装载搜索路径默认的行为
参考资料
desktop-app/lib_base: Different useful utilities. (github.com)
Windows DLL Hijacking (Hopefully) Clarified | itm4n’s blog
Dynamic-Link Library Search Order - Win32 apps | Microsoft Docs
Windows: Add explicit manifest to Windows build · Issue #2326 · curl/curl (github.com)