概述
远程线程注入的核心思想是利用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
#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:rn");
scanf_s("%d", &ulProcessID, sizeof(ULONG32));
DWORD iOk = GetWowByReadFile(ulProcessID);
switch (iOk)
{
case WOW_64:
if (InjectDllByRemoteThread(ulProcessID, L"InjectTest64.dll"))
{
printf("Inject Success!rn");
}
case WOW_86:
if (InjectDllByRemoteThread(ulProcessID, L"InjectTest32.dll"))
{
printf("Inject Success!rn");
}
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;
}
最后
以上就是大胆招牌为你收集整理的java远程线程注入_注入(3)--远程线程注入(CreateRemoteThread)的全部内容,希望文章能够帮你解决java远程线程注入_注入(3)--远程线程注入(CreateRemoteThread)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复