Run the WInArk under System account.

This commit is contained in:
CORP\zengquan
2022-09-20 18:21:18 +08:00
parent 0acb03657d
commit a54b37c932
4 changed files with 181 additions and 8 deletions
+23 -3
View File
@@ -239,7 +239,11 @@ void CMainFrame::InitDriverInterface() {
if (!DriverHelper::IsDriverLoaded()) {
if (!SecurityHelper::IsRunningElevated()) {
if (AtlMessageBox(nullptr, L"Kernel Driver not loaded. Some functionality will not be available. Install?", IDS_TITLE, MB_YESNO | MB_ICONQUESTION) == IDYES) {
if (!SecurityHelper::RunElevated(L"install", false)) {
if (SecurityHelper::IsSysRun()) {
if(!SecurityHelper::SysRun(L"install"))
AtlMessageBox(*this, L"Error running driver installer", IDS_TITLE, MB_ICONERROR);
}
else if (!SecurityHelper::RunElevated(L"install", false)) {
AtlMessageBox(*this, L"Error running driver installer", IDS_TITLE, MB_ICONERROR);
}
}
@@ -261,7 +265,12 @@ void CMainFrame::InitDriverInterface() {
}
else {
DriverHelper::CloseDevice();
SecurityHelper::RunElevated(L"update", false);
if (SecurityHelper::IsSysRun()) {
if (!SecurityHelper::SysRun(L"update"))
AtlMessageBox(*this, L"Error update driver service", IDS_TITLE, MB_ICONERROR);
}
else
SecurityHelper::RunElevated(L"update", false);
}
}
}
@@ -310,6 +319,12 @@ void CMainFrame::InitConfigView() {
}
LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
if (SecurityHelper::EnablePrivilege(SE_DEBUG_NAME, true)) {
if (!SecurityHelper::IsSysRun()) {
if (SecurityHelper::SysRun(L"runas"))
SendMessage(WM_CLOSE);
}
}
LoadSettings();
CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
@@ -319,7 +334,11 @@ LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/
hMenu.GetSubMenu(0).DeleteMenu(ID_FILE_RUNASADMIN, MF_BYCOMMAND);
CString text;
GetWindowText(text);
SetWindowText(text + L" (Administrator)");
CString append = L" (Administrator)";
if (SecurityHelper::IsSysRun()) {
append = L" (System)";
}
SetWindowText(text + append);
}
UIAddMenu(hMenu);
@@ -410,6 +429,7 @@ LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/
pLoop->AddIdleHandler(this);
InitDriverInterface();
InitProcessTable();
InitNetworkTable();
InitKernelModuleTable();
+7 -4
View File
@@ -15,6 +15,7 @@
#include <Helpers.h>
#include "SymbolHelper.h"
CAppModule _Module;
HWND _hMainWnd;
AppSettings _Settings;
@@ -215,10 +216,12 @@ LONG WINAPI SelfUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo)
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) {
g_hSingleInstMutex = ::CreateMutex(nullptr, FALSE, L"WinArkSingleInstanceMutex");
if (g_hSingleInstMutex) {
if (::GetLastError() == ERROR_ALREADY_EXISTS) {
MessageBox(nullptr, L"请勿重复启动!!!", L"Error", MB_ICONERROR);
return -1;
if (!::wcsstr(lpstrCmdLine, L"runas")) {
if (g_hSingleInstMutex) {
if (::GetLastError() == ERROR_ALREADY_EXISTS) {
MessageBox(nullptr, L"请勿重复启动!!!", L"Error", MB_ICONERROR);
return -1;
}
}
}
HRESULT hRes = ::CoInitializeEx(nullptr,COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE);
+145
View File
@@ -3,6 +3,34 @@
#include <sddl.h>
#include <shellapi.h>
#include "DriverHelper.h"
#include <WtsApi32.h>
#include <WinBase.h>
#pragma comment(lib,"wtsapi32")
bool SecurityHelper::IsSysRun() {
static bool runningSystem = false;
static bool runningSystemCheck = false;
if (runningSystemCheck)
return runningSystem;
runningSystemCheck = true;
wil::unique_handle hToken;
if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, hToken.addressof()))
return false;
BYTE buffer[128];
DWORD len;
if (::GetTokenInformation(hToken.get(), TokenUser, &buffer, sizeof(buffer), &len)) {
auto user = reinterpret_cast<TOKEN_USER*>(buffer);
runningSystem = IsSystemSid(user->User.Sid);
}
return runningSystem;
}
bool SecurityHelper::IsSystemSid(PSID sid) {
return ::IsWellKnownSid(sid, WinLocalSystemSid);
}
bool SecurityHelper::IsRunningElevated() {
static bool runningElevated = false;
@@ -34,6 +62,7 @@ HICON SecurityHelper::GetShieldIcon() {
bool SecurityHelper::RunElevated(PCWSTR param, bool ui) {
WCHAR path[MAX_PATH];
::GetModuleFileName(nullptr, path, _countof(path));
SHELLEXECUTEINFO shi = { sizeof(shi) };
shi.lpFile = path;
shi.nShow = SW_SHOWDEFAULT;
@@ -52,6 +81,97 @@ bool SecurityHelper::RunElevated(PCWSTR param, bool ui) {
return rc == WAIT_OBJECT_0;
}
// find first SYSTEM process with a good token to use
HANDLE SecurityHelper::OpenSystemProcessToken() {
PWTS_PROCESS_INFO pInfo;
DWORD count;
if (!::WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pInfo, &count)) {
return nullptr;
}
HANDLE hToken{};
for (DWORD i = 0; i < count && !hToken; i++) {
if (pInfo[i].SessionId == 0 && IsSystemSid(pInfo[i].pUserSid)
&& !_wcsicmp(pInfo[i].pProcessName,L"services.exe")) {
auto hProcess = DriverHelper::OpenProcess(pInfo[i].ProcessId, PROCESS_QUERY_INFORMATION);
if (hProcess) {
::OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_IMPERSONATE, &hToken);
::CloseHandle(hProcess);
}
}
}
::WTSFreeMemory(pInfo);
return hToken;
}
bool SecurityHelper::SysRun(PCWSTR param) {
auto hToken = OpenSystemProcessToken();
if (!hToken)
return false;
HANDLE hDupToken, hPrimary;
::DuplicateTokenEx(hToken, TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_PRIVILEGES,
nullptr, SecurityImpersonation, TokenImpersonation, &hDupToken);
::DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, nullptr, SecurityImpersonation, TokenPrimary, &hPrimary);
::CloseHandle(hToken);
if (hDupToken == nullptr) {
return false;
}
WCHAR path[MAX_PATH];
::GetModuleFileName(nullptr, path, _countof(path));
STARTUPINFO si = { sizeof(si) };
si.lpDesktop = const_cast<wchar_t*>(L"Winsta0\\default");
PROCESS_INFORMATION pi;
BOOL impersonated = ::SetThreadToken(nullptr, hDupToken);
if (!impersonated)
return false;
HANDLE hCurrentToken = INVALID_HANDLE_VALUE;
DWORD session = 0, len = sizeof(session);
bool ok = ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &hCurrentToken);
if (!ok)
return false;
::GetTokenInformation(hCurrentToken, TokenSessionId, &session, len, &len);
::CloseHandle(hCurrentToken);
if (!SetPrivilege(hDupToken, SE_ASSIGNPRIMARYTOKEN_NAME, true) ||
!SetPrivilege(hDupToken, SE_INCREASE_QUOTA_NAME, true)) {
return false;
}
std::wstring commandLine = path;
commandLine += L" ";
commandLine += param;
ok = ::SetTokenInformation(hPrimary, TokenSessionId, &session, sizeof(session));
if (!::CreateProcessAsUser(hPrimary, nullptr,
const_cast<wchar_t*>(commandLine.c_str()), nullptr, nullptr,
FALSE, 0, nullptr, nullptr,
&si, &pi)) {
DWORD error = ::GetLastError();
if (error == ERROR_PRIVILEGE_NOT_HELD) {
if (!SetPrivilege(hDupToken, SE_IMPERSONATE_NAME, true))
return false;
if (!::CreateProcessWithTokenW(hPrimary, 0, nullptr,
const_cast<wchar_t*>(commandLine.c_str()), 0, nullptr, nullptr,
&si, &pi)) {
return false;
}
}
else
return false;
}
::CloseHandle(hPrimary);
::CloseHandle(hDupToken);
return true;
}
bool SecurityHelper::EnablePrivilege(PCWSTR privName, bool enable) {
HANDLE hToken;
if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
@@ -69,6 +189,31 @@ bool SecurityHelper::EnablePrivilege(PCWSTR privName, bool enable) {
return result;
}
bool SecurityHelper::SetPrivilege(HANDLE hToken, PCWSTR privName, bool enable) {
TOKEN_PRIVILEGES tp;
LUID luid;
if (!::LookupPrivilegeValue(nullptr, privName, &luid))
return false;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (enable)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr)) {
return false;
}
if (::GetLastError() == ERROR_NOT_ALL_ASSIGNED)
return false;
return true;
}
std::wstring SecurityHelper::GetSidFromUser(PCWSTR name) {
BYTE sid[SECURITY_MAX_SID_SIZE];
DWORD size = sizeof(sid);
+6 -1
View File
@@ -1,10 +1,15 @@
#pragma once
struct SecurityHelper final {
static bool IsSysRun();
static bool IsRunningElevated();
static HICON GetShieldIcon();
static bool RunElevated(PCWSTR privName, bool enable);
static bool IsSystemSid(PSID sid);
static bool RunElevated(PCWSTR param, bool ui);
static bool SysRun(PCWSTR param);
static HANDLE OpenSystemProcessToken();
static bool EnablePrivilege(PCWSTR privName, bool enable);
static std::wstring GetSidFromUser(PCWSTR name);
static HANDLE DupHandle(HANDLE hSoruce, DWORD sourcePid, DWORD access = 0);
static bool SetPrivilege(HANDLE hToken, PCWSTR privName, bool enable);
};