[host] service: use SYSTEM token attached to the current process

Since with the service, we are already running as SYSTEM, we don't need
to use dupeSystemProcessToken to get the token for SYSTEM. This removes
the need for having SeDebugPrivilege, SeTcbPrivilege, and
SeAssignPrimaryTokenPrivilege, or otherwise doing sketchy things.

Furthermore, we now only open the token with the privileges we actually
need.
This commit is contained in:
Quantum 2021-07-19 06:32:45 -04:00 committed by Geoffrey McRae
parent 16ee1a825c
commit ebda52b18b

View file

@ -158,73 +158,6 @@ bool disablePriv(const char * name)
return adjustPriv(name, 0);
}
HANDLE dupeSystemProcessToken(void)
{
DWORD count = 0;
DWORD returned;
do
{
count += 512;
DWORD pids[count];
EnumProcesses(pids, count * sizeof(DWORD), &returned);
}
while(returned / sizeof(DWORD) == count);
DWORD pids[count];
EnumProcesses(pids, count * sizeof(DWORD), &returned);
returned /= sizeof(DWORD);
char systemSidBuf[SECURITY_MAX_SID_SIZE];
PSID systemSid = (PSID) systemSidBuf;
DWORD cbSystemSid = sizeof systemSidBuf;
if (!CreateWellKnownSid(WinLocalSystemSid, NULL, systemSid, &cbSystemSid))
{
doLog("failed to create local system SID");
return NULL;
}
for(DWORD i = 0; i < returned; ++i)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pids[i]);
if (!hProcess)
continue;
HANDLE hToken;
if (!OpenProcessToken(hProcess,
TOKEN_QUERY | TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_QUERY_SOURCE |
TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_EXECUTE, &hToken))
goto err_proc;
DWORD tmp;
char userBuf[1024];
TOKEN_USER * user = (TOKEN_USER *)userBuf;
if (!GetTokenInformation(hToken, TokenUser, user, sizeof(userBuf), &tmp))
goto err_token;
if (EqualSid(user->User.Sid, systemSid))
{
CloseHandle(hProcess);
// duplicate the token so we can use it
HANDLE hDupe = NULL;
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation,
TokenPrimary, &hDupe))
hDupe = NULL;
CloseHandle(hToken);
return hDupe;
}
err_token:
CloseHandle(hToken);
err_proc:
CloseHandle(hProcess);
}
return NULL;
}
void Launch(void)
{
if (service.process)
@ -239,32 +172,29 @@ void Launch(void)
return;
}
if (!enablePriv(SE_DEBUG_NAME))
{
doLog("failed to enable " SE_DEBUG_NAME);
return;
}
HANDLE hToken = dupeSystemProcessToken();
if (!hToken)
HANDLE hSystemToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE |
TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_DEFAULT,
&hSystemToken))
{
doLog("failed to get the system process token\n");
return;
}
if (!disablePriv(SE_DEBUG_NAME))
doLog("failed to disable " SE_DEBUG_NAME);
HANDLE hToken;
if (!DuplicateTokenEx(hSystemToken, 0, NULL, SecurityAnonymous,
TokenPrimary, &hToken))
{
doLog("failed to duplicate the system process token\n");
CloseHandle(hSystemToken);
return;
}
CloseHandle(hSystemToken);
DWORD origSessionID, targetSessionID, returnedLen;
GetTokenInformation(hToken, TokenSessionId, &origSessionID,
sizeof(origSessionID), &returnedLen);
if (!enablePriv(SE_TCB_NAME))
{
doLog("failed to enable " SE_TCB_NAME);
goto fail_token;
}
targetSessionID = WTSGetActiveConsoleSessionId();
if (origSessionID != targetSessionID)
{
@ -277,9 +207,6 @@ void Launch(void)
}
}
if (!disablePriv(SE_TCB_NAME))
doLog("failed to disable " SE_TCB_NAME);
LPVOID pEnvironment = NULL;
if (!CreateEnvironmentBlock(&pEnvironment, hToken, TRUE))
{
@ -288,12 +215,6 @@ void Launch(void)
goto fail_token;
}
if (!enablePriv(SE_ASSIGNPRIMARYTOKEN_NAME))
{
doLog("failed to enable " SE_ASSIGNPRIMARYTOKEN_NAME);
goto fail_token;
}
if (!enablePriv(SE_INCREASE_QUOTA_NAME))
{
doLog("failed to enable " SE_INCREASE_QUOTA_NAME);
@ -345,9 +266,6 @@ void Launch(void)
if (!disablePriv(SE_INCREASE_QUOTA_NAME))
doLog("failed to disable " SE_INCREASE_QUOTA_NAME);
if (!disablePriv(SE_ASSIGNPRIMARYTOKEN_NAME))
doLog("failed to disable " SE_ASSIGNPRIMARYTOKEN_NAME);
CloseHandle(pi.hThread);
service.process = pi.hProcess;
service.running = true;