注入(3)--远程线程注入(CreateRemoteThread)

远程线程注入的核心思想是利用windows提供的远程机制,在目标进程中开启一个加载模块的远程线程,使钩子被该远程线程加载到目标地址空间中。
远程线程使用的关键API有WriteProcessMemory、CreateRemoteThread、和LoadLibrary.
原型如下:
BOOL
WINAPI
WriteProcessMemory(
    _In_ HANDLE hProcess,
    _In_ LPVOID lpBaseAddress,
    _In_reads_bytes_(nSize) LPCVOID lpBuffer,
    _In_ SIZE_T nSize,
    _Out_opt_ SIZE_T * lpNumberOfBytesWritten
    );
hProcess:远程线程句柄
lpBaseAddress:远程进程待写地址
lpBuffer:本进程空间buffer地址
nSize:lpBuffer所指空间的大小
lpNumberOfBytesWritten:返回实际写入远近程的字节数


HANDLE
WINAPI
CreateRemoteThread(
    _In_ HANDLE hProcess,
    _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
    _In_ SIZE_T dwStackSize,
    _In_ LPTHREAD_START_ROUTINE lpStartAddress,
    _In_opt_ LPVOID lpParameter,
    _In_ DWORD dwCreationFlags,
    _Out_opt_ LPDWORD lpThreadId
    );
hProcess:远近程句柄
lpThreadAttributes:线程安全描述字,指向SECURITY_ATTRIBUTES结构的指针
dwStackSize:线程栈大小,以字节为单位表示
lpStartAddress:一个LPTHREAD_START_ROUTINE类型的指针,指向在远程进程中执行的函数地址
lpParameter:传入参数
dwCreationFlags:创建线程的其他标志
lpThreadId:线程ID,如果为NULL则不反回


HMODULE
WINAPI
LoadLibraryW(
    _In_ LPCWSTR lpLibFileName
    );
lpLibFileName:待加载模块的文件路径
// CreatRemoteThread.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include <iostream>
using namespace std;

enum TargetType
{
	WOW_86,
	WOW_64,
	WOW_ERROR
};
BOOL EnableDebugPrivilege();
TargetType GetWowByReadFile(ULONG32  ulProcessID);
HMODULE GetModuleBaseAddressByProcessHandle(HANDLE ProcessHandle);
BOOL  InjectDllByRemoteThread(ULONG32 ulProcessID, WCHAR* wzDllFullPath);
int main()
{
	if (EnableDebugPrivilege() == FALSE)
	{
		return 0;
	}
	ULONG32 ulProcessID = 0;
	printf("Input A ProcessID to Inject:
");
	scanf_s("%d", &ulProcessID, sizeof(ULONG32));

	DWORD iOk = GetWowByReadFile(ulProcessID);
	switch (iOk)
	{
	case WOW_64:
		if (InjectDllByRemoteThread(ulProcessID, L"InjectTest64.dll"))
		{
			printf("Inject Success!
");
		}
	case WOW_86:
		if (InjectDllByRemoteThread(ulProcessID, L"InjectTest32.dll"))
		{
			printf("Inject Success!
");
		}
	default:
		break;
	}
    return 0;
}

//提权函数 提权操作一共四步 1.Open打开 2.Lookup查看当前 3.Adjust调整 4.Close关闭
BOOL EnableDebugPrivilege()
{

	HANDLE TokenHandle = NULL;
	TOKEN_PRIVILEGES TokenPrivilege;
	LUID uID;

	//打开权限令牌
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))  
	{
		return FALSE;
	}

	if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &uID))
	{

		CloseHandle(TokenHandle);
		TokenHandle = INVALID_HANDLE_VALUE;
		return FALSE;
	}

	TokenPrivilege.PrivilegeCount = 1;
	TokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	TokenPrivilege.Privileges[0].Luid = uID;

	//在这里我们进行调整权限
	if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivilege, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
	{
		CloseHandle(TokenHandle);
		TokenHandle = INVALID_HANDLE_VALUE;
		return  FALSE;
	}

	CloseHandle(TokenHandle);
	TokenHandle = INVALID_HANDLE_VALUE;
	return TRUE;
}
//通过解析exe文件(magic数)判断进程是x64还是x86
TargetType GetWowByReadFile(ULONG32  ulProcessID)
{
	HANDLE  ProcessHandle = INVALID_HANDLE_VALUE;
	ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ulProcessID);

	if (ProcessHandle == NULL)
	{
		return WOW_ERROR;
	}
	//获得Exe模块基地址
	ULONG64 ulModuleBaseAddress = (ULONG64)GetModuleBaseAddressByProcessHandle(ProcessHandle);

	if (ulModuleBaseAddress == NULL)
	{
		CloseHandle(ProcessHandle);
		return WOW_ERROR;
	}

	IMAGE_DOS_HEADER   DosHeader = { 0 };
	//读取Dos头
	if (ReadProcessMemory(ProcessHandle, (PVOID)ulModuleBaseAddress, &DosHeader, sizeof(IMAGE_DOS_HEADER), NULL) == FALSE)
	{
		CloseHandle(ProcessHandle);
		return WOW_ERROR;
	}

	WORD  wMagic = 0;
	//模块加载基地址+Dos头部e_lfanew成员(PE头相对于文件的偏移 4字节)+标准PE头+4字节
	if (ReadProcessMemory(ProcessHandle, (PVOID)(ulModuleBaseAddress + DosHeader.e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)), &wMagic, sizeof(WORD), NULL) == FALSE)
	{
		CloseHandle(ProcessHandle);
		return WOW_ERROR;
	}

	CloseHandle(ProcessHandle);
	if (wMagic == 0x20b)//x64
	{
		return WOW_64;
	}
	else if (wMagic == 0x10b)//x86
	{
		return WOW_86;
	}
	else
	{
		return WOW_ERROR;
	}
}

HMODULE GetModuleBaseAddressByProcessHandle(HANDLE ProcessHandle)
{
	HMODULE ModulesHandle[1024] = { 0 };
	DWORD dwReturn = 0;
	if (EnumProcessModules(ProcessHandle, ModulesHandle, sizeof(ModulesHandle), &dwReturn))
	{
		return ModulesHandle[0];
	}
	return NULL;
}

BOOL  InjectDllByRemoteThread(ULONG32 ulProcessID, WCHAR* wzDllFullPath)
{
	HANDLE  ProcessHandle = NULL;
	ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ulProcessID);

	if (ProcessHandle==NULL)
	{
		return FALSE;
	}

	WCHAR* VirtualAddress = NULL;

	ULONG32 ulDllLength = (ULONG32)_tcslen(wzDllFullPath) + 1;

	VirtualAddress = (WCHAR*)VirtualAllocEx(ProcessHandle, NULL, ulDllLength * sizeof(WCHAR),
		MEM_COMMIT, PAGE_READWRITE);


	if (VirtualAddress==NULL)
	{
		CloseHandle(ProcessHandle);
		return FALSE;
	}
	// 在目标进程的内存空间中写入所需参数(模块名)
	if (!WriteProcessMemory(ProcessHandle, VirtualAddress, (LPVOID)wzDllFullPath, ulDllLength * sizeof(WCHAR), NULL))
	{
		VirtualFreeEx(ProcessHandle, VirtualAddress, ulDllLength, MEM_DECOMMIT);
		CloseHandle(ProcessHandle);
		return FALSE;
	}


	LPTHREAD_START_ROUTINE FunctionAddress = NULL;

	FunctionAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");

	HANDLE ThreadHandle = INVALID_HANDLE_VALUE;
	//启动远程线程
	ThreadHandle = ::CreateRemoteThread(ProcessHandle, NULL, 0, FunctionAddress, VirtualAddress, 0, NULL);
	if (ThreadHandle==FALSE)
	{
		VirtualFreeEx(ProcessHandle, VirtualAddress, ulDllLength, MEM_DECOMMIT);
		CloseHandle(ProcessHandle);
		return FALSE;
	}

	// 等待远程线程结束
	WaitForSingleObject(ThreadHandle, INFINITE);
	// 清理
	VirtualFreeEx(ProcessHandle, VirtualAddress, ulDllLength, MEM_DECOMMIT);
	CloseHandle(ThreadHandle);
	CloseHandle(ProcessHandle);
	return TRUE;
}


原文地址:https://www.cnblogs.com/Toring/p/6628286.html