-
-
记一次调用ETW-TI
-
发表于: 2024-10-6 23:24 2760
-
0x00 前言
相信大家都对Microsoft-Windows-Threat-Intelligence这个名字十分熟悉
因为不少杀软都用ETW-TI来进行保护系统,例如Elastic等
那Microsoft-Windows-Threat-Intelligence的调用条件是什么呢
要成功注册的事件使用者,我们至少需要以PPL进程的身份运行,而最优雅的方式是使用Microsoft验证的证书(使用代码签名EKU)对软件进行签名,或者使用测试签名模拟
我使用了前者 给自己加PPL 虽然这不是一个很优雅的方式 但是至少能用
同时我们想要用CPP来调用他 只需要了解一下这个库https://github.com/microsoft/krabsetw
思路大概如下
创建新的跟踪对象->创建新的提供者对象->加过滤器(与回调)->启动ETW-TI
那么话不多说 我们直接开始
0x01 PPL进程
这不是一个困难的任务 基本上会内核的都会一点这个
因为我们没有EKU或者懒得用测试签名模拟
我们可以直接改EPROCESS结构里面的SignatureLevel
我就不班门弄斧了 直接放代码吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | typedef struct _PS_PROTECTION { UCHAR Type : 3 ; UCHAR Audit : 1 ; UCHAR Signer : 4 ; } PS_PROTECTION, * PPS_PROTECTION; typedef struct _PROCESS_SIGNATURE { UCHAR SignatureLevel; UCHAR SectionSignatureLevel; PS_PROTECTION Protection; } PROCESS_SIGNATURE, * PPROCESS_SIGNATURE; struct ProcessSignature { ULONG Pid; UCHAR SignerType; UCHAR SignatureSigner; }; NTSTATUS SetProcessSignature(ProcessSignature * ProcessSignature) { if (!SignatureLevelOffset) { SignatureLevelOffset = GetSignatureLevelOffset(); } if (SignatureLevelOffset) { PEPROCESS process; NTSTATUS status = STATUS_SUCCESS; status = PsLookupProcessByProcessId(ULongToHandle(ProcessSignature - >Pid), &process); if (!NT_SUCCESS(status)) { return status; } UCHAR newSignatureLevel = (ProcessSignature - >SignerType << 4 ) | ProcessSignature - >SignatureSigner; PPROCESS_SIGNATURE processSignature = (PPROCESS_SIGNATURE)(UINT64(process) + SignatureLevelOffset); processSignature - >SignatureLevel = newSignatureLevel; processSignature - >Protection. Type = ProcessSignature - >SignerType; processSignature - >Protection.Signer = ProcessSignature - >SignatureSigner; ObDereferenceObject(process); return status; } } |
我们只需要在应用层给他填入TYPE和SIGNER就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | enum SignatureType { PsProtectedTypeNone = 0 , PsProtectedTypeProtectedLight = 1 , PsProtectedTypeProtected = 2 }; enum SignatureSigner { PsProtectedSignerNone = 0 , / / 0 PsProtectedSignerAuthenticode, / / 1 PsProtectedSignerCodeGen, / / 2 PsProtectedSignerAntimalware, / / 3 PsProtectedSignerLsa, / / 4 PsProtectedSignerWindows, / / 5 PsProtectedSignerWinTcb, / / 6 PsProtectedSignerWinSystem, / / 7 PsProtectedSignerApp, / / 8 PsProtectedSignerMax / / 9 }; |
0x02 寻找Microsoft-Windows-Threat-Intelligence
你可以去https://github.com/jdu2600/Windows10EtwEvents/blob/main/manifest/Microsoft-Windows-Threat-Intelligence.tsv寻找他
当然.我这里用了一个十分好用的工具(https://github.com/zodiacon/EtwExplorer)
由此可见 我们可以直接找到他!
他提供了很多事件给我们!
0x03 编写调用代码
既然我们找到了他 也知道PPL进程怎么设置了
那么我们开始编写调用ETW-TI的代码吧!
先看到Keywords
转换为CPP如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #define KERNEL_THREATINT_KEYWORD_ALLOCVM_LOCAL 0x1 #define KERNEL_THREATINT_KEYWORD_ALLOCVM_LOCAL_KERNEL_CALLER 0x2 #define KERNEL_THREATINT_KEYWORD_ALLOCVM_REMOTE 0x4 #define KERNEL_THREATINT_KEYWORD_ALLOCVM_REMOTE_KERNEL_CALLER 0x8 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL 0x10 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL_KERNEL_CALLER 0x20 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE 0x40 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE_KERNEL_CALLER 0x80 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_LOCAL 0x100 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_LOCAL_KERNEL_CALLER 0x200 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_REMOTE 0x400 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_REMOTE_KERNEL_CALLER 0x800 #define KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_REMOTE 0x1000 #define KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_REMOTE_KERNEL_CALLER 0x2000 #define KERNEL_THREATINT_KEYWORD_SETTHREADCONTEXT_REMOTE 0x4000 #define KERNEL_THREATINT_KEYWORD_SETTHREADCONTEXT_REMOTE_KERNEL_CALLER 0x8000 #define KERNEL_THREATINT_KEYWORD_READVM_LOCAL 0x10000 #define KERNEL_THREATINT_KEYWORD_READVM_REMOTE 0x20000 #define KERNEL_THREATINT_KEYWORD_WRITEVM_LOCAL 0x40000 #define KERNEL_THREATINT_KEYWORD_WRITEVM_REMOTE 0x80000 #define KERNEL_THREATINT_KEYWORD_SUSPEND_THREAD 0x100000 #define KERNEL_THREATINT_KEYWORD_RESUME_THREAD 0x200000 #define KERNEL_THREATINT_KEYWORD_SUSPEND_PROCESS 0x400000 #define KERNEL_THREATINT_KEYWORD_RESUME_PROCESS 0x800000 #define KERNEL_THREATINT_KEYWORD_FREEZE_PROCESS 0x1000000 #define KERNEL_THREATINT_KEYWORD_THAW_PROCESS 0x2000000 #define KERNEL_THREATINT_KEYWORD_CONTEXT_PARSE 0x4000000 #define KERNEL_THREATINT_KEYWORD_EXECUTION_ADDRESS_VAD_PROBE 0x8000000 #define KERNEL_THREATINT_KEYWORD_EXECUTION_ADDRESS_MMF_NAME_PROBE 0x10000000 #define KERNEL_THREATINT_KEYWORD_READWRITEVM_NO_SIGNATURE_RESTRICTION 0x20000000 #define KERNEL_THREATINT_KEYWORD_DRIVER_EVENTS 0x40000000 #define KERNEL_THREATINT_KEYWORD_DEVICE_EVENTS 0x80000000 |
每个事件有很多东西你可以获取
我这里监控了其中几个常用的函数
不用多说 代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | #include <krabs.hpp> #define KERNEL_THREATINT_KEYWORD_ALLOCVM_LOCAL 0x1 #define KERNEL_THREATINT_KEYWORD_ALLOCVM_LOCAL_KERNEL_CALLER 0x2 #define KERNEL_THREATINT_KEYWORD_ALLOCVM_REMOTE 0x4 #define KERNEL_THREATINT_KEYWORD_ALLOCVM_REMOTE_KERNEL_CALLER 0x8 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL 0x10 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL_KERNEL_CALLER 0x20 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE 0x40 #define KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE_KERNEL_CALLER 0x80 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_LOCAL 0x100 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_LOCAL_KERNEL_CALLER 0x200 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_REMOTE 0x400 #define KERNEL_THREATINT_KEYWORD_MAPVIEW_REMOTE_KERNEL_CALLER 0x800 #define KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_REMOTE 0x1000 #define KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_REMOTE_KERNEL_CALLER 0x2000 #define KERNEL_THREATINT_KEYWORD_SETTHREADCONTEXT_REMOTE 0x4000 #define KERNEL_THREATINT_KEYWORD_SETTHREADCONTEXT_REMOTE_KERNEL_CALLER 0x8000 #define KERNEL_THREATINT_KEYWORD_READVM_LOCAL 0x10000 #define KERNEL_THREATINT_KEYWORD_READVM_REMOTE 0x20000 #define KERNEL_THREATINT_KEYWORD_WRITEVM_LOCAL 0x40000 #define KERNEL_THREATINT_KEYWORD_WRITEVM_REMOTE 0x80000 #define KERNEL_THREATINT_KEYWORD_SUSPEND_THREAD 0x100000 #define KERNEL_THREATINT_KEYWORD_RESUME_THREAD 0x200000 #define KERNEL_THREATINT_KEYWORD_SUSPEND_PROCESS 0x400000 #define KERNEL_THREATINT_KEYWORD_RESUME_PROCESS 0x800000 #define KERNEL_THREATINT_KEYWORD_FREEZE_PROCESS 0x1000000 #define KERNEL_THREATINT_KEYWORD_THAW_PROCESS 0x2000000 #define KERNEL_THREATINT_KEYWORD_CONTEXT_PARSE 0x4000000 #define KERNEL_THREATINT_KEYWORD_EXECUTION_ADDRESS_VAD_PROBE 0x8000000 #define KERNEL_THREATINT_KEYWORD_EXECUTION_ADDRESS_MMF_NAME_PROBE 0x10000000 #define KERNEL_THREATINT_KEYWORD_READWRITEVM_NO_SIGNATURE_RESTRICTION 0x20000000 #define KERNEL_THREATINT_KEYWORD_DRIVER_EVENTS 0x40000000 #define KERNEL_THREATINT_KEYWORD_DEVICE_EVENTS 0x80000000 std::string ProtectToString(DWORD protect) { switch (protect) { case PAGE_NOACCESS: return "<N/A>" ; case PAGE_READONLY: return "READ" ; case PAGE_READWRITE: return "READ_WRITE" ; case PAGE_WRITECOPY: return "WRITE_COPY" ; case PAGE_EXECUTE: return "EXECUTE" ; case PAGE_EXECUTE_READ: return "READ_EXECUTE" ; case PAGE_EXECUTE_READWRITE: return "READWRITE_EXECUTE" ; case PAGE_EXECUTE_WRITECOPY: return "WRITECOPY_EXECUTE" ; case PAGE_GUARD: return "<G/P>" ; case PAGE_NOCACHE: return "<N/C>" ; case PAGE_WRITECOMBINE: return "<W/C>" ; default: return "<N/P>" ; } } std::string StateToString(DWORD state) { switch (state) { case MEM_COMMIT: return "Committed" ; case MEM_RESERVE: return "Reserved" ; case MEM_FREE: return "Free" ; default: return "Unknown State" ; } } std::string TypeToString(DWORD type ) { switch ( type ) { case MEM_PRIVATE: return "Private Memory" ; case MEM_MAPPED: return "Mapped Memory" ; case MEM_IMAGE: return "Image Memory" ; default: return "Unknown Type" ; } } extern krabs::user_trace g_trace(L "EtwTi-CallMonitor" ); krabs::event_filter AddRemoteSetThreadContextEventFilter() { / * PC (Program Counter): 程序计数器,指向下一条将要执行的指令的地址。 Sp (Stack Pointer): 栈指针,指向当前栈的顶部位置,用于管理函数调用和局部变量。 Lr (Link Register): 链接寄存器,通常用于保存返回地址,以便在函数调用完成后能返回到正确的位置。 Fp (Frame Pointer): 帧指针,指向当前函数调用的栈帧,用于访问函数参数和局部变量。 * / krabs::event_filter EventFilter(krabs::predicates::id_is( 5 )); auto EventCallback = [](const EVENT_RECORD& record, const krabs::trace_context& trace_context) { FAST_TRY_START krabs::schema schema(record, trace_context.schema_locator); krabs::parser parser(schema); auto ProcessID = parser.parse<DWORD>(L "CallingProcessId" ); auto ThreadID = parser.parse<DWORD>(L "CallingThreadId" ); auto TargetID = parser.parse<DWORD>(L "TargetProcessId" ); auto TargetThreadID = parser.parse<DWORD>(L "TargetThreadProcessId" ); auto Pc = parser.parse<PVOID>(L "Pc" ); auto Sp = parser.parse<PVOID>(L "Sp" ); auto Lr = parser.parse<PVOID>(L "Lr" ); auto Fp = parser.parse<PVOID>(L "Fp" ); std::ostringstream ShowMsg; ShowMsg << "[EtwTi]" << "[Remote SetThreadContext] " << "CallingProcessId : " << ProcessID << " | " << "CallThreadId : " << ThreadID << " | " << "TargetProcessId : " << TargetID << " | " << "TargetThreadId : " << TargetThreadID << " | " << "Program Counter : " << std:: hex << std::showbase << reinterpret_cast<uintptr_t>(Pc) << " | " << "Stack Pointer : " << std:: hex << std::showbase << reinterpret_cast<uintptr_t>(Sp) << " | " << "Link Register : " << std:: hex << std::showbase << reinterpret_cast<uintptr_t>(Lr) << " | " << "Frame Pointer : " << std:: hex << std::showbase << reinterpret_cast<uintptr_t>(Fp) <<std::endl; WriteLogger::WriteLoggerInformation(ShowMsg. str (), WriteLogger::WARNING_TYPE); FAST_TRY_END }; EventFilter.add_on_event_callback(EventCallback); return EventFilter; } / / 以他作为示例 剩下的可以自己写 void RunEtwTi() { WriteLogger::WriteLoggerInformation( "Try to load EtwTi Service" , WriteLogger::INFO_TYPE); WriteLogger::WriteLoggerInformation( "EtwTi Add Filters Success | Number : 1" , WriteLogger::INFO_TYPE); krabs::provider<> ti_provider(L "Microsoft-Windows-Threat-Intelligence" ); ti_provider. any (KERNEL_THREATINT_KEYWORD_ALLOCVM_REMOTE | KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE | KERNEL_THREATINT_KEYWORD_MAPVIEW_REMOTE | KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_REMOTE | KERNEL_THREATINT_KEYWORD_SETTHREADCONTEXT_REMOTE | KERNEL_THREATINT_KEYWORD_ALLOCVM_LOCAL | KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL | KERNEL_THREATINT_KEYWORD_MAPVIEW_LOCAL | KERNEL_THREATINT_KEYWORD_WRITEVM_REMOTE | KERNEL_THREATINT_KEYWORD_READVM_REMOTE); / / ti_provider.add_filter(AddRemoteVirtualAllocateEventFilter()); / / ti_provider.add_filter(AddRemoteVirtualProtectEventFilter()); / / ti_provider.add_filter(AddRemoteMapViewEventFilter()); / / ti_provider.add_filter(AddRemoteQueueUserApcEventFilter()); ti_provider.add_filter(AddRemoteSetThreadContextEventFilter()); / / ti_provider.add_filter(AddRemoteReadProcessMemoryEventFilter()); / / ti_provider.add_filter(AddRemoteWriteProcessMemoryEventFilter()); / / ti_provider.add_filter(AddLocalMapViewEventFilter()); / / ti_provider.add_filter(AddLocalVirtualProtectEventFilter()); / / ti_provider.add_filter(AddLocalVirtualAllocateEventFilter()); g_trace.enable(ti_provider); g_trace.start(); WriteLogger::WriteLoggerInformation( "Run EtwTi (Microsoft-Windows-Threat-Intelligence) Service Success" , WriteLogger::INFO_TYPE); } void StopEtwTi() { WriteLogger::WriteLoggerInformation( "Stop EtwTi Service Success" , WriteLogger::INFO_TYPE); g_trace.stop(); } |
0x04 引用
https://github.com/zodiacon/EtwExplorer
https://github.com/microsoft/krabsetw
https://github.com/jdu2600/Windows10EtwEvents/blob/main/manifest/Microsoft-Windows-Threat-Intelligence.tsv
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- 记一次调用ETW-TI 2761
- [分享]一个MiniFilter的遍历 3470
- 最近看到自制杀软自己的一些感悟 3136
- [原创]分析一个由DCRAT二开而得的远控木马 3841
- [原创]新人第一篇 (一个通用的简单反远控技术) 11532