利用dll劫持实现免杀与维权
根据软件工程高内聚低耦合的思想,把程序要重复使用的代码封装成函数/类方法,将软件要重复使用的程序封装成链接库。库分为静态链接库和动态链接库,静态链接库顾名思义就是在程序链接阶段打包进文件中,而动态链接库则是在程序运行时再导入调用。动态链接库有着加载时复用节省内存、补丁更新时可符合开闭原则等优点,也有容易发生版本冲突、容易被劫持等缺点。Windows平台下的动态链接库常为dll文件,linux则常为so文件。
dll劫持概念与类型
dll劫持就是要想方设法地调用到恶意dll。为了便于理解,需要了解一下目前Windows默认的dll调用顺序:
Known DLL
特指 定义在HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
中且只能在System目录中加载的dll们
由此可以引出几种dll劫持的形式:
直接将恶意dll暴力替换掉正常dll,软件正常功能会受影响
将恶意dll作为中间人,转发调用正常dll的导出函数,同时加入额外的恶意操作
利用加载顺序的机制,让恶意dll先于正常dll加载
利用软件本身缺失的dll加载恶意dll
更改环境变量或是.exe.manifest/.exe.local文件实现dll重定向
- 如果利用低权限劫持的dll文件,会被高权限程序加载运行,就是一个权限提升漏洞
找dll劫持的一种方法
通过 Process Monitor 监控dll调用是一种最基础的寻找dll劫持的方式,在filter中添加Path ends with .dll
和Result is NAME NOT FOUND
规则,并且可以加上Process Name contains xxx
来针对性的找xxx的dll劫持。
编写一个加载dll的demo,让它加载一个不存在的dll,可以监控到加载的路径顺序(请无视中文路径乱码Orz)。如果这是一个真实的常用软件,则可以用来实现上文中的第4种劫持。
1 |
|
劫持notepad++的dll
下面以notepad++为例,实现上文中的第2种劫持,这类dll转发利用#pragma comment(linker, "/EXPORT:xxx,@y)
可以很方便地实现。
出于免杀上线以及权限维持的考虑,我们物色一下尽量符合这些特点的dll:
后台进程稳定不挂,避免主进程退出导致dll一起挂了
容易触发上线,行为隐蔽不易被杀软和人工发现
然后我看到了会被 updater/GUP.exe
拉起的 libcurl.dll
,以及安装版中存在且可方便地附加到绿色版中的 NppShell_06.dll
。前者是一个软件更新组件,后者是Windows右键中Edit with Notepad++
的组件,会随explorer.exe加载且不会重复执行,只要在文件上按右键就会触发(并不需要点击它,看到时就已经加载了dll):
由于 GUP.exe
容易退出,需要让它加到常驻服务里去,我们优先看看 NppShell_06.dll
。这是一个会随安装包的Context Menu Enty
选项一起安装到软件目录的dll,通过 Process Monitor 监控并筛选注册表,发现有如下变动:
1 | [HKEY_CLASSES_ROOT\CLSID\{B298D29A-A6ED-11DE-BA8C-A68E55D89593}] |
也就是说只需要将安装文件中的 NppShell_06.dll
拷贝到绿色版文件中,并将上述变动导入注册表就可以手动实现添加右键打开的功能,不过该操作需要管理员权限。
regedit /s nppi.reg
构造了还不错的触发条件后,接下来将原dll更名为 NppShell_05.dll
、找出导出函数,在我们的恶意dll中按顺序转发原函数调用并附加恶意操作(比如加载shellcode),目前已经有很多成熟的工具可以帮助找出这些导出函数们:
- 开始调试时为了避免干扰因素,通常不会直接上shellcode而是用MessageBox弹窗做试验
免杀与权限维持
将恶意dll的shellcode简单处理一下后再伪造一个原dll的签名,此时就是正常签名程序->伪造签名的dll->正常签名的dll,测试了几款主流杀软和defender,可以挺人畜无害地上线CS:
对于权限维持而言,恶意dll会在第一次导入注册表操作时加载,之后可由任意文件上右键的行为被explore进程拉起,不会在任务管理器中看到恶意进程,也没有类似于开机自启这种敏感行为。而且有意思的是管理员会因为右键用杀软扫描文件的行为而上线2333
这是Web狗学习Windows的一点小测试记录,希望师傅们能分享更多好玩的tricks鸭~
参考链接
Dynamic-Link Library Search Order