zoukankan      html  css  js  c++  java
  • 注入(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;
    }


  • 相关阅读:
    log4j.properties配置
    5.1properties属性
    Bootstrap-datepicker设置开始时间结束时间范围
    mybatis学习笔记2
    mysql中插入中文时显示乱码
    mybatis入门总结一
    mybatis学习笔记一
    SqlMapConfig.xml配置文件
    Java连接SQL Server:jTDS驱动兼容性问题
    Sublime Text3注册码(可用)
  • 原文地址:https://www.cnblogs.com/Toring/p/6628286.html
Copyright © 2011-2022 走看看