Fix EngineSetDebugPrivilege deadlocking the system when trying to debug lsass.exe

This commit is contained in:
Matthijs Lavrijsen 2020-08-18 05:25:55 +02:00
parent 51ba022c29
commit 3ec69c8c2b
No known key found for this signature in database
GPG Key ID: D40D1DBE299B83EA
3 changed files with 69 additions and 29 deletions

View File

@ -2031,34 +2031,37 @@ ULONG_PTR EngineGlobalAPIHandler(HANDLE handleProcess, ULONG_PTR EnumedModulesBa
DWORD EngineSetDebugPrivilege(HANDLE hProcess, bool bEnablePrivilege) DWORD EngineSetDebugPrivilege(HANDLE hProcess, bool bEnablePrivilege)
{ {
DWORD dwLastError; HANDLE TokenHandle;
HANDLE hToken = 0; NTSTATUS Status = NtOpenProcessToken(hProcess,
if(!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
{ &TokenHandle);
dwLastError = GetLastError(); if (!NT_SUCCESS(Status))
if(hToken) return RtlNtStatusToDosError(Status);
CloseHandle(hToken);
return dwLastError; LUID LuidPrivilege;
} LuidPrivilege.LowPart = SE_DEBUG_PRIVILEGE;
TOKEN_PRIVILEGES tokenPrivileges; LuidPrivilege.HighPart = 0;
memset(&tokenPrivileges, 0, sizeof(TOKEN_PRIVILEGES));
LUID luid; TOKEN_PRIVILEGES Privileges;
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) Privileges.PrivilegeCount = 1;
{ Privileges.Privileges[0].Luid = LuidPrivilege;
dwLastError = GetLastError(); Privileges.Privileges[0].Attributes = bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0;
CloseHandle(hToken);
return dwLastError; ULONG ReturnLength;
} Status = NtAdjustPrivilegesToken(TokenHandle,
tokenPrivileges.PrivilegeCount = 1; FALSE,
tokenPrivileges.Privileges[0].Luid = luid; &Privileges,
if(bEnablePrivilege) sizeof(Privileges),
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; nullptr,
else &ReturnLength);
tokenPrivileges.Privileges[0].Attributes = 0; NtClose(TokenHandle);
AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
dwLastError = GetLastError(); // Map the success code NOT_ALL_ASSIGNED to an appropriate error
CloseHandle(hToken); // since we're only trying to adjust one privilege.
return dwLastError; if (Status == STATUS_NOT_ALL_ASSIGNED)
Status = STATUS_PRIVILEGE_NOT_HELD;
return NT_SUCCESS(Status) ? ERROR_SUCCESS : RtlNtStatusToDosError(Status);
} }
HANDLE EngineOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId) HANDLE EngineOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId)

View File

@ -200,7 +200,6 @@ __declspec(dllexport) void* TITCALL InitNativeDebugW(wchar_t* szFileName, wchar_
} }
// Enable SE_DEBUG if needed // Enable SE_DEBUG if needed
const LONG SE_DEBUG_PRIVILEGE = 20L;
BOOLEAN SeDebugWasEnabled = FALSE; BOOLEAN SeDebugWasEnabled = FALSE;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
if(engineEnableDebugPrivilege) if(engineEnableDebugPrivilege)

View File

@ -451,6 +451,44 @@ typedef struct _FILE_POSITION_INFORMATION
LARGE_INTEGER CurrentByteOffset; LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
// Privileges
#define SE_MIN_WELL_KNOWN_PRIVILEGE (2L)
#define SE_CREATE_TOKEN_PRIVILEGE (2L)
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L)
#define SE_LOCK_MEMORY_PRIVILEGE (4L)
#define SE_INCREASE_QUOTA_PRIVILEGE (5L)
#define SE_MACHINE_ACCOUNT_PRIVILEGE (6L)
#define SE_TCB_PRIVILEGE (7L)
#define SE_SECURITY_PRIVILEGE (8L)
#define SE_TAKE_OWNERSHIP_PRIVILEGE (9L)
#define SE_LOAD_DRIVER_PRIVILEGE (10L)
#define SE_SYSTEM_PROFILE_PRIVILEGE (11L)
#define SE_SYSTEMTIME_PRIVILEGE (12L)
#define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L)
#define SE_INC_BASE_PRIORITY_PRIVILEGE (14L)
#define SE_CREATE_PAGEFILE_PRIVILEGE (15L)
#define SE_CREATE_PERMANENT_PRIVILEGE (16L)
#define SE_BACKUP_PRIVILEGE (17L)
#define SE_RESTORE_PRIVILEGE (18L)
#define SE_SHUTDOWN_PRIVILEGE (19L)
#define SE_DEBUG_PRIVILEGE (20L)
#define SE_AUDIT_PRIVILEGE (21L)
#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE (22L)
#define SE_CHANGE_NOTIFY_PRIVILEGE (23L)
#define SE_REMOTE_SHUTDOWN_PRIVILEGE (24L)
#define SE_UNDOCK_PRIVILEGE (25L)
#define SE_SYNC_AGENT_PRIVILEGE (26L)
#define SE_ENABLE_DELEGATION_PRIVILEGE (27L)
#define SE_MANAGE_VOLUME_PRIVILEGE (28L)
#define SE_IMPERSONATE_PRIVILEGE (29L)
#define SE_CREATE_GLOBAL_PRIVILEGE (30L)
#define SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE (31L)
#define SE_RELABEL_PRIVILEGE (32L)
#define SE_INC_WORKING_SET_PRIVILEGE (33L)
#define SE_TIME_ZONE_PRIVILEGE (34L)
#define SE_CREATE_SYMBOLIC_LINK_PRIVILEGE (35L)
#define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_SYMBOLIC_LINK_PRIVILEGE
typedef struct _THREAD_BASIC_INFORMATION typedef struct _THREAD_BASIC_INFORMATION
{ {
NTSTATUS ExitStatus; NTSTATUS ExitStatus;