RtlCreateUserThread實現Dll注入

RtlCreateUserThread函數當然也是ntdll導出的函數,這個比之前的NtCreateThreadEx是要強點的,最起碼還能看得見參數有幾個,hhhhh,難頂啊。
在這裏插入圖片描述
在這裏插入圖片描述
其實CreateRemote和Nt系列和Rtl系列的注入方式和思路基本是一致的,但是這裏還是按照慣例,bb一下我的實現思路(這思路我願意稱之爲套娃):

  • 從控制檯得到想要實施注入的目標進程名字
  • 得到當前進程所在的目錄(GetCurrentDirectory),並保存
  • 得到當前進程的位數 (IsWow64Process)
  • 根據進程名字得到當前進程的Id
  • 根據進程Id得到當前進程的完整路徑
  • 通過進程完整路徑對PE文件解析得到目標進程位數
  • 目標與當前進程的位數進行匹配,決定加載哪一個dll(x86 or x64)
  • 根據當前進程目錄,得到dll完整路徑
  • 通過GetModuleHandle得ntdll和kernel32模塊得句柄
  • 通過GetProcAddress分別從ntdll和kernel32中得到RtlCreateUserThread和LoadLibraryA
  • 通過目標進程Id,打開目標進程,獲得進程句柄
  • 在目標進程中申請內存
  • 在申請好的內存中寫入Dll完整路徑
  • 利用RtlCreateUserThread啓動遠程線程執行加載Dll,完成注入

重要部分源碼(Win 7 Win10測試):

#include"RtlCreateUserThread.h"
#include"Helper.h"

#ifdef UNICODE
LPFN_LOADLIBRARYW __LoadLibrary = NULL;
#else
LPFN_LOADLIBRARYA __LoadLibrary = NULL;
#endif
LPFN_RTLCREATEUSERTHREAD __RtlCreateUserThread = NULL;


int _tmain()
{
	//控制檯識別中文
	setlocale(LC_ALL, "Chinese-simplified");

	TCHAR ProcessImageName[MAX_PATH] = { 0 };//保存進程名字

	TCHAR CurrentFullPath[MAX_PATH] = { 0 }; //當前進程的完整路徑

	TCHAR TargetProcessFullPath[MAX_PATH] = { 0 };//目標進程的完整路徑
	ULONG_PTR TargetProcessPathLength = MAX_PATH;

	ULONG ProcessId = 0;//目標進程Id


	HANDLE ProcessHandle = INVALID_HANDLE_VALUE;//進程句柄
	LPVOID VirtualAddress = NULL;

	SIZE_T ReturnLength = 0;

	BOOL  IsOk = FALSE;

	//注入的啓動程序和目標程序的位數
	BOOL  SourceIsWow64 = FALSE;
	BOOL  TargetIsWow64 = FALSE;


	_tprintf(_T("輸入一個進程ImageName\r\n"));


	TCHAR RcceiveChar = _gettchar();//接受字符串
	int i = 0;//用來偏移ProcessName字符數組
	while (RcceiveChar != '\n')
	{
		ProcessImageName[i++] = RcceiveChar;
		RcceiveChar = _gettchar();
		//ProcessImageName = 0x000000db28fceed0 "Taskmgr.exe"
	}

	GetCurrentDirectory(MAX_PATH, CurrentFullPath);//保存當前進程的完整路徑

	IsWow64Process(GetCurrentProcess(), &SourceIsWow64);//得到當前進程位數
	//SourceIsWow64 = 0x00000000
	ProcessId = KtGetProcessIdentify(ProcessImageName);//通過進程名得到進程Id
	//ProcessId = 0x00003aa0
	if (ProcessId == 0)
	{
		return 0;
	}
	IsOk = KtGetProcessFullPath(TargetProcessFullPath,
		&TargetProcessPathLength, ProcessId, FALSE);

	if (IsOk == FALSE)
	{
		return 0;
	}
	//判斷目標進程位數
	KtIsWow64Process(TargetProcessFullPath, &TargetIsWow64);
	//TargetIsWow64 = 0x00000000
	if (SourceIsWow64 == TRUE && TargetIsWow64 == TRUE)
	{
		_tcscat_s(CurrentFullPath, _T("\\Dll.dll"));
	}
	else if (SourceIsWow64 == FALSE && TargetIsWow64 == FALSE)
	{
		_tcscat_s(CurrentFullPath, _T("\\Dll.dll"));
	}
	//_tcscat_s(CurrentFullPath, _T("\\Dll.dll"));//Win 7 32位測試用  因爲我的32位虛擬機這函數IsWow64Process得不到正確值

	//CurrentFullPath = 0x000000db28fcf000 "Z:\\Ring3層代碼\\[2]Ring3注入\\RtlCreateUserThread\\RtlCreateUserThread\\Dll.dll"
	HMODULE  NtdllModuleBase = NULL;
	HMODULE  Kernel32ModuleBase = NULL;
	NtdllModuleBase = GetModuleHandle(_T("NTDLL.DLL"));
	//NtdllModuleBase = ntdll.dll!0x00007ffe84160000 (加載符號以獲取其他信息) {unused=0x00905a4d }
	Kernel32ModuleBase = GetModuleHandle(_T("KERNEL32.DLL"));
	//Kernel32ModuleBase = kernel32.dll!0x00007ffe83fa0000 (加載符號以獲取其他信息) {unused=0x00905a4d }
	if (NtdllModuleBase == NULL || Kernel32ModuleBase == NULL)
	{
		KtCloseHandle(ProcessHandle);
		return 0;
	}
	//獲取Native API函數的地址
	__RtlCreateUserThread = (LPFN_RTLCREATEUSERTHREAD)GetProcAddress(NtdllModuleBase,
		"RtlCreateUserThread");
	//__RtlCreateUserThread = ntdll.dll!0x00007ffe84166080 (加載符號以獲取其他信息)
	if (__RtlCreateUserThread == NULL)
	{
		return 0;
	}
#ifdef UNICODE
	__LoadLibrary = (LPFN_LOADLIBRARYW)GetProcAddress(Kernel32ModuleBase, "LoadLibraryW");
#else
	__LoadLibrary = (LPFN_LOADLIBRARYA)GetProcAddress(Kernel32ModuleBase, "LoadLibraryA");
#endif

	if (__LoadLibrary == NULL) {

		KtCloseHandle(ProcessHandle);
		return 0;
	}


	ProcessHandle = KtOpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
	ULONG BufferLength = 0;
	//在目標進程空間中申請內存
	BufferLength = (_tcslen(CurrentFullPath) + 1) * sizeof(TCHAR);

	//目標進程空間中申請內存
	VirtualAddress = VirtualAllocEx(ProcessHandle, NULL, BufferLength, MEM_COMMIT, PAGE_READWRITE);

	if (VirtualAddress == NULL)
	{
		KtCloseHandle(ProcessHandle);
		return 0;
	}
	//目標進程空間中寫入數據
	if (KtProcessMemoryWriteSafe(ProcessHandle, VirtualAddress, CurrentFullPath, BufferLength, &ReturnLength) == FALSE)
	{
		KtCloseHandle(ProcessHandle);
		return 0;
	}

	HANDLE ThreadHandle = INVALID_HANDLE_VALUE;
	CLIENT_ID ClientId;
	NTSTATUS Status = __RtlCreateUserThread(
		ProcessHandle,
		NULL, 
		0,
		0,
		0,
		0,
		(PTHREAD_START_ROUTINE)__LoadLibrary,
		VirtualAddress,
		&ThreadHandle,
		&ClientId);
	if (Status >= 0)
	{
		WaitForSingleObject(ThreadHandle, INFINITE);
		VirtualFreeEx(ProcessHandle, VirtualAddress, BufferLength, MEM_RELEASE);
		KtCloseHandle(ProcessHandle);
	}
	else
	{

		VirtualFreeEx(ProcessHandle, VirtualAddress, BufferLength, MEM_RELEASE);
		KtCloseHandle(ProcessHandle);
		return 0;
	}
	return 0;
}
// dllmain.cpp : 定義 DLL 應用程序的入口點。
#include "stdafx.h"
#include <tchar.h>
BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved
)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{
		MessageBox(NULL, _T("RtlCreateUserThread"), _T("RtlCreateUserThread"), NULL);
	}
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}


測試通過Win7 x86(Explorer.exe)和Win10 x64(Taskmgr.exe)
在這裏插入圖片描述
在這裏插入圖片描述
今日自勉:永遠不要停下自己前進的腳步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章