首页
社区
课程
招聘
[原创]微软轻量级系统监控工具sysmon原理与实现完全分析(下篇)
发表于: 2018-9-19 19:22 5573

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

2018-9-19 19:22
5573

Sysmon的ring0实现原理

作者:浪子_三少

上文讲解了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;


然后从pRegistry注册表中去获取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”


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


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


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


如果支持只实现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。


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


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


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还注册表注册表CmRegisterCallback(RegisterCallback, 0, &Cookie);回调,


为了记录进程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);



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


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

二、           IRP_MJ_DEVICE_CONTROL例程

Case 0x83400000:

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



Case  0x83400004:

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


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-9-20 14:27 被basketwill编辑 ,原因:
收藏
免费 1
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  junkboy   +1.00 2018/09/19
最新回复 (2)
雪    币: 441
活跃值: (1060)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
2
IDA不是都给出源码 了
2019-5-30 15:38
0
雪    币: 1994
活跃值: (1526)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
编程小白 IDA不是都给出源码 了
ida离源码还十万八千里。。
2019-5-31 09:15
0
游客
登录 | 注册 方可回帖
返回
//