mirror of
https://github.com/8damon/Blackbird-Platform
synced 2026-06-21 13:41:12 +00:00
604 lines
23 KiB
C
604 lines
23 KiB
C
#include <fltkernel.h>
|
|
#include <ntstrsafe.h>
|
|
#include "..\core\control.h"
|
|
#include "..\core\tempus_debug.h"
|
|
#include "..\core\runtime_config.h"
|
|
#include "..\core\unicode_utils.h"
|
|
#include "..\hooks\monitor\ntapi_monitor.h"
|
|
#include "filesystem_monitor.h"
|
|
|
|
static PFLT_FILTER g_FileSystemFilter = NULL;
|
|
static volatile LONG g_FileSystemMonitorRegistered = 0;
|
|
static volatile LONG g_FileSystemMonitorFailureCounter = 0;
|
|
|
|
#define BK_FS_TARGET_STREAM_MASK \
|
|
(BK_STREAM_HANDLE | BK_STREAM_MEMORY | BK_STREAM_THREAD | BK_STREAM_FILESYSTEM | BK_STREAM_REGISTRY | \
|
|
BK_STREAM_TIMING | BK_STREAM_ENTERPRISE)
|
|
#define BK_FS_LIT_CHARS(_Literal) ((USHORT)(RTL_NUMBER_OF(_Literal) - 1))
|
|
|
|
static BOOLEAN BkcfsIsTargetProcess(_In_ UINT32 ProcessId)
|
|
{
|
|
return (BkctlIsArmedFast() && BkctlHasPidInterest(ProcessId, 0, BK_FS_TARGET_STREAM_MASK));
|
|
}
|
|
|
|
static BOOLEAN BkcfsPathContainsBlackbirdArtifact(_In_opt_z_ PCWSTR Path)
|
|
{
|
|
UNICODE_STRING pathUs;
|
|
|
|
if (Path == NULL || Path[0] == L'\0')
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&pathUs, Path);
|
|
return (
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\programdata\\blackbird",
|
|
BK_FS_LIT_CHARS(L"\\programdata\\blackbird")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\blackbird\\", BK_FS_LIT_CHARS(L"\\blackbird\\")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\blackbird", BK_FS_LIT_CHARS(L"\\blackbird")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"blackbird.sys", BK_FS_LIT_CHARS(L"blackbird.sys")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"blackbirdcontroller.exe",
|
|
BK_FS_LIT_CHARS(L"blackbirdcontroller.exe")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"blackbirdinterface.exe",
|
|
BK_FS_LIT_CHARS(L"blackbirdinterface.exe")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"blackbirdnetsvc.exe", BK_FS_LIT_CHARS(L"blackbirdnetsvc.exe")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"blackbirddllhost.exe", BK_FS_LIT_CHARS(L"blackbirddllhost.exe")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"sr71.dll", BK_FS_LIT_CHARS(L"sr71.dll")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"j58.dll", BK_FS_LIT_CHARS(L"j58.dll")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"bkdc.dll", BK_FS_LIT_CHARS(L"bkdc.dll")));
|
|
}
|
|
|
|
static BOOLEAN BkcfsPathContainsBlackbirdRuntimeAccessArtifact(_In_opt_z_ PCWSTR Path)
|
|
{
|
|
UNICODE_STRING pathUs;
|
|
|
|
if (Path == NULL || Path[0] == L'\0')
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&pathUs, Path);
|
|
return (BkstrUnicodeContainsInsensitive(&pathUs, L"sr71.dll", BK_FS_LIT_CHARS(L"sr71.dll")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"j58.dll", BK_FS_LIT_CHARS(L"j58.dll")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"bkdc.dll", BK_FS_LIT_CHARS(L"bkdc.dll")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"sr71-", BK_FS_LIT_CHARS(L"sr71-")));
|
|
}
|
|
|
|
static BOOLEAN BkcfsShouldConcealBlackbirdArtifact(_In_ const BK_FILE_EVENT *Event)
|
|
{
|
|
if (Event == NULL || !BkcfsPathContainsBlackbirdArtifact(Event->Path))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return !BkcfsPathContainsBlackbirdRuntimeAccessArtifact(Event->Path);
|
|
}
|
|
|
|
static BOOLEAN BkcfsShouldHidePath(_In_opt_z_ PCWSTR Path)
|
|
{
|
|
UNICODE_STRING pathUs;
|
|
|
|
if (Path == NULL || Path[0] == L'\0' || !BkrtIsAntiVirtualizationEnabled())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&pathUs, Path);
|
|
return (BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vmhgfs.sys", 35) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vmmouse.sys", 36) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vmrawdsk.sys", 37) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vmusbmouse.sys", 39) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vmci.sys", 33) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vsock.sys", 34) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vmbus.sys", 34) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\hyperkbd.sys", 37) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\vmstorfl.sys", 37) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\program files\\vmware\\vmware tools", 34));
|
|
}
|
|
|
|
static BOOLEAN BkcfsFileOperationIsWriteLike(_In_ const BK_FILE_EVENT *Event)
|
|
{
|
|
if (Event == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (Event->Operation == BlackbirdFileOperationWrite || Event->Operation == BlackbirdFileOperationSetInformation ||
|
|
Event->Operation == BlackbirdFileOperationFsControl)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (Event->Operation != BlackbirdFileOperationCreate)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ((Event->DesiredAccess &
|
|
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | DELETE)) != 0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return (Event->CreateDisposition == FILE_CREATE || Event->CreateDisposition == FILE_OPEN_IF ||
|
|
Event->CreateDisposition == FILE_OVERWRITE || Event->CreateDisposition == FILE_OVERWRITE_IF ||
|
|
Event->CreateDisposition == FILE_SUPERSEDE);
|
|
}
|
|
|
|
static UINT32 BkcfsEnterpriseAccessFlags(_In_ const BK_FILE_EVENT *Event)
|
|
{
|
|
UINT32 flags = 0;
|
|
BOOLEAN writeLike = BkcfsFileOperationIsWriteLike(Event);
|
|
|
|
if (Event == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (writeLike)
|
|
{
|
|
flags |= BK_ENTERPRISE_FLAG_WRITE;
|
|
}
|
|
else
|
|
{
|
|
flags |= BK_ENTERPRISE_FLAG_QUERY;
|
|
}
|
|
if (Event->Operation == BlackbirdFileOperationCreate)
|
|
{
|
|
flags |= BK_ENTERPRISE_FLAG_CREATE;
|
|
}
|
|
|
|
return flags;
|
|
}
|
|
|
|
static BOOLEAN BkcfsClassifyEnterprisePath(_In_opt_z_ PCWSTR Path, _In_ const BK_FILE_EVENT *Event,
|
|
_Out_ UINT32 *Operation, _Out_ UINT32 *Flags)
|
|
{
|
|
UNICODE_STRING pathUs;
|
|
UINT32 accessFlags;
|
|
|
|
if (Path == NULL || Path[0] == L'\0' || Event == NULL || Operation == NULL || Flags == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&pathUs, Path);
|
|
accessFlags = BkcfsEnterpriseAccessFlags(Event);
|
|
|
|
if (BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\config\\sam",
|
|
BK_FS_LIT_CHARS(L"\\windows\\system32\\config\\sam")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\config\\security",
|
|
BK_FS_LIT_CHARS(L"\\windows\\system32\\config\\security")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\config\\system",
|
|
BK_FS_LIT_CHARS(L"\\windows\\system32\\config\\system")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\config\\regback\\sam",
|
|
BK_FS_LIT_CHARS(L"\\windows\\system32\\config\\regback\\sam")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\config\\regback\\security",
|
|
BK_FS_LIT_CHARS(L"\\windows\\system32\\config\\regback\\security")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\config\\regback\\system",
|
|
BK_FS_LIT_CHARS(L"\\windows\\system32\\config\\regback\\system")))
|
|
{
|
|
*Operation = BkEnterpriseOperationFileCredentialStoreAccess;
|
|
*Flags = BK_ENTERPRISE_FLAG_HIGH_SIGNAL | BK_ENTERPRISE_FLAG_CRITICAL | accessFlags |
|
|
BK_ENTERPRISE_FLAG_CREDENTIAL_FILE | BK_ENTERPRISE_FLAG_SECURITY_HIVE |
|
|
BK_ENTERPRISE_FLAG_KERBEROS_NTLM;
|
|
return TRUE;
|
|
}
|
|
|
|
if (BkstrUnicodeContainsInsensitive(&pathUs, L"\\ntds.dit", BK_FS_LIT_CHARS(L"\\ntds.dit")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\ntds\\", BK_FS_LIT_CHARS(L"\\windows\\ntds\\")))
|
|
{
|
|
*Operation = BkEnterpriseOperationFileCredentialStoreAccess;
|
|
*Flags = BK_ENTERPRISE_FLAG_HIGH_SIGNAL | BK_ENTERPRISE_FLAG_CRITICAL | accessFlags |
|
|
BK_ENTERPRISE_FLAG_CREDENTIAL_FILE | BK_ENTERPRISE_FLAG_KERBEROS_NTLM;
|
|
return TRUE;
|
|
}
|
|
|
|
if (BkstrUnicodeContainsInsensitive(&pathUs, L"\\microsoft\\credentials\\",
|
|
BK_FS_LIT_CHARS(L"\\microsoft\\credentials\\")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\microsoft\\protect\\",
|
|
BK_FS_LIT_CHARS(L"\\microsoft\\protect\\")) ||
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\microsoft\\vault\\", BK_FS_LIT_CHARS(L"\\microsoft\\vault\\")))
|
|
{
|
|
*Operation = BkEnterpriseOperationFileDirectoryCredentialAccess;
|
|
*Flags = BK_ENTERPRISE_FLAG_HIGH_SIGNAL | accessFlags | BK_ENTERPRISE_FLAG_CREDENTIAL_FILE;
|
|
return TRUE;
|
|
}
|
|
|
|
if (BkcfsFileOperationIsWriteLike(Event) &&
|
|
BkstrUnicodeContainsInsensitive(&pathUs, L"\\windows\\system32\\drivers\\",
|
|
BK_FS_LIT_CHARS(L"\\windows\\system32\\drivers\\")))
|
|
{
|
|
*Operation = BkEnterpriseOperationFileDriverArtifactAccess;
|
|
*Flags = BK_ENTERPRISE_FLAG_HIGH_SIGNAL | accessFlags | BK_ENTERPRISE_FLAG_DRIVER_ARTIFACT;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static VOID BkcfsPublishEnterpriseEvent(_In_ const BK_FILE_EVENT *FileEvent)
|
|
{
|
|
BK_ENTERPRISE_EVENT event;
|
|
UINT32 operation = BkEnterpriseOperationUnknown;
|
|
UINT32 flags = 0;
|
|
UINT32 pid32;
|
|
|
|
if (FileEvent == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pid32 = (UINT32)FileEvent->ProcessId;
|
|
if (pid32 == 0 || !BkctlHasPidInterest(pid32, 0, BK_STREAM_ENTERPRISE))
|
|
{
|
|
return;
|
|
}
|
|
if (!BkcfsClassifyEnterprisePath(FileEvent->Path, FileEvent, &operation, &flags))
|
|
{
|
|
return;
|
|
}
|
|
|
|
RtlZeroMemory(&event, sizeof(event));
|
|
event.ProcessId = FileEvent->ProcessId;
|
|
event.ThreadId = FileEvent->ThreadId;
|
|
event.ObjectAddress = FileEvent->FileObject;
|
|
event.Aux0 = FileEvent->Length;
|
|
event.Aux1 = FileEvent->FileId;
|
|
event.Operation = operation;
|
|
event.SubOperation = FileEvent->Operation;
|
|
event.Flags = flags;
|
|
event.DesiredAccess = FileEvent->DesiredAccess;
|
|
event.Status = (UINT32)FileEvent->Status;
|
|
BkctlPublishEnterpriseEvent(&event);
|
|
}
|
|
|
|
static UINT32 BkcfsMapMajorToFileOperation(_In_ UCHAR MajorFunction)
|
|
{
|
|
switch (MajorFunction)
|
|
{
|
|
case IRP_MJ_CREATE:
|
|
return BlackbirdFileOperationCreate;
|
|
case IRP_MJ_READ:
|
|
return BlackbirdFileOperationRead;
|
|
case IRP_MJ_WRITE:
|
|
return BlackbirdFileOperationWrite;
|
|
case IRP_MJ_CLOSE:
|
|
return BlackbirdFileOperationClose;
|
|
case IRP_MJ_CLEANUP:
|
|
return BlackbirdFileOperationCleanup;
|
|
case IRP_MJ_SET_INFORMATION:
|
|
return BlackbirdFileOperationSetInformation;
|
|
case IRP_MJ_QUERY_INFORMATION:
|
|
return BlackbirdFileOperationQueryInformation;
|
|
case IRP_MJ_DIRECTORY_CONTROL:
|
|
return BlackbirdFileOperationDirectoryControl;
|
|
case IRP_MJ_FILE_SYSTEM_CONTROL:
|
|
return BlackbirdFileOperationFsControl;
|
|
default:
|
|
return BlackbirdFileOperationUnknown;
|
|
}
|
|
}
|
|
|
|
static VOID BkcfsCaptureFilePath(_In_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects,
|
|
_Out_writes_z_(PathChars) PWSTR Path, _In_ size_t PathChars)
|
|
{
|
|
NTSTATUS status;
|
|
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
|
|
|
|
if (Path == NULL || PathChars == 0)
|
|
{
|
|
return;
|
|
}
|
|
Path[0] = L'\0';
|
|
|
|
if (KeGetCurrentIrql() <= APC_LEVEL)
|
|
{
|
|
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo);
|
|
if (NT_SUCCESS(status) && nameInfo != NULL)
|
|
{
|
|
(void)FltParseFileNameInformation(nameInfo);
|
|
if (nameInfo->Name.Buffer != NULL && nameInfo->Name.Length != 0)
|
|
{
|
|
(void)RtlStringCchCopyNW(Path, PathChars, nameInfo->Name.Buffer, nameInfo->Name.Length / sizeof(WCHAR));
|
|
}
|
|
FltReleaseFileNameInformation(nameInfo);
|
|
if (Path[0] != L'\0')
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FltObjects != NULL && FltObjects->FileObject != NULL && FltObjects->FileObject->FileName.Buffer != NULL &&
|
|
FltObjects->FileObject->FileName.Length != 0)
|
|
{
|
|
(void)RtlStringCchCopyNW(Path, PathChars, FltObjects->FileObject->FileName.Buffer,
|
|
FltObjects->FileObject->FileName.Length / sizeof(WCHAR));
|
|
}
|
|
}
|
|
|
|
static VOID BkcfsFillCommonFileEventFields(_In_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects,
|
|
_Out_ BK_FILE_EVENT *Event)
|
|
{
|
|
const FLT_IO_PARAMETER_BLOCK *iopb;
|
|
UINT32 flags = 0;
|
|
ULONG createOptionsRaw = 0;
|
|
|
|
iopb = Data->Iopb;
|
|
Event->ProcessId = (UINT64)(ULONG_PTR)PsGetCurrentProcessId();
|
|
Event->ThreadId = (UINT64)(ULONG_PTR)PsGetCurrentThreadId();
|
|
Event->Operation = BkcfsMapMajorToFileOperation(iopb->MajorFunction);
|
|
Event->MajorCode = iopb->MajorFunction;
|
|
Event->MinorCode = iopb->MinorFunction;
|
|
Event->IrpFlags = iopb->IrpFlags;
|
|
Event->Status = (UINT64)(UINT32)Data->IoStatus.Status;
|
|
Event->Information = (UINT64)Data->IoStatus.Information;
|
|
Event->FileObject = (UINT64)(ULONG_PTR)FltObjects->FileObject;
|
|
Event->FileId = (FltObjects->FileObject != NULL) ? (UINT64)(ULONG_PTR)FltObjects->FileObject->FsContext : 0;
|
|
Event->Flags = BK_FILE_FLAG_PRE_OPERATION;
|
|
|
|
if ((iopb->IrpFlags & IRP_PAGING_IO) != 0)
|
|
{
|
|
flags |= BK_FILE_FLAG_PAGING_IO;
|
|
}
|
|
if ((iopb->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) != 0)
|
|
{
|
|
flags |= BK_FILE_FLAG_SYNCHRONOUS_IO;
|
|
}
|
|
if ((iopb->IrpFlags & IRP_NOCACHE) != 0)
|
|
{
|
|
flags |= BK_FILE_FLAG_NON_CACHED_IO;
|
|
}
|
|
|
|
if (iopb->MajorFunction == IRP_MJ_CREATE)
|
|
{
|
|
if (iopb->Parameters.Create.SecurityContext != NULL)
|
|
{
|
|
Event->DesiredAccess = iopb->Parameters.Create.SecurityContext->DesiredAccess;
|
|
}
|
|
Event->ShareAccess = iopb->Parameters.Create.ShareAccess;
|
|
createOptionsRaw = iopb->Parameters.Create.Options;
|
|
Event->CreateDisposition = (createOptionsRaw >> 24) & 0xFFu;
|
|
Event->CreateOptions = createOptionsRaw & 0x00FFFFFFu;
|
|
|
|
if ((Event->CreateOptions & FILE_DIRECTORY_FILE) != 0)
|
|
{
|
|
flags |= BK_FILE_FLAG_DIRECTORY_FILE;
|
|
}
|
|
if ((Event->CreateOptions & FILE_DELETE_ON_CLOSE) != 0)
|
|
{
|
|
flags |= BK_FILE_FLAG_DELETE_ON_CLOSE;
|
|
}
|
|
if ((Event->CreateOptions & FILE_OPEN_REPARSE_POINT) != 0)
|
|
{
|
|
flags |= BK_FILE_FLAG_REPARSE_POINT;
|
|
}
|
|
}
|
|
else if (iopb->MajorFunction == IRP_MJ_READ)
|
|
{
|
|
Event->Length = iopb->Parameters.Read.Length;
|
|
Event->ByteOffset = (UINT64)iopb->Parameters.Read.ByteOffset.QuadPart;
|
|
}
|
|
else if (iopb->MajorFunction == IRP_MJ_WRITE)
|
|
{
|
|
Event->Length = iopb->Parameters.Write.Length;
|
|
Event->ByteOffset = (UINT64)iopb->Parameters.Write.ByteOffset.QuadPart;
|
|
}
|
|
else if (iopb->MajorFunction == IRP_MJ_SET_INFORMATION)
|
|
{
|
|
Event->Length = iopb->Parameters.SetFileInformation.Length;
|
|
}
|
|
else if (iopb->MajorFunction == IRP_MJ_QUERY_INFORMATION)
|
|
{
|
|
Event->Length = iopb->Parameters.QueryFileInformation.Length;
|
|
}
|
|
else if (iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL)
|
|
{
|
|
if (iopb->MinorFunction == IRP_MN_QUERY_DIRECTORY)
|
|
{
|
|
Event->Length = iopb->Parameters.DirectoryControl.QueryDirectory.Length;
|
|
}
|
|
else if (iopb->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY)
|
|
{
|
|
Event->Length = iopb->Parameters.DirectoryControl.NotifyDirectory.Length;
|
|
}
|
|
}
|
|
|
|
Event->Flags |= flags;
|
|
}
|
|
|
|
_Function_class_(FLT_PRE_OPERATION_CALLBACK) static FLT_PREOP_CALLBACK_STATUS
|
|
BkcfsPreOperation(_Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects,
|
|
_Outptr_result_maybenull_ PVOID *CompletionContext)
|
|
{
|
|
ULONGLONG tempusStartQpc = BktmpEnter(BktmpSubsystemFileSystemMonitor);
|
|
BK_FILE_EVENT event;
|
|
UINT32 processPid32;
|
|
BOOLEAN hasFilesystemInterest;
|
|
BOOLEAN hasEnterpriseInterest;
|
|
BOOLEAN isTargetProcess;
|
|
|
|
UNREFERENCED_PARAMETER(CompletionContext);
|
|
|
|
if (Data == NULL || FltObjects == NULL || Data->Iopb == NULL)
|
|
{
|
|
BktmpLeave(BktmpSubsystemFileSystemMonitor, tempusStartQpc);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
if (!BkctlIsArmedFast())
|
|
{
|
|
BktmpLeave(BktmpSubsystemFileSystemMonitor, tempusStartQpc);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
processPid32 = (UINT32)(ULONG_PTR)PsGetCurrentProcessId();
|
|
hasFilesystemInterest = BkctlHasPidInterest(processPid32, 0, BK_STREAM_FILESYSTEM);
|
|
hasEnterpriseInterest = BkctlHasPidInterest(processPid32, 0, BK_STREAM_ENTERPRISE);
|
|
isTargetProcess = BkcfsIsTargetProcess(processPid32);
|
|
if (!hasFilesystemInterest && !hasEnterpriseInterest && !isTargetProcess)
|
|
{
|
|
BktmpLeave(BktmpSubsystemFileSystemMonitor, tempusStartQpc);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
RtlZeroMemory(&event, sizeof(event));
|
|
BkcfsFillCommonFileEventFields(Data, FltObjects, &event);
|
|
BkcfsCaptureFilePath(Data, FltObjects, event.Path, RTL_NUMBER_OF(event.Path));
|
|
|
|
if (isTargetProcess && (BkcfsShouldHidePath(event.Path) || BkcfsShouldConcealBlackbirdArtifact(&event)))
|
|
{
|
|
BkntkiRecordSanitizerHit(BkcfsShouldConcealBlackbirdArtifact(&event) ? BkDiagSanitizerFilesystemBlackbird
|
|
: BkDiagSanitizerFilesystemAntiVm);
|
|
Data->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
|
Data->IoStatus.Information = 0;
|
|
BktmpLeave(BktmpSubsystemFileSystemMonitor, tempusStartQpc);
|
|
return FLT_PREOP_COMPLETE;
|
|
}
|
|
|
|
if (hasFilesystemInterest)
|
|
{
|
|
BkctlPublishFileEvent(&event);
|
|
}
|
|
if (hasEnterpriseInterest)
|
|
{
|
|
BkcfsPublishEnterpriseEvent(&event);
|
|
}
|
|
|
|
BktmpLeave(BktmpSubsystemFileSystemMonitor, tempusStartQpc);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
_Function_class_(PFLT_FILTER_UNLOAD_CALLBACK) static NTSTATUS BkcfsFilterUnload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags)
|
|
{
|
|
UNREFERENCED_PARAMETER(Flags);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
_Function_class_(PFLT_INSTANCE_SETUP_CALLBACK) static NTSTATUS
|
|
BkcfsInstanceSetup(_In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
|
_In_ DEVICE_TYPE VolumeDeviceType, _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType)
|
|
{
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(Flags);
|
|
UNREFERENCED_PARAMETER(VolumeDeviceType);
|
|
UNREFERENCED_PARAMETER(VolumeFilesystemType);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
static const FLT_OPERATION_REGISTRATION g_BlackbirdFsCallbacks[] = {
|
|
{IRP_MJ_CREATE, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_READ, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_WRITE, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_CLOSE, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_CLEANUP, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_SET_INFORMATION, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_QUERY_INFORMATION, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_DIRECTORY_CONTROL, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_FILE_SYSTEM_CONTROL, 0, BkcfsPreOperation, NULL},
|
|
{IRP_MJ_OPERATION_END}};
|
|
|
|
static const FLT_REGISTRATION g_BlackbirdFsRegistration = {sizeof(FLT_REGISTRATION),
|
|
FLT_REGISTRATION_VERSION,
|
|
0,
|
|
NULL,
|
|
g_BlackbirdFsCallbacks,
|
|
BkcfsFilterUnload,
|
|
BkcfsInstanceSetup,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL};
|
|
|
|
NTSTATUS
|
|
BkcfsInitialize(_In_ PDRIVER_OBJECT DriverObject)
|
|
{
|
|
NTSTATUS status;
|
|
LONG failures;
|
|
|
|
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
|
|
{
|
|
return STATUS_INVALID_DEVICE_STATE;
|
|
}
|
|
if (DriverObject == NULL)
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
if (InterlockedCompareExchange(&g_FileSystemMonitorRegistered, 0, 0) != 0)
|
|
{
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
status = FltRegisterFilter(DriverObject, &g_BlackbirdFsRegistration, &g_FileSystemFilter);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
failures = InterlockedIncrement(&g_FileSystemMonitorFailureCounter);
|
|
if (failures == 1 || ((failures & 0xFF) == 0))
|
|
{
|
|
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
|
|
"BK: filesystem monitor filter registration failed status=0x%08X total=%lu.\n", status,
|
|
(ULONG)failures);
|
|
}
|
|
g_FileSystemFilter = NULL;
|
|
return status;
|
|
}
|
|
|
|
status = FltStartFiltering(g_FileSystemFilter);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
failures = InterlockedIncrement(&g_FileSystemMonitorFailureCounter);
|
|
if (failures == 1 || ((failures & 0xFF) == 0))
|
|
{
|
|
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
|
|
"BK: filesystem monitor start filtering failed status=0x%08X total=%lu.\n", status,
|
|
(ULONG)failures);
|
|
}
|
|
FltUnregisterFilter(g_FileSystemFilter);
|
|
g_FileSystemFilter = NULL;
|
|
return status;
|
|
}
|
|
|
|
InterlockedExchange(&g_FileSystemMonitorRegistered, 1);
|
|
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "BK: filesystem monitor initialized.\n");
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
VOID BkcfsUninitialize(VOID)
|
|
{
|
|
PFLT_FILTER filter;
|
|
|
|
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
|
|
{
|
|
return;
|
|
}
|
|
if (InterlockedCompareExchange(&g_FileSystemMonitorRegistered, 0, 0) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
InterlockedExchange(&g_FileSystemMonitorRegistered, 0);
|
|
filter = g_FileSystemFilter;
|
|
g_FileSystemFilter = NULL;
|
|
if (filter != NULL)
|
|
{
|
|
FltUnregisterFilter(filter);
|
|
}
|
|
|
|
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "BK: filesystem monitor uninitialized.\n");
|
|
}
|
|
|
|
BOOLEAN
|
|
BkcfsSelfCheck(VOID)
|
|
{
|
|
if (InterlockedCompareExchange(&g_FileSystemMonitorRegistered, 0, 0) == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return (g_FileSystemFilter != NULL);
|
|
}
|