dll劫持
dll介绍即作用
动态链接库(英语:Dynamic-link library,缩写为DLL)是微软公司在 Windows 操作系统中实现共享函数库概念的一种实现方式。这些库函数的扩展名是.DLL
、.OCX
(包含ActiveX控制的库)或者.DRV
(旧式的系统驱动程序)。
所谓动态链接,就是把一些经常会共享的代码(静态链接的OBJ程序库)制作成DLL档,当可执行文件调用到DLL档内的函数时,Windows操作系统才会把DLL档加载存储器内,DLL档本身的结构就是可执行档,当程序有需求时函数才进行链接。通过动态链接方式,存储器浪费的情形将可大幅降低。静态链接库则是直接链接到可执行文件。
DLL的文件格式与视窗EXE文件一样——也就是说,等同于32位视窗的可移植执行文件(PE)和16位视窗的New Executable(NE)。作为EXE格式,DLL可以包括源代码、数据 “数据 (计算机)”)和资源 “资源 (Windows)”)的多种组合。
在更广泛的意义上说,任何同样文件格式的电脑文件都可以称作资源DLL。这样的DLL的例子有扩展名为ICL
的图标库、扩展名为FON
和FOT
的字体文件。
作用
DLL动态链接库,是程序进行动态链接时加载的库函数。
故动态链接最直接的好处是磁盘和内存的消耗减少,这也是dll最初的目的。
不过,dll也有缺点,就是容易造成版本冲突,比如不同的应用程序共享同一个dll,而它们需求的是不同的版本,这就会出现矛盾,解决办法是把不同版本的dll放在不同的文件夹中。
dll劫持原理
劫持DLL(又称为DLL劫持、DLL搜索顺序劫持或二进制植入)是一种攻击技术,如果在进程尝试加载一个DLL时没有并没有指定DLL的绝对路径,那么Windows会尝试去按照顺序搜索这些特定目录来查找这个DLL,,如果攻击者能够将恶意的DLL放在优先于正常DLL所在的目录,那么就能够欺骗系统去加载恶意的DLL(利用Windows操作系统在加载DLL(动态链接库)时的搜索顺序漏洞,使得恶意DLL被误加载到受害进程中。)这种攻击方法可以让攻击者在受害进程的上下文中执行任意代码。
当一个应用程序需要加载DLL时,Windows系统会按照特定的顺序搜索DLL。搜索顺序通常如下:
- 应用程序的目录。
- 系统目录(如System32)。
- 16位系统目录。
- Windows目录。
- 当前工作目录。
- 环境变量
PATH
中列出的目录。
劫持目的:
- 常见的白加黑,利用可信任的(最好被微软签名过)可执行程序加载恶意 DLL
- 劫持目标操作系统中已预先安装并且会定期运行的软件所需加载的 DLL
- 如果目标应用程序正以高权限运行,劫持后的恶意代码也会以相应的权限执行
dl劫持方法
- 用恶意的DLL替换掉合法的DLL,可以将其与dll代理( DLL Proxying )结合使用,以确保原DLL的所有功能均保持不变。
- 当应用程序加载DLL的时候,如果没有带指定DLL的路径,那么程序将会以特定的顺序依次在指定的路径下搜索待加载的DLL。通过将恶意DLL放在真实DLL之前的搜索位置,就可以劫持搜索顺序,劫持的目录有时候包括目标应用程序的工作目录。
- 释放一个恶意 DLL 来代替丢失的或者不存在的 要被合法应用程序加载的DLL。
- 更改DLL搜索的路径,比如通过编辑 %PATH% 环境变量或 .exe.manifest/.exe.local文件以将搜索路径定位到包含恶意DLL的地方。
- 将目标DLL相关的WinSxS文件夹中的合法的DLL替换为恶意DLL。
- 将合法的应用程序复制(并有选择地重命名)与恶意的DLL一起放入到用户可写的文件夹中。在使用方法上,它与(带签名的)二进制代理执行 有相似之处。它的一个变体是(有点矛盾地称为)“bring your own LOLbin”,其中合法的应用程序带有恶意的DLL(而不是从受害者机器上的合法位置复制)。
dll劫持测试
环境:Windows11、vs2022、ChkDllHijack ,AheadLib+、Process Monitor 或者ProcessExplorer、qq音乐
ChkDllHijack是一款自动化验证dll劫持注入漏洞工具,相同可替换工具也有很多,可以在github中找到
AheadLib是一款自动化dll劫持代码生成工具,由于原版仅支持x86,这里使用看雪大神的AheadLib+改版,更新了x64支持类/命名空间。
Process Monitor:负责监控可执行程序运行时系统调用加载的dll链接库
vs2022 c++实现dll创建和调用
文件创建
使用vs2022的c++dll模板创建一个文件,其中模板信息如下;
1 | // dllmain.cpp : 定义 DLL 应用程序的入口点。 |
新建一个头文件以及源文件
头文件的代码如下:
1 |
|
源文件如下:
1 | // MathLibrary.cpp : 定义 DLL 的导出函数 |
之后接着选择 生成->生成解决方案
生成之后,你可以在x64这个文件夹下找到生成的dll和lib文件
隐式调用Dll
重新创建一个c++的空项目或者控制台应用
然后生成一个源文件,代码如下:
1 | // MathClient.cpp : Client app for MathLibrary DLL. |
然后生成,不出意外会显示这个
只需要去刚才生成的dll文件下,把 .dll和.lib文件拷贝到当前文件下就可以了
再次运行
1 | import re |
打开ProcessExplorer查看qq音乐的进程和dll调用情况
CTRL+s保存成txt文件,使用正则脚本,将txt文件的内容简化成纯路径文件
1 | import re |
生成文件如下
打开ChkDllHijack,将路径粘贴进去,点击验证
得到
说明C:\Windows\SysWOW64\d2d1.dll
这个dll文件可以进行dll劫持
SysWOW64是Windows为了让用户在x64系统环境下一样能够运行x86程序而创建一个子系统。该文件夹下存放的都是32位应用程序。所以使
用的是AheadLib.exe来导出.cpp文件。以及在后面编译的时候也选择Release或者Debug X86环境,否则编译出来运行将会导致cobalt strike不
上线。
打开AheadLib,将那个dll拖入
生成的cpp文件就是转发操作,以及将原dll名改为d2d1Org
在vs新建一个dll项目
其中dllmain.cpp如下写:
1 | // dllmain.cpp : 定义 DLL 应用程序的入口点。 |
无非就是将刚才AheadLib生成的代码赋值过来之后,加上了shellcode(这个shellcode需要使用x86的
framework.h文件如下:
1 |
|
其他文件不变,生成dll文件
然后将这个dll文件重命名为d2d1.dll然后将之前的dll重命名为d2d1Org.dll,然后将两个文件一个复制一份到QQ music的根目录下
运行qq音乐发现cs成功上线
这里可能是转发生成有点问题,所以导致qq音乐这个地方运行有点问题
对此发现这个dll调用频率不是很高所以将转发注释之后,测试,发现效果更好(只适用于这里
1 | // dllmain.cpp : 定义 DLL 应用程序的入口点。 |
防御方法
1.使用完整路径加载 DLL
- 明确指定路径: 在代码中使用 DLL 的完整路径,避免使用不明确的相对路径或环境变量。
2. 使用安全的 DLL 加载函数
-
LoadLibraryEx
函数: 使用LoadLibraryEx
的LOAD_LIBRARY_AS_DATAFILE
选项,可以防止加载同名 DLL。
3. 控制 DLL 的搜索路径
- 设置 DLL 搜索路径: 调用
SetDllDirectory
来指定有效的 DLL 搜索路径,限制可加载的 DLL 来源。
4. 使用 Windows 保护机制
- 启用 Windows Defender: 确保 Windows Defender 或其他安全软件在运行,以监控和拦截可疑活动。
- 使用数字签名: 对 DLL 和可执行文件进行数字签名,确保文件的来源可信。
5. 应用程序清单
- 使用应用程序清单: 通过清单文件配置安全特性,指定使用哪些库,确保优先加载特定版本的 DLL。
6. 代码审计和监控
- 定期代码审计: 检查代码中潜在的 DLL 加载风险并进行必要的修复。
- 监控 DLL 加载活动: 使用监控工具检测和记录 DLL 加载,快速响应可疑行为。
7. 最小化用户权限
- 限制应用程序权限:以最小权限原则运行应用程序,减少脚本和应用程序能访问的资源。
8. 采取安全编程实践
- 输入验证与输出编码: 确保程序安全,防止注入和其他攻击,减少被劫持的机会。
白加黑介绍和原理
白加黑是一种利用 DLL 劫持技术来绕过安全软件的主动防御,以达到加载恶意程序的目的。通过劫持合法程序的DLL文件,将恶意代码嵌入其中,使得恶意程序能够在不被安全软件检测到的情况下运行。
白名单程序一般是指有正规签名的程序只要有正规签名的程序一般都或多或少都有一定的白名单权限,权限有大有小,具体看该程序相对于杀软来说的重要程度,该程序越重要白名单权限越高。部分程序即便有正规签名也会被杀软重点监控如有微软签名的 Procdump。
- Exe(白) —load—> dll(黑)
- Exe(白) —load—> dll(黑)—load—> 恶意代码
补充:
dll劫持产生条件:
- 不再’HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs’注册表中
- 其dll是EXE程序首先加载的DLL,而不是依赖其他DLL加载的。
- DLL确实被加载进内存中
判断dll是否可以劫持:
手动方法:
利用进程查看软件,查看dll是否存KnownDlls注册表中。
自动审计方法:即上面测试所采用的工具和方法