bool CTokenSyscallProxy::NtOpenThreadToken( __in HANDLE threadHandle, __in DWORD desiredAccess, __in BOOL openAsSelf, __out PHANDLE tokenHandle ) { return NtOpenThreadTokenEx(threadHandle, desiredAccess, openAsSelf, 0, tokenHandle); }
NTSTATUS SERVICECALL NtOpenThreadToken(IN HANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN BOOLEAN OpenAsSelf, OUT PHANDLE TokenHandle) { ktrace("\n"); return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0, TokenHandle); }
/* * SfuAdjustCurrentThreadPriv * * Purpose: * * Impersonate thread and adjust privileges. * */ BOOL SfuAdjustCurrentThreadPriv( PCLIENT_ID SourceThread ) { BOOL cond = FALSE; NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE hThread = NULL, hToken = NULL; OBJECT_ATTRIBUTES obja; SECURITY_QUALITY_OF_SERVICE SecurityQos; TOKEN_PRIVILEGES *NewState = NULL; ULONG uLen; do { InitializeObjectAttributes(&obja, NULL, 0, NULL, NULL); status = NtOpenThread(&hThread, THREAD_DIRECT_IMPERSONATION, &obja, SourceThread); if (!NT_SUCCESS(status)) break; SecurityQos.Length = sizeof(SecurityQos); SecurityQos.ImpersonationLevel = SecurityImpersonation; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SecurityQos.EffectiveOnly = FALSE; status = NtImpersonateThread(NtCurrentThread(), hThread, &SecurityQos); if (!NT_SUCCESS(status)) break; status = NtOpenThreadTokenEx(NtCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, 0, &hToken); if (!NT_SUCCESS(status)) break; uLen = sizeof(TOKEN_PRIVILEGES) + (6 * sizeof(LUID_AND_ATTRIBUTES)); NewState = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, uLen); if (NewState == NULL) break; NewState->PrivilegeCount = 6; NewState->Privileges[0].Luid.LowPart = SE_TCB_PRIVILEGE; NewState->Privileges[0].Luid.HighPart = 0; NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[1].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; NewState->Privileges[1].Luid.HighPart = 0; NewState->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[2].Luid.LowPart = SE_RESTORE_PRIVILEGE; NewState->Privileges[2].Luid.HighPart = 0; NewState->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[3].Luid.LowPart = SE_DEBUG_PRIVILEGE; NewState->Privileges[3].Luid.HighPart = 0; NewState->Privileges[3].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[4].Luid.LowPart = SE_LOAD_DRIVER_PRIVILEGE; NewState->Privileges[4].Luid.HighPart = 0; NewState->Privileges[4].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[5].Luid.LowPart = SE_SECURITY_PRIVILEGE; NewState->Privileges[5].Luid.HighPart = 0; NewState->Privileges[5].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; status = NtAdjustPrivilegesToken(hToken, FALSE, NewState, 0, NULL, NULL); } while (cond); if (hToken != NULL) NtClose(hToken); if (hThread != NULL) NtClose(hThread); if (NewState != NULL) RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, NewState); return NT_SUCCESS(status); }