远程线程注入的核心思想是利用windows提供的远程机制,在目标进程中开启一个加载模块的远程线程,使钩子被该远程线程加载到目标地址空间中。远程线程使用的关键API有WriteProcessMemory、CreateRemoteThread、和LoadLibrary.原型如下:BOOLWINAPIWriteProcessMemory( _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:返回实际写入远近程的字节数HANDLEWINAPICreateRemoteThread( _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则不反回HMODULEWINAPILoadLibraryW( _In_ LPCWSTR lpLibFileName );lpLibFileName:待加载模块的文件路径
// CreatRemoteThread.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include #include #include #include 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:\r\n"); scanf_s("%d", &ulProcessID, sizeof(ULONG32)); DWORD iOk = GetWowByReadFile(ulProcessID); switch (iOk) { case WOW_64: if (InjectDllByRemoteThread(ulProcessID, L"InjectTest64.dll")) { printf("Inject Success!\r\n"); } case WOW_86: if (InjectDllByRemoteThread(ulProcessID, L"InjectTest32.dll")) { printf("Inject Success!\r\n"); } 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还是x86TargetType 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;}