api: manipulate process token if thread token didn't require impersonation
Otherwise rundll32.exe fails if we're already SYSTEM. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
c581a9f6cd
commit
3dbaafd4ae
@ -124,7 +124,7 @@ cleanup:
|
||||
|
||||
_Return_type_success_(return != NULL) HANDLE GetPrimarySystemTokenFromThread(void)
|
||||
{
|
||||
HANDLE CurrentThreadToken, DuplicatedToken;
|
||||
HANDLE CurrentToken, DuplicatedToken;
|
||||
BOOL Ret;
|
||||
DWORD LastError;
|
||||
TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } };
|
||||
@ -143,13 +143,16 @@ _Return_type_success_(return != NULL) HANDLE GetPrimarySystemTokenFromThread(voi
|
||||
return NULL;
|
||||
}
|
||||
Ret = OpenThreadToken(
|
||||
GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_DUPLICATE, FALSE, &CurrentThreadToken);
|
||||
GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_DUPLICATE, FALSE, &CurrentToken);
|
||||
if (!Ret && GetLastError() == ERROR_NO_TOKEN)
|
||||
Ret = OpenProcessToken(
|
||||
GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_DUPLICATE, &CurrentToken);
|
||||
if (!Ret)
|
||||
{
|
||||
LastError = LOG_LAST_ERROR(L"Failed to open thread token");
|
||||
LastError = LOG_LAST_ERROR(L"Failed to open token");
|
||||
return NULL;
|
||||
}
|
||||
Ret = GetTokenInformation(CurrentThreadToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
|
||||
Ret = GetTokenInformation(CurrentToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
|
||||
if (!Ret)
|
||||
{
|
||||
LastError = LOG_LAST_ERROR(L"Failed to get token information");
|
||||
@ -167,14 +170,14 @@ _Return_type_success_(return != NULL) HANDLE GetPrimarySystemTokenFromThread(voi
|
||||
LastError = LOG_LAST_ERROR(L"Failed to lookup privilege value");
|
||||
goto cleanup;
|
||||
}
|
||||
Ret = AdjustTokenPrivileges(CurrentThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
|
||||
Ret = AdjustTokenPrivileges(CurrentToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
|
||||
if (!Ret)
|
||||
{
|
||||
LastError = LOG_LAST_ERROR(L"Failed to adjust token privileges");
|
||||
goto cleanup;
|
||||
}
|
||||
Ret = DuplicateTokenEx(
|
||||
CurrentThreadToken,
|
||||
CurrentToken,
|
||||
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
|
||||
NULL,
|
||||
SecurityImpersonation,
|
||||
@ -185,11 +188,11 @@ _Return_type_success_(return != NULL) HANDLE GetPrimarySystemTokenFromThread(voi
|
||||
LastError = LOG_LAST_ERROR(L"Failed to duplicate token");
|
||||
goto cleanup;
|
||||
}
|
||||
CloseHandle(CurrentThreadToken);
|
||||
CloseHandle(CurrentToken);
|
||||
return DuplicatedToken;
|
||||
|
||||
cleanup:
|
||||
CloseHandle(CurrentThreadToken);
|
||||
CloseHandle(CurrentToken);
|
||||
SetLastError(LastError);
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user