STATEMENT
声明
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。
雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
简介
Sysmon是一款基于Windows平台的监控工具,具有进程监控、网络连接、文件监控、管道监控等一系列对系统的监控功能,可以通过其xml配置文件对其监控进行灵活更改,收集到系统的日志来进行后续的分析。这次我们通过逆向分析Sysmon来认识系统监控是如何实现的。
下面主要以sysmon v 1364位来逆向分析,先分析sysmon的ring3部分开始,然后深入ring0的部分。
sysmon.exe (ring3)
sysmon安装:
一开始sysmon会对所传入的各个参数进行判断:
下面我们先看看-i安装所涉及到的操作,-i是初始化安装sysmon,程序先判断是否有sysmon64、sysmonDrv服务,如果没有则再进行后续安装操作:
再找到存放在资源段中的名为“BINRES”的sys驱动:
然后在C:\Windows目录下释放SysmonDrv.sys:
先后创建服务Sysmon64、SysmonDrv:
设置计算机
\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Sysmon64\Parameters
计算机
\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SysmonDrv\Instances
计算机
\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SysmonDrv\Parameters
注册表中的值,后面ring0的驱动部分会读取这些值:
分别启动SysmonDrv、Sysmon64:
sysmon服务
接下来就是Sysmon服务方面的内容,主要包括控制码的发送、网络连接、DNS监控、剪切板监控等。我们先注册服务入口函数ServiceMain_1400D2260:
在该函数中先发送0x83400000控制码给SysmonDrv驱动设备,准备开始在驱动中的文件进程线程注册表的监控:
发送0x83400004控制码,不断获取驱动设备返回的数据,并在后面对数据进行解析:
网络连接
下面是创建ETW事件监控网络连接,这里StartTrace传入的是KERNEL_LOGGER_NAME,不需要使用EnableTraceEx2来开启,所设置session的EnableFlags 为EVENT_TRACE_FLAG_NETWORK_TCPIP:
接着新建线程调用OpenTrace()打开事件通道,对指定LOGGER_NAME的Etw进行解析:
DNS监控
DNS监控也是使用ETW事件进行监听,不同的是这里自定义LOGSESSION_NAME为SysmonDnsEtwSession,通过EnableTraceEx2传入一个需要监控的ProviderGuid(DNSClientProviderGuid),并传入EVENT_CONTROL_CODE_ENABLE_PROVIDER(1)来开启ETW的监控:
DNSClientProviderGuid值:
OpenTrace() 打开事件通道,processTrace()去开启监控:
剪切板监控
接着是对剪切板进行监控,下面是其实现过程:
先新建一个window窗口,并在窗口回调中SetClipboardViewer设置窗口为剪切板查看器,并处理WM_DRAWCLIPBOARD、WM_CLIPBOARDUPDATE消息,该消息是用于监控剪切板内容的变化:
在ClipBoardData_1400FF7A0中处理了三种数据格式CF_OEMTEXT、CF_TEXT、CF_UNICODETEXT的内容,并通过GetClipboardData()、GlobalLock()获取到内容:
更新规则:
Sysmon -c 可以用来更新自己写的xml规则,会把规则位置、规则内容、规则hash等一系列数据存放在注册表中:
sys驱动 (ring0)
具体流程
下面我们先看驱动的具体流程,在驱动中会先判断当前的系统版本比win8、2012高,然后读取之前在注册表中设置的信息:
如果是win8\2012以上的就只实现IRP_MJ_CREATE、IRP_MJ_CLOSE 、IRP_MJ_DEVICE_CONTROL的消息处理,同时会注册miniFlt过滤,如果不支持Flt则用回 Sfilter:
IoCreateDevice创建设备,IoCreateSysmbolicLink创建该设备的符号连接,注册minifilter过滤器:
最后对进程、线程、注册表、对象进行监控回调的设置,后面会逐一来看:
设置Minifilter过滤器
Sysmon与文件相关的监控主要由Minifilter过滤器实现。minifilter的设置需先设置程序过滤的IRP消息,然后使用FltRegisterFilter注册过滤器,接着使用FltStartFiltering开启过滤器,最后当驱动卸载时要使用FltUnRegisterFilter卸载过滤器。
下面开始注册minifilter过滤器并开始过滤:
设置
IRP_MJ_CREATE
IRP_MJ_CREATE_NAMED_PIPE
IRP_MJ_CLOSE
IRP_MJ_WRITE
IRP_MJ_CLEANUP
IRP_MJ_SET_INFORMATION
这六个IRP消息,当有文件管道创建、写入、属性修改等操作都会触发回调函数
FltPostOperation_180001000()
FltPreOperation_1800021A0()
FltPreOperation_1800021A0是操作前的回调函数,其具体实现基本是根据CAllbackData->Iopd->MajorFunction的消息类型来进行后续的过滤操作,像下图是如果获取到IRP_MJ_CREATE就调用FltGetFileNameInformation
FltParseFileNameInformation
获取并解析文件或目录的信息:
进程监控:
进程监控功能主要包含了事件 ID 1:进程创建,进程创建事件提供有关新创建的进程的扩展信息。
系统主要使用了PsSetCreateProcessNotifyRoutine\PsSetCreateProcessNotifyRoutineEx2函数设置进程创建回调,从而实现对系统进程创建进行监控,函数声明如下,其中参数NotifyInformation是一个特定的函数指针,当进程创建或退出时会触发到:
回调函数如下,参数比较关键分别为ParentId父进程ID、ProcessId进程ID、CreateInfo PS_CREATE_NOTIFY_INFO的结构体指针:
当CreateInfo结构体不为NULL,则代表是进程创建,下面是通过对CreateInfo结构体进行解析收集所创建进程的信息:
线程监控:
线程监控功能主要包含了事件 ID 8:CreateRemoteThread,该事件检测到一个进程在另一个进程中创建线程的行为。恶意软件常用此技术来注入代码并在其他进程中进行隐藏或其他有害操作。
与进程监控类似,系统可以使用PsSetCreateThreadNotifyRoutine函数设置线程创建的1回调,函数声明如下,其中参数NotifyInformation同样是一个特函数指针:
在回调函数函数中收集相关的进程信息:
模块监控
模块监控功能包含了事件 ID 6:已加载驱动程序与事件 ID 7:加载的图像,模块监控会对系统驱动程序加载的事件和对特定进程中加载模块时的信息进行记录。
系统同样也提供了PsSetLoadImageNotifyRoutine函数对系统模块加载进行监视,函数声明如下:
PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine是回调函数指针,可以获取系统中驱动模块和DLL模块的加载信息,其声明如下:
其回调函数的参数分别为FullImageName加载模块的进程名称、ProcessId加载模块的进程ID、ImageInfo指向IMAGE_INFO的结构体指针,下面会对相关的模块信息进行收集:
注册表监控
注册表监控包括:事件 ID 12:RegistryEvent (注册表项和值创建和删除)、事件 ID 13:RegistryEvent (注册表值修改)、事件 ID 14:RegistryEvent (注册表项和值重命名)。
系统同样提供了CmRegisterCallback函数对系统设置注册表进行监控,其函数声明如下,其中主要关注PEX_CALLBACK_FUNCTION这个参数为回调函数:
RegisterCallbackFunc_18000A6C0的声明如下,主要关注Argument1(操作类型)与Argument2两个参数(操作详细信息的结构体指针),可以通过对操作类型的判断然后从结构体指针获取信息:
这里sysmon对RegNtDeleteKey、RegNtPreRenameKey、RegNtPostCreateKey、RegNtPostDeleteKey、RegNtPostSetValueKey、RegNtPostDeleteValueKey等一系列注册表操作进行判断,通过ObQueryNameString获取到所操作的注册表路径:
对象监控
对象监控对应事件 ID 10:ProcessAccess,该功能是对一个进程在打开另一个进程时访问事件进行记录。进程访问该操作通常后续会对进程内存进行读取或写入目标进程的地址空间。这使得某些工具Mimikatz能读取Lsass.exe 等进程的内存,以窃取凭据以用于传递哈希攻击。
同样系统提供了ObRegisterCallbcaks函数对对象回调进行注册,实现监控系统对象。以下为该函数的声明,其中主要关注第一个参数CallbackRegistration,该参数指向了一个OB_CALLBACK_REGISTRATION结构体,需要为其注册信息:
在OB_CALLBACK_REGISTRATION结构体中主要包含了5个参数,主要看第五个参数OperationRegistration,指向OB_OPERATION_REGISTRATION结构体指针,在该结构体中由两个函数指针_In_ POB_PRE_OPERATION_CALLBACK PreOperation、In POB_POST_OPERATION_CALLBACK PostOperation,分别是请求操作前后的回调函数:
下面分别是设置OB_CALLBACK_REGISTRATION、OB_OPERATION_REGISTRATION两个指针,ObProcessPreCall_1800098F0为操作前的回调函数:
在回调中对操作类型:进行判断是否为创建句柄,然后通过pObPreOperationInfo对象获取具体信息:
管道监控
管道事件的监控使用了过滤驱动的方式,具体流程如下:
首先,程序调用IoCreateDevice函数创建了名为\Device\SysmonPipFilter的设备,然后调用IoGetDeviceObjectPointer函数获取到\Device\NamePipe驱动设备对象,最后通过IoAttachDeviceToDeviceStack函数将创建的设备附加到\Device\NamePipe设备对像的设备堆栈上。这样所创建的\Device\SysmonPipFilter的设备就是设备栈的栈顶,当有相关消息时,该设备最先获取到该消息。
总结
本文章主要浅析了 sysmon中各个监控功能点是如何实现的,加深对系统功能监控实现的理解,同时可以站在系统防御者的角度去观察攻击工具可监测到的点。然而这次分析的内容只是sysmon的冰山一角,还有更多的内容需要继续探究。
安恒信息
✦
杭州亚运会网络安全服务官方合作伙伴
成都大运会网络信息安全类官方赞助商
武汉军运会、北京一带一路峰会
青岛上合峰会、上海进博会
厦门金砖峰会、G20杭州峰会
支撑单位北京奥运会等近百场国家级
重大活动网络安保支撑单位
END
长按识别二维码关注我们