Windows ObjectType Hook 之 SecurityProcedure

编程入门 行业动态 更新时间:2024-10-27 18:19:49

Windows <a href=https://www.elefans.com/category/jswz/34/1624796.html style=ObjectType Hook 之 SecurityProcedure"/>

Windows ObjectType Hook 之 SecurityProcedure

1、背景

  Object Type Hook 是基于 Object Type的一种深入的 Hook,比起常用的 SSDT Hook 更为深入。

  有关 Object Type 的分析见文章 《Windows驱动开发学习记录-ObjectType Hook之ObjectType结构相关分析》。

  这里进行的 Hook 为 其中之一的 SecurityProcedure。文章实现进程打开的过滤。

2、SecurityProcedure函数声明

  见文章 《Windows驱动开发学习记录-ObjectType Hook之ObjectType结构相关分析》。

  这里取 x64 环境下结构:

typedef NTSTATUS (*OB_SECURITY_METHOD)(IN PVOID Object,IN SECURITY_OPERATION_CODE OperationCode,IN PSECURITY_INFORMATION SecurityInformation,IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,IN OUT PULONG CapturedLength,IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,IN POOL_TYPE PoolType,IN PGENERIC_MAPPING GenericMapping);

  

3、SecurityProcedure 使用逻辑分析

  用 IDA 分析 Win11 22621 版本的 ntoskrnl.exe,查找 SecurityProcedure 的使用逻辑,如下:

__int64 __fastcall ObpCreateHandle(int a1, _QWORD* a2, signed int a3, __int64 a4, int a5, int a6, char a7, __int64 a8, int a9, PVOID* a10, _QWORD* a11)
{......v79 = (_OBJECT_TYPE*)ObTypeIndexTable[(unsigned __int8)ObHeaderCookie ^ v78];v139 = v79;if ((_UNKNOWN*)v79->TypeInfo.SecurityProcedure == &SeDefaultObjectMethod){......}v84 = ExAllocatePool2(256i64, (unsigned int)ObpDefaultSecurityDescriptorLength, 1901290063i64);if (v84){v105 = v79->TypeInfo.SecurityProcedure;GenericMapping = &v79->TypeInfo.GenericMapping;v122 = v139->TypeInfo.PoolType;v138 = (void**)(v77 + 40);v29 = v105(Object,QuerySecurityDescriptor,(unsigned int*)&v141,(void*)v84,&v137,(void**)v77 + 5,v122,GenericMapping,AccessMode);if (v29 == 0xC0000023){......}if (v29 >= 0){......}ExFreePoolWithTag((PVOID)v84, 0);}return (unsigned int)v29;
}

  可以看到在调用 ObpCreateHandle 中有判断 SecurityProcedure 是否为默认的 SeDefaultObjectMethod,不为则调用指定的 SecurityProcedure  ,若 SecurityProcedure  返回失败,则整个 ObpCreateHandle 返回失败。

  于是我们的实验逻辑即过滤进程对象的 SecurityProcedure ,再用任务管理器结束过滤的进程。

4、进程对象过滤

4.1 代码

  .h

#pragma once
#include <ntifs.h>#if DBG
#define KDPRINT(projectName, format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,\projectName "::【" __FUNCTION__  "】" ##format, \##__VA_ARGS__ ) 
#else
#define KDPRINT(format, ...)
#endiftypedef struct _OBJECT_TYPE_FLAGS {UCHAR CaseInsensitive : 1;UCHAR UnnamedObjectsOnly : 1;UCHAR UseDefaultObject : 1;UCHAR SecurityRequired : 1;UCHAR MaintainHandleCount : 1;UCHAR MaintainTypeList : 1;UCHAR SupportsObjectCallbacks : 1;UCHAR CacheAligned : 1;
}OBJECT_TYPE_FLAGS, * P_OBJECT_TYPE_FLAGS;#ifdef _AMD64_
typedef struct _OBJECT_TYPE_INITIALIZER {USHORT				wLength;OBJECT_TYPE_FLAGS	ObjectTypeFlags;ULONG				ObjcetTypeCode;ULONG				InvalidAttributes;GENERIC_MAPPING		GenericMapping;ULONG				ValidAccessMask;ULONG				RetainAccess;ULONG				PoolType;ULONG				DefaultPagedPoolCharge;ULONG				DefaultNonPagedPoolCharge;PVOID				DumpProcedure;PVOID				OpenProcedure;PVOID				CloseProcedure;PVOID				DeleteProcedure;PVOID				ParseProcedure;PVOID				SecurityProcedure;PVOID				QueryNameProcedure;PVOID				OkayToCloseProcedure;
}OBJECT_TYPE_INITIALIZER, * POBJECT_TYPE_INITIALIZER;
#else // _AMD64_
typedef struct _OBJECT_TYPE_INITIALIZER {USHORT Length;BOOLEAN UseDefaultObject;BOOLEAN CaseInsensitive;ULONG InvalidAttributes;_GENERIC_MAPPING GenericMapping;ULONG ValidAccessMask;UCHAR SecurityRequired;UCHAR MaintainHandleCount;UCHAR MaintainTypeList;_POOL_TYPE PoolType;ULONG DefaultPagedPoolCharge;ULONG DefaultNonPagedPoolCharge;PVOID DumpProcedure;PVOID OpenProcedure;PVOID CloseProcedure;PVOID DeleteProcedure;PVOID ParseProcedure;PVOID SecurityProcedure;PVOID QueryNameProcedure;PVOID OkayToCloseProcedure;
}OBJECT_TYPE_INITIALIZER, * POBJECT_TYPE_INITIALIZER;
#endif#ifdef _AMD64_
typedef struct _OBJECT_TYPE_EX {LIST_ENTRY					TypeList;UNICODE_STRING				Name;PVOID					DefaultObject;ULONG						Index;ULONG						TotalNumberOfObjects;ULONG						TotalNumberOfHandles;ULONG						HighWaterNumberOfObjects;ULONG						HighWaterNumberOfHandles;OBJECT_TYPE_INITIALIZER		TypeInfo;ULONGLONG					TypeLock;ULONG						Key;LIST_ENTRY					CallbackList;
}OBJECT_TYPE_EX, * POBJECT_TYPE_EX;
#else
typedef struct _OBJECT_TYPE_EX {UCHAR                                           Unamed[0x38];LIST_ENTRY					TypeList;UNICODE_STRING				Name;PVOID					DefaultObject;ULONG						Index;ULONG						TotalNumberOfObjects;ULONG						TotalNumberOfHandles;ULONG						HighWaterNumberOfObjects;ULONG						HighWaterNumberOfHandles;OBJECT_TYPE_INITIALIZER		TypeInfo;ULONG						Key;LIST_ENTRY					CallbackList;
}OBJECT_TYPE_EX, * POBJECT_TYPE_EX;
#endiftypedef enum _OB_OPEN_REASON {ObCreateHandle,ObOpenHandle,ObDuplicateHandle,ObInheritHandle,ObMaxOpenReason
} OB_OPEN_REASON;typedef 
NTSTATUS 
(NTAPI *PSECURITY_PROCEDURE)(IN PVOID Object,IN SECURITY_OPERATION_CODE OperationCode,IN PSECURITY_INFORMATION SecurityInformation,IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,IN OUT PULONG CapturedLength,IN OUT PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,IN POOL_TYPE PoolType,IN PGENERIC_MAPPING GenericMapping,IN CHAR Flag);typedef struct _OBJECT_TYPE_HOOK_INFORMATION
{POBJECT_TYPE_EX pHookedObject;PSECURITY_PROCEDURE pOringinalSecurityProcedureAddress;
}OBJECT_TYPE_HOOK_INFORMATION, * POBJECT_TYPE_HOOK_INFORMATION;EXTERN_C
NTKERNELAPI
POBJECT_TYPE
NTAPI
ObGetObjectType(PVOID Object
);#ifdef _AMD64_
EXTERN_C
NTKERNELAPI
NTSTATUS
PsReferenceProcessFilePointer(IN PEPROCESS Process,OUT PVOID* pFilePointer
);
#endifEXTERN_C
NTKERNELAPI
PCHAR 
PsGetProcessImageFileName(PEPROCESS pEProcess);void UnHookObjectType();

  .cpp

#include "ObjectTypeHook.h"OBJECT_TYPE_HOOK_INFORMATION g_HookInfomation = { 0 };
UNICODE_STRING g_usCurrentProcessName = RTL_CONSTANT_STRING(L"*TASKMGR.EXE*");
UNICODE_STRING g_usTargetProcessName = RTL_CONSTANT_STRING(L"*DBGVIEW64.EXE*");NTSTATUS
NTAPI CustomQuerySecurityProcedure(IN PVOID Object,IN SECURITY_OPERATION_CODE OperationCode,IN PSECURITY_INFORMATION SecurityInformation,IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,IN OUT PULONG CapturedLength,IN OUT PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,IN POOL_TYPE PoolType,IN PGENERIC_MAPPING GenericMapping,IN CHAR Flag)
{NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;PFILE_OBJECT pTargetFileObject = NULL;PFILE_OBJECT pCurrentFileObject = NULL;POBJECT_NAME_INFORMATION pTargetProcessNameInformation = NULL;POBJECT_NAME_INFORMATION pCurrentProcessNameInformation = NULL;BOOLEAN bDenied = false;do {if (!Object){KDPRINT("【ObjectTypeHook】", "Object  is Null\r\n");break;}POBJECT_TYPE pObjectType = ObGetObjectType(Object);if (pObjectType != *PsProcessType){break;}if (OperationCode != SECURITY_OPERATION_CODE::QuerySecurityDescriptor){break;}ntStatus = PsReferenceProcessFilePointer((PEPROCESS)Object, (PVOID*)&pTargetFileObject);if (!NT_SUCCESS(ntStatus)){//KDPRINT("【ObjectTypeHook】", "PsReferenceProcessFilePointer failed, cod:0x%08x\r\n", ntStatus);break;}ntStatus = IoQueryFileDosDeviceName(pTargetFileObject, &pTargetProcessNameInformation);if (!NT_SUCCESS(ntStatus)){KDPRINT("【ObjectTypeHook】", "IoQueryFileDosDeviceName failed 1\r\n");break;}if (!FsRtlIsNameInExpression(&g_usTargetProcessName, &pTargetProcessNameInformation->Name, true, NULL)){break;}PEPROCESS pCurrentProcess = PsGetCurrentProcess();ntStatus = PsReferenceProcessFilePointer(pCurrentProcess, (PVOID*)&pCurrentFileObject);if (!NT_SUCCESS(ntStatus)){//KDPRINT("【ObjectTypeHook】", "PsReferenceProcessFilePointer failed, cod:0x%08x\r\n", ntStatus);break;}ntStatus = IoQueryFileDosDeviceName(pCurrentFileObject, &pCurrentProcessNameInformation);if (!NT_SUCCESS(ntStatus)){KDPRINT("【ObjectTypeHook】", "IoQueryFileDosDeviceName failed 2\r\n");break;}if (!FsRtlIsNameInExpression(&g_usCurrentProcessName, &pCurrentProcessNameInformation->Name, true, NULL)){break;}KDPRINT("【ObjectTypeHook】", "Action denied\r\n");KDPRINT("【ObjectTypeHook】", "Target Process: %wZ\r\n", &pTargetProcessNameInformation->Name);KDPRINT("【ObjectTypeHook】", "Current Operation Process: %wZ\r\n", &pCurrentProcessNameInformation->Name);bDenied = true;} while (false);if (pCurrentFileObject){ObDereferenceObject(pCurrentFileObject);pCurrentFileObject = NULL;}if (pTargetFileObject){ObDereferenceObject(pTargetFileObject);pTargetFileObject = NULL;}if (pCurrentProcessNameInformation){ExFreePoolWithTag(pCurrentProcessNameInformation, '0');pCurrentProcessNameInformation = NULL;}if (pTargetProcessNameInformation){ExFreePoolWithTag(pTargetProcessNameInformation, '0');pTargetProcessNameInformation = NULL;}if (bDenied){ntStatus = STATUS_ACCESS_DENIED;}else{if (g_HookInfomation.pOringinalSecurityProcedureAddress){ntStatus = g_HookInfomation.pOringinalSecurityProcedureAddress(Object, OperationCode, SecurityInformation, SecurityDescriptor, CapturedLength,ObjectsSecurityDescriptor, PoolType, GenericMapping, Flag);}}return ntStatus;}void UnHookObjectType()
{KDPRINT("【ObjectTypeHook】", "UnHook...\r\n");if (g_HookInfomation.pHookedObject){InterlockedExchangePointer((PVOID*)(&g_HookInfomation.pHookedObject->TypeInfo.SecurityProcedure),g_HookInfomation.pOringinalSecurityProcedureAddress);}
}VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{UNREFERENCED_PARAMETER(pDriverObject);KDPRINT("【ObjectTypeHook】", "CurrentProcessId : 0x%p CurrentIRQL : 0x%u \r\n",PsGetCurrentProcessId(),KeGetCurrentIrql());UnHookObjectType();
}EXTERN_C NTSTATUS  DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{UNREFERENCED_PARAMETER(pDriverObject);UNREFERENCED_PARAMETER(pRegistryPath);NTSTATUS ntStatus = STATUS_SUCCESS;KDPRINT("【ObjectTypeHook】", " Hello Kernel World! CurrentProcessId:0x%p CurrentIRQL:0x%u\r\n",PsGetCurrentProcessId(),KeGetCurrentIrql());pDriverObject->DriverUnload = DriverUnload;g_HookInfomation.pHookedObject = (POBJECT_TYPE_EX)(*PsProcessType);g_HookInfomation.pOringinalSecurityProcedureAddress =(PSECURITY_PROCEDURE)(((POBJECT_TYPE_EX)(*PsProcessType))->TypeInfo.SecurityProcedure);InterlockedExchangePointer((PVOID*)(&g_HookInfomation.pHookedObject->TypeInfo.SecurityProcedure),CustomQuerySecurityProcedure);KDPRINT("【ObjectTypeHook】", "Hook QueryNameProcedure!\r\n");return ntStatus;
}

  代码实现了任务管理器进程 Taskmgr.exe 打开 DbgView64.exe 时 SecurityProcedure 返回拒绝访问,也即 ObpCreateHandle 返回失败。

4.2 实验效果

  加载驱动后打开 DbgView64.exe, 然后在进程管理器中结束该进程,效果如下:

  

更多推荐

Windows ObjectType Hook 之 SecurityProcedure

本文发布于:2023-11-16 00:41:45,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1610808.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:ObjectType   Windows   SecurityProcedure   Hook

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!