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)
|
_Return_type_success_(return != NULL) HANDLE GetPrimarySystemTokenFromThread(void)
|
||||||
{
|
{
|
||||||
HANDLE CurrentThreadToken, DuplicatedToken;
|
HANDLE CurrentToken, DuplicatedToken;
|
||||||
BOOL Ret;
|
BOOL Ret;
|
||||||
DWORD LastError;
|
DWORD LastError;
|
||||||
TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } };
|
TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } };
|
||||||
@ -143,13 +143,16 @@ _Return_type_success_(return != NULL) HANDLE GetPrimarySystemTokenFromThread(voi
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Ret = OpenThreadToken(
|
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)
|
if (!Ret)
|
||||||
{
|
{
|
||||||
LastError = LOG_LAST_ERROR(L"Failed to open thread token");
|
LastError = LOG_LAST_ERROR(L"Failed to open token");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Ret = GetTokenInformation(CurrentThreadToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
|
Ret = GetTokenInformation(CurrentToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes);
|
||||||
if (!Ret)
|
if (!Ret)
|
||||||
{
|
{
|
||||||
LastError = LOG_LAST_ERROR(L"Failed to get token information");
|
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");
|
LastError = LOG_LAST_ERROR(L"Failed to lookup privilege value");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
Ret = AdjustTokenPrivileges(CurrentThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
|
Ret = AdjustTokenPrivileges(CurrentToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL);
|
||||||
if (!Ret)
|
if (!Ret)
|
||||||
{
|
{
|
||||||
LastError = LOG_LAST_ERROR(L"Failed to adjust token privileges");
|
LastError = LOG_LAST_ERROR(L"Failed to adjust token privileges");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
Ret = DuplicateTokenEx(
|
Ret = DuplicateTokenEx(
|
||||||
CurrentThreadToken,
|
CurrentToken,
|
||||||
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
|
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
|
||||||
NULL,
|
NULL,
|
||||||
SecurityImpersonation,
|
SecurityImpersonation,
|
||||||
@ -185,11 +188,11 @@ _Return_type_success_(return != NULL) HANDLE GetPrimarySystemTokenFromThread(voi
|
|||||||
LastError = LOG_LAST_ERROR(L"Failed to duplicate token");
|
LastError = LOG_LAST_ERROR(L"Failed to duplicate token");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
CloseHandle(CurrentThreadToken);
|
CloseHandle(CurrentToken);
|
||||||
return DuplicatedToken;
|
return DuplicatedToken;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
CloseHandle(CurrentThreadToken);
|
CloseHandle(CurrentToken);
|
||||||
SetLastError(LastError);
|
SetLastError(LastError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user