0x00 前言
前段时间比较忙,好久没发东西了。最近重新学习了DLL劫持漏洞相关,想着分享几个案例。
0x01 DLL劫持漏洞
首先从挖洞角度来看,这个洞对厂商没有什么太大的意义,可能都会被忽略掉。但是从Windows系统持久化维权角度来看,是非常常用也很好用的方法之一,部分公司的某些产品在很多计算机都有默认安装,如果存在DLL劫持漏洞,那么作为白+黑(白程序+黑DLL)权限维持就很容易了。
1.原理:
首先来理解DLL在Windows系统中的作用,DLL全称Dynamic Link Library,称为动态连接库,在Windows系统中,大多数程序并不是一个单独的可执行文件,而是有一些单独的存放动态链接库在系统中,当需要某些功能时,通过DLL执行相应的功能,即DLL调用。
那么既然程序执行某些功能时,可能会通过DLL调用,从利用角度来看,如果替换了这个DLL文件,或者导出了原DLL的导出函数并恶意构造,在原程序调用正常DLL前调用了我们预先构造好的恶意DLL,那么就达到了劫持的效果。
所以手法可以有多种,比如替换原DLL文件,黑DLL放置最先路径,DLL转发等。
2.DLL搜索顺序
这里还需要提及另一个概念。正常程序运行时,应用程序可以通过指定完整路径、使用 DLL重定向或通过使用清单 来控制 DLL 的加载 位置。
如果未使用这些方法,则系统在加载时搜索 DLL。参考文档如下:
这里有几个比较重要的概念单独摘了出来。
在系统搜索 DLL 之前,它会检查以下内容:
- 如果内存中已加载同一模块名称的 DLL,则无论加载的 DLL 位于哪个目录中,系统都使用加载的 DLL。 系统不搜索 DLL。
- 如果 DLL 位于运行应用程序的 Windows 版本的已知 DLL 列表中,则系统将使用其已知 DLL (的副本和已知 DLL 的依赖 DLL(如果有) )。 系统不搜索 DLL。 有关当前系统上的已知 DLL 的列表,请参阅以下注册表项 :HKEY _ LOCAL MACHINE _ SYSTEM CurrentControlSet Control Session Manager KnownDLLs。
如果 DLL 具有依赖项,则系统会搜索依赖 DLL,就像它们仅用模块名称加载一样。 即使通过指定完整路径加载了第一个 DLL,也是如此。
再者就是标准DLL搜索顺序,取决于一个叫做保险箱DLL 搜索模式(SafeDllSearchMode)的Windows机制。
Windows XP sp2前:
Windows查找DLL的目录以及对应的顺序:
- 进程对应的应用程序所在目录;
- 当前目录(Current Directory);
- 系统目录(通过 GetSystemDirectory 获取);
- 16位系统目录;
- Windows目录(通过 GetWindowsDirectory 获取);
- PATH环境变量中的各个目录;
Winxdows XPs sp2后:
默认启动了SafeDllSearchMode,注册表查询,开启则键值为1:
reg query "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode"
- 进程对应的应用程序所在目录(可理解为程序安装目录比如C:ProgramFilesuTorrent);
- 系统目录(即%windir%system32);
- 16位系统目录(即%windir%system);
- Windows目录(即%windir%);
- 当前目录(运行的某个文件所在目录,比如C:DocumentsandSettingsAdministratorDesktoptest);
- PATH环境变量中的各个目录;请注意,这不包括应用路径注册表项指定的 每个应用程序路径 。 计算 DLL 搜索路径时,不会使用应用路径密钥。
如果 SafeDllSearchMode 已禁用,则搜索顺序如下所示:
- 从其中加载应用程序的目录。
- 当前目录。
- 系统目录(即%windir%system32);
- 16 位系统目录(即%windir%system);
- Windows目录(即%windir%);
- PATH 环境变量中的各个目录;请注意,这不包括应用路径注册表项指定的 每个应用程序路径 。 计算 DLL 搜索路径时,不会使用应用路径密钥。
Windows 7后:
系统默认不在存在SafeDllSearchMode,使用了KnownDLLs列表,注册表查询如下:
reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs"
例Windows 10 KnowDLLs:
所以,看完这些机制,如果想要尝试DLL劫持,只需要放置黑DLL在优先于正常DLL的目录,并且DLL本身不在Windows KnowDLLs列表中,就能达到DLL劫持的效果。
0x02 准备一个测试DLL
1.环境目标
开发环境:Visual Studio 2019
DLL功能:弹计算器
2.代码:
dllmain.cpp
```
include "pch.h"
include
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: //DLL进程装载
system("calc");
case DLL_THREAD_ATTACH: //DLL线程装载
case DLL_THREAD_DETACH: //DLL线程卸载
case DLL_PROCESS_DETACH: //DLL进程卸载
break;
}
return TRUE;
}
```
代码很简单实现,弹计算器即可,这里需要编译一个x64和一个x86的dll,运行库指定MT,编译即可。
0x03 挖掘劫持的场景
下面分享下几种场景下的DLL劫持。
1.劫持存在的DLL
场景如下:已知目标存在必然会被使用的某个程序,希望劫持当前程序调用的DLL,所以在本地模拟了当前程序运行过程,发现了一个被调用的DLL。
这里用到了一个很好用的工具:procmon,这款工具是微软官方出的进程监视器,用于显示实时文件系统、注册表和进程/线程活动,这里用于观察进程运行过程的DLL调用。
https://docs.microsoft.com/zh-cn/sysinternals/downloads/procmon
这里拿navicat.exe来举例子。
通过运行procmon设置filter,运行navicat.exe观察DLL调用。
procmon的filter规则,可以设置指定processname,并且观察原程序path路径下的文件调用。如图所示配置filter:
之后配置完filter运行navicat.exe,观察到当前libcurl.dll的stack,我们看到了LoadLibrary函数,说明当前DLL是被动态调用的,一般DLL中会存在多个导出函数,通过另一个工具api monitor我们可以观察到navicat.exe原程序,具体用了哪个导出函数,方便我们写一个转发DLL,或者也可以直接用工具转发。
古老工具:
DLL_Hijacker:https://github.com/zhaoed/DLL_Hijacker
aheadlib:
通过判断使用了哪个导出函数可以定制修改指定的导出函数(在指定位置加入恶意代码)。
对于这类已经存在的DLL,也可以直接用工具生成转发DLL,这里使用了aheadlib生成转发DLL的cpp代码。
既然是劫持存在的DLL,通过DLL转发需要修改原DLL名称,如果转发了所有的导出函数,这里加入恶意代码可以直接在DllMain入口函数加入恶意代码。
通过aheadlib生成的DLL指定的原DLL名加上了ORG,这里修改原DLL名为libcurlOrg.dll。修改生成的DLL名为libcurl.dll。
需要注意DLL的位数。这里原来的libcurl.dll是x86位,生成x86 DLL,字符集多字节字符集,生成运行库无依赖多线程(MT)。
运行navicat成功执行恶意代码。
2.劫持不存在的DLL
场景如下:程序在运行时,会尝试加载某些可能在当前环境不存在的DLL,通过放入我们的恶意DLL,在预先加载DLL的路径执行我们的DLL(多用于维权)。
还是拿navicat来举例。通过procmon观察。
这里设置Filter需要稍做修改。
- Process name is navicat.exe
- Result is NAME NOT FOUND
- Path ends with .dll
运行navicat.exe,复制提取procmon拦截的内容,最终提取下DLL,这里可以用一种批量的验证工具,感觉挺好用的,推荐ChkDllHijack。
选择劫持的程序,贴入需要验证的DLL即可,测试DLL倒也可以手工替换为自己的,或者干脆就自己手工测试。
手工测试的话,查看procmon,如果当前DLL不存在,并且在stack中看到调用了LoadLibrary函数,那么放入目录我们的DLL文件即可劫持。
最终效果如下。
0x04 白加黑思路场景汇总
这里其实主要是思路,关于劫持DLL这块其实Defenfer杀的比较死,一般来说DLL都可以直接被拿来分析,但是一些特殊场景还是可以用的。
举个例子,某内网机器出网,但是只能smb连接上传下载文件,没有创建服务执行命令权限,存在某常用软件,这个时候就可以放一个黑DLL进去,当程序被运行时,以此进行维权操作or上线。
再者就是,通过打包上传白文件(exe)+黑(DLL),执行白文件,用以目标主机维权or上线等等。
思路场景有很多,最近项目上也遇到了。这里还是可以挖掘一下常用的软件,还是有蛮多DLL劫持的。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论