Sysmon是如何实现监控的?

Sysmon安装后会生成如下两个文件:

C:WindowsSysmon.exe
C:WindowsSysmonDrv.sys

显然Sysmon使用了驱动级监控,需要IDA+WinDBG+VMware组合,搭建双机驱动调试环境才能对SysmonDrv.sys进行有效的调试。

通过IDA+WinDBG的静态分析和动态跟踪,发现其使用PsSetCreateProcessNotifyRoutine函数,来监控进程的创建。关键代码如下:

.text:FFFFF880018AEA99 ; ---------------------------------------------------------------------------
.text:FFFFF880018AEA99
.text:FFFFF880018AEA99 loc_FFFFF880018AEA99:                   ; CODE XREF: sub_FFFFF880018AE730+349
.text:FFFFF880018AEA99 mov     rcx, cs:qword_FFFFF880018B4498
.text:FFFFF880018AEAA0 call    cs:FltStartFiltering
.text:FFFFF880018AEAA6 call    sub_FFFFF880018ADD00
.text:FFFFF880018AEAAB lea     rcx, sub_FFFFF880018ADBA0
.text:FFFFF880018AEAB2 call    cs:PsSetCreateThreadNotifyRoutine
.text:FFFFF880018AEAB8 lea     rcx, sub_FFFFF880018ADC40
.text:FFFFF880018AEABF xor     edx, edx
.text:FFFFF880018AEAC1 call    cs:PsSetCreateProcessNotifyRoutine
.text:FFFFF880018AEAC7 xor     eax, eax

回调函数地址为:sub_FFFFF880018ADC40(动态地址)。每当有新进程创建时,都会回调这个函数。回调时,寄存器RCX保存父进程PID,RDX保存子进程PID。

PsSetCreateProcessNotifyRoutine函数定义如下:

NTSTATUS PsSetCreateProcessNotifyRoutine(
  _In_  PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
  _In_  BOOLEAN Remove
);

回调函数定义如下:

VOID
(*PCREATE_PROCESS_NOTIFY_ROUTINE) (
    IN HANDLE  ParentId,
    IN HANDLE  ProcessId,
    IN BOOLEAN  Create
    );

对于文件创建时间修改的监控,则是通过Minifilter驱动实现的。大体原理是,注册一个文件过滤器,监控对文件的操作,一旦发现有修改文件日期的行为,就记录日志。过程如下:

注册过滤器:

.text:FFFFF8800164FA5E                 mov     rcx, rdi
.text:FFFFF8800164FA61                 mov     cs:qword_FFFFF880016554A8, rax
.text:FFFFF8800164FA68                 mov     cs:qword_FFFFF880016554A0, rax
.text:FFFFF8800164FA6F                 call    cs:FltRegisterFilter

启动过滤器:

.text:FFFFF8800164FA99 ; ---------------------------------------------------------------------------
.text:FFFFF8800164FA99
.text:FFFFF8800164FA99 loc_FFFFF8800164FA99:                   ; CODE XREF: sub_FFFFF8800164F730+349
.text:FFFFF8800164FA99                 mov     rcx, cs:qword_FFFFF88001655498
.text:FFFFF8800164FAA0                 call    cs:FltStartFiltering

回调函数:

.text:FFFFF8800164DBD9 loc_FFFFF8800164DBD9:                   ; CODE XREF: sub_FFFFF8800164DB90+39
.text:FFFFF8800164DBD9                 cmp     [rdi+50h], bl
.text:FFFFF8800164DBDC                 jnz     short loc_FFFFF8800164DC21
.text:FFFFF8800164DBDE                 cmp     dword ptr [rax+20h], 4
.text:FFFFF8800164DBE2                 jnz     short loc_FFFFF8800164DC21
.text:FFFFF8800164DBE4                 cmp     dword ptr [rax+18h], 28h ; \'(\'
.text:FFFFF8800164DBE8                 jb      short loc_FFFFF8800164DC21
.text:FFFFF8800164DBEA                 mov     rdi, [rax+38h]
.text:FFFFF8800164DBEE                 test    rdi, rdi
.text:FFFFF8800164DBF1                 jz      short loc_FFFFF8800164DC21
.text:FFFFF8800164DBF3                 mov     rax, [rdi]
.text:FFFFF8800164DBF6                 add     rax, 2
.text:FFFFF8800164DBFA                 cmp     rax, 2
.text:FFFFF8800164DBFE                 jbe     short loc_FFFFF8800164DC21
.text:FFFFF8800164DC00                 mov     rcx, rsi
.text:FFFFF8800164DC03                 call    sub_FFFFF8800164D6B0 ; 这里调用文件信息查询函数FltQueryInformationFile,查询是否符合条件。符合条件返回1,可以人工修改结果使其效果相反。
.text:FFFFF8800164DC08                 test    al, al
.text:FFFFF8800164DC0A                 jz      short loc_FFFFF8800164DC21
.text:FFFFF8800164DC0C                 mov     rdx, [rdi]
.text:FFFFF8800164DC0F                 mov     rcx, rsi
.text:FFFFF8800164DC12                 call    sub_FFFFF8800164D720 ; 如果确实是需要记录的操作,那么调用此子函数,获取文件信息以及调用者的PID。
.text:FFFFF8800164DC17                 test    rax, rax
.text:FFFFF8800164DC1A                 jz      short loc_FFFFF8800164DC21
.text:FFFFF8800164DC1C                 mov     [r14], rax
.text:FFFFF8800164DC1F                 xor     ebx, ebx

每次回调时通过FltQueryInformationFile函数查询文件的信息,来判断是否修改。

NTSTATUS FltQueryInformationFile(
  _In_       PFLT_INSTANCE Instance,
  _In_       PFILE_OBJECT FileObject,
  _Out_      PVOID FileInformation,
  _In_       ULONG Length,
  _In_       FILE_INFORMATION_CLASS FileInformationClass,
  _Out_opt_  PULONG LengthReturned
);

FILE_INFORMATION_CLASS结构体是多种类型的,FILE_NETWORK_OPEN_INFORMATION类型保存了文件的各个时间属性。

发表评论

电子邮件地址不会被公开。