你的MiniFilter安全吗?

简介

筛选器管理器 (FltMgr.sys)是Windows系统提供的内核模式驱动程序, 用于实现和公开文件系统筛选器驱动程序中通常所需的功能; 第三方文件系统筛选器开发人员可以使用FltMgr的功能可以更加简单的编写文件过滤驱动, 这种驱动我们通常称为MiniFilter, 下面是MiniFilter的基本框架:
MiniFilter
简单的说就是我们可以通过微软提供的一些接口, 可以使我们方便的在内核层监控文件的操作(创建, 删除, 读写等), 例如杀毒软件利用MiniFilter监控文件的创建, 在文件创建时对文件进行病毒查杀; 又例如安全产品利用MiniFilter, 阻止第三方程序在自己的目录下面写文件等…

MiniFilter

由于在MiniFilter中我们不用关心IRP的处理工作, 这些都可以交给 Filter Manager处理, 所以我们要编写一个MiniFilter是很简单的, 只有调用几个API函数, 并在参数中填写我们关心的或者需要处理的结构就可以了;

FltRegisterFilter

我们使用FltRegisterFilter来注册一个过滤器:

NTSTATUS FLTAPI FltRegisterFilter([in]  PDRIVER_OBJECT         Driver,[in]  const FLT_REGISTRATION *Registration,[out] PFLT_FILTER            *RetFilter
);

第一个参数和DriverEntry的第一个参数一样, 第三参数RetFilter作为输出, 主要用于后续调用FltUnregisterFilter时注销MiniFilter:

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING reg_path)
{NTSTATUS status;	DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DriverEntry Entry!\n");ExInitializeResourceLite(&GlobalResource);status = FltRegisterFilter(DriverObject, &FilterRegistration, &gFilterHandle);if (NT_SUCCESS(status)) {status = FltStartFiltering(gFilterHandle);if (!NT_SUCCESS(status)) {DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "FltUnregisterFilter status: %lx\n", status);FltUnregisterFilter(gFilterHandle);}else {DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "FltRegisterFilter Start!\n");}}else {DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "status: %lx\n", status);}DriverObject->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

最重要的是第两个参数Registration, 这个参数中定义了一系列的结构, 用于注册监控文件操作的回调等;

typedef struct _FLT_REGISTRATION {USHORT                                      Size;USHORT                                      Version;FLT_REGISTRATION_FLAGS                      Flags;const FLT_CONTEXT_REGISTRATION              *ContextRegistration;const FLT_OPERATION_REGISTRATION            *OperationRegistration;PFLT_FILTER_UNLOAD_CALLBACK                 FilterUnloadCallback;PFLT_INSTANCE_SETUP_CALLBACK                InstanceSetupCallback;PFLT_INSTANCE_QUERY_TEARDOWN_CALLBACK       InstanceQueryTeardownCallback;PFLT_INSTANCE_TEARDOWN_CALLBACK             InstanceTeardownStartCallback;PFLT_INSTANCE_TEARDOWN_CALLBACK             InstanceTeardownCompleteCallback;PFLT_GENERATE_FILE_NAME                     GenerateFileNameCallback;PFLT_NORMALIZE_NAME_COMPONENT               NormalizeNameComponentCallback;PFLT_NORMALIZE_CONTEXT_CLEANUP              NormalizeContextCleanupCallback;PFLT_TRANSACTION_NOTIFICATION_CALLBACK      TransactionNotificationCallback;PFLT_NORMALIZE_NAME_COMPONENT_EX            NormalizeNameComponentExCallback;PFLT_SECTION_CONFLICT_NOTIFICATION_CALLBACK SectionNotificationCallback;
} FLT_REGISTRATION, *PFLT_REGISTRATION;

可以看到FLT_REGISTRATION有很多字段, 但是我们用到的通常是:

CONST FLT_REGISTRATION FilterRegistration = {sizeof(FLT_REGISTRATION),			//  SizeFLT_REGISTRATION_VERSION,           //  Version0,                                  //  FlagsNULL,                               //  ContextCallbacks,                          //  Operation callbacksPtUnload,                           //  MiniFilterUnloadPtInstanceSetup,                    //  实例绑定回调函数,可以决定绑定哪些卷PtInstanceQueryTeardown,            //  InstanceQueryTeardownPtInstanceTeardownStart,            //  InstanceTeardownStartPtInstanceTeardownComplete,         /** 过滤管理器在发送的I/O请求都被完成的时候,调用这个函数, 在这个函数中,微过滤驱动关闭所有还被打开的文件*/NULL,                               //  GenerateFileNameNULL,                               //  GenerateDestinationFileNameNULL                                //  NormalizeNameComponent
};

FLT_OPERATION_REGISTRATION这个结构中我们定义我们关心的文件操作:

const FLT_OPERATION_REGISTRATION Callbacks[] = {{IRP_MJ_CREATE,0,NPPreCreate,   	// 生成预操作回调函数NPPostCreate	// 生成后操作回调函数},{ IRP_MJ_OPERATION_END }
};

IRP_MJ_CREATE, IRP_MJ_SET_INFORMATION等是IPR请求信息, 操作系统发送 IRP_MJ_CREATE 请求,以打开文件对象或设备对象的句柄。 例如,当驱动程序调用 ZwCreateFile 时,操作系统会发送 IRP_MJ_CREATE 请求以执行实际打开操作; 每个FLT_OPERATION_REGISTRATION都必须以IRP_MJ_OPERATION_END结尾;
所以我们这里注册了有关IRP_MJ_CREATE的回调, 当有IRP_MJ_CREATE请求时, 就会触发我们的回调, 会进入我们的NPPreCreate回调函数, 我们可以在这个函数中处理文件, 例如阻止test1.exe的操作:

FLT_PREOP_CALLBACK_STATUS NPPreCreate(PFLT_CALLBACK_DATA Data,PCFLT_RELATED_OBJECTS FltObjects,PVOID *ComletionContext
) {char Filename[256] = { "X:" };NTSTATUS status;PFLT_FILE_NAME_INFORMATION nameinfo;UNREFERENCED_PARAMETER(FltObjects);UNREFERENCED_PARAMETER(ComletionContext);PAGED_CODE();__try {status = FltGetFileNameInformation(Data,FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,&nameinfo);if (NT_SUCCESS(status)) {FltParseFileNameInformation(nameinfo);if (NPUnicodeStringToChar(&nameinfo->Name, Filename)) {if (strstr(Filename, "test1.exe") > 0) {DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[NPPreCreate] Filename :%s\n", Filename);Data->IoStatus.Status = STATUS_ACCESS_DENIED;Data->IoStatus.Information = 0;FltReleaseFileNameInformation(nameinfo);return FLT_PREOP_COMPLETE;}}FltReleaseFileNameInformation(nameinfo);}}__except (EXCEPTION_EXECUTE_HANDLER) {DbgPrint("NPPreCreate EXCEPTION_EXECUTE_HANDLER");}return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

.inf文件

MiniFilter驱动加载到系统时, 和常规的驱动加载不太一样, 需要写注册表项, 定义一些字段, 例如Altitude, 这是最重要的一个字段之一;
因为不同的高度意味在不同的加载顺序和分组, 高度越高越会被先执行, 具体的高度以及分组可以参考微软的文档:
在这里插入图片描述
inf驱动安装文件:

;;;
;;; MiniFile
;;;
;;;
;;; Copyright (c) 1999 - 2002, Microsoft Corporation
;;;[Version]
Signature   = "$Windows NT$"
Class       = "ActivityMonitor"             ;This is determined by the work this filter driver does
ClassGuid   = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}    ;This value is determined by the Class
Provider    = %ProviderString%
DriverVer   = 06/16/2007,1.0.0.0
CatalogFile = MiniFile.cat[DestinationDirs]
DefaultDestDir          = 12
MiniFile.DriverFiles  = 12;;
;; Default install sections
;;[DefaultInstall]
OptionDesc  = %ServiceDescription%
CopyFiles   = MiniFile.DriverFiles[DefaultInstall.Services]
AddService  = %ServiceName%,,MiniFile.Service;;
;; Default uninstall sections
;;[DefaultUninstall]
DelFiles   = MiniFile.DriverFiles[DefaultUninstall.Services]
DelService = %ServiceName%,0x200      ;Ensure service is stopped before deleting;
; Services Section
;[MiniFile.Service]
DisplayName      = %ServiceName%
Description      = %ServiceDescription%
ServiceBinary    = %12%\%DriverName%.sys
Dependencies     = "FltMgr"
ServiceType      = 2                        ;SERVICE_FILE_SYSTEM_DRIVER
StartType        = 3                        ;SERVICE_DEMAND_START
ErrorControl     = 1                        ;SERVICE_ERROR_NORMAL
LoadOrderGroup   = "FSFilter Activity Monitor"
AddReg           = MiniFile.AddRegistry;
; Registry Modifications
;[MiniFile.AddRegistry]
HKR,,"SupportedFeatures",0x00010001,0x3
HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance%
HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude%
HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags%;
; Copy Files
;[MiniFile.DriverFiles]
%DriverName%.sys[SourceDisksFiles]
MiniFile.sys = 1,,[SourceDisksNames]
1 = %DiskId1%,,,;;
;; String Section
;;[Strings]
ProviderString          = "TODO-Set-Provider"
ServiceDescription      = "MiniFile mini-filter driver"
ServiceName             = "MiniFile"
DriverName              = "MiniFile"
DiskId1                 = "MiniFile Device Installation Disk";Instances specific information.
DefaultInstance         = "Null Instance"
Instance1.Name          = "Null Instance"
Instance1.Altitude      = "370030"
Instance1.Flags         = 0          ; Suppress automatic attachments

FltCreateCommunicationPort

FltCreateCommunicationPort函数可以创建一个通信服务器端口,微筛选器驱动程序可在该端口上接收来自用户模式应用程序的连接请求; 也通过这个函数注册就是可以让ring3的程序直接和MiniFilter驱动进行通信, FltCreateCommunicationPort函数原型如下:

NTSTATUS FLTAPI FltCreateCommunicationPort([in]           PFLT_FILTER            Filter,[out]          PFLT_PORT              *ServerPort,[in]           POBJECT_ATTRIBUTES     ObjectAttributes,[in, optional] PVOID                  ServerPortCookie,[in]           PFLT_CONNECT_NOTIFY    ConnectNotifyCallback,[in]           PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback,[in, optional] PFLT_MESSAGE_NOTIFY    MessageNotifyCallback,[in]           LONG                   MaxConnections
);

处理与应用层程序通信的逻辑主要就是就在MessageNotifyCallback回调当中;

Flt函数

通过以上的基础知识, 我们知道了在实际的应用当中我们可以通过MiniFilter来监控文件操作, 并且杀毒软件也是通过这种机制来监控文件的创建等事件, 对我们落盘的文件进行查杀的; 同时安全软件软件EDR产品等也会通过这种方式来对自己的安装目录进行保护, 禁止第三方软件等往自己的目录写入文件, 例如我们往一个受保护的目录中创建一个新文件, 会被阻止:
Can't
如果我们在自己的MiniFilter驱动中调用FltCreateFileEx, FltWriteFile, FltReadFile等函数去操作文件, 会不会被其他MiniFilter拦截呢?
我们来看看微软的文档中对FltCreateFileEx的描述, 原型是这样的:

NTSTATUS FLTAPI FltCreateFileEx([in]           PFLT_FILTER        Filter,[in, optional] PFLT_INSTANCE      Instance,[out]          PHANDLE            FileHandle,[out]          PFILE_OBJECT       *FileObject,[in]           ACCESS_MASK        DesiredAccess,[in]           POBJECT_ATTRIBUTES ObjectAttributes,[out]          PIO_STATUS_BLOCK   IoStatusBlock,[in, optional] PLARGE_INTEGER     AllocationSize,[in]           ULONG              FileAttributes,[in]           ULONG              ShareAccess,[in]           ULONG              CreateDisposition,[in]           ULONG              CreateOptions,[in, optional] PVOID              EaBuffer,[in]           ULONG              EaLength,[in]           ULONG              Flags
);

在这这些参数中, 微软对第二个参数Instance有这样的描述:

[in, optional] Instance
创建请求要发送到的微筛选器驱动程序实例的不透明实例指针。
实例必须附加到文件或目录所在的卷。
此参数是可选的,可以为 NULL。 
如果此参数为 NULL,则请求将发送到卷的文件系统驱动程序堆栈顶部的设备对象。 
如果为非 NULL,则请求仅发送到附加到指定实例下方的微型筛选器驱动程序实例。

这里有一个问题, 假如我们有两个MiniFilter驱动AB, A的高度也就是Altitude是370030, B的高度是180000; 如果在B中调用FltCreateFileEx函数并且第二个参数设置为非 NULL, 这个时候对文件的操作在驱动A中就收不到相关的回调, 因为A的高度比B的高, 所以文件操作的请求发不到A去;
同样的, 在FltWriteFile, FltReadFile等函数中, 也有这种机制:
FltWriteFile
FltReadFile
如果有这样的MiniFilter驱动, 满足了这两个条件:

  1. Altitude比杀软或者EDR的Altitude低;
  2. 存在文件读写的接口;

那我们是不是就可以绕过杀毒软件或者EDR的自保了呢:

Wcifs.sys

在Windows中有一个驱动, 是处理容器相关的, 叫做wcifs.sys:
wcifs
这个驱动注册了MiniFilter, 并且Altitude也比较低, 远远小于常规EDR注册的MiniFilter的高度:
Altitude
在这个驱动中还注册了与应用层之间的通信接口:
FltCreateCommunicationPort
WcPortMessage函数中, MessageCode == 4时, 有一个WcCopyFileHandler函数
WcPortMessage
WcCopyFileHandler函数中利用FltWriteFileFltReadFile实现了一个文件拷贝的功能:
FltWrite
并且文件打开时是用的FltCreateFileEx2函数, 并且Instance参数并不是为NULL:
FltCreateFileEx2
这就导致如果使用wcifs.sys提供的文件拷贝功能, 那么常规的EDR或者杀软的MiniFilter根本就监控不到, 因为wcifs.sys的高度更低, 这就导致我们可以绕过EDR或者杀软的自保;
调用驱动需要的结构体:

struct WcifsPortMessageCopyFileHandler
{/*0*/   DWORD MessageVersionOrCode;/*4*/   DWORD MessageSize;/*8*/   wchar_t InstanceName[50];/*108*/ DWORD InstanceNameLength;/*112*/ DWORD ReparseTag;/*116*/ DWORD OffsetToSourceContainerRootId;/*120*/ DWORD SizeOfSourceContainerRootId;/*124*/ DWORD OffsetToTargetContainerRootId;/*128*/ DWORD SizeOfTargetContainerRootId;/*132*/ DWORD OffsetToSourceFileRelativePath;/*136*/ DWORD SizeOfSourceFileRelativePath;/*140*/ DWORD OffsetToTargetFileRelativePath;/*144*/ DWORD SizeOfTargetFileRelativePath;/*148*/ char UnionData[]; // 2*ContainerRootId + source & target relative paths
};

总结

wcifs.sys是系统自带的, 并且默认就会加载, 所以利用该驱动的接口来拷贝文件对于绕过一些文件过滤驱动是很方便的, 同时作为EDR或者杀软产品也不能绝对的相信自己的MiniFilter可以阻止第三方文件的写入, 应该做一些额外的验证, 确保自保目录的安全;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/660359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java多线程--解决单例模式中的懒汉式的线程安全问题

文章目录 一、单例设计模式的线程安全问题(1)饿汉式没有线程安全问题(2)懒汉式线程安全问题1、案例2、方式1-同步方法3、方式2-同步代码块4、优化 二、代码(1)实现线程安全的懒汉式(2&#xff0…

猫什么时候发腮?公认发腮效果好的生骨肉冻干推荐

猫什么时候发腮是许多猫主人非常关心的问题。在猫咪的成长过程中,发腮是一项重要的体征,也是猫咪成熟的标志。想要让猫咪拥有可爱的肉嘟嘟脸型,主人需要在适龄的年龄段加强营养补给,不要错失最佳发腮期。那么,猫咪的最…

api接口1688商品详情接口采集商品详情数据商品价格详情页数据可支持高并发调用演示示例

接入1688商品详情API接口的步骤如下: 注册账号:首先,你需要在1688开放平台注册一个账号。 创建应用:登录后,在控制台中找到“我的应用”,点击“创建应用”。 获取API密钥:创建应用后&#xff…

【Linux】VMware Workstation16安装银河麒麟高级服务器操作系统V10 SP3 AMD64

目录 一、麒麟服务器概述 二、安装步骤 设置硬盘大小 完成配置 修改内存 处理器等设备配置 选择直接安装 配置磁盘 网络配置 设置root账号密码 开始安装 启动完成 一、麒麟服务器概述 银河麒麟高级服务器操作系统V10是针对企业级关键业务,适应虚拟化、云…

时间序列预测——GRU模型

时间序列预测——GRU模型 在深度学习领域,循环神经网络(RNN)是处理时间序列数据的一种常见选择。上期已介绍了LSTM的单步和多步预测。本文将深入介绍一种LSTM变体——门控循环单元(GRU)模型,包括其理论基础…

Flutter canvas 画一条会动的波浪线 进度条

之前用 Flutter Canvas 画过一个三角三角形,html 的 Canvas 也画过一次类似的, 今天用 Flutter Canvas 试了下 感觉差不多: html 版本 大致效果如下: 思路和 html 实现的类似: 也就是找出点的位置,使用二阶…

Cannot assign to read only property ‘exports‘ of object ‘#<Object>‘

看下多语言js文件中,是否同级出现相同名称。

3D 转换

1,3D的特点: 近小远大 物体后面遮挡不可见 2,3D移动 translate3d 3D移动在2D移动的基础上多加了一个可以移动的方向,就是z轴方向 transform:translateX(100px):仅仅是在x轴上移动…

【C/C++ 07】词频统计

一、题目 读入一篇英文短文&#xff0c;去除介词、连词、冠词、副词、代词等非关键性单词后&#xff0c;统计每个单词出现的次数&#xff0c;并将单词按出现次数的降序和单词字符的升序进行显示5个单词。 二、算法 1. 通过<fstream>库创建fstream流对象&#xff0c;并从…

美区或其他外区Appstore账号AppleID注册教程,简单快速,苹果必备!

▍前言 现在越来越多的APP在国区APPstore下架&#xff0c;如果想有更好的使用体验&#xff0c;不得不去外区下载APP&#xff0c;那就需要一个外区的apple id&#xff0c;注册也很简单&#xff0c;今天大鹏通过电脑ipad给大家注册一个&#xff0c;建议大家直接使用iPhone或者iPa…

好书推荐丨保姆级Midjourney教程,这本写给大家看的设计书闭眼入!

文章目录 写在前面好书推荐Part.1Part.2Part.3 粉丝福利写在后面 写在前面 在AI绘画界&#xff0c;有每日经典一问&#xff1a;“你今天用Midjourney画了啥&#xff1f;”晒作品成为重头戏。 小红书上关于Midjourney出的图片点赞数惊人。 reddit上的恶搞幽默图片热度居高不下…

GSM-TRIAL-21.04.9-VMware-Workstation.OVA安装教程,GreenBone虚拟机安装教程

将GSM-TRIAL-21.04.9-VMware-Workstation.ova用VMware打开 先设置好网络和内存&#xff1a; 1、打开虚拟机&#xff0c;显示&#xff1a;你的GSM还不能完全正常工作。您想现在完成设置吗? 点击yes 2、创建用户&#xff0c;一会儿登录网页要用&#xff0c;点击yes 3、创建用户…

指向 Data Member 的指针

看一下很简单的一个例子&#xff1a; #include <stdlib.h> #include <stdio.h> #include <malloc.h>class origin { public:virtual ~origin(){} public:int x; };int main() {origin A;printf("&origin::x %p, &A.x %p\n", &origi…

小黄鸭聊电脑(4)硬盘分区

小黄鸭聊电脑(4)硬盘分区 夜深人静&#xff0c;万籁俱寂&#xff0c;老郭趴在电脑桌上打盹&#xff0c;桌子上的小黄鸭和桌子旁的冰箱又开始窃窃私语…… 小黄鸭&#xff1a;冰箱大哥&#xff0c;上次你说的那个“分区”和“格式化”是什么意思&#xff1f; 冰箱&#xff1a;…

洛夫克拉夫特与文学中的超自然恐怖:前哥特时代

洛夫克拉夫特与文学中的超自然恐怖&#xff1a;前哥特时代 ![ 洛夫克拉夫特是美国恐怖、科幻与奇幻小说作家&#xff0c;尤以其怪奇小说著称&#xff0c;他在自己的一系列小说中开发出了克苏鲁神话体系。他的创作对后世恐怖小说创造影响深远&#xff0c;我们可以在许多当代文…

[leetcode] 21. 合并两个有序链表

文章目录 题目描述解题方法双指针遍历java代码 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff…

自动驾驶:Apollo如何塑造人类的未来出行

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言1. 什么是自定义指令&#xff1f;2. Apollo中的自定义指令2.1 查询中的自定…

鸿蒙HarmonyOS——AVSession开发指导

AVSession开发指导 说明&#xff1a; AVSession的所有接口均为系统接口&#xff0c;其功能仅提供给系统应用使用。 会话接入端开发指导 基本概念 会话元数据AVMetadata: 媒体数据相关属性&#xff0c;包含标识当前媒体的ID(assetId)&#xff0c;上一首媒体的ID(previousAsset…

17. Spring Boot Actuator

17. Spring Boot Actuator Spring Boot执行器(Actuator)提供安全端点&#xff0c;用于监视和管理Spring Boot应用程序。 默认情况下&#xff0c;所有执行器端点都是安全的。 在本章中&#xff0c;将详细了解如何为应用程序启用Spring Boot执行器。 启用Spring Boot Actuator …

光纤熔接-热熔

实验教学日的及具体要求 目的 1.掌握室外光缆、皮线光缆的开剥方法。 2.掌握应用光纤切割刀制作光纤端面的方法 3.掌握光纤熔接的基本知识。 4.掌握光纤熔接机的使用方法及接续步骤。 任务 1.完成2芯光缆在终端盒内与尾纤的熔接 2.用激光笔完成光纤熔接检测。 …