You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
286 lines
6.4 KiB
C++
286 lines
6.4 KiB
C++
#include "trusted.hpp"
|
|
|
|
namespace trusted
|
|
{
|
|
// Enable prvileges
|
|
//
|
|
bool enable_privilege(std::string privilege)
|
|
{
|
|
HANDLE hToken;
|
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
|
|
return false;
|
|
|
|
LUID luid;
|
|
if (!LookupPrivilegeValueA(nullptr, privilege.c_str(), &luid))
|
|
{
|
|
CloseHandle(hToken);
|
|
return false;
|
|
}
|
|
|
|
TOKEN_PRIVILEGES tp;
|
|
tp.PrivilegeCount = 1;
|
|
tp.Privileges[0].Luid = luid;
|
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))
|
|
{
|
|
CloseHandle(hToken);
|
|
return false;
|
|
}
|
|
|
|
CloseHandle(hToken);
|
|
return true;
|
|
}
|
|
|
|
// Give system permissions
|
|
//
|
|
bool impersonate_system()
|
|
{
|
|
auto systemPid = util::get_pid("winlogon.exe");
|
|
HANDLE hSystemProcess;
|
|
if ((hSystemProcess = OpenProcess(
|
|
PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION,
|
|
FALSE,
|
|
systemPid)) == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
HANDLE hSystemToken;
|
|
if (!OpenProcessToken(
|
|
hSystemProcess,
|
|
MAXIMUM_ALLOWED,
|
|
&hSystemToken))
|
|
{
|
|
CloseHandle(hSystemProcess);
|
|
return false;
|
|
}
|
|
|
|
HANDLE hDupToken;
|
|
SECURITY_ATTRIBUTES tokenAttributes;
|
|
tokenAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
tokenAttributes.lpSecurityDescriptor = nullptr;
|
|
tokenAttributes.bInheritHandle = FALSE;
|
|
if (!DuplicateTokenEx(
|
|
hSystemToken,
|
|
MAXIMUM_ALLOWED,
|
|
&tokenAttributes,
|
|
SecurityImpersonation,
|
|
TokenImpersonation,
|
|
&hDupToken))
|
|
{
|
|
CloseHandle(hSystemToken);
|
|
return false;
|
|
}
|
|
|
|
if (!ImpersonateLoggedOnUser(hDupToken))
|
|
{
|
|
CloseHandle(hDupToken);
|
|
CloseHandle(hSystemToken);
|
|
return false;
|
|
}
|
|
|
|
// Optional
|
|
//
|
|
if (!SetThreadToken(0, hDupToken))
|
|
return false;
|
|
|
|
CloseHandle(hDupToken);
|
|
CloseHandle(hSystemToken);
|
|
|
|
return true;
|
|
}
|
|
|
|
// Start the trusted installer service
|
|
//
|
|
DWORD start_trusted()
|
|
{
|
|
auto sc_manager = OpenSCManagerA(
|
|
nullptr,
|
|
SERVICES_ACTIVE_DATABASE,
|
|
GENERIC_EXECUTE
|
|
);
|
|
|
|
if (!sc_manager)
|
|
return -1;
|
|
|
|
auto service = OpenServiceA(
|
|
sc_manager,
|
|
"TrustedInstaller",
|
|
GENERIC_READ | GENERIC_EXECUTE
|
|
);
|
|
|
|
if (!service)
|
|
{
|
|
CloseServiceHandle(sc_manager);
|
|
return -1;
|
|
}
|
|
|
|
SERVICE_STATUS_PROCESS statusBuffer;
|
|
DWORD bytesNeeded;
|
|
while (QueryServiceStatusEx(
|
|
service,
|
|
SC_STATUS_PROCESS_INFO,
|
|
reinterpret_cast<LPBYTE>(&statusBuffer),
|
|
sizeof(SERVICE_STATUS_PROCESS),
|
|
&bytesNeeded))
|
|
{
|
|
if (statusBuffer.dwCurrentState == SERVICE_STOPPED)
|
|
{
|
|
if (!StartServiceW(service, 0, nullptr))
|
|
{
|
|
CloseServiceHandle(service);
|
|
CloseServiceHandle(sc_manager);
|
|
return -1;
|
|
}
|
|
}
|
|
if (statusBuffer.dwCurrentState == SERVICE_START_PENDING ||
|
|
statusBuffer.dwCurrentState == SERVICE_STOP_PENDING)
|
|
{
|
|
Sleep(statusBuffer.dwWaitHint);
|
|
continue;
|
|
}
|
|
if (statusBuffer.dwCurrentState == SERVICE_RUNNING)
|
|
{
|
|
CloseServiceHandle(service);
|
|
CloseServiceHandle(sc_manager);
|
|
return statusBuffer.dwProcessId;
|
|
}
|
|
}
|
|
CloseServiceHandle(service);
|
|
CloseServiceHandle(sc_manager);
|
|
|
|
return -1;
|
|
}
|
|
|
|
// Being a process as TrustedInstaller
|
|
//
|
|
bool create_process(std::string commandLine)
|
|
{
|
|
auto pid = start_trusted();
|
|
|
|
enable_privilege(SE_DEBUG_NAME);
|
|
enable_privilege(SE_IMPERSONATE_NAME);
|
|
impersonate_system();
|
|
|
|
auto hTIProcess = OpenProcess(
|
|
PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION,
|
|
FALSE, pid
|
|
);
|
|
|
|
if (!hTIProcess)
|
|
return false;
|
|
|
|
HANDLE hTIToken;
|
|
if (!OpenProcessToken(hTIProcess, MAXIMUM_ALLOWED, &hTIToken))
|
|
{
|
|
CloseHandle(hTIProcess);
|
|
return false;
|
|
}
|
|
|
|
HANDLE hDupToken;
|
|
SECURITY_ATTRIBUTES tokenAttributes;
|
|
tokenAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
tokenAttributes.lpSecurityDescriptor = nullptr;
|
|
tokenAttributes.bInheritHandle = FALSE;
|
|
|
|
if (!DuplicateTokenEx(
|
|
hTIToken,
|
|
MAXIMUM_ALLOWED,
|
|
&tokenAttributes,
|
|
SecurityImpersonation,
|
|
TokenImpersonation,
|
|
&hDupToken
|
|
))
|
|
{
|
|
CloseHandle(hTIToken);
|
|
return false;
|
|
}
|
|
|
|
STARTUPINFOW startupInfo;
|
|
ZeroMemory(&startupInfo, sizeof(STARTUPINFOW));
|
|
startupInfo.lpDesktop = (LPWSTR)L"Winsta0\\Default";
|
|
PROCESS_INFORMATION processInfo;
|
|
ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
|
|
|
|
if (!CreateProcessWithTokenW(
|
|
hDupToken,
|
|
LOGON_WITH_PROFILE,
|
|
nullptr,
|
|
const_cast<LPWSTR>(util::string_to_wide(commandLine).c_str()),
|
|
CREATE_UNICODE_ENVIRONMENT,
|
|
nullptr,
|
|
nullptr,
|
|
&startupInfo,
|
|
&processInfo
|
|
))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Check current permissions for SYSTEM
|
|
//
|
|
bool is_system_group()
|
|
{
|
|
DWORD dw_size = 0;
|
|
DWORD dw_result = 0;
|
|
HANDLE token;
|
|
PTOKEN_USER token_user;
|
|
LPWSTR SID = NULL;
|
|
|
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
|
return false;
|
|
|
|
if (!GetTokenInformation(token, TokenUser, NULL, dw_size, &dw_size))
|
|
{
|
|
dw_result = GetLastError();
|
|
if (dw_result != ERROR_INSUFFICIENT_BUFFER)
|
|
return false;
|
|
}
|
|
|
|
token_user = (PTOKEN_USER)GlobalAlloc(GPTR, dw_size);
|
|
|
|
if (!GetTokenInformation(token, TokenUser, token_user, dw_size, &dw_size))
|
|
return false;
|
|
|
|
if (!token_user)
|
|
return false;
|
|
|
|
if (!ConvertSidToStringSidW(token_user->User.Sid, &SID))
|
|
return false;
|
|
|
|
// All SID can be found here:
|
|
// https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows
|
|
// S-1-5-18 Local System A service account that is used by the operating system.
|
|
//
|
|
if (_wcsicmp(L"S-1-5-18", SID) == 0)
|
|
return true;
|
|
|
|
if (token_user)
|
|
GlobalFree(token_user);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Checks if the current process is elevated
|
|
//
|
|
bool has_admin()
|
|
{
|
|
BOOL ret = FALSE;
|
|
HANDLE token = NULL;
|
|
|
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
|
{
|
|
TOKEN_ELEVATION elevation;
|
|
DWORD rlen = sizeof(TOKEN_ELEVATION);
|
|
|
|
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &rlen))
|
|
ret = elevation.TokenIsElevated;
|
|
}
|
|
|
|
if (token)
|
|
CloseHandle(token);
|
|
|
|
return ret;
|
|
}
|
|
} |