0x1 前言

DLL劫持,老生长谈的技术了,虽然老但至今仍旧有效,前两天看的一个APT攻击样本分析,攻击入口用的就是搜狗输入法的一个DLL劫持,最近回顾了这项技术,想写篇博客记录,没有什么新的技术

0x2 劫持原理

Windows下开发大型应用程序,出于代码复用和模块化的意图,都会将功能拆分成一个个dll,结果就是安装目录下有exe和大量dll(包括Windows操作系统本身也是这个思想),当exe想要执行dll的时候,采用的搜索顺序是:

  1. 进程对应的应用程序所在的目录
  2. 进程执行所在的目录
  3. C:\Windows\System32目录
  4. 16位Windows系统的系统目录(早期Windows系统的系统目录)
  5. C:\Windows目录
  6. Path环境变量中各个目录

自Windows XP SP2开始,默认启用安全机制SafeDllSearchMode,开关位于注册表项:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode,启用这个安全机制后,搜索顺序变为:

  1. 进程对应的应用程序所在的目录
  2. C:\Windows\System32目录
  3. 16位Windows系统的系统目录(早期Windows系统的系统目录)
  4. C:\Windows目录
  5. 进程执行所在的目录
  6. Path环境变量中各个目录

然而,自Windows 7开始,SafeDllSearchMode的机制保留了下来,但不再有注册表项SafeDllSearchMode,同时一个叫KnownDLLs的机制进一步加强,它位于注册表项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs,它的作用是,位于KnownDLLs中的dll(都是系统dll)优先从系统目录C:\Windows\System32中加载,忽略进程对应的应用程序所在的目录,以此来防范dll劫持

image

需要注意,如果要劫持的dll在内存中已存在,则不会再搜索dll,而是使用内存中的dll,所以我们要挖掘dll劫持,只需要将黑dll放置在优于白dll的上述搜索位置,且劫持的dll不能是KnownDLLs中的dll即可

0x3 劫持实现

实现方式通常分为2种,如果你找到一个可以被劫持的dll,将白exe和要劫持的dll拷贝出来,运行白exe不报错,那只需要通过pe-bear获取被劫持dll的导出函数,然后在导出函数中实现恶意代码即可,但如果将白exe和要劫持的dll拷贝出来后,运行白exe报错,就表示白exe需要被劫持dll中的函数的功能,这个时候就需要函数转发,实现也不难,下面展示了将导出函数beNotified转发给原始dll original-NppExport.dll中的导出函数beNotified,并指定序号为1

1
#pragma comment(linker, "/EXPORT:beNotified=original-NppExport.beNotified,@1")

项目HijackLibs会发布一些新的可被劫持的dll和exe,可以参考,https://hijacklibs.net/

0x4 防御策略

目前在初始阶段除了校验dll的数字签名好像没有更好的方式,在后续阶段的检测就是对dll的导出函数、API行为、内存特征的检测了

0x5 参考链接

https://print3m.github.io/blog/dll-sideloading-for-initial-access