/*++ * @name CsrImpersonateClient * @implemented NT4 * * The CsrImpersonateClient will impersonate the given CSR Thread. * * @param CsrThread * Pointer to the CSR Thread to impersonate. * * @return TRUE if impersonation succeeded, FALSE otherwise. * * @remarks Impersonation can be recursive. * *--*/ BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread) { NTSTATUS Status; PCSR_THREAD CurrentThread = CsrGetClientThread(); /* Use the current thread if none given */ if (!CsrThread) CsrThread = CurrentThread; /* Still no thread, something is wrong */ if (!CsrThread) { /* Failure */ return FALSE; } /* Make the call */ Status = NtImpersonateThread(NtCurrentThread(), CsrThread->ThreadHandle, &CsrSecurityQos); if (!NT_SUCCESS(Status)) { /* Failure */ DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status); // if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint(); return FALSE; } /* Increase the impersonation count for the current thread */ if (CurrentThread) ++CurrentThread->ImpersonationCount; /* Return Success */ return TRUE; }
/* * 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); }
BOOL GetPrivilege(ULONG Priviliage) { BOOL bRet = FALSE; NTSTATUS St; BOOLEAN bEnable; bRet = NT_SUCCESS(RtlAdjustPrivilege(Priviliage,TRUE,FALSE,&bEnable)) || NT_SUCCESS(RtlAdjustPrivilege(Priviliage,TRUE,TRUE,&bEnable)); if (!bRet) { PSYSTEM_PROCESSES_INFORMATION Processes = (PSYSTEM_PROCESSES_INFORMATION)GetSystemInformation(SystemProcessInformation); if (Processes) { UNICODE_STRING ProcessName = RTL_CONSTANT_STRING(L"services.exe"); for (PSYSTEM_PROCESSES_INFORMATION Proc=Processes; ; *(ULONG*)&Proc += Proc->NextEntryDelta) { if (RtlEqualUnicodeString(&Proc->ProcessName,&ProcessName,TRUE)) { HANDLE hThread; OBJECT_ATTRIBUTES ObjAttr; InitializeObjectAttributes(&ObjAttr,NULL,0,0,0); St = NtOpenThread(&hThread,THREAD_DIRECT_IMPERSONATION,&ObjAttr,&Proc->Threads[0].ClientId); if (NT_SUCCESS(St)) { SECURITY_QUALITY_OF_SERVICE SecurityQos = {0}; SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); SecurityQos.ImpersonationLevel = SecurityImpersonation; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; St = NtImpersonateThread(NtCurrentThread(),hThread,&SecurityQos); if (NT_SUCCESS(St)) { St = RtlAdjustPrivilege(Priviliage,TRUE,TRUE,&bEnable); bRet = NT_SUCCESS(St); if (!bRet) { DbgPrint(__FUNCTION__"(): RtlAdjustPrivilege failed with status %x\n",St); } } else { DbgPrint(__FUNCTION__"(): NtImpersonateThread failed with status %x\n",St); } NtClose(hThread); } else { DbgPrint(__FUNCTION__"(): NtOpenThread failed with status %x\n",St); } break; } if (!Proc->NextEntryDelta) break; } free(Processes); } } return bRet; }