From 089651339bc13bf8ff583ce720ba8213e127f480 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Tue, 15 Dec 2020 18:21:40 +0100 Subject: [PATCH] Properly fix the debug privilege functionality --- TitanEngine/Global.Debugger.cpp | 1 - TitanEngine/Global.Debugger.h | 1 - .../TitanEngine.Debugger.DebugLoop.cpp | 5 -- TitanEngine/TitanEngine.Debugger.cpp | 60 +++---------------- TitanEngine/TitanEngine.Engine.cpp | 2 + 5 files changed, 10 insertions(+), 59 deletions(-) diff --git a/TitanEngine/Global.Debugger.cpp b/TitanEngine/Global.Debugger.cpp index 3bcbbe1..67762fd 100644 --- a/TitanEngine/Global.Debugger.cpp +++ b/TitanEngine/Global.Debugger.cpp @@ -20,7 +20,6 @@ ULONG_PTR DebugDebuggingMainModuleBase = NULL; ULONG_PTR DebugDebuggingDLLBase = NULL; HANDLE DebugDLLFileMapping; bool DebugAttachedToProcess = false; -bool DebugRemoveDebugPrivilege = false; bool DebugDebuggingDLL = false; wchar_t* DebugDebuggingDLLFullFileName; wchar_t* DebugDebuggingDLLFileName; diff --git a/TitanEngine/Global.Debugger.h b/TitanEngine/Global.Debugger.h index 237272a..7ea275d 100644 --- a/TitanEngine/Global.Debugger.h +++ b/TitanEngine/Global.Debugger.h @@ -15,7 +15,6 @@ extern ULONG_PTR DebugModuleEntryPoint; extern ULONG_PTR DebugModuleImageBase; extern ULONG_PTR DebugAttachedProcessCallBack; extern bool DebugAttachedToProcess; -extern bool DebugRemoveDebugPrivilege; extern ULONG_PTR DebugReserveModuleBase; extern ULONG_PTR DebugDebuggingMainModuleBase; extern ULONG_PTR DebugDebuggingDLLBase; diff --git a/TitanEngine/TitanEngine.Debugger.DebugLoop.cpp b/TitanEngine/TitanEngine.Debugger.DebugLoop.cpp index 238d8c8..8b0864c 100644 --- a/TitanEngine/TitanEngine.Debugger.DebugLoop.cpp +++ b/TitanEngine/TitanEngine.Debugger.DebugLoop.cpp @@ -25,8 +25,6 @@ __declspec(dllexport) void TITCALL DebugLoop() bool hListThreadFirst = true; bool hListLibraryFirst = true; bool MemoryBpxFound = false; - bool RemoveDebugPrivilege = DebugRemoveDebugPrivilege; //store the flag in a local variable - DebugRemoveDebugPrivilege = false; //reset this flag PLIBRARY_ITEM_DATAW hLoadedLibData = NULL; PLIBRARY_BREAK_DATA ptrLibrarianData = NULL; typedef void(TITCALL * fCustomBreakPoint)(void); @@ -162,9 +160,6 @@ __declspec(dllexport) void TITCALL DebugLoop() NewThreadData.ThreadStartAddress = (void*)DBGEvent.u.CreateProcessInfo.lpStartAddress; NewThreadData.ThreadLocalBase = (void*)DBGEvent.u.CreateProcessInfo.lpThreadLocalBase; hListThread.push_back(NewThreadData); - //remove debug privilege from child process - if(RemoveDebugPrivilege) - EngineSetDebugPrivilege(DBGEvent.u.CreateProcessInfo.hProcess, false); } //update process list PROCESS_ITEM_DATA NewProcessItem; diff --git a/TitanEngine/TitanEngine.Debugger.cpp b/TitanEngine/TitanEngine.Debugger.cpp index 3214c0d..db151cd 100644 --- a/TitanEngine/TitanEngine.Debugger.cpp +++ b/TitanEngine/TitanEngine.Debugger.cpp @@ -54,11 +54,6 @@ __declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szC DebugConsoleFlag = CREATE_NO_WINDOW; } - if(engineEnableDebugPrivilege) - { - EngineSetDebugPrivilege(GetCurrentProcess(), true); - DebugRemoveDebugPrivilege = true; - } wchar_t* szFileNameCreateProcess; wchar_t* szCommandLineCreateProcess; std::wstring createWithCmdLine; @@ -77,7 +72,13 @@ __declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szC szCommandLineCreateProcess = (wchar_t*)createWithCmdLine.c_str(); szFileNameCreateProcess = 0; } - if(CreateProcessW(szFileNameCreateProcess, szCommandLineCreateProcess, NULL, NULL, false, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | DebugConsoleFlag | CREATE_NEW_CONSOLE, NULL, szCurrentFolder, &dbgStartupInfo, &dbgProcessInformation)) + // Temporarily disable the debug privilege so the child doesn't inherit it (this evades debugger detection) + if (engineEnableDebugPrivilege) + EngineSetDebugPrivilege(GetCurrentProcess(), false); + auto createProcessResult = CreateProcessW(szFileNameCreateProcess, szCommandLineCreateProcess, NULL, NULL, false, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | DebugConsoleFlag | CREATE_NEW_CONSOLE, NULL, szCurrentFolder, &dbgStartupInfo, &dbgProcessInformation); + if (engineEnableDebugPrivilege) + EngineSetDebugPrivilege(GetCurrentProcess(), true); + if(createProcessResult) { DebugAttachedToProcess = false; DebugAttachedProcessCallBack = NULL; @@ -86,11 +87,6 @@ __declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szC else { DWORD lastError = GetLastError(); - if(engineEnableDebugPrivilege) - { - EngineSetDebugPrivilege(GetCurrentProcess(), false); - DebugRemoveDebugPrivilege = false; - } memset(&dbgProcessInformation, 0, sizeof(PROCESS_INFORMATION)); SetLastError(lastError); return 0; @@ -197,20 +193,6 @@ __declspec(dllexport) void* TITCALL InitNativeDebugW(wchar_t* szFileName, wchar_ return NULL; } - // Enable SE_DEBUG if needed - BOOLEAN SeDebugWasEnabled = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - if(engineEnableDebugPrivilege) - { - Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, - TRUE, - FALSE, - &SeDebugWasEnabled); - DebugRemoveDebugPrivilege = true; - } - if(!NT_SUCCESS(Status)) - goto finished; - // Convert command line and directory to UNICODE_STRING if present SIZE_T ArgumentsLength = szCommandLine != NULL ? lstrlenW(szCommandLine) : 0; SIZE_T BufferSize = ImagePath.Length + ((ArgumentsLength + 4) * sizeof(wchar_t)); @@ -235,7 +217,7 @@ __declspec(dllexport) void* TITCALL InitNativeDebugW(wchar_t* szFileName, wchar_ // Create the process parameter block PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; PRTL_USER_PROCESS_PARAMETERS OwnParameters = NtCurrentPeb()->ProcessParameters; - Status = fnRtlCreateProcessParametersEx(&ProcessParameters, + NTSTATUS Status = fnRtlCreateProcessParametersEx(&ProcessParameters, &ImagePath, NULL, // Create a new DLL path PtrCurrentDirectory, @@ -375,22 +357,6 @@ finished: } } - // Release SE_DEBUG if we acquired it previously - if(engineEnableDebugPrivilege && !SeDebugWasEnabled) - RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, - FALSE, - FALSE, - &SeDebugWasEnabled); - - if(!NT_SUCCESS(Status)) - { - // Set error status - ULONG Win32Error = RtlNtStatusToDosError(Status); - RtlSetLastWin32Error(Win32Error); - DebugRemoveDebugPrivilege = false; - return NULL; - } - DebugAttachedToProcess = false; DebugAttachedProcessCallBack = NULL; @@ -542,11 +508,6 @@ __declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnEx if(ProcessId != NULL && dbgProcessInformation.hProcess == NULL) { - if(engineEnableDebugPrivilege) - { - EngineSetDebugPrivilege(GetCurrentProcess(), true); - DebugRemoveDebugPrivilege = true; - } if(DebugActiveProcess_(ProcessId)) { funcDebugSetProcessKillOnExit = GetProcAddress(GetModuleHandleA("kernel32.dll"), "DebugSetProcessKillOnExit"); @@ -566,11 +527,6 @@ __declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnEx return true; } } - if (engineEnableDebugPrivilege) - { - EngineSetDebugPrivilege(GetCurrentProcess(), false); - DebugRemoveDebugPrivilege = false; - } return false; } diff --git a/TitanEngine/TitanEngine.Engine.cpp b/TitanEngine/TitanEngine.Engine.cpp index 75945e4..6305a20 100644 --- a/TitanEngine/TitanEngine.Engine.cpp +++ b/TitanEngine/TitanEngine.Engine.cpp @@ -5,6 +5,7 @@ #include "Global.Engine.Hook.h" #include "Global.Engine.GUI.h" #include "Global.Engine.Extension.h" +#include "Global.Debugger.h" // TitanEngine.Engine.functions: __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool VariableSet) @@ -41,6 +42,7 @@ __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool Vari else if(VariableId == UE_ENGINE_SET_DEBUG_PRIVILEGE) { engineEnableDebugPrivilege = VariableSet; + EngineSetDebugPrivilege(GetCurrentProcess(), VariableSet); } else if(VariableId == UE_ENGINE_SAFE_ATTACH) {