Init commit
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
#include "Common.h"
|
||||
#include "ProcessUtils.h"
|
||||
#include "TokenUtils.h"
|
||||
#include "Logger.h"
|
||||
|
||||
DWORD GetPidByName(const wchar_t* exeName)
|
||||
{
|
||||
if (!exeName)
|
||||
return 0;
|
||||
|
||||
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (snap == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
PROCESSENTRY32W pe{};
|
||||
pe.dwSize = sizeof(pe);
|
||||
|
||||
if (!Process32First(snap, &pe))
|
||||
{
|
||||
CloseHandle(snap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (_wcsicmp(pe.szExeFile, exeName) == 0)
|
||||
{
|
||||
DWORD pid = pe.th32ProcessID;
|
||||
CloseHandle(snap);
|
||||
return pid;
|
||||
}
|
||||
} while (Process32Next(snap, &pe));
|
||||
|
||||
CloseHandle(snap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ProcessExistsByName(const wchar_t* exeName)
|
||||
{
|
||||
return GetPidByName(exeName) != 0;
|
||||
}
|
||||
|
||||
static bool BuildCommandLine(
|
||||
const wchar_t* exePath,
|
||||
const wchar_t* args,
|
||||
std::wstring& fullPath,
|
||||
std::wstring& commandLine)
|
||||
{
|
||||
if (!exePath || !*exePath)
|
||||
return false;
|
||||
|
||||
wchar_t abs[4096]{};
|
||||
DWORD n = GetFullPathNameW(exePath, _countof(abs), abs, nullptr);
|
||||
|
||||
if (n == 0)
|
||||
wcscpy_s(abs, _countof(abs), exePath);
|
||||
|
||||
fullPath = abs;
|
||||
|
||||
if (GetFileAttributesW(fullPath.c_str()) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
Log(L"[-] Executable not found: %s", fullPath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
commandLine.clear();
|
||||
commandLine += L'"';
|
||||
commandLine += fullPath;
|
||||
commandLine += L'"';
|
||||
|
||||
if (args && *args)
|
||||
{
|
||||
commandLine += L' ';
|
||||
commandLine += args;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateProcessAsSystemImpl(
|
||||
HANDLE systemToken,
|
||||
const wchar_t* exePath,
|
||||
const wchar_t* args,
|
||||
bool interactive,
|
||||
bool suspended,
|
||||
NewProcInfo* out)
|
||||
{
|
||||
if (out)
|
||||
*out = NewProcInfo();
|
||||
|
||||
if (!systemToken || !exePath)
|
||||
return false;
|
||||
|
||||
HANDLE tok = DuplicateSystemTokenFromHandle(systemToken);
|
||||
if (!tok)
|
||||
{
|
||||
Log(L"[-] Failed to duplicate SYSTEM token for process creation");
|
||||
return false;
|
||||
}
|
||||
|
||||
EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME);
|
||||
EnablePrivilege(SE_INCREASE_QUOTA_NAME);
|
||||
|
||||
if (interactive)
|
||||
{
|
||||
DWORD session = WTSGetActiveConsoleSessionId();
|
||||
|
||||
if (session != 0xFFFFFFFF)
|
||||
{
|
||||
if (!SetTokenInformation(tok, TokenSessionId, &session, sizeof(session)))
|
||||
{
|
||||
Log(L"[!] SetTokenInformation(TokenSessionId) failed: %lu", GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LPVOID env = nullptr;
|
||||
BOOL createdEnv = CreateEnvironmentBlock(&env, tok, FALSE);
|
||||
|
||||
STARTUPINFOW si{};
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = interactive ? SW_SHOWDEFAULT : SW_HIDE;
|
||||
|
||||
if (interactive)
|
||||
si.lpDesktop = const_cast<LPWSTR>(L"Winsta0\\Default");
|
||||
|
||||
std::wstring fullPath;
|
||||
std::wstring cmd;
|
||||
|
||||
if (!BuildCommandLine(exePath, args, fullPath, cmd))
|
||||
{
|
||||
if (createdEnv)
|
||||
DestroyEnvironmentBlock(env);
|
||||
|
||||
CloseHandle(tok);
|
||||
return false;
|
||||
}
|
||||
|
||||
PROCESS_INFORMATION pi{};
|
||||
|
||||
DWORD creationFlags = 0;
|
||||
|
||||
if (!interactive)
|
||||
creationFlags |= CREATE_NO_WINDOW;
|
||||
|
||||
if (suspended)
|
||||
creationFlags |= CREATE_SUSPENDED;
|
||||
|
||||
BOOL ok = CreateProcessAsUserW(
|
||||
tok,
|
||||
fullPath.c_str(),
|
||||
cmd.data(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
FALSE,
|
||||
creationFlags,
|
||||
createdEnv ? env : nullptr,
|
||||
nullptr,
|
||||
&si,
|
||||
&pi);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
Log(L"[-] CreateProcessAsUserW failed: %lu", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(L"[+] Created process: PID %lu", pi.dwProcessId);
|
||||
|
||||
if (out)
|
||||
{
|
||||
out->hProcess = pi.hProcess;
|
||||
out->hThread = pi.hThread;
|
||||
out->processId = pi.dwProcessId;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pi.hThread)
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
if (pi.hProcess)
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
}
|
||||
|
||||
if (createdEnv)
|
||||
DestroyEnvironmentBlock(env);
|
||||
|
||||
CloseHandle(tok);
|
||||
|
||||
return ok == TRUE;
|
||||
}
|
||||
|
||||
bool StartProcessAsSystem(
|
||||
HANDLE systemToken,
|
||||
const wchar_t* exePath,
|
||||
const wchar_t* args,
|
||||
bool interactive)
|
||||
{
|
||||
return CreateProcessAsSystemImpl(systemToken, exePath, args, interactive, false, nullptr);
|
||||
}
|
||||
|
||||
bool CreateProcessSuspendedAsSystem(
|
||||
HANDLE systemToken,
|
||||
const wchar_t* exePath,
|
||||
const wchar_t* args,
|
||||
bool interactive,
|
||||
NewProcInfo* out)
|
||||
{
|
||||
return CreateProcessAsSystemImpl(systemToken, exePath, args, interactive, true, out);
|
||||
}
|
||||
Reference in New Issue
Block a user