api: elevate rundll32 calls to SYSTEM
I need this for debugging. In production environment, WoW64 clients will already call rundll32 elevated to SYSTEM. Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
ac6db7788a
commit
369801cdfa
@ -28,4 +28,5 @@
|
||||
#include <SetupAPI.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <string.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <wchar.h>
|
||||
|
@ -7,6 +7,100 @@
|
||||
|
||||
#if defined(_M_AMD64) || defined(_M_ARM64)
|
||||
|
||||
static BOOL ElevateToSystem(VOID)
|
||||
{
|
||||
HANDLE CurrentProcessToken, ThreadToken, ProcessSnapshot, WinlogonProcess, WinlogonToken, DuplicatedToken;
|
||||
PROCESSENTRY32W ProcessEntry = { .dwSize = sizeof(PROCESSENTRY32W) };
|
||||
BOOL Ret;
|
||||
DWORD LastError = ERROR_SUCCESS;
|
||||
TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } };
|
||||
CHAR LocalSystemSid[0x400];
|
||||
DWORD RequiredBytes = sizeof(LocalSystemSid);
|
||||
struct
|
||||
{
|
||||
TOKEN_USER MaybeLocalSystem;
|
||||
CHAR LargeEnoughForLocalSystem[0x400];
|
||||
} TokenUserBuffer;
|
||||
|
||||
Ret = CreateWellKnownSid(WinLocalSystemSid, NULL, &LocalSystemSid, &RequiredBytes);
|
||||
LastError = GetLastError();
|
||||
if (!Ret)
|
||||
goto cleanup;
|
||||
Ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken);
|
||||
LastError = GetLastError();
|
||||
if (!Ret)
|
||||
goto cleanup;
|
||||
Ret =
|
||||
GetTokenInformation(CurrentProcessToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
|
||||
LastError = GetLastError();
|
||||
CloseHandle(CurrentProcessToken);
|
||||
if (!Ret)
|
||||
goto cleanup;
|
||||
if (EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))
|
||||
return TRUE;
|
||||
Ret = LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid);
|
||||
LastError = GetLastError();
|
||||
if (!Ret)
|
||||
goto cleanup;
|
||||
ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
LastError = GetLastError();
|
||||
if (ProcessSnapshot == INVALID_HANDLE_VALUE)
|
||||
goto cleanup;
|
||||
for (Ret = Process32FirstW(ProcessSnapshot, &ProcessEntry); Ret;
|
||||
Ret = Process32NextW(ProcessSnapshot, &ProcessEntry))
|
||||
{
|
||||
if (_wcsicmp(ProcessEntry.szExeFile, L"winlogon.exe"))
|
||||
continue;
|
||||
RevertToSelf();
|
||||
Ret = ImpersonateSelf(SecurityImpersonation);
|
||||
LastError = GetLastError();
|
||||
if (!Ret)
|
||||
continue;
|
||||
Ret = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken);
|
||||
LastError = GetLastError();
|
||||
if (!Ret)
|
||||
continue;
|
||||
Ret = AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
|
||||
LastError = GetLastError();
|
||||
CloseHandle(ThreadToken);
|
||||
if (!Ret)
|
||||
continue;
|
||||
|
||||
WinlogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessEntry.th32ProcessID);
|
||||
LastError = GetLastError();
|
||||
if (!WinlogonProcess)
|
||||
continue;
|
||||
Ret = OpenProcessToken(WinlogonProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &WinlogonToken);
|
||||
LastError = GetLastError();
|
||||
CloseHandle(WinlogonProcess);
|
||||
if (!Ret)
|
||||
continue;
|
||||
Ret = DuplicateToken(WinlogonToken, SecurityImpersonation, &DuplicatedToken);
|
||||
LastError = GetLastError();
|
||||
CloseHandle(WinlogonToken);
|
||||
if (!Ret)
|
||||
continue;
|
||||
if (!GetTokenInformation(DuplicatedToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes))
|
||||
goto next;
|
||||
if (SetLastError(ERROR_ACCESS_DENIED), !EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid))
|
||||
goto next;
|
||||
if (!SetThreadToken(NULL, DuplicatedToken))
|
||||
goto next;
|
||||
CloseHandle(DuplicatedToken);
|
||||
CloseHandle(ProcessSnapshot);
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
return TRUE;
|
||||
next:
|
||||
LastError = GetLastError();
|
||||
CloseHandle(DuplicatedToken);
|
||||
}
|
||||
RevertToSelf();
|
||||
CloseHandle(ProcessSnapshot);
|
||||
cleanup:
|
||||
SetLastError(LastError);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
__declspec(dllexport) VOID __stdcall CreateAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hwnd);
|
||||
@ -28,7 +122,9 @@ __declspec(dllexport) VOID __stdcall CreateAdapter(HWND hwnd, HINSTANCE hinst, L
|
||||
goto cleanupArgv;
|
||||
WINTUN_ADAPTER *Adapter;
|
||||
BOOL RebootRequired = FALSE;
|
||||
ElevateToSystem();
|
||||
DWORD Result = WintunCreateAdapter(Argv[2], Argv[3], Argc > 4 ? &RequestedGUID : NULL, &Adapter, &RebootRequired);
|
||||
RevertToSelf();
|
||||
if (Result != ERROR_SUCCESS)
|
||||
goto cleanupArgv;
|
||||
|
||||
@ -53,7 +149,9 @@ __declspec(dllexport) VOID __stdcall DeleteAdapter(HWND hwnd, HINSTANCE hinst, L
|
||||
if (FAILED(CLSIDFromString(Argv[2], &Adapter.CfgInstanceID)))
|
||||
goto cleanupArgv;
|
||||
BOOL RebootRequired = FALSE;
|
||||
ElevateToSystem();
|
||||
WintunDeleteAdapter(&Adapter, &RebootRequired);
|
||||
RevertToSelf();
|
||||
|
||||
cleanupArgv:
|
||||
LocalFree(Argv);
|
||||
|
Loading…
Reference in New Issue
Block a user