diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-11-06 17:05:56 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-11-07 15:04:33 +0100 |
commit | 3dbaafd4ae288abc51d82bf2463275ac6f07467b (patch) | |
tree | 2a530cb4cb0128cb8b976f3a091a9575674c271e /api/elevate.c | |
parent | api: fix Function and Prefix logging order (diff) | |
download | wintun-3dbaafd4ae288abc51d82bf2463275ac6f07467b.tar.xz wintun-3dbaafd4ae288abc51d82bf2463275ac6f07467b.zip |
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>
Diffstat (limited to '')
-rw-r--r-- | api/elevate.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/api/elevate.c b/api/elevate.c index 57bafbf..47dcbd1 100644 --- a/api/elevate.c +++ b/api/elevate.c @@ -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; } |