ETW (Event Tracing for Windows) 在 Windows 2000 引入,从这时候起,OS Kernel 和 Service 都会通过 ETW 记录。Windows Vista 之後引入了统一的事件提供程序模型和 API,并在 Windows7 得到增强。
由於 ETW 的功能和性能,第三方的日志系统逐渐式微。ETW 的优点包含
ETW 的运作主要有三个角色,Controller、Provider、Consumer。
Controller 负责控制 Session 开关,决定要不要在 Session 接收 Provider。每个 Session 可以同时从多个 Provider 抓取事件,Controller 也能在程序运行的途中开启或关闭 Session。
Provider 负责提供事件,把事件产生给 Session 处理。Provider 是可以扩展的,能够自己定义事件栏位。
Consumer 负责透过 Session 接收从 Provider 来的事件。
蓝队的部分,因为有 Callback 机制,可以被动且即时的收到事件。
以 Provider Microsoft-Windows-Threat-Intelligence 为例,它能够监测 AllocationType、RegionSizes、ProtectionMask,其中的 ProtectionMask 如果是可读、可写、可执行的一块记忆体,则比较有可能是恶意程序。虽然无法断言只要看到可读、可写、可执行的记忆体就代表是恶意程序,不过经过种种方式寻找证据,就可以有一定的信心判断它是不是恶意程序。
再以 Provider Microsoft-Windows-Kernel-Registry 为例,它可以监测有没有透过 Registry 实作的 Persistence 行为。比如侦测一个程序是否有写入以下 Registry
既然 ETW 对於篮队是一个十分有效的工具,那红队这边当然也会有对应策略。
在 Usermode,也就是 Ring3 中,可以透过 Hook EtwEventWrite 的方式拦截事件写入的函数;或是使用 EtwEventUnregister 取消注册 ETW Event。之後的文章会介绍一些在 Usermode 绕过 ETW 的方法。
在 Kernelmode,也就是 Ring0 中,有个方法叫做 GITL(Ghost In The Logs),原理是透过 Hook Kernel API NtTraceEvent 达到绕过 ETW 的效果。
Windows 有个内建工具 - Logman,可以用来查看 Provider 的资讯和 Session 的状态,也可以建立 Session 收取事件。
指令logman query providers
,回传结果如下图。输出有两栏,分别是 Provider 和 GUID,其中 GUID 是用来辨别 Provider 的唯一的 ID。
如果想要知道一个 Provider 更详细的资讯,只要在刚刚指令的 providers
後面加上 Provider 名称或 GUID。指令 logman query providers <provider name>
或 logman query providers <GUID>
,回传结果如下。
可以看到除了之前看到的 Provider 和 GUID 外,还多了下面两个表格。
其中第二个表格是这个 Provider 的 Flag,因为一个 Provider 可能可以监听不同种类的事件,这些 Flag 就是用来从 Provider 提供的事件中挑选我们需要的事件。假设我们想要监听其中的 GCKeyword 和 GCHandleKeyword,则输入的 Flag 就是 0x1 + 0x10 = 0x11
,等等在建立 Session 时会需要填入 Flag。
第三个表格则是指定的安全层级(Security Level),每个事件都会有个安全层级。如果选了安全层级高的,则比选择低的选项也都会一起被启用。这个安全层级在等等建立 Session 时也需要填入。
# logman query providers ".NET Common Language Runtime"
Provider GUID
-------------------------------------------------------------------------------
.NET Common Language Runtime {E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}
Value Keyword Description
-------------------------------------------------------------------------------
0x0000000000000001 GCKeyword GC
0x0000000000000002 GCHandleKeyword GCHandle
0x0000000000000004 FusionKeyword Binder
0x0000000000000008 LoaderKeyword Loader
0x0000000000000010 JitKeyword Jit
0x0000000000000020 NGenKeyword NGen
0x0000000000000040 StartEnumerationKeyword StartEnumeration
0x0000000000000080 EndEnumerationKeyword StopEnumeration
0x0000000000000400 SecurityKeyword Security
0x0000000000000800 AppDomainResourceManagementKeyword AppDomainResourceManagement
0x0000000000001000 JitTracingKeyword JitTracing
0x0000000000002000 InteropKeyword Interop
0x0000000000004000 ContentionKeyword Contention
0x0000000000008000 ExceptionKeyword Exception
0x0000000000010000 ThreadingKeyword Threading
0x0000000000020000 JittedMethodILToNativeMapKeyword JittedMethodILToNativeMap
0x0000000000040000 OverrideAndSuppressNGenEventsKeyword OverrideAndSuppressNGenEvents
0x0000000000080000 TypeKeyword Type
0x0000000000100000 GCHeapDumpKeyword GCHeapDump
0x0000000000200000 GCSampledObjectAllocationHighKeyword GCSampledObjectAllocationHigh
0x0000000000400000 GCHeapSurvivalAndMovementKeyword GCHeapSurvivalAndMovement
0x0000000000800000 GCHeapCollectKeyword GCHeapCollect
0x0000000001000000 GCHeapAndTypeNamesKeyword GCHeapAndTypeNames
0x0000000002000000 GCSampledObjectAllocationLowKeyword GCSampledObjectAllocationLow
0x0000000020000000 PerfTrackKeyword PerfTrack
0x0000000040000000 StackKeyword Stack
0x0000000080000000 ThreadTransferKeyword ThreadTransfer
0x0000000100000000 DebuggerKeyword Debugger
0x0000000200000000 MonitoringKeyword Monitoring
Value Level Description
-------------------------------------------------------------------------------
0x00 win:LogAlways Log Always
0x02 win:Error Error
0x04 win:Informational Information
0x05 win:Verbose Verbose
logman create trace <session name> -p <provider name / GUID> <flags> <security level> -o <path to log file>
logman start <session name>
logman stop <session name>
logman delete <session name>
以下示范使用 Provider Microsoft-Windows-Kernel-Process 的 Session。在启用 Session 之後可以稍微打几个指令,要打会开启 Process 的指令例如 whoami
、net user
等,之後查看输出时可以观察到。
:: 1. 建立 Session
logman create trace example -p Microsoft-Windows-Kernel-Process 0x10 0x4 -o C:\example.etl
:: 2. 启用 Session
logman start example
:: 3. 停用 Session
logman stop example
:: 4. 删除 Session
logman delete example
产生出来的档案室 etl 档,可以用 tracerpt
转成 xml 档,指令如下
tracerpt example.etl -o example.xml
。
打开档案後,有在档案中发现你刚刚打的那些指令的话就成功了。以下是我输入 whoami
指令後产生的输出。
<EventData>
<Data Name="ProcessID"> 23836</Data>
<Data Name="ProcessSequenceNumber">70760</Data>
<Data Name="CreateTime">2021-10-05T15:41:44.135049700Z</Data>
<Data Name="ExitTime">2021-10-05T15:41:44.150097300Z</Data>
<Data Name="ExitCode"> 0</Data>
<Data Name="TokenElevationType"> 1</Data>
<Data Name="HandleCount"> 54</Data>
<Data Name="CommitCharge">1732608</Data>
<Data Name="CommitPeak">1937408</Data>
<Data Name="CPUCycleCount">17963357</Data>
<Data Name="ReadOperationCount"> 0</Data>
<Data Name="WriteOperationCount"> 0</Data>
<Data Name="ReadTransferKiloBytes"> 0</Data>
<Data Name="WriteTransferKiloBytes"> 0</Data>
<Data Name="HardFaultCount"> 15</Data>
<Data Name="ImageName">whoami.exe</Data>
</EventData>
今天只是简单介绍 ETW 和 Windows 内建的工具,但是其实能做到的不只是产生日志档案。之後会讲解如何写程序,即时的抓取事件并分析操作。
<<: Day-26 Process Synchronization
>>: [Day23]ISO 27001 附录 A.11 实体及环境安全
上面这个是今天会提到的内容,如果你已经可以轻松看懂,欢迎直接左转去看我队友们的精彩文章! 昨天我们...
上一章我们了解了分散式系统是什麽、为什麽要让系统分散, 也大概知道分散式系统会遇到节点死掉、网路断掉...
如果有错误,欢迎留言指教~ Q_Q 如果你要成功更新画面,你必须经过两个步骤: render fu...
我们现在有了许多的基础的 parser function 了,我们直接来看怎麽样组合这些 funct...
我们昨天顺利把借物归还事件可以自动化上传到 Google Calendar 上,但是如果借阅人不看 ...