DLL劫持原理及其漏洞挖掘(一) dll劫持提权
bigegpt 2024-10-07 06:25 3 浏览
0x0 前言
简单叙述下自己研究DLL劫持的原因。
- 0.学习window的库加载思想
- 1.为了在sangforSRC挖个洞去长沙打个卡。
- 2.免杀及其权限持久化维持的一个思路
0x1 DLL是什么
动态链接库(Dynamic-Link-Library,缩写dll), 是微软公司在微软视窗操作系统中实现共享函数库概念的一种实现方式。这些库函数的扩展名是.DLL、.OCX(包含ActiveX控制的库)或者.DRV(旧式的系统的驱动程序)
所谓动态链接,就是把一些经常会共享的代码(静态链接的OBJ程序库)制作成DLL档,当可执行文件调用到DLL档内的函数时,Windows操作系统才会把DLL档加载进存储器内,DLL档本身的结构就是可执行档,当程序有需求时函数才进行链接。通过动态链接方式,存储器浪费的情形将可大幅降低。静态链接库则是直接链接到可执行文件
DLL的文件格式与视窗EXE文件一样——也就是说,等同于32位视窗的可移植执行文件(PE)和16位视窗的New Executable(NE)。作为EXE格式,DLL可以包括源代码、数据&action=edit&redlink=1)和资源&action=edit&redlink=1)的多种组合。
还有更广泛的定义,这个没必要去理解了。
一些与之相关的概念:
静态库与动态库的比较
静态库被链接后直接嵌入可执行文件中
好处: 不需要外部函数支持,无环境依赖,兼容性好。
坏处: 容易浪费空间,不方便修复bug。
动态库的好处与静态库相对。
Linux下静态库名字一般是: libxxx.a window则是: *.lib、*.h
Linux下动态库名字一般是:libxxx.so window则是: .dll、.OCX(..etc)
0x2 DLL的用途
DLL动态链接库,是程序进行动态链接时加载的库函数。
故动态链接最直接的好处是磁盘和内存的消耗减少,这也是dll最初的目的。
不过,dll也有缺点,就是容易造成版本冲突,比如不同的应用程序共享同一个dll,而它们需求的是不同的版本,这就会出现矛盾,解决办法是把不同版本的dll放在不同的文件夹中。
0x3 入门DLL的使用
0x3.1 编写TestDll.dll
1.采用vs2017新建DLL项目
2.分析DLL的组成
其中dllmain.cpp代码如下
每个DLL都可以有一个入口点函数DllMain,系统会在不同时刻调用此函数。
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule, // 模块句柄
DWORD ul_reason_for_call, // 调用原因
LPVOID lpReserved // 参数保留
)
{
switch (ul_reason_for_call) // 根据调用原因选择不不同的加载方式
{
case DLL_PROCESS_ATTACH: // DLL被某个程序加载
case DLL_THREAD_ATTACH: // DLL被某个线程加载
case DLL_THREAD_DETACH: // DLL被某个线程卸载
case DLL_PROCESS_DETACH: //DLL被某个程序卸载
break;
}
return TRUE;
}
我们可以在该文件下引入Windows.h库,然后编写一个msg的函数。
#include <Windows.h>
void msg() {
MessageBox(0, L"Dll-1 load succeed!", 0, 0);
}
接下来在解决方案资源管理下的项目下打开头文件中的framework.h来导出msg函数.
#pragma once
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
// Windows 头文件
#include <windows.h>
extern "C" __declspec(dllexport) void msg(void);
然后点击生成中的重新生成解决方案编译得到TestDll.dll文件。
可以用16进制文件查看下dll的文件头,正如上面所说的一样,和exe是一样的。
0x3.2 调用dll文件
解决方案处右键新建一个项目,选择>控制台应用取名hello
修改hello.cpp的文件内容如下:
// hello.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
// 定义一个函数类DLLFUNC
typedef void(*DLLFUNC)(void);
DLLFUNC GetDllfunc = NULL;
// 指定动态加载dll库
HINSTANCE hinst = LoadLibrary(L"TestDll.dll");
if (hinst != NULL) {
// 获取函数位置
GetDllfunc = (DLLFUNC)GetProcAddress(hinst, "msg");
}
if (GetDllfunc != NULL) {
//运行msg函数
(*GetDllfunc)();
}
}
然后ctrl+F5,运行调试。
可以看到成功加载了我们写的msg函数。
有关代码中更多的细节的解释可以参考: C++编写DLL文件
0x4 DLL劫持漏洞
0x4.1 原理简述
什么是DLL劫持漏洞(DLL Hijacking Vulnerability)?
如果在进程尝试加载一个DLL时没有并没有指定DLL的绝对路径,那么Windows会尝试去按照顺序搜索这些特定目录来查找这个DLL,如果攻击者能够将恶意的DLL放在优先于正常DLL所在的目录,那么就能够欺骗系统去加载恶意的DLL,形成”劫持”,CWE将其归类为UntrustedSearch Path Vulnerability,比较直译的一种解释。
0x4.2 查找DLL目录的顺序
正如动态链接库安全 、动态链接库搜索顺序微软的官方文档所说,
在Windows XP SP2 之前(不包括), 默认未启用DLL搜索模式。
Windows查找DLL目录及其顺序如下:
The directory from which the application loaded.The current directory.The system directory. Use the GetSystemDirectory function to get the path of this directory.The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
在Windows下, 几乎每一种文件类型都会关联一个对应的处理程序。
首先DLL会先尝试搜索启动程序所处的目录(1),没有找到,则搜索被打开文件所在的目录(2),若还没有找到,则搜索系统目录(3),若还没有找到,则向下搜索16位系统目录,…Windows目录…Path环境变量的各个目录。
这样的加载顺序很容易导致一个系统dll被劫持,因为只要攻击者将目标文件和恶意dll放在一起即可,导致恶意dll先于系统dll加载,而系统dll是非常常见的,所以当时基于这样的加载顺序,出现了大量受影响软件。
后来为了减轻这个影响,默认情况下,从Windows XP Service Pack 2(SP2)开始启用安全DLL搜索模式。
The directory from which the application loaded.The system directory. Use the GetSystemDirectory function to get the path of this directory.The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.The current directory.The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
可以看到当前目录被放置在了后面,对系统dll起到一定的保护作用。
注:
强制关闭SafeDllSearchMode的方法:
创建注册表项:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
值为0
不过从上面分析可以知道,系统dll应该是经常调用的,如果我们对程序安装的目录拥有替换权限,比如装在了非系统盘,那么我们同样可以利用加载顺序的(1)来劫持系统的DLL。
从Windows7 之后, 微软为了更进一步的防御系统的DLL被劫持,将一些容易被劫持的系统DLL写进了一个注册表项中,那么凡是此项下的DLL文件就会被禁止从EXE自身所在的目录下调用,而只能从系统目录即SYSTEM32目录下调用。注册表路径如下:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
win10的键值项,如图:
这样子就进一步保护了系统dll,防止这些常用的dll被劫持加载。
但是如果开发者滥用DLL目录,依然会导致DLL劫持问题。(开发真难…orz)
0x4.3 防御思路
- 调用第三方DLL时,使用绝对路径
- 调用API SetDllDirectory(L”“)将当前目录从DLL加载顺序中移除
- 开发测试阶段,可以采用Process Monitor进行黑盒复测
0x5 实例演示
这里我们需要使用一个工具:Process Monitor v3.60
操作过程如动态链接库安全所说:
打开进程监视器的时候,会要求填入过滤器。
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确实的路径)
然后我们随便打开一个程序,这里我使用的是深x服的EasyConnectInstaller:
可以看到这里最终会去尝试加载当前目录的一些dll,这里可以尝试进行替换rattler中的payload.dll名字即可,点击执行就可以弹出calc了。
0x6 自动化挖掘
0x6.1 Ratter
1.下载地址:https://github.com/sensepost/rattler/releases/
2.使用
Rattler_x64.exe NDP461-KB3102438-Web.exe 1
结果发现这个并没有检测出来,可能是calc.exe启动失败的原因,个人感觉这个工具并不是很准确。
0x6.2 ChkDllHijack
1.下载地址:[https://github.com/anhkgg/anhkgg-tools]
2.使用windbg导出module
然后打开chkDllHijack,粘贴处要验证的DLL内容
然后让他自己跑完即可,如果成功下面就会出现结果。
否则就是失败:
0x7 总结
综合来说,我个人还是比较推荐采用Process monitor作为辅助工具,然后自己手工验证这种挖掘思路的,不过自动化的确挺好的,可以尝试自己重新定制下检测判断规则。本文依然倾向于入门的萌新选手,后面可能会回归DLL代码细节和免杀利用方面来展开(这个过程就比较需要耗时间Orz,慢慢填坑吧)。
0x8 参考链接
.dll 文件编写和使用
DLL劫持-免杀
DLL劫持漏洞自动化识别工具Rattler测试
注入技术系列:一个批量验证DLL劫持的工具
恶意程序研究之DLL劫持
相关推荐
- 5分钟调色大片的方法(5分钟调色大片的方法有哪些)
-
哈喽大家好。在大家印象中一定觉得ps非常难学非常难。大家不要着急,小编的教学都是针对ps零基础的同学的,而且非常实用哦。只要大家跟着图文练习一两遍,保证大家立马学会~!好了,废话少说,下面开始我们今天...
- 闪白特效原来是这么用的(闪白特效怎么使用)
-
作者|高艳侠订阅|010-86092062闪白特效是影视作品中应用比较多的效果之一,那么具体该在哪些场景使用闪白特效?具体该如何操作?下面就以AdobePremiere(以下简称PR)为例,...
- ppt常用小图标去哪里找?3个矢量素材网站推荐!
-
ppt是一个注重可视化表达的演示载体,除了高清图片,ppt中另一类常用的素材是各种小图标,也叫矢量图标,巧妙运用小图标能提升整体美观度和表现力,那么ppt常用小图标去哪里找呢?为方便各位快速找到合适的...
- 有什么好用的截图录屏工具?试试这9款
-
经常有朋友反馈苦于缺乏截屏和录屏的趁手工具,本期我们分享几个相当好用的截屏和录屏工具,希望能帮到大家。ScreenToGifScreenToGif是一款免费且开源的录屏工具。此款工具最大的特点是可以...
- 配色苦手福音!专业快速色环配色PS插件
-
今天橘子老师给的大家介绍的是一款快速配色的插件,非常强大配色苦手福音来啦!(获取方式见文末)【插件介绍】配色在后期设计中占有主导地位,好的配色能让作品更加抢眼Coolorus这款专业的配色插件,能够...
- 如何用PS抠主体?(ps怎么抠主体)
-
1.主体法抠图-抠花苞和花梗导入一张荷花苞的照片,点击上图中顶部“选择”菜单栏,下拉单击“主体”。可以看到,只有花苞被选中,但是花梗并没有被选中。接下来单击上图中左侧工具栏的“快速选择工具”,上图中顶...
- 2799元的4K电视,有保障吗?(买4k电视机哪个品牌好)
-
在上一期《电脑报》的3·15专题报道中,我们揭露了一款不靠谱的42英寸4K智能电视——TCLD42A561U。这款售价2699元的4K智能电视不仅4K画质方面存在严重问题,而且各种功能和应用体验也不理...
- 苹果电脑的Touch Bar推出一段时间了 这款工具可以帮你开发适用于它的APP
-
距离苹果推出带有TouchBar的MacBookPro已经有一段时间了,除了那些像Adobe、Google和Microsoft大公司在开发适用于TouchBar的应用之外,其实还有很多独立的开...
- 如魔法般吸取颜色的桌灯(如魔法般吸取颜色的桌灯叫什么)
-
色彩为生活带来的感官刺激,逐渐被视为理所当然。一盏桌灯运用它的神奇力量,将隐藏于物件中的颜色逐一释放,成为装点环境的空间魔法师。ColorUp是一款可以改变颜色的吸色台灯,沿用传统灯泡的造型,融入了拾...
- 一篇文章带你用jquery mobile设计颜色拾取器
-
【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...
- ps拾色器快捷键是什么?(ps2019拾色器快捷键)
-
ps拾色器快捷键是什么?文章末尾有获取方式,按照以下步骤就能自动获得!学会制作PS特效需要一定程度的耐心和毅力。初学者可以从基本的工具和技术开始学习,逐渐提高他们的技能水平。同时,观看更多优秀的特效作...
- 免费开源的 Windows 截图录屏工具,支持 OCR 识别和滚动截图等
-
功能很强大、安装很小巧的免费截图、录屏工具,提供很多使用的工具来帮我么能解决问题,推荐给大家。关于ShareXShareX是一款免费的windows工具,起初是一个小巧的截图工具,经过多年的迭...
- 入门到精通系列PS教程:第13篇 · 拾色器、颜色问题说明及补充
-
入门到精通系列PS教程:第13篇·拾色器、颜色问题说明及补充作者|侯潇问题说明我的第12篇教程里,有个小问题没有说清楚。要说是错误,又不算是错误,只是没有说准确。写完那篇教程后,因为已经到了深...
- PS冷知识:用吸管工具吸取屏幕上的任意颜色
-
今天,我们给大家介绍PS中的一个冷知识:用吸管工具可以吸取屏幕上的任意颜色。其实,操作起来是非常简单的。大多数情况下,我们认为,PS的吸管工具只能吸取PS软件作图区域范围内的颜色,最多加上画布四周的...
- Windows 11 将提供内置颜色选择器工具
-
Windows11内置了颜色选择器,可以扫描并识别屏幕上的颜色并生成颜色代码。此外,微软还利用人工智能技术,让屏幕上的文本扫描和选择变得更加便捷。这两项功能均已在SnippingToolv1...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)