zoukankan      html  css  js  c++  java
  • 文件防删除保护(miniifiter)

    0x01 思路(原理)

      驱动层文件保护的思路是通过minifilter过滤文件删除相关的IRP,并将目标文件与被保护文件相比较,命中保护规则的话返回STATUS_ACCESS_DENIED拒绝访问;也可以进一步利用回调函数获取的FLT_CALLBACK_DATA结构体解析文件删除操作对应的发起者进程,与白名单进程(允许执行删除操作的进程)相比较。

          

      需要过滤的IRP类型:IRP_MJ_SET_INFORMATION与IRP_MJ_CREATE(或还有其他类型IRP需要过滤,尚未知)

           IRP_MJ_SET_INFORMATION的产生原因一般是请求设置文件属性等等,比如ZwSetInformationFile函数可以发起此IRP.这里顺带说一句的是,许多驱动都用ZwSetInformationFile函数来实现强删文件的,比如腾讯电脑管家中的TSSysKit.sys驱动中文件穿透操作的删除文件就是调用ZwSetInformationFile函数将FileInformationClass设为FileDispositionInformation且((PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->DeleteFile设为TRUE来达到删除文件的目的(如果是强删正在运行的文件,那么还需将文件对象的SectionObjectPointer->ImageSectionObject和 SectionObjectPointer->DataSectionObject 两个字段置零)。因此,对于IRP_MJ_SET_INFORMATION,应当检查FileInformationClass是否是FileRenameInformation和FileShortNameInformation标志。

      IRP_MJ_CREATE的产生原因一般是请求打开文件句柄,文件对象以及其他内核对象等等,比如ZwCreateFile函数可以发起此IRP.如果ZwCreateFile函数指定了FILE_DELETE_ON_CLOSE标志,那么当最后一个文件句柄被NtClose关闭时,文件会被删除,这也就是过滤IRP_MJ_CREATE的原因。因此,对于IRP_MJ_CREATE,应当检查是否有FILE_DELETE_ON_CLOSE 标志指定。

     

    0x01 源码及注释如下

      1 #include <fltKernel.h>
      2 //#include "FileDeleteProtect.h"
      3 
      4 #define DEBUG
      5 #ifdef DEBUG
      6 #define DBG_PRINTF(_fmt, ...) DbgPrint(_fmt, __VA_ARGS__)
      7 #else
      8 #define DBG_PRINTF(_fmt, ...) { NOTHING; }
      9 #endif
     10 
     11 
     12 DRIVER_INITIALIZE DriverEntry;
     13 
     14 NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath);
     15 NTSTATUS Unload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags);
     16 FLT_PREOP_CALLBACK_STATUS PreAntiDelete(_Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext);
     17 
     18 //过滤IRP的回调数组
     19 CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
     20     { IRP_MJ_CREATE, 0, PreAntiDelete, NULL },                // DELETE_ON_CLOSE 标志.
     21     { IRP_MJ_SET_INFORMATION, 0, PreAntiDelete, NULL },        // FileDispositionInformation(Ex).
     22     { IRP_MJ_OPERATION_END }
     23 };
     24 
     25 CONST FLT_REGISTRATION FilterRegistration = {
     26     sizeof(FLT_REGISTRATION),                // Size
     27     FLT_REGISTRATION_VERSION,                // Version
     28     0,                                        // Flags
     29     NULL,                                    // ContextRegistration
     30     Callbacks,                                // OperationRegistration
     31     Unload,                                    // FilterUnloadCallback
     32     NULL,                                    // InstanceSetupCallback
     33     NULL,                                    // InstanceQueryTeardownCallback
     34     NULL,                                    // InstanceTeardownStartCallback
     35     NULL,                                    // InstanceTeardownCompleteCallback
     36     NULL,                                    // GenerateFileNameCallback
     37     NULL,                                    // NormalizeNameComponentCallback
     38     NULL                                    // NormalizeContextCleanupCallback
     39 };
     40 
     41 PFLT_FILTER Filter;
     42 static UNICODE_STRING Protected = RTL_CONSTANT_STRING(L"EXE");
     43 
     44 NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {
     45 
     46     UNREFERENCED_PARAMETER(RegistryPath);
     47 
     48     NTSTATUS Status = FltRegisterFilter(DriverObject, &FilterRegistration, &Filter);
     49     if (!NT_SUCCESS(Status)) {
     50         DBG_PRINTF("Failed to register filter: <0x%08x>.
    ", Status);
     51         return Status;
     52     }
     53 
     54     Status = FltStartFiltering(Filter);
     55     if (!NT_SUCCESS(Status)) {
     56         DBG_PRINTF("Failed to start filter: <0x%08x>.
    ", Status);
     57         FltUnregisterFilter(Filter);
     58     }
     59 
     60     return Status;
     61 }
     62 
     63 NTSTATUS Unload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags) {
     64     UNREFERENCED_PARAMETER(Flags);
     65     DBG_PRINTF("Unload called.
    ");
     66     FltUnregisterFilter(Filter);
     67 
     68     return STATUS_SUCCESS;
     69 }
     70 
     71 /*
     72 * PreCallback的调用时机
     73 * IRP_MJ_CREATE——ZwCreateFile
     74 * IRP_MJ_SET_INFORMATION——ZwSetInformation.
     75 */
     76 FLT_PREOP_CALLBACK_STATUS PreAntiDelete(_Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext) {
     77     UNREFERENCED_PARAMETER(CompletionContext);
     78     PAGED_CODE();//PreCallback的IRQL应当<= APC_LEVEL
     79 
     80     FLT_PREOP_CALLBACK_STATUS Status = FLT_PREOP_SUCCESS_NO_CALLBACK;//不再调用postoperation callback routine,
     81 
     82 
     83     BOOLEAN IsDirectory;//目录操作跳过,不管
     84     NTSTATUS status = FltIsDirectory(FltObjects->FileObject, FltObjects->Instance, &IsDirectory);
     85     if (NT_SUCCESS(status)) {
     86         if (IsDirectory == TRUE) {
     87             return Status;
     88         }
     89     }
     90 
     91     if (Data->Iopb->MajorFunction == IRP_MJ_CREATE) {
     92         if (!FlagOn(Data->Iopb->Parameters.Create.Options, FILE_DELETE_ON_CLOSE)) {
     93             return Status;
     94         }
     95     }
     96 
     97 
     98     if (Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) {
     99         switch (Data->Iopb->Parameters.SetFileInformation.FileInformationClass) {
    100         case FileRenameInformation:
    101         case FileRenameInformationEx:
    102         case FileDispositionInformation:
    103         case FileDispositionInformationEx:
    104         case FileRenameInformationBypassAccessCheck:
    105         case FileRenameInformationExBypassAccessCheck:
    106         case FileShortNameInformation:
    107             break;
    108         default:
    109             return Status;
    110         }
    111     }
    112 
    113     /*
    114     ZwCreateFile和ZwSetInformation函数都是运行在PASSIVE_LEVEL的,所以当前的线程上下文
    115     应当就是ZwCreateFile或ZwSetInformation函数的调用者进程对应的线程的上下文Context,
    116     所以这里可以判断调用者进程是否在白名单中(如果存在白名单进程的话)
    117     if (IoThreadToProcess(Data->Thread) == WhiteListProcess) {
    118     return FLT_PREOP_SUCCESS_NO_CALLBACK;
    119     }
    120     */
    121 
    122     PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
    123     if (FltObjects->FileObject != NULL) {
    124         status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);
    125         if (NT_SUCCESS(status)) {
    126             FltParseFileNameInformation(FileNameInfo);
    127             //if (RtlCompareUnicodeString(&FileNameInfo->Name, &Protected, TRUE) == 0) {
    128             if (RtlCompareUnicodeString(&FileNameInfo->Extension, &Protected, TRUE) == 0) {
    129                 DBG_PRINTF("Protecting file deletion/rename!");
    130                 Data->IoStatus.Status = STATUS_ACCESS_DENIED;
    131                 Data->IoStatus.Information = 0;
    132                 Status = FLT_PREOP_COMPLETE;
    133             }
    134             // Clean up file name information.
    135             FltReleaseFileNameInformation(FileNameInfo);
    136         }
    137     }
    138 
    139     return Status;
    140 }
    View Code
  • 相关阅读:
    PLSQL设置中文
    新建oracle实例
    eclipse中导入项目后中文成乱码解决办法
    安装oracle
    配置java环境变量
    学习springMVC实例1——配置和跳转到HelloWorld
    突破变态限制快捷方式提权法
    对象的内存布局
    XMl转Map-map调用公共模板
    对象的创建
  • 原文地址:https://www.cnblogs.com/lsh123/p/10405002.html
Copyright © 2011-2022 走看看