实现保护文件或目录、R3层通过与过滤驱动通讯通知要保护的文件或目录,可执行创建不可删除或修改。
R3层
#include<Windows.h>
#include<fltUser.h>
#include<iostream>
HANDLE g_hPort = INVALID_HANDLE_VALUE;
#define NPMINI_NAME L"FileiPortMin"
#define NPMINI_PORT_NAME L"\\FileiPortMin"
#pragma comment (lib,"fltLib.lib")
typedef struct _COMAND_MESSAGE
{wchar_t Command[512];
}COMMAND_MESSAGE, * PCOMMAND_MESSAGE;
int NPSendMessage(PVOID InputBuffer) {DWORD bytesReturned = 0;DWORD hResult = 0;PCOMMAND_MESSAGE command_message = (PCOMMAND_MESSAGE)InputBuffer;hResult=FilterSendMessage(g_hPort, command_message,sizeof(COMMAND_MESSAGE),NULL,NULL,&bytesReturned);if (hResult!=S_OK) {printf("消息发送失败:%d\r\n", hResult);return hResult;}else {return true;}
}
LPWSTR ConvertAnsiToUnicode(LPSTR ansiString) {int requiredSize = MultiByteToWideChar(CP_ACP, 0, ansiString, -1, NULL, 0);if (requiredSize > 0) {LPWSTR unicodeString = (LPWSTR)malloc(requiredSize * sizeof(wchar_t));if (unicodeString != NULL) {MultiByteToWideChar(CP_ACP, 0, ansiString, -1, unicodeString, requiredSize);return unicodeString;}}return NULL;
}
int main(){DWORD hResult = FilterConnectCommunicationPort(NPMINI_PORT_NAME, 0, NULL, 0, NULL, &g_hPort);if (hResult != S_OK) {printf("通讯失败\r\n");printf("%d\r\n", hResult);return hResult;}else {printf("通讯成功\r\n");wchar_t buffer[512];LPWSTR cmdLineW = GetCommandLine();LPSTR cmdLineA = GetCommandLineA();int argc;if (cmdLineW != NULL && cmdLineW[0] != L'\0' && wcslen(cmdLineW) > 0) {LPWSTR* argv = CommandLineToArgvW(cmdLineW, &argc);if (argv[1] != NULL) {ZeroMemory(buffer, 512);wcscpy(buffer, argv[1]);printf("w:%ws", buffer);NPSendMessage(buffer);exit(0);}}if (cmdLineA != NULL && cmdLineA[0] != '\0' && strlen(cmdLineA) > 0) {LPWSTR res = ConvertAnsiToUnicode(cmdLineA);LPWSTR* argv = CommandLineToArgvW(res, &argc);if (argv[1] != NULL) {ZeroMemory(buffer, 512);wcscpy(buffer, argv[1]);printf("A:%ws", buffer);NPSendMessage(buffer);exit(0);}}}return 0;
}
内核层
#include <ntifs.h>
#include <ntstrsafe.h>
#include <fltKernel.h>
#define MINISPY_PORT_NAME L"\\FileiPortMin" PFLT_PORT gServerPort;
PFLT_PORT gClientPort;
static UNICODE_STRING ProtectedExtention = RTL_CONSTANT_STRING(L"com");
wchar_t fileName[512]=L"mimikatz";
typedef enum _MINI_COMMAND {ENUM_PASS = 0,ENUM_BLOCK
} MINI_COMMAND;
typedef struct _COMMAND_MESSAGE {MINI_COMMAND Command;
} COMMAND_MESSAGE, * PCOMMAND_MESSAGE;
FLT_PREOP_CALLBACK_STATUS NPPreCreate(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID* CompletionContext) {UNREFERENCED_PARAMETER(CompletionContext);PAGED_CODE();FLT_PREOP_CALLBACK_STATUS ret = FLT_PREOP_SUCCESS_NO_CALLBACK;NTSTATUS status;PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;if (Data->Iopb->MajorFunction == IRP_MJ_CREATE) {if (!FlagOn(Data->Iopb->Parameters.Create.Options, FILE_DISALLOW_EXCLUSIVE)) {return ret;}}if (FltObjects->FileObject != NULL) {status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);if (NT_SUCCESS(status)) {FltParseFileNameInformation(FileNameInfo);WCHAR pTempBuf[512] = { 0 };RtlCopyMemory(pTempBuf, FileNameInfo->Name.Buffer, FileNameInfo->Name.MaximumLength);if (wcsstr(pTempBuf, fileName) != NULL) {Data->IoStatus.Status = STATUS_ACCESS_DENIED;Data->IoStatus.Information = 0;ret = FLT_PREOP_COMPLETE;}if (RtlCompareUnicodeString(&FileNameInfo->Extension, &ProtectedExtention, TRUE) == 0) {Data->IoStatus.Status = STATUS_ACCESS_DENIED;Data->IoStatus.Information = 0;ret = FLT_PREOP_COMPLETE;}FltReleaseFileNameInformation(FileNameInfo);}}return ret;
}
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {{ IRP_MJ_CREATE, 0, NPPreCreate, NULL }, { IRP_MJ_SET_INFORMATION, 0, NPPreCreate, NULL }, { IRP_MJ_OPERATION_END }
};
PFLT_FILTER gFileterHandle;
NTSTATUS PtUnload(__in FLT_FILTER_UNLOAD_FLAGS Flags) {UNREFERENCED_PARAMETER(Flags);FltUnregisterFilter(gFileterHandle);return STATUS_SUCCESS;
}CONST FLT_REGISTRATION FilterRegistration = {sizeof(FLT_REGISTRATION),FLT_REGISTRATION_VERSION,0,NULL,Callbacks,PtUnload,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
NTSTATUS OnConnectInternal(IN PFLT_PORT ClientPort,IN PVOID ServerPortCookie,IN PVOID ConnectionContext,IN ULONG SizeOfContext,OUT PVOID* ConnectionPortCookie
) {DbgPrint("OnConnectInternal");return 0;
}VOID OnDisconnectInternal(IN PVOID ConnectionContext
) {DbgPrint("OnDisconnectInternal");
}VOID MessData(__in PVOID ConnectionCookie,__in_bcount_opt(InputBufferSize) PVOID InputBuffer,__in ULONG InputBufferSize,__out_bcount_part_opt(OutputBufferSize, *ReturnOutputBufferLength) PVOID OutputBuffer,__in ULONG OutputBufferSize,__out PULONG ReturnOutputBufferLength) {MINI_COMMAND command;NTSTATUS status;PAGED_CODE();UNREFERENCED_PARAMETER(ConnectionCookie);UNREFERENCED_PARAMETER(OutputBufferSize);UNREFERENCED_PARAMETER(OutputBuffer);if (InputBufferSize>0) {DbgPrint("InputBuffer: %s\r\n", (wchar_t*)InputBuffer);RtlCopyMemory(fileName, InputBuffer, InputBufferSize);}
}NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT DriverObject,_In_ PUNICODE_STRING RegistryPath
)
{DbgPrint("DriverEntryOK\r\n");NTSTATUS status;PSECURITY_DESCRIPTOR sd;OBJECT_ATTRIBUTES oa;UNICODE_STRING uniString;UNREFERENCED_PARAMETER(RegistryPath);status = FltRegisterFilter(DriverObject,&FilterRegistration,&gFileterHandle);FLT_ASSERT(NT_SUCCESS(status));if (NT_SUCCESS(status)) {status = FltStartFiltering(gFileterHandle);if (!NT_SUCCESS(status)) {FltUnregisterFilter(gFileterHandle);}}status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);RtlInitUnicodeString(&uniString, MINISPY_PORT_NAME);InitializeObjectAttributes(&oa,&uniString,OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,NULL,sd);status = FltCreateCommunicationPort(gFileterHandle, &gServerPort, &oa, NULL, OnConnectInternal, OnDisconnectInternal, MessData, 1);DbgPrint("FltCreateCommunicationPort OK\r\n");return status;
}