From ddd2e8626ec4bd36997ce02da05786c32bb57b43 Mon Sep 17 00:00:00 2001 From: wj32 Date: Tue, 21 Dec 2010 02:48:21 +0000 Subject: [PATCH] * don't show impersonation levels for primary tokens * better linked token support in PhCreateProcessAsUser git-svn-id: svn://svn.code.sf.net/p/processhacker/code@3909 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- 2.x/trunk/ProcessHacker/tokprp.c | 33 ++++++++++++++++----------- 2.x/trunk/phlib/support.c | 38 +++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/2.x/trunk/ProcessHacker/tokprp.c b/2.x/trunk/ProcessHacker/tokprp.c index 79a8ba674..960ad73dc 100644 --- a/2.x/trunk/ProcessHacker/tokprp.c +++ b/2.x/trunk/ProcessHacker/tokprp.c @@ -972,20 +972,27 @@ INT_PTR CALLBACK PhpTokenAdvancedPageProc( break; } - switch (statistics.ImpersonationLevel) + if (statistics.TokenType == TokenImpersonation) { - case SecurityAnonymous: - tokenImpersonationLevel = L"Anonymous"; - break; - case SecurityIdentification: - tokenImpersonationLevel = L"Identification"; - break; - case SecurityImpersonation: - tokenImpersonationLevel = L"Impersonation"; - break; - case SecurityDelegation: - tokenImpersonationLevel = L"Delegation"; - break; + switch (statistics.ImpersonationLevel) + { + case SecurityAnonymous: + tokenImpersonationLevel = L"Anonymous"; + break; + case SecurityIdentification: + tokenImpersonationLevel = L"Identification"; + break; + case SecurityImpersonation: + tokenImpersonationLevel = L"Impersonation"; + break; + case SecurityDelegation: + tokenImpersonationLevel = L"Delegation"; + break; + } + } + else + { + tokenImpersonationLevel = L"N/A"; } PhPrintPointer(tokenLuid, (PVOID)statistics.TokenId.LowPart); diff --git a/2.x/trunk/phlib/support.c b/2.x/trunk/phlib/support.c index 51820bae6..f4e020d9a 100644 --- a/2.x/trunk/phlib/support.c +++ b/2.x/trunk/phlib/support.c @@ -2695,39 +2695,51 @@ NTSTATUS PhCreateProcessAsUser( if (Flags & PH_CREATE_PROCESS_USE_LINKED_TOKEN) { HANDLE linkedTokenHandle; + TOKEN_TYPE tokenType; + ULONG returnLength; + + // NtQueryInformationToken normally returns an impersonation token with SecurityIdentification, + // but if the process is running with SeTcbPrivilege, it returns a primary token. We can never + // duplicate a SecurityIdentification impersonation token to make it a primary token, so we just + // check if the token is primary before using it. if (NT_SUCCESS(PhGetTokenLinkedToken(tokenHandle, &linkedTokenHandle))) { - NtClose(tokenHandle); - tokenHandle = linkedTokenHandle; - needsDuplicate = TRUE; // returned linked token handle is an impersonation token; need to convert to primary + if (NT_SUCCESS(NtQueryInformationToken( + linkedTokenHandle, + TokenType, + &tokenType, + sizeof(TOKEN_TYPE), + &returnLength + )) && tokenType == TokenPrimary) + { + NtClose(tokenHandle); + tokenHandle = linkedTokenHandle; + } + else + { + NtClose(linkedTokenHandle); + } } } if (needsDuplicate) { HANDLE newTokenHandle; - OBJECT_ATTRIBUTES oa; - SECURITY_QUALITY_OF_SERVICE securityQos; - - securityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); - securityQos.ImpersonationLevel = SecurityImpersonation; - securityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; - securityQos.EffectiveOnly = FALSE; + OBJECT_ATTRIBUTES objectAttributes; InitializeObjectAttributes( - &oa, + &objectAttributes, NULL, 0, NULL, NULL ); - oa.SecurityQualityOfService = &securityQos; status = NtDuplicateToken( tokenHandle, TOKEN_ALL_ACCESS, - &oa, + &objectAttributes, FALSE, TokenPrimary, &newTokenHandle