DLL劫持
0x1 前言
DLL劫持,老生长谈的技术了,虽然老但至今仍旧有效,前两天看的一个APT攻击样本分析,攻击入口用的就是搜狗输入法的一个DLL劫持,最近回顾了这项技术,想写篇博客记录,没有什么新的技术
0x2 劫持原理
Windows下开发大型应用程序,出于代码复用和模块化的意图,都会将功能拆分成一个个dll,结果就是安装目录下有exe和大量dll(包括Windows操作系统本身也是这个思想),当exe想要执行dll的时候,采用的搜索顺序是:
- 进程对应的应用程序所在的目录
- 进程执行所在的目录
- C:\Windows\System32目录
- 16位Windows系统的系统目录(早期Windows系统的系统目录)
- C:\Windows目录
- Path环境变量中各个目录
自Windows XP SP2开始,默认启用安全机制SafeDllSearchMode,开关位于注册表项:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode,启用这个安全机制后,搜索顺序变为:
- 进程对应的应用程序所在的目录
- C:\Windows\System32目录
- 16位Windows系统的系统目录(早期Windows系统的系统目录)
- C:\Windows目录
- 进程执行所在的目录
- Path环境变量中各个目录
然而,自Windows 7开始,SafeDllSearchMode的机制保留了下来,但不再有注册表项SafeDllSearchMode,同时一个叫KnownDLLs的机制进一步加强,它位于注册表项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs,它的作用是,位于KnownDLLs中的dll(都是系统dll)优先从系统目录C:\Windows\System32中加载,忽略进程对应的应用程序所在的目录,以此来防范dll劫持

需要注意,如果要劫持的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
