void GetDebugPriv(void) { HANDLE hToken; DWORD dwRet; NTSTATUS status; TOKEN_PRIVILEGES Privileges = {1,{0x14,0,SE_PRIVILEGE_ENABLED}}; NtOpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); status = NtAdjustPrivilegesToken(hToken, 0, &Privileges, sizeof(Privileges), 0, &dwRet); if (STATUS_SUCCESS == status) { admin = 1; } else { WCHAR buffer[0x10]; swprintf(buffer, L"%.8X",status); MessageBox(0, NotAdmin, buffer, 0); } NtClose(hToken); }
HANDLE OpenToken( HANDLE hMyToken, ACCESS_MASK DesiredAccess) { NTSTATUS Status; HANDLE Token; HANDLE Process; PMYTOKEN pMyToken = (PMYTOKEN)hMyToken; DWORD ThreadId = pMyToken->ThreadId; DWORD ProcessId = pMyToken->ProcessId; Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessId); if (Process == NULL) { DbgPrint("SECEDIT: OpenProcess failed, last error = %ld\n", GetLastError()); return(NULL); } Status = NtOpenProcessToken( Process, DesiredAccess, &Token ); CloseHandle(Process); if (!NT_SUCCESS(Status)) { DbgPrint("SECEDIT: Failed to open token with access = 0x%x, status = 0x%lx\n", DesiredAccess, Status); return(NULL); } return(Token); }
NTSTATUS PhRunAsServiceStart( _In_ PPH_STRING ServiceName ) { HANDLE tokenHandle; SERVICE_TABLE_ENTRY entry; // Enable some required privileges. if (NT_SUCCESS(NtOpenProcessToken( NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &tokenHandle ))) { PhSetTokenPrivilege(tokenHandle, L"SeAssignPrimaryTokenPrivilege", NULL, SE_PRIVILEGE_ENABLED); PhSetTokenPrivilege(tokenHandle, L"SeBackupPrivilege", NULL, SE_PRIVILEGE_ENABLED); PhSetTokenPrivilege(tokenHandle, L"SeImpersonatePrivilege", NULL, SE_PRIVILEGE_ENABLED); PhSetTokenPrivilege(tokenHandle, L"SeIncreaseQuotaPrivilege", NULL, SE_PRIVILEGE_ENABLED); PhSetTokenPrivilege(tokenHandle, L"SeRestorePrivilege", NULL, SE_PRIVILEGE_ENABLED); NtClose(tokenHandle); } RunAsServiceName = ServiceName; entry.lpServiceName = ServiceName->Buffer; entry.lpServiceProc = RunAsServiceMain; StartServiceCtrlDispatcher(&entry); return STATUS_SUCCESS; }
/* * supEnablePrivilege * * Purpose: * * Enable/Disable given privilege. * * Return FALSE on any error. * */ BOOL supEnablePrivilege( _In_ DWORD PrivilegeName, _In_ BOOL fEnable ) { BOOL bResult = FALSE; NTSTATUS status; HANDLE hToken; TOKEN_PRIVILEGES TokenPrivileges; status = NtOpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); if (!NT_SUCCESS(status)) { return bResult; } TokenPrivileges.PrivilegeCount = 1; TokenPrivileges.Privileges[0].Luid.LowPart = PrivilegeName; TokenPrivileges.Privileges[0].Luid.HighPart = 0; TokenPrivileges.Privileges[0].Attributes = (fEnable) ? SE_PRIVILEGE_ENABLED : 0; status = NtAdjustPrivilegesToken(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL); if (status == STATUS_NOT_ALL_ASSIGNED) { status = STATUS_PRIVILEGE_NOT_HELD; } bResult = NT_SUCCESS(status); NtClose(hToken); return bResult; }
void get_privilege(long id) { HANDLE h; ULONG status=NtOpenProcessToken( NtCurrentProcess() ,0x20 ,&h); CHECKER(status) TOKEN_PRIVILEGES tp; tp.count = 1; tp.Privileges[0].Luid = NT::RtlConvertLongToLuid(id); tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; status = NtAdjustPrivilegesToken( h ,false ,&tp ,0 ,0 ,0); CHECKER(status) ZwClose(h); }
static int enable_shutdown_privilege() { void *token; TOKEN_PRIVILEGES privilege; memset(&privilege, 0, sizeof privilege); privilege.PrivilegeCount = 1; privilege.Privileges[0].Luid.LowPart = SE_SHUTDOWN_PRIVILEGE; privilege.Privileges[0].Luid.HighPart = 0; privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; #ifdef _WIN32_WNT_NATIVE long int status = NtOpenProcessToken((void *)-1, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token); if(status < 0) { __set_errno_from_ntstatus(status); return -1; } status = NtAdjustPrivilegesToken(token, 0, &privilege, sizeof privilege, NULL, NULL); NtClose(token); if(status < 0) { __set_errno_from_ntstatus(status); return -1; } return 0; #else //LUID id; //memset(&id, 0, sizeof id); if(!OpenProcessToken((void *)-1, TOKEN_ADJUST_PRIVILEGES, &token)) { __set_errno_from_oserror(); return -1; } //if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &id)) return -1; int ok = AdjustTokenPrivileges(token, 0, &privilege, sizeof privilege, NULL, NULL); if(!ok) __set_errno_from_oserror(); CloseHandle(token); return ok ? 0 : -1; #endif }
/* * ucmShowProcessIntegrityLevel * * Purpose: * * Output current integrity level of target application. * */ void ucmShowProcessIntegrityLevel( VOID ) { NTSTATUS status; HANDLE hToken; ULONG LengthNeeded; PTOKEN_MANDATORY_LABEL pTIL = NULL; DWORD dwIntegrityLevel; WCHAR *t = NULL; WCHAR szBuffer[MAX_PATH + 1]; status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &hToken); if (NT_SUCCESS(status)) { status = NtQueryInformationToken(hToken, TokenIntegrityLevel, NULL, 0, &LengthNeeded); if (status == STATUS_BUFFER_TOO_SMALL) { pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, LengthNeeded); if (pTIL) { status = NtQueryInformationToken(hToken, TokenIntegrityLevel, pTIL, LengthNeeded, &LengthNeeded); if (NT_SUCCESS(status)) { dwIntegrityLevel = *RtlSubAuthoritySid(pTIL->Label.Sid, (DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pTIL->Label.Sid) - 1)); if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID) { t = L"Low Process"; } else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID) { t = L"Medium Process"; } else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) { t = L"High Integrity Process"; } else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID) { t = L"System Integrity Process"; } RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); wsprintf(szBuffer, L"PID=%lu, IntegrityLevel=%ws", GetCurrentProcessId(), t); } LocalFree(pTIL); } } NtClose(hToken); } if (t) MessageBox(GetDesktopWindow(), szBuffer, GetCommandLineW(), MB_ICONINFORMATION); }
VOID NTAPI LoadCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { HANDLE tokenHandle; if (NT_SUCCESS(NtOpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &tokenHandle))) { PhSetTokenPrivilege(tokenHandle, SE_SYSTEM_ENVIRONMENT_NAME, NULL, SE_PRIVILEGE_ENABLED); NtClose(tokenHandle); } }
VOID PhpEnablePrivileges( VOID ) { HANDLE tokenHandle; if (NT_SUCCESS(NtOpenProcessToken( NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &tokenHandle ))) { CHAR privilegesBuffer[FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges) + sizeof(LUID_AND_ATTRIBUTES) * 8]; PTOKEN_PRIVILEGES privileges; ULONG i; privileges = (PTOKEN_PRIVILEGES)privilegesBuffer; privileges->PrivilegeCount = 8; for (i = 0; i < privileges->PrivilegeCount; i++) { privileges->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED; privileges->Privileges[i].Luid.HighPart = 0; } privileges->Privileges[0].Luid.LowPart = SE_DEBUG_PRIVILEGE; privileges->Privileges[1].Luid.LowPart = SE_INC_BASE_PRIORITY_PRIVILEGE; privileges->Privileges[2].Luid.LowPart = SE_INC_WORKING_SET_PRIVILEGE; privileges->Privileges[3].Luid.LowPart = SE_LOAD_DRIVER_PRIVILEGE; privileges->Privileges[4].Luid.LowPart = SE_PROF_SINGLE_PROCESS_PRIVILEGE; privileges->Privileges[5].Luid.LowPart = SE_RESTORE_PRIVILEGE; privileges->Privileges[6].Luid.LowPart = SE_SHUTDOWN_PRIVILEGE; privileges->Privileges[7].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; NtAdjustPrivilegesToken( tokenHandle, FALSE, privileges, 0, NULL, NULL ); NtClose(tokenHandle); } }
/* TODO: This function should be placed in a better place */ static PSID get_user_sid() { if (cached_sid_initialized) return cached_sid; else { HANDLE token; NTSTATUS status; NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &token); DWORD len; NtQueryInformationToken(token, TokenUser, cached_token_user, sizeof(cached_token_user), &len); TOKEN_USER *token_user = (TOKEN_USER *)cached_token_user; cached_sid = token_user->User.Sid; cached_sid_initialized = 1; NtClose(token); return cached_sid; } }
/* * @implemented */ BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle) { NTSTATUS Status; Status = NtOpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle); if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } return TRUE; }
BOOLEAN main() { NTSTATUS Status; HANDLE ProcessToken; TSeVariableInitialization(); // Initialize global variables printf("\n"); // // Open our process token // Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_QUERY, &ProcessToken ); if (!NT_SUCCESS(Status)) { printf("I'm terribly sorry, but you don't seem to have access to\n"); printf("open your own process's token.\n"); printf("\n"); return(FALSE); } printf("Your process level security context is:\n"); printf("\n"); DisplaySecurityContext( ProcessToken ); Status = NtClose( ProcessToken ); return(TRUE); }
void test8(void) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; NTSTATUS Status; LONG dwError; TOKEN_PRIVILEGES NewPrivileges; HANDLE Token,hKey; LUID Luid = {0}; BOOLEAN bRes; Status=NtOpenProcessToken(GetCurrentProcess() ,TOKEN_ADJUST_PRIVILEGES,&Token); // ,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&Token); dprintf("\t\t\t\tStatus =%x\n",Status); // bRes=LookupPrivilegeValueA(NULL,SE_RESTORE_NAME,&Luid); // dprintf("\t\t\t\tbRes =%x\n",bRes); NewPrivileges.PrivilegeCount = 1; NewPrivileges.Privileges[0].Luid = Luid; // NewPrivileges.Privileges[0].Luid.u.LowPart=18; // NewPrivileges.Privileges[0].Luid.u.HighPart=0; NewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Status = NtAdjustPrivilegesToken( bRes = AdjustTokenPrivileges( Token, FALSE, &NewPrivileges, 0, NULL, NULL ); dprintf("\t\t\t\tbRes =%x\n",bRes); // Status=NtClose(Token); // dprintf("\t\t\t\tStatus =%x\n",Status); RtlRosInitUnicodeStringFromLiteral(&KeyName,L"test5"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE , NULL, NULL); Status = NtLoadKey((HANDLE)HKEY_LOCAL_MACHINE,&ObjectAttributes); dprintf("\t\t\t\tStatus =%x\n",Status); dwError=RegLoadKey(HKEY_LOCAL_MACHINE,"def" ,"test5"); dprintf("\t\t\t\tdwError =%x\n",dwError); dprintf("NtOpenKey \\Registry\\Machine : "); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status=NtOpenKey( &hKey, MAXIMUM_ALLOWED, &ObjectAttributes); dprintf("\t\t\tStatus =%x\n",Status); RtlRosInitUnicodeStringFromLiteral(&KeyName,L"test5"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE , NULL, NULL); Status = NtLoadKey(hKey,&ObjectAttributes); dprintf("\t\t\t\tStatus =%x\n",Status); }
/* * supUserIsFullAdmin * * Purpose: * * Tests if the current user is admin with full access token. * */ BOOL supUserIsFullAdmin( VOID ) { BOOL bResult = FALSE, cond = FALSE; HANDLE hToken = NULL; NTSTATUS status; DWORD i, Attributes; ULONG ReturnLength = 0; PTOKEN_GROUPS pTkGroups; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PSID AdministratorsGroup = NULL; status = NtOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken); if (!NT_SUCCESS(status)) return bResult; do { if (!AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup)) break; status = NtQueryInformationToken(hToken, TokenGroups, NULL, 0, &ReturnLength); if (status != STATUS_BUFFER_TOO_SMALL) break; pTkGroups = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (SIZE_T)ReturnLength); if (pTkGroups == NULL) break; status = NtQueryInformationToken(hToken, TokenGroups, pTkGroups, ReturnLength, &ReturnLength); if (NT_SUCCESS(status)) { if (pTkGroups->GroupCount > 0) for (i = 0; i < pTkGroups->GroupCount; i++) { Attributes = pTkGroups->Groups[i].Attributes; if (EqualSid(AdministratorsGroup, pTkGroups->Groups[i].Sid)) if ( (Attributes & SE_GROUP_ENABLED) && (!(Attributes & SE_GROUP_USE_FOR_DENY_ONLY)) ) { bResult = TRUE; break; } } } HeapFree(GetProcessHeap(), 0, pTkGroups); } while (cond); if (AdministratorsGroup != NULL) { FreeSid(AdministratorsGroup); } NtClose(hToken); return bResult; }
/*++ * @name CsrGetProcessLuid * @implemented NT4 * * The CsrGetProcessLuid routine gets the LUID of the given process. * * @param hProcess * Optional handle to the process whose LUID should be returned. * * @param Luid * Pointer to a LUID Pointer which will receive the CSR Process' LUID. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks If hProcess is not supplied, then the current thread's token will * be used. If that too is missing, then the current process' token * will be used. * *--*/ NTSTATUS NTAPI CsrGetProcessLuid(IN HANDLE hProcess OPTIONAL, OUT PLUID Luid) { HANDLE hToken = NULL; NTSTATUS Status; ULONG Length; PTOKEN_STATISTICS TokenStats; /* Check if we have a handle to a CSR Process */ if (!hProcess) { /* We don't, so try opening the Thread's Token */ Status = NtOpenThreadToken(NtCurrentThread(), TOKEN_QUERY, FALSE, &hToken); /* Check for success */ if (!NT_SUCCESS(Status)) { /* If we got some other failure, then return and quit */ if (Status != STATUS_NO_TOKEN) return Status; /* We don't have a Thread Token, use a Process Token */ hProcess = NtCurrentProcess(); hToken = NULL; } } /* Check if we have a token by now */ if (!hToken) { /* No token yet, so open the Process Token */ Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); if (!NT_SUCCESS(Status)) { /* Still no token, return the error */ return Status; } } /* Now get the size we'll need for the Token Information */ Status = NtQueryInformationToken(hToken, TokenStatistics, NULL, 0, &Length); /* Allocate memory for the Token Info */ if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length))) { /* Fail and close the token */ NtClose(hToken); return STATUS_NO_MEMORY; } /* Now query the information */ Status = NtQueryInformationToken(hToken, TokenStatistics, TokenStats, Length, &Length); /* Close the handle */ NtClose(hToken); /* Check for success */ if (NT_SUCCESS(Status)) { /* Return the LUID */ *Luid = TokenStats->AuthenticationId; } /* Free the query information */ RtlFreeHeap(CsrHeap, 0, TokenStats); /* Return the Status */ return Status; }
/* * @implemented */ BOOL WINAPI CheckTokenMembership(IN HANDLE ExistingTokenHandle, IN PSID SidToCheck, OUT PBOOL IsMember) { PISECURITY_DESCRIPTOR SecurityDescriptor = NULL; ACCESS_MASK GrantedAccess; struct { PRIVILEGE_SET PrivilegeSet; LUID_AND_ATTRIBUTES Privileges[4]; } PrivBuffer; ULONG PrivBufferSize = sizeof(PrivBuffer); GENERIC_MAPPING GenericMapping = { STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE, STANDARD_RIGHTS_ALL }; PACL Dacl; ULONG SidLen; HANDLE hToken = NULL; NTSTATUS Status, AccessStatus; /* doesn't return gracefully if IsMember is NULL! */ *IsMember = FALSE; SidLen = RtlLengthSid(SidToCheck); if (ExistingTokenHandle == NULL) { Status = NtOpenThreadToken(NtCurrentThread(), TOKEN_QUERY, FALSE, &hToken); if (Status == STATUS_NO_TOKEN) { /* we're not impersonating, open the primary token */ Status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hToken); if (NT_SUCCESS(Status)) { HANDLE hNewToken = FALSE; BOOL DupRet; /* duplicate the primary token to create an impersonation token */ DupRet = DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityImpersonation, TokenImpersonation, &hNewToken); NtClose(hToken); if (!DupRet) { WARN("Failed to duplicate the primary token!\n"); return FALSE; } hToken = hNewToken; } } if (!NT_SUCCESS(Status)) { goto Cleanup; } } else { hToken = ExistingTokenHandle; } /* create a security descriptor */ SecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(SECURITY_DESCRIPTOR) + sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE)); if (SecurityDescriptor == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* set the owner and group */ Status = RtlSetOwnerSecurityDescriptor(SecurityDescriptor, SidToCheck, FALSE); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = RtlSetGroupSecurityDescriptor(SecurityDescriptor, SidToCheck, FALSE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* create the DACL */ Dacl = (PACL)(SecurityDescriptor + 1); Status = RtlCreateAcl(Dacl, sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE), ACL_REVISION); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, 0x1, SidToCheck); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* assign the DACL to the security descriptor */ Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE, Dacl, FALSE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* it's time to perform the access check. Just use _some_ desired access right (same as for the ACE) and see if we're getting it granted. This indicates our SID is a member of the token. We however can't use a generic access right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */ Status = NtAccessCheck(SecurityDescriptor, hToken, 0x1, &GenericMapping, &PrivBuffer.PrivilegeSet, &PrivBufferSize, &GrantedAccess, &AccessStatus); if (NT_SUCCESS(Status) && NT_SUCCESS(AccessStatus) && (GrantedAccess == 0x1)) { *IsMember = TRUE; } Cleanup: if (hToken != NULL && hToken != ExistingTokenHandle) { NtClose(hToken); } if (SecurityDescriptor != NULL) { RtlFreeHeap(RtlGetProcessHeap(), 0, SecurityDescriptor); } if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } return TRUE; }
ULONG BaseSrvDebugProcess( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) { NTSTATUS Status; PBASE_DEBUGPROCESS_MSG a = (PBASE_DEBUGPROCESS_MSG)&m->u.ApiMessageData; HANDLE Thread,ProcessHandle,Token; PCSR_PROCESS Process; DWORD ThreadId; PTOKEN_DEFAULT_DACL lpDefaultDacl; TOKEN_DEFAULT_DACL DefaultDacl; ULONG DaclLength; SECURITY_ATTRIBUTES ThreadAttributes; SECURITY_DESCRIPTOR SecurityDescriptor; UNICODE_STRING ModuleNameString_U; PVOID ModuleHandle; STRING ProcedureNameString; PCREATE_REMOTE_THREAD CreateRemoteThreadRoutine; if (a->dwProcessId == -1 && a->AttachCompleteRoutine == NULL) { HANDLE DebugPort; DebugPort = (HANDLE)NULL; Status = NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, (PVOID)&DebugPort, sizeof(DebugPort), NULL ); if ( NT_SUCCESS(Status) && DebugPort ) { return (ULONG)STATUS_ACCESS_DENIED; } return STATUS_SUCCESS; } #if DEVL if (a->dwProcessId != -1) { #endif // DEVL if ( a->AttachCompleteRoutine == NULL ) { Status = CsrLockProcessByClientId((HANDLE)a->dwProcessId,&Process); if ( NT_SUCCESS(Status) ) { ProcessHandle = Process->ProcessHandle; Status = NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &Token ); if ( !NT_SUCCESS(Status) ) { CsrUnlockProcess(Process); return Status; } lpDefaultDacl = &DefaultDacl; Status = NtQueryInformationToken(Token, TokenDefaultDacl, lpDefaultDacl, sizeof(DefaultDacl), &DaclLength ); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) { Status = STATUS_ACCESS_DENIED; } else { Status = STATUS_SUCCESS; } if ( Process->DebugUserInterface.UniqueProcess || Process->DebugUserInterface.UniqueThread ) { Status = STATUS_ACCESS_DENIED; } NtClose(Token); CsrUnlockProcess(Process); } return (ULONG)Status; } // // Can't call base, but I know it is there // RtlInitUnicodeString( &ModuleNameString_U, L"kernel32" ); Status = LdrLoadDll( UNICODE_NULL, NULL, &ModuleNameString_U, &ModuleHandle ); if ( !NT_SUCCESS(Status) ) { return (ULONG)Status; } RtlInitString( &ProcedureNameString, "CreateRemoteThread" ); Status = LdrGetProcedureAddress( ModuleHandle, &ProcedureNameString, (ULONG) NULL, (PVOID *) &CreateRemoteThreadRoutine ); if ( !NT_SUCCESS(Status) ) { LdrUnloadDll( ModuleHandle ); return (ULONG)Status; } Status = CsrLockProcessByClientId((HANDLE)a->dwProcessId,&Process); if ( NT_SUCCESS(Status) ) { ProcessHandle = Process->ProcessHandle; Status = NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &Token ); if (!NT_SUCCESS(Status)) { CsrUnlockProcess(Process); LdrUnloadDll( ModuleHandle ); return (ULONG)Status; } lpDefaultDacl = &DefaultDacl; Status = NtQueryInformationToken(Token, TokenDefaultDacl, lpDefaultDacl, sizeof(DefaultDacl), &DaclLength ); if (!NT_SUCCESS(Status)) { lpDefaultDacl = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ), DaclLength); if (lpDefaultDacl) { Status = NtQueryInformationToken(Token, TokenDefaultDacl, lpDefaultDacl, DaclLength, &DaclLength ); } else { Status = STATUS_NO_MEMORY; } NtClose(Token); if (!NT_SUCCESS(Status)) { CsrUnlockProcess(Process); LdrUnloadDll( ModuleHandle ); return (ULONG)Status; } } else { NtClose(Token); } ThreadAttributes.nLength = sizeof(ThreadAttributes); RtlCreateSecurityDescriptor(&SecurityDescriptor,SECURITY_DESCRIPTOR_REVISION1); ThreadAttributes.lpSecurityDescriptor = &SecurityDescriptor; SecurityDescriptor.Control = SE_DACL_PRESENT; SecurityDescriptor.Dacl = lpDefaultDacl->DefaultDacl; ThreadAttributes.bInheritHandle = FALSE; CsrUnlockProcess(Process); } #if DEVL } #endif // DEVL // // Set up the specified user-interface as the debugger of the // target process. Whip through the target process and // suspend all threads. Then Send CreateProcess, LoadModule, and // CreateThread Messages. Finally send the attach complete // exception. // Status = CsrDebugProcess( a->dwProcessId, &a->DebuggerClientId, (PCSR_ATTACH_COMPLETE_ROUTINE)a->AttachCompleteRoutine ); #if DEVL if (a->dwProcessId != -1) { #endif // DEVL if ( NT_SUCCESS(Status) ) { Thread = (PVOID)(CreateRemoteThreadRoutine)(ProcessHandle, &ThreadAttributes, 0L, (LPTHREAD_START_ROUTINE)a->AttachCompleteRoutine, 0, 0, &ThreadId ); LdrUnloadDll( ModuleHandle ); if ( lpDefaultDacl != &DefaultDacl ) { RtlFreeHeap(RtlProcessHeap(), 0,lpDefaultDacl); } if ( !Thread ) { return (ULONG)STATUS_UNSUCCESSFUL; } NtClose(Thread); } #if DEVL } #endif // DEVL return (ULONG) Status; }
/****************************************************************************** * OpenProcessToken [ADVAPI32.@] * Opens the access token associated with a process * * PARAMS * ProcessHandle [I] Handle to process * DesiredAccess [I] Desired access to process * TokenHandle [O] Pointer to handle of open access token * * RETURNS STD */ BOOL WINAPI OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess, HANDLE *TokenHandle ) { CallWin32ToNt(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle )); }
BOOLEAN OpenDotNetPublicControlBlock_V4( _In_ BOOLEAN IsImmersive, _In_ HANDLE ProcessHandle, _In_ HANDLE ProcessId, _Out_ HANDLE* BlockTableHandle, _Out_ PVOID* BlockTableAddress ) { BOOLEAN result = FALSE; PVOID boundaryDescriptorHandle = NULL; HANDLE privateNamespaceHandle = NULL; HANDLE blockTableHandle = NULL; HANDLE tokenHandle = NULL; PSID everyoneSIDHandle = NULL; PVOID blockTableAddress = NULL; LARGE_INTEGER sectionOffset = { 0 }; SIZE_T viewSize = 0; UNICODE_STRING prefixNameUs; UNICODE_STRING sectionNameUs; UNICODE_STRING boundaryNameUs; OBJECT_ATTRIBUTES namespaceObjectAttributes; OBJECT_ATTRIBUTES sectionObjectAttributes; PTOKEN_APPCONTAINER_INFORMATION appContainerInfo = NULL; SID_IDENTIFIER_AUTHORITY SIDWorldAuth = SECURITY_WORLD_SID_AUTHORITY; if (!PhStringRefToUnicodeString(&GenerateBoundaryDescriptorName(ProcessId)->sr, &boundaryNameUs)) goto CleanupExit; if (!(boundaryDescriptorHandle = RtlCreateBoundaryDescriptor(&boundaryNameUs, 0))) goto CleanupExit; if (!NT_SUCCESS(RtlAllocateAndInitializeSid(&SIDWorldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyoneSIDHandle))) goto CleanupExit; if (!NT_SUCCESS(RtlAddSIDToBoundaryDescriptor(&boundaryDescriptorHandle, everyoneSIDHandle))) goto CleanupExit; if (WINDOWS_HAS_IMMERSIVE && IsImmersive) { if (NT_SUCCESS(NtOpenProcessToken(&tokenHandle, TOKEN_QUERY, ProcessHandle))) { ULONG returnLength = 0; if (NtQueryInformationToken( tokenHandle, TokenAppContainerSid, NULL, 0, &returnLength ) != STATUS_BUFFER_TOO_SMALL) { goto CleanupExit; } appContainerInfo = PhAllocate(returnLength); if (!NT_SUCCESS(NtQueryInformationToken( tokenHandle, TokenAppContainerSid, appContainerInfo, returnLength, &returnLength ))) { goto CleanupExit; } if (!NT_SUCCESS(RtlAddSIDToBoundaryDescriptor(&boundaryDescriptorHandle, appContainerInfo->TokenAppContainer))) goto CleanupExit; } } RtlInitUnicodeString(&prefixNameUs, CorSxSReaderPrivateNamespacePrefix); InitializeObjectAttributes( &namespaceObjectAttributes, &prefixNameUs, OBJ_CASE_INSENSITIVE, boundaryDescriptorHandle, NULL ); if (!NT_SUCCESS(NtOpenPrivateNamespace( &privateNamespaceHandle, MAXIMUM_ALLOWED, &namespaceObjectAttributes, boundaryDescriptorHandle ))) { goto CleanupExit; } RtlInitUnicodeString(§ionNameUs, CorSxSVistaPublicIPCBlock); InitializeObjectAttributes( §ionObjectAttributes, §ionNameUs, OBJ_CASE_INSENSITIVE, privateNamespaceHandle, NULL ); if (!NT_SUCCESS(NtOpenSection( &blockTableHandle, SECTION_MAP_READ, §ionObjectAttributes ))) { goto CleanupExit; } if (!NT_SUCCESS(NtMapViewOfSection( blockTableHandle, NtCurrentProcess(), &blockTableAddress, 0, viewSize, §ionOffset, &viewSize, ViewShare, 0, PAGE_READONLY ))) { goto CleanupExit; } *BlockTableHandle = blockTableHandle; *BlockTableAddress = blockTableAddress; result = TRUE; CleanupExit: if (!result) { if (blockTableHandle) { NtClose(blockTableHandle); } if (blockTableAddress) { NtUnmapViewOfSection(NtCurrentProcess(), blockTableAddress); } *BlockTableHandle = NULL; *BlockTableAddress = NULL; } if (tokenHandle) { NtClose(tokenHandle); } if (appContainerInfo) { PhFree(appContainerInfo); } if (privateNamespaceHandle) { NtClose(privateNamespaceHandle); } if (everyoneSIDHandle) { RtlFreeSid(everyoneSIDHandle); } if (boundaryDescriptorHandle) { RtlDeleteBoundaryDescriptor(boundaryDescriptorHandle); } return result; }
/*++ * @name CsrSetProcessSecurity * * The CsrSetProcessSecurity routine protects access to the CSRSS process * from unauthorized tampering. * * @param None. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrSetProcessSecurity(VOID) { NTSTATUS Status; HANDLE hToken, hProcess = NtCurrentProcess(); ULONG Length; PTOKEN_USER TokenInfo = NULL; PSECURITY_DESCRIPTOR ProcSd = NULL; PACL Dacl; PSID UserSid; /* Open our token */ Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); if (!NT_SUCCESS(Status)) goto Quickie; /* Get the Token User Length */ NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length); /* Allocate space for it */ TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length); if (!TokenInfo) { Status = STATUS_NO_MEMORY; goto Quickie; } /* Now query the data */ Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length); NtClose(hToken); if (!NT_SUCCESS(Status)) goto Quickie; /* Now check the SID Length */ UserSid = TokenInfo->User.Sid; Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); /* Allocate a buffer for the Security Descriptor, with SID and DACL */ ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); if (!ProcSd) { Status = STATUS_NO_MEMORY; goto Quickie; } /* Set the pointer to the DACL */ Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH); /* Now create the SD itself */ Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status); goto Quickie; } /* Create the DACL for it*/ Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status); goto Quickie; } /* Create the ACE */ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE | PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME | PROCESS_QUERY_INFORMATION | READ_CONTROL, UserSid); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status); goto Quickie; } /* Clear the DACL in the SD */ Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status); goto Quickie; } /* Write the SD into the Process */ Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status); goto Quickie; } /* Free the memory and return */ Quickie: if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd); RtlFreeHeap(CsrHeap, 0, TokenInfo); return Status; }
NTSTATUS SspCreateTokenDacl( HANDLE Token ) /*++ RoutineDescription: Creates a new DACL for the token granting the server and client all access to the token. Arguments: Token - Handle to an impersonation token open for TOKEN_QUERY and WRITE_DAC Return Value: STATUS_INSUFFICIENT_RESOURCES - insufficient memory to complete the function. Errors from NtSetSecurityObject --*/ { NTSTATUS Status; PTOKEN_USER ProcessTokenUser = NULL; PTOKEN_USER ThreadTokenUser = NULL; HANDLE ProcessToken = NULL; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; ULONG AclLength; PACL NewDacl = NULL; SECURITY_DESCRIPTOR SecurityDescriptor; // // Build the two well known sids we need. // EnterCriticalSection(&csCheaterList); if (SspGlobalLocalSystemSid == NULL) { Status = RtlAllocateAndInitializeSid( &NtAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0,0,0,0,0,0,0, &SspGlobalLocalSystemSid ); if (!NT_SUCCESS(Status)) { LeaveCriticalSection(&csCheaterList); goto Cleanup; } } if (SspGlobalAliasAdminsSid == NULL) { Status = RtlAllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0,0,0,0,0,0, &SspGlobalAliasAdminsSid ); if (!NT_SUCCESS(Status)) { LeaveCriticalSection(&csCheaterList); goto Cleanup; } } LeaveCriticalSection(&csCheaterList); // // Open the process token to find out the user sid // Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_QUERY, &ProcessToken ); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = SspGetTokenUser( ProcessToken, &ProcessTokenUser ); if (!NT_SUCCESS(Status)) { goto Cleanup; } // // Now get the token user for the thread. // Status = SspGetTokenUser( Token, &ThreadTokenUser ); if (!NT_SUCCESS(Status)) { goto Cleanup; } AclLength = 4 * sizeof( ACCESS_ALLOWED_ACE ) - 4 * sizeof( ULONG ) + RtlLengthSid( ProcessTokenUser->User.Sid ) + RtlLengthSid( ThreadTokenUser->User.Sid ) + RtlLengthSid( SspGlobalLocalSystemSid ) + RtlLengthSid( SspGlobalAliasAdminsSid ) + sizeof( ACL ); NewDacl = LocalAlloc(0, AclLength ); if (NewDacl == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } Status = RtlCreateAcl( NewDacl, AclLength, ACL_REVISION2 ); ASSERT(NT_SUCCESS( Status )); Status = RtlAddAccessAllowedAce ( NewDacl, ACL_REVISION2, TOKEN_ALL_ACCESS, ProcessTokenUser->User.Sid ); ASSERT( NT_SUCCESS( Status )); Status = RtlAddAccessAllowedAce ( NewDacl, ACL_REVISION2, TOKEN_ALL_ACCESS, ThreadTokenUser->User.Sid ); ASSERT( NT_SUCCESS( Status )); Status = RtlAddAccessAllowedAce ( NewDacl, ACL_REVISION2, TOKEN_ALL_ACCESS, SspGlobalAliasAdminsSid ); ASSERT( NT_SUCCESS( Status )); Status = RtlAddAccessAllowedAce ( NewDacl, ACL_REVISION2, TOKEN_ALL_ACCESS, SspGlobalLocalSystemSid ); ASSERT( NT_SUCCESS( Status )); Status = RtlCreateSecurityDescriptor ( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); ASSERT( NT_SUCCESS( Status )); Status = RtlSetDaclSecurityDescriptor( &SecurityDescriptor, TRUE, NewDacl, FALSE ); ASSERT( NT_SUCCESS( Status )); Status = NtSetSecurityObject( Token, DACL_SECURITY_INFORMATION, &SecurityDescriptor ); ASSERT( NT_SUCCESS( Status )); Cleanup: if (ThreadTokenUser != NULL) { LocalFree( ThreadTokenUser ); } if (ProcessTokenUser != NULL) { LocalFree( ProcessTokenUser ); } if (NewDacl != NULL) { LocalFree( NewDacl ); } if (ProcessToken != NULL) { NtClose(ProcessToken); } return( Status ); }
// Takes ownership on handle (file or registry key). // The handle must be open for WRITE_OWNER access static NTSTATUS NtTakeOwnershipObject(HANDLE ObjectHandle) { SECURITY_DESCRIPTOR sd; PTOKEN_USER pTokenUser = NULL; NTSTATUS Status; HANDLE TokenHandle = NULL; ULONG cbTokenUser = 0; // Open the token of the current process Status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &TokenHandle); if(NT_SUCCESS(Status)) { NtQueryInformationToken(TokenHandle, TokenUser, pTokenUser, cbTokenUser, &cbTokenUser); if(cbTokenUser == 0) { NtClose(TokenHandle); return STATUS_UNSUCCESSFUL; } pTokenUser = (PTOKEN_USER)RtlAllocateHeap(RtlProcessHeap(), 0, cbTokenUser); if(pTokenUser != NULL) { Status = NtQueryInformationToken(TokenHandle, TokenUser, pTokenUser, cbTokenUser, &cbTokenUser); } else { Status = STATUS_NO_MEMORY; } } // Initialize the blank security descriptor if(NT_SUCCESS(Status)) { Status = RtlCreateSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); } // Set the owner to the security descriptor if(NT_SUCCESS(Status)) { Status = RtlSetOwnerSecurityDescriptor(&sd, pTokenUser->User.Sid, FALSE); } // Apply the owner to the object handle if(NT_SUCCESS(Status)) { Status = NtSetSecurityObject(ObjectHandle, OWNER_SECURITY_INFORMATION, &sd); } // Free buffers if(pTokenUser != NULL) RtlFreeHeap(RtlProcessHeap(), 0, pTokenUser); if(TokenHandle != NULL) NtClose(TokenHandle); return Status; }
HANDLE InternalCreateCallbackThread( HANDLE hProcess, DWORD lpfn, DWORD dwData) { LONG BasePriority; HANDLE hThread, hToken; PTOKEN_DEFAULT_DACL lpDaclDefault; TOKEN_DEFAULT_DACL daclDefault; ULONG cbDacl; SECURITY_ATTRIBUTES attrThread; SECURITY_DESCRIPTOR sd; DWORD idThread; NTSTATUS Status; hThread = NULL; Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); if (!NT_SUCCESS(Status)) { KdPrint(("NtOpenProcessToken failed, status = %x\n", Status)); return NULL; } cbDacl = 0; NtQueryInformationToken(hToken, TokenDefaultDacl, &daclDefault, sizeof(daclDefault), &cbDacl); EnterCrit(); // to synchronize heap lpDaclDefault = (PTOKEN_DEFAULT_DACL)LocalAlloc(LMEM_FIXED, cbDacl); LeaveCrit(); if (lpDaclDefault == NULL) { KdPrint(("LocalAlloc failed for lpDaclDefault")); goto closeexit; } Status = NtQueryInformationToken(hToken, TokenDefaultDacl, lpDaclDefault, cbDacl, &cbDacl); if (!NT_SUCCESS(Status)) { KdPrint(("NtQueryInformationToken failed, status = %x\n", Status)); goto freeexit; } if (!NT_SUCCESS(RtlCreateSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION1))) { UserAssert(FALSE); goto freeexit; } RtlSetDaclSecurityDescriptor(&sd, TRUE, lpDaclDefault->DefaultDacl, TRUE); attrThread.nLength = sizeof(attrThread); attrThread.lpSecurityDescriptor = &sd; attrThread.bInheritHandle = FALSE; GetLastError(); hThread = CreateRemoteThread(hProcess, &attrThread, 0L, (LPTHREAD_START_ROUTINE)lpfn, (LPVOID)dwData, 0, &idThread); if (hThread != NULL) { BasePriority = THREAD_PRIORITY_HIGHEST; NtSetInformationThread(hThread, ThreadBasePriority, &BasePriority, sizeof(LONG)); } freeexit: EnterCrit(); // to synchronize heap LocalFree((HANDLE)lpDaclDefault); LeaveCrit(); closeexit: NtClose(hToken); return hThread; }