微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

栏目: 服务器 · 发布时间: 7年前

内容简介:上文讲解了sysmon的ring3部分实现原理,本文则开始讲解ring0部分。Sysmon的ring0是一个minifilter类型的驱动,内部实现了进程信息、文件访问信息以及注册表访问信息的记录,下面开始具体讲解它的实现流程。从DriverEntry(PDRIVER_OBJECT DriverObject, UNICODE_STRING *pRegistry)的pRegistry中截取末尾名称去获取并计算出设备名和DosDevices的名字。

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

上文讲解了sysmon的ring3部分实现原理,本文则开始讲解ring0部分。Sysmon的ring0是一个minifilter类型的驱动,内部实现了进程信息、文件访问信息以及注册表访问信息的记录,下面开始具体讲解它的实现流程。

  • 驱动DriverEntry的初始化

从DriverEntry(PDRIVER_OBJECT DriverObject, UNICODE_STRING *pRegistry)的pRegistry中截取末尾名称去获取并计算出设备名和DosDevices的名字。

pDriverName = pRegistry->Buffer;

Len = pRegistry->Length >> 1;

pFirstName = &pDriverName[Len];

if ( pFirstName == pDriverName )

{

LABEL_8:

if ( *pFirstName != '\\' )

goto LABEL_10;

}

else

{

while ( *pFirstName != '\\' )

{

--pFirstName;

if ( pFirstName == pDriverName )

goto LABEL_8;

}

}

++pFirstName;

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

然后从pRegistry注册表中去获取sysmon的策略规则

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

使用RtlQueryRegistryValues函数,填入5个RTL_QUERY_REGISTRY_TABLE结构体

RTL_QUERY_REGISTRY_TABLE QueryRegTable[5];

RtlInitUnicodeString(&g_ProcessAccessNamesRule, 0);

memset(QueryRegTable, 0, 560u);

QueryRegTable[0].Flags = 1;

QueryRegTable[0].Name = L"Parameters";

QueryRegTable[3].EntryContext = &OptionRulesv18;

QueryRegTable[4].EntryContext = &hash_alogrithms;

QueryRegTable[1].Flags = 304;

QueryRegTable[1].Name = g_Name_ProcessAccessNames;

QueryRegTable[1].EntryContext = &g_ProcessAccessNamesRule;

QueryRegTable[1].DefaultType = 0x7000007;

QueryRegTable[1].DefaultData = &unk_10015C34;

QueryRegTable[1].DefaultLength = 4;

QueryRegTable[2].Flags = 304;

QueryRegTable[2].Name = L"ProcessAccessMasks";

QueryRegTable[2].EntryContext = &g_ProcessAccessMasksRule;

QueryRegTable[2].DefaultType = 0x3000000;

QueryRegTable[3].Flags = 304;

QueryRegTable[3].Name = (PWSTR)&g_wOption;

QueryRegTable[3].DefaultType = 0x4000000;

QueryRegTable[4].Flags = 304;

QueryRegTable[4].Name = (PWSTR)&g_wHashingalgorithm;

QueryRegTable[4].DefaultType = 0x4000000;

RtlQueryRegistryValues(0, g_SysmonRegisterPath.Buffer, QueryRegTable, 0, 0);

if ( !g_ProcessAccessNamesRule.Buffer

|| g_ProcessAccessNamesRule.Length <= 2u

|| g_ProcessAccessNamesRule.MaximumLength <= 4u )

{

RtlFreeUnicodeString(&g_ProcessAccessNamesRule);

RtlInitUnicodeString(&g_ProcessAccessNamesRule, 0);

}

g_OptionRules = (OptionRulesv18 >> 1) & 1;

对应的注册表键分别是L”Parameters”、L”ProcessAccessNames”、 L”ProcessAccessMasks” 、L” Option”、L” Hashingalgorithm”

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

然后再次获取L”Parameters”项下面的对应的L”Rules”的KeyValues信息,这里是驱动设置的规则。

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

下面展示出部分规则的数组

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

上面的过程结束后就开始判断操作系统是否支持flt

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

如果支持只实现IRP_MJ_CREATE、IRP_MJ_CLOSE 、IRP_MJ_DEVICE_CONTROL三个例程,后续会注册miniFlt过滤,如果不支持Flt就使用老的模式Sfilter的模式

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

if ( IsOpenPipeConnect && !IsSupportFlt )

{

DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[1] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_SET_EA] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_POWER] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CHANGE] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = (PDRIVER_DISPATCH)SysmonDispatchIrp;

}

然后就是常规过程,IoCreateDevice、IoCreateSymbolicLink。

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

然后根据操作系统是否支持FltRegisterFilter(Driver, &g_Registration, &g_pFilter);

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

具体创建了哪些minifilter,接着看结构体

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

OperationRegistration dd IRP_MJ_CREATE  ; DATA XREF: .data:10015014↓o

.rdata:10013454                 dd 0

.rdata:10013458                 dd offset PreOperation

.rdata:1001345C                 dd offset PostOperation

.rdata:10013460                 dd 0

.rdata:10013464                 dd IRP_MJ_CLEANUP

.rdata:10013468                 dd 0

.rdata:1001346C                 dd offset PreOperation

.rdata:10013470                 dd offset PostOperation

.rdata:10013474                 dd 0

.rdata:10013478                 dd IRP_MJ_SET_INFORMATION

.rdata:1001347C                 dd 0

.rdata:10013480                 dd offset PreOperation

.rdata:10013484                 dd offset PostOperation

.rdata:10013488                 dd 0

.rdata:1001348C                 dd IRP_MJ_CLOSE

.rdata:10013490                 dd 0

.rdata:10013494                 dd offset PreOperation

.rdata:10013498                 dd offset PostOperation

.rdata:1001349C                 dd 0

.rdata:100134A0                 dd IRP_MJ_CREATE_NAMED_PIPE

.rdata:100134A4                 dd 0

.rdata:100134A8                 dd offset PreOperation

.rdata:100134AC                 dd offset PostOperation

.rdata:100134B0                 dd 0

.rdata:100134B4                 dd IRP_MJ_OPERATION_END

.rdata:100134B8                 dd 0

.rdata:100134BC                 dd 0

.rdata:100134C0                 dd 0

.rdata:100134C4                 dd 0

从上可以看到minifilter过滤了IRP_MJ_CREATE、IRP_MJ_CLEANUP、IRP_MJ_SET_INFORMATION、IRP_MJ_CLOSE、IRP_MJ_CREATE_NAMED_PIPE

文件系统相关的注册完毕,然后就是设置一些进程、线程相关的回调函数例程

PsSetLoadImageNotifyRoutine(SysmonLoadImageNotifyRoutine);

PsSetCreateThreadNotifyRoutine(PsCreateThreadNotifyRoutine);

PsSetCreateProcessNotifyRoutine(PsCreateProcessNotifyRoutine, 0);

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

为了记录注册表sysmon还注册表注册表CmRegisterCallback(RegisterCallback, 0, &Cookie);回调,

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

为了记录进程open对象的事件注册了ob事件

g_bIsRegisterCallback = 1;

g_OperationRegistration.ObjectType = (POBJECT_TYPE *)PsProcessType;

g_OperationRegistration.Operations = 1;

g_OperationRegistration.PreOperation = PreProcessOperation;

g_OperationRegistration.PostOperation = PostProcessOperation;

g_CallbackRegistration.OperationRegistration = &g_OperationRegistration;

*(_DWORD *)&g_CallbackRegistration.Version = 0x10100;

g_CallbackRegistration.RegistrationContext = 0;

RtlInitUnicodeString(&g_CallbackRegistration.Altitude, L"1000");

Status = g_ObRegisterCallbacks(&g_CallbackRegistration, &RegistrationHandle);

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

为了获取管道的事件,它挂接了设备L \\Device\\NamedPipe ,创建了L \\Device\\SysmonPipeFilter 的过滤设备

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

至此sysmon的DriverEntry的初始化动作基本结束了。

  • IRP_MJ_DEVICE_CONTROL例程

Case 0x83400000:

打开驱动开启标志,并且获取且保存当前UI进程的句柄

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

Case  0x83400004:

Ring3请求事件信息,并返回到ring3的缓冲区

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

Case 0x83400008:

加载策略规则

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

Case 0x8340000C:

获取传入进程的相关信息(包括TokenUser、pTokenStatics、TokenGroup、TokenSeesion)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

还会获取进程pImagePathName、pCommandLine、CurrentDirectory

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

获取进程的CreateTime

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

该事件类型为4或者1

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

  • 文件信息的记录

Minifilter的PreOperation(PFLT_CALLBACK_DATA pData, PFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext)例程为主要的判断逻辑例程,先判断当前FileObject的路径是否为管道路径,管道事件直接记录上报事件

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

特别判断下IRP_MJ_SET_INFORMATION、IRP_MJ_CLEANUP,并且分别上报_,注意在判断IRP_MJ_SET_INFORMATION的时候只记录了RequestorMode是1即USER_MODE,并且是设置FileBasicInformation的请求。

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

PreOperation处理完毕,则PostOperation(PFLT_CALLBACK_DATA pData, PFLT_RELATED_OBJECTS pFltFileObj, PVOID CompletionContext, int Flags)对前者处理的上下文CompletionContext进行记录日志或者释放的处理,以IRP_MJ_SET_INFORMATION为例,PostOPerate则对PreOperate的CompletionContext的数据进行上报。

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

  • 注册表信息的记录

Sysmon初始化的时候注册了一个注册表过滤,CmRegisterCallback(RegisterCallback, 0, &Cookie);回调函数是NTSTATUS __stdcall RegisterCallback(PVOID CallbackContext, PVOID Argument1, PVOID Argument2),参数Argument1是过滤的注册表操作类型,sysmon过滤了0(RegNtDeleteKey   /  RegNtPreDeleteKey) 、4( RegNtRenameKey\RegNtPreRenameKey)、11(RegNtPostCreateKey)、15(RegNtPostDeleteKey)、16(RegNtPostSetValueKey)、17(RegNtPostDeleteValueKey)、19(RegNtPostRenameKey)27(RegNtPostCreateKeyEx)的注册表操作

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

  • 进程操作过滤

Sysmon注册了进程操作过滤,g_ObRegisterCallbacks(&g_CallbackRegistration, &RegistrationHandle);,

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

他只记录操作类型为OB_OPERATION_HANDLE_CREATE,并且只记录A进程操作B进程,A和B不是同一个进程,注意RtlWalkFrameChain这个函数是获取当前操作线程的线程栈,KeQuerySystemTime(&pOpenInfo.CreateTime);是获取当前系统时间,并且会把这些信息上报。

  • 其他重点技术细节
  1. 进程模块的枚举

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &ProcessInformation, 0x18u, 0)获取ProcessInformation的信息,从PebBaseAddress = ProcessInformation.PebBaseAddress;取得进程PEB的地址,在PEB结构中得到LDR的地址,LDR是进程加载模块的结构体,

struct _PEB

{

UCHAR InheritedAddressSpace;

UCHAR ReadImageFileExecOptions;

UCHAR BeingDebugged;

UCHAR BitField;

PVOID Mutant;

PVOID ImageBaseAddress;

PPEB_LDR_DATA Ldr;

PRTL_USER_PROCESS_PARAMETERS ProcessParameters;

PVOID SubSystemData;

PVOID ProcessHeap;

PRTL_CRITICAL_SECTION FastPebLock;

PVOID AtlThunkSListPtr;

PVOID IFEOKey;

ULONG CrossProcessFlags;

unsigned __int32 ProcessInJob : 1;

unsigned __int32 ProcessInitializing : 1;

unsigned __int32 ReservedBits0 : 30;

union

{

PVOID KernelCallbackTable;

PVOID UserSharedInfoPtr;

};

ULONG SystemReserved[1];

。。。。。。

}

PPEB_LDR_DATA Ldr;这个就是加载模块的结构,有三种加载表内存加载表,加载顺序表,初始化加载表从中可以枚举出模块信息。

struct _PEB_LDR_DATA

{

ULONG Length;

UCHAR Initialized;

PVOID SsHandle;

LIST_ENTRY InLoadOrderModuleList;

LIST_ENTRY InMemoryOrderModuleList;

LIST_ENTRY InInitializationOrderModuleList;

};

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

  1. 进程参数的获取

大致可以看到如下,首先要KeStackAttachProcess进程的空间,然后获取PEB地址,从PEB中的到ProcessParameters的结构

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

ProcessParameters结构如下:

struct _RTL_USER_PROCESS_PARAMETERS

{

ULONG MaximumLength;

ULONG Length;

ULONG Flags;

ULONG DebugFlags;

PVOID ConsoleHandle;

ULONG ConsoleFlags;

PVOID StandardInput;

PVOID StandardOutput;

PVOID StandardError;

CURDIR CurrentDirectory;

UNICODE_STRING DllPath;

UNICODE_STRING ImagePathName;

UNICODE_STRING CommandLine;

PVOID Environment;

ULONG StartingX;

ULONG StartingY;

ULONG CountX;

ULONG CountY;

ULONG CountCharsX;

ULONG CountCharsY;

ULONG FillAttribute;

ULONG WindowFlags;

ULONG ShowWindowFlags;

UNICODE_STRING WindowTitle;

UNICODE_STRING DesktopInfo;

UNICODE_STRING ShellInfo;

UNICODE_STRING RuntimeData;

RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];

ULONG EnvironmentSize;

};

可以看到该结构中进程参数相关的各种信息。

  1. 进程Token相关信息的获取

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)

都是通过ZwQueryInformationToken函数去获取,只是是使用不同的ClassInformation类去获取,定义如下

typedef enum _TOKEN_INFORMATION_CLASS {

  TokenUser                             ,

  TokenGroups                           ,

  TokenPrivileges                       ,

  TokenOwner                            ,

  TokenPrimaryGroup                     ,

  TokenDefaultDacl                      ,

  TokenSource                           ,

  TokenType                             ,

  TokenImpersonationLevel               ,

  TokenStatistics                       ,

  TokenRestrictedSids                   ,

  TokenSessionId                        ,

  TokenGroupsAndPrivileges              ,

  TokenSessionReference                 ,

  TokenSandBoxInert                     ,

  TokenAuditPolicy                      ,

  TokenOrigin                           ,

  TokenElevationType                    ,

  TokenLinkedToken                      ,

  TokenElevation                        ,

  TokenHasRestrictions                  ,

  TokenAccessInformation                ,

  TokenVirtualizationAllowed            ,

  TokenVirtualizationEnabled            ,

  TokenIntegrityLevel                   ,

  TokenUIAccess                         ,

  TokenMandatoryPolicy                  ,

  TokenLogonSid                         ,

  TokenIsAppContainer                   ,

  TokenCapabilities                     ,

  TokenAppContainerSid                  ,

  TokenAppContainerNumber               ,

  TokenUserClaimAttributes              ,

  TokenDeviceClaimAttributes            ,

  TokenRestrictedUserClaimAttributes    ,

  TokenRestrictedDeviceClaimAttributes  ,

  TokenDeviceGroups                     ,

  TokenRestrictedDeviceGroups           ,

  TokenSecurityAttributes               ,

  TokenIsRestricted                     ,

  TokenProcessTrustLevel                ,

  TokenPrivateNameSpace                 ,

  TokenSingletonAttributes              ,

  TokenBnoIsolation                     ,

  TokenChildProcessFlags                ,

  MaxTokenInfoClass

} TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS;

需要获取那个就可以选择那一个。

本文大致讲解完毕,内部还有很多很有意思的技术细节由于篇幅原因,读者可以自己深入挖掘,在做一个产品的时候,我们可以分析他人的产品,不仅可以了解他人的产品的长处和不足,同时也可以补充自己产品的不足的之处,一个好的产品就是在不断的琢磨研究与推翻,更重要的是细节的体现才能做好产品。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

jQuery实战(第2版)

jQuery实战(第2版)

[美]Bear Bibeault、[美]Yehuda Katz / 三生石上 / 人民邮电出版社 / 2012-3 / 69.00元

jQuery 是目前最受欢迎的JavaScript/Ajax 库之一,能用最少的代码实现最多的功能。本书全面介绍jQuery 知识,展示如何遍历HTML 文档、处理事件、执行动画、给网页添加Ajax 以及jQuery UI 。书中紧紧地围绕“用实际的示例来解释每一个新概念”这一宗旨,生动描述了jQuery 如何与其他工具和框架交互以及如何生成jQuery 插件。 本书适合各层次Web 开发人......一起来看看 《jQuery实战(第2版)》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具