DLL劫持技术

1、介绍

DLL劫持技术是一种权限维持的手段, 通过劫持正常程序DLL的执行流让程序执行恶意代码。

流程

  1. 正常程序 —-调用—-» 正常的DLL —-执行—» 正常功能

DLL劫持就可以通过劫持正常的DLL, 让恶意的DLL被正常的程序调用。

  1. 正常程序 —-调用—-» 恶意DLL — 执行 —» 恶意代码 —转发—» 正常DLL —执行—» 执行正常功能

2、DLL介绍

DLL中文名动态链接库 你可以把它看作一个自身无法执行的exe程序通过exe对DLL操作调用DLL里的方法实现相对应的功能
学DLL劫持就学两点就行

  1. DLL生命周期
  2. DLL导出函数

2.1、 DLL生命周期

DLL生命周期是指DLL从加载到卸载的个个状态,下面看代码DLL默认就是

#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
 DWORD ul_reason_for_call,
 LPVOID lpReserved
 ) //DLL的入口函数
{
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH: //DLL被加载时候执行
 case DLL_THREAD_ATTACH: //线程被创建的时候执行
 case DLL_THREAD_DETACH: //线程结束时执行
 case DLL_PROCESS_DETACH: //DLL被卸载时执行
 break;
 }
 return TRUE;
}

这就是DLL的生命周期 执行到对应的生命周期会执行对应的case代码块

2.2、DLL导出函数

DLL导出函数是DLL提供对外部的函数, 外部的程序可以通过加载DLL访问导出函数从而执行导出函数的功能。

这是DLL里的导出函数

//语言类型    调用约定                
extern "C" __declspec(dllexport) void aaa()
{
    MessageBoxA(NULL,"我是导出函数", "aaaa", MB_OK);
}

完整的DLL代码

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>
#include <iostream>
#include <string>
extern "C" __declspec(dllexport) void aaa()
{
    MessageBoxA(NULL,"我是导出函数", "aaaa", MB_OK);
}



BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBoxA(NULL, "DLL加载case", "aaa", MB_HELP);
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

写一个程序调用DLL文件

#include <iostream>
#include <Windows.h>
typedef void(*Func)(); //DLL中的函数被默认为私有函数,不会被其他程序调用。因此,需要通过定义导出函数以便其他程序能够调用它们。

int main()
{
	HINSTANCE hinst  = LoadLibraryA("TestDLL.dll"); //执行到这的时候会调用 MessageBoxA(NULL, "DLL加载case", "aaa", MB_HELP);
	Func GetDLLFunc = (Func)GetProcAddress(hinst, "aaa");
	GetDLLFunc(); //执行到这执行导出函数 MessageBoxA(NULL,"我是导出函数", "aaaa", MB_OK);
	
	return 0; 
}

执行第一次弹出弹窗,是DLL被加载的弹窗。 点击确定后,弹出了第二个弹窗,这显示是导出函数被加载执行了。

3、DLL劫持

现在要完成DLL劫持的流程:
正常程序 —-调用—-» 恶意DLL — 执行 —» 恶意代码 —转发—» 正常DLL —执行—» 执行正常功能

正常情况下我们没正常程序的DLL源码

  1. 通过Process Monitor找到程序调用神那么DLL文件从而修改。

这样就可以看到都加载了什么DLL文件

  1. 然后使用工具AheaLib.exe 得到转发
// 头文件
#include <Windows.h>
// 导出函数
#pragma comment(linker, "/EXPORT:aaa=TestDLLOrg.aaa,@1")
// 入口函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH) //当DLL被加载到进程的地址空间时会执行。
	{
		
		DisableThreadLibraryCalls(hModule); //DisableThreadLibraryCalls用来决定DLL线程通知开启与关闭  什么是线程通知 DLL_PROCESS_ATTACH 和 DLL_PROCESS_DETACH 这种就是线程通知
	}
	else if (dwReason == DLL_PROCESS_DETACH) //当DLL被卸载的时候执行
	{
		MessageBoxW(NULL, L"aaa", L"tttt", 0x2L); //我自己写的充当恶意代码
	}
	return TRUE;
}
  • 把原来的TestDLL改名为TestDLLOrg。
  • 编译这个DLL文件替换掉原来的TestDLL文件。