ETW绕过实战教程

极客

本文目录导读:

ETW绕过实战教程

  1. 开头先唠两句:这ETW到底是啥“门神”?
  2. 先别急着动手!咱们得先“看懂”日志在哪儿
  3. 核心思路来了:三种“花式”绕过姿势
  4. 实战演练:完整代码逻辑与避坑指南
  5. 事后总结:绕过之后,咱们还得干点啥?

ETW绕过实战手记:一场与蓝队的“猫鼠游戏”全记录

导语:说实话,每次看到网上那些讲ETW绕过的文章,不是太理论就是直接甩代码,看得人一头雾水,今天咱不整虚的,直接把我实战中踩过的坑、绕过的弯、以及最终成功的那点小心得全盘托出,如果你也在研究这个,相信我,这篇ETW绕过实战教程能让你少走至少三天的弯路。


开头先唠两句:这ETW到底是啥“门神”?

兄弟们,咱们得先搞清楚对手是谁。ETW(Event Tracing for Windows) ,这玩意儿说白了就是Windows系统自带的“监控摄像头”,从进程创建到网络连接,啥都要记录一笔,你想想,你辛辛苦苦搞了个免杀,结果一执行,ETW转身就给EDR(端点检测响应系统)打了小报告——“哥们,这儿有个可疑线程在搞事情!”

嘿,你说气不气人?我之前就有一次实战,马儿落地后权限都拿到了,结果就是因为没处理ETW,对面蓝队15分钟就溯源到我C2服务器了,当场给我来个“拔线”体验,所以啊,想当个“合规”的红队,这ETW绕过实战是必修课,没得商量。

先别急着动手!咱们得先“看懂”日志在哪儿

这里我不跟你扯那些高大上的API内部结构,咱就用最笨但最有效的方法——动手试,你打开Process Monitor或者用logman query providers命令,你就能看到一堆Provider挂着,那些关键的网络、进程、文件操作的Provider,比如Microsoft-Windows-Kernel-ProcessMicrosoft-Windows-Threat-Intelligence,就是咱们要重点“照顾”的对象。

实战小插曲:我刚开始的时候,直接一股脑想关掉所有Provider,结果好家伙,系统直接崩溃了,蓝屏重启,当时我那个尴尬啊……所以各位记住了,ETW绕过不是把所有日志全关死,而是“精准屏蔽” ,就像你关监控摄像头,只遮挡对着你家门口那个,而不是把整个小区的电闸都拉了。

核心思路来了:三种“花式”绕过姿势

咱们这行,讲究个“道法术”,直接上代码那是“术”,但咱们得先聊“法”,也就是思路,目前网上流传比较广的,也就这三大流派:

下“迷魂药”——Patch回调函数

这个方法咱得深入骨髓,ETW的核心是每个Provider里都有一堆回调函数(Callback),数据就是通过这些回调传给消费者的,咱的做法很简单粗暴,直接内存补丁(Inline Hook) 把那几个关键函数给“阉割”了。

就比如EtwEventWrite这个函数,你直接给它补个mov eax, 0; ret的壳,让它干瞪眼没法干活,不过说实在的,这招现在EDR也不是吃素的,人家有“完整性校验”,你补丁一下,它马上自检然后报警,所以你得先提权到内核态,把检测机制的线程给挂起,然后利用KeStackAttachProcess切到系统进程再去打补丁,这套连招下来,成功率能到七成。

玩“金蝉脱壳”——篡改Provider GUID

这个思路比较骚,太硬刚容易头破血流,咱玩点智取,ETW消费端是靠GUID来订阅特定事件的,咱可以动态创建一个假Provider,把真Provider的GUID给替换掉,这样蓝队订阅的还是老GUID,但咱们的敏感操作早就从新通道溜走了。这招的好处是,不碰内核,只改用户态注册表配置,隐蔽性极高。

我得提醒一句,这个方法对某些硬编码GUID的EDR无效,比如那个 Microsoft-Windows-Threat-Intelligence 的GUID是写死在驱动里的,你改注册表没用,人家直接硬编码轮询,这时候就得换招了。

用“障眼法”——断开Event Tracing Session

这招最直接,那就是把当前正在监听ETW的会话(Session)给“踢下线”,怎么踢?调用StartTrace创建一个相同名称的Session,或者直接找到EDR开启的Session,然后调用ControlTrace发个STOP命令

这招有个风险,就是太暴力了,跟直接拔摄像头电源似的,容易被在重启后发现,最好是在Session连上来但还没开始消费的时候,给它踩一脚刹车。

实战演练:完整代码逻辑与避坑指南

咱光说不练没用,我把我那个自认为最优雅的代码片段逻辑分享给大家,代码不长,但逻辑得对。

// 伪代码逻辑,重在思路
NtProtectVirtualMemory(...); // 去掉内存保护
// 核心思路:定位函数地址,这是关键
if (g_pEtwEventWrite == NULL) {
    g_pEtwEventWrite = (DWORD_PTR)GetProcAddress(LoadLibrary("ntdll.dll"), "EtwEventWrite");
}
// 写入shellcode补丁,改成 ret
BYTE patch[] = { 0xC3 }; // ret指令
WriteProcessMemory(GetCurrentProcess(), (LPVOID)g_pEtwEventWrite, patch, 1, &oldProtect);
// 关键点:在Patch之前,一定要先向CurrentThreadId发一个假事件,确保ETW缓冲区更新
EtwEventWrite(...) // 假装正常调用,确认没崩

避坑提示:兄弟们,这里千万注意,别一上来就全局patch,有的EDR会在系统里开一个专门的线程来监控ntdll!EtwEventWrite的字节码完整性,你光patch这一个点,人家一查CRC或者页属性,直接露馅,所以最佳实践是先EtwEventWrite一次,然后Patch,再立刻调用RtlCaptureContext看有没有触发异常,如果没有异常再继续往下走

事后总结:绕过之后,咱们还得干点啥?

做完上面的ETW绕过实战,你是不是觉得万事大吉了?非也非也!我跟你说,EDR的逻辑是“多源关联”,你只是把ETW这个源给堵了,但人家还有内核回调(Callback)、AMSI、WMI事件订阅呢。

所以咱们的哲学是:ETW绕过只是“敲门砖”,不是“免死金牌” ,绕过了ETW,你得立刻去清理事件日志,比如wevtutil cl Systemwevtutil cl Security这些,然后把相关的ETW Provider的EnableFlags也恢复原状,免得蓝队事后复查发现Provider被异常关闭。

最后说点真心话:其实搞这行,技术只是一方面,心态也很重要,那次我在客户现场做测试,绕过ETW之后,手都在抖,因为那是在内网核心区,但当你看到日志里那片“静默”,那种成就感,哎呀,别提了,不过咱还是得守规矩,技术本身无罪,就看怎么用啦。

这篇ETW绕过实战教程算是把我压箱底的经验都掏出来了,希望能帮到正在卡壳的你,如果你在实战中遇到了别的奇葩姿势,欢迎来我这个主页流言区一起聊聊,咱这行就得互相切磋着涨经验不是?(笑)下次有机会,我还准备写写如何绕过内核回调那点事儿,记得关注我啊,拜了个拜!

文章版权声明:除非注明,否则均为极客网安-咸鱼原创文章,转载或复制请以超链接形式并注明出处。

目录[+]