首页
社区
课程
招聘
[原创]InfinityHook 可兼容最新版windows
发表于: 2024-4-22 16:30 16070

[原创]InfinityHook 可兼容最新版windows

2024-4-22 16:30
16070

前言

最近看到各位师傅疯狂蹂躏TX安全竞赛的题,文章写得好到让我泪流满面。不由的羡慕起来师傅们的技术...

ETW HOOK是一个经久不衰的话题了,本质上是微软的漏洞,再微软进行记录ETW时候系统调用的时候,被ETW相关组件拦截跑到记录的代码,因为涉及到的代码量实在太大,微软这里面老是会有一些函数指针的使用,从而可以把他替换成我们自己函数回调,而不会触发PG拦截系统调用(无法拦截直接内核NtXXX)。

项目地址:b49K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6a6P5s2W2Y4k6h3^5I4j5e0q4Q4x3V1k6u0L8X3k6A6L8X3W2@1P5f1S2G2L8$3E0Q4y4h3k6D9j5i4c8W2M7%4b7`.

项目地址

早期的ETW HOOK实现概要

早期的ETW HOOK替换的一些HalPxx指针已经被PG监控

43bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6W2N6X3g2J5k6r3!0^5i4K6u0r3d9h3&6X3K9h3&6A6N6s2W2t1L8$3!0C8

到后来第二个版本的ETW,原理和EAC接管系统异常差不多,这一版本的也是再ETW HOOK的必经之路上面修改函数指针:

原理是EAC通过修改HalpStallCounter[0xE]的这个位置,以及NtGlobalFlags这个标志位。

HalpStallCounter[0xE] 函数原本是HalpTscQueryCounterOrdered,修改这个之后,一些异常(包括kernel mode)就会走到这从而被EAC接管;

下图是发生异常时候的调用栈从windg可以看到,EAC修改了HalpStallCounter来进行接管异常

可以兼容最新版 windows 的ETW HOOK

第二版的ETW Hook现在还可以用,但是用起来非常复杂,光是不同系统兼容、修栈就要耗费巨大精力。

因此这里参考国外的一个大佬文章,他提出了更新版本的ETW-HOOK,具体原理如下

WINDOWS的.data节一般是存放可以变的全局变量的,所谓的偷指针就是修改.data节区的指针。

而在这里,最好玩的是HalPrivateDispatchTable,这个是windows 的ntoskenl.exe为了方便使用HAL的导出函数,把他们存放在统一的地方。而HAL,用到的地方肯定很多,ETW 正是如此。

我们来看一下系统调用ETW的调用路径

image-20240419102113440

这里其实可以看到,call rax其实就是正常的系统调用,而再进入ETW系统调用之前,他把原始的系统调用存放在了栈上,这就导致我们拦截到ETW的时候,可以修改栈上的位置,来进行HOOK Syscall。

进入这个函数

image-20240419102337381

如果说之前无法定位,现在可以通过这个栈上面的magic number来定位syscall的地址,从而替换了。

继续跟到EtwTraceSiloKernelEvent里面,可以发现,无论参数怎么样,这个函数调用了EtwpLogKernelEvent

void __fastcall EtwTraceSiloKernelEvent(
       __int64 a1,
       __int64 a2,
       unsigned int a3,
       unsigned int a4,
       unsigned __int16 a5,
       int a6)
{
 unsigned __int64 v9; // rsi
 unsigned int v10; // ebx
 bool v11; // zf
 unsigned int v12; // ecx
 __int64 v13; // r8
 __int64 v14; // rcx
 __int64 v15; // rbx
 unsigned int v16; // edi
 __int64 v17; // rdx
 __int64 v18; // rcx
 unsigned int v19; // ecx

 v9 = a4;
 v10 = *(_DWORD *)(EtwpHostSiloState + 4224);
 while ( 1 )
 {
   v11 = !_BitScanForward(&v12, v10);
   if ( v11 )
     break;
   v10 &= v10 - 1;
   v13 = v12;
   v14 = 32i64 * v12 + EtwpHostSiloState + 4260;
   if ( v14 )
   {
     if ( ((unsigned int)v9 & *(_DWORD *)(v14 + 4 * (v9 >> 29)) & 0x1FFFFFFF) != 0 )
       EtwpLogKernelEvent(a2, EtwpHostSiloState, *(unsigned __int8 *)(EtwpHostSiloState + 2 * v13 + 4208), a3, a5, a6);
   }
 }
 if ( a1 )
 {
   v15 = *(_QWORD *)(*(_QWORD *)(a1 + 1272) + 864i64);
   if ( v15 )
   {
     v16 = *(_DWORD *)(v15 + 4224);
     while ( 1 )
     {
       v11 = !_BitScanForward(&v19, v16);
       if ( v11 )
         break;
       v17 = v19;
       v16 &= v16 - 1;
       v18 = 32i64 * v19 + v15 + 4260;
       if ( v18 && ((unsigned int)v9 & *(_DWORD *)(v18 + 4 * (v9 >> 29)) & 0x1FFFFFFF) != 0 )
         EtwpLogKernelEvent(a2, v15, *(unsigned __int8 *)(v15 + 2 * v17 + 4208), a3, a5, a6);
     }
   }
 }
}

EtwpLogKernelEvent就是这次事件的主角,关键部分代码为


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-4-23 09:27 被Oxygen1a1编辑 ,原因: 啦啦啦
收藏
免费 23
支持
分享
最新回复 (29)
雪    币: 6304
活跃值: (5192)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
2
mark
2024-4-22 19:04
0
雪    币: 1143
活跃值: (3131)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2024-4-22 21:11
0
雪    币: 287
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
假装看懂了,马克一下!感谢楼主无私分享
2024-4-22 21:31
0
雪    币: 1989
活跃值: (4245)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2024-4-22 21:43
0
雪    币: 2052
活跃值: (2188)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
mark
2024-4-23 08:44
0
雪    币: 1488
活跃值: (1668)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
mark
2024-4-23 08:48
0
雪    币: 2139
活跃值: (5094)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
mark
2024-4-23 09:23
0
雪    币: 459
活跃值: (535)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
mark
2024-4-23 09:57
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
感谢分享
2024-4-23 12:26
0
雪    币: 11338
活跃值: (3270)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
11
tql
2024-4-23 15:03
0
雪    币: 4033
活跃值: (31446)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感谢分享
2024-4-24 09:22
1
雪    币: 1999
活跃值: (5103)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
count > EtwpMaxPmcCounter这一个必须成立是不是弄错了
2024-4-24 10:18
0
雪    币: 2272
活跃值: (5451)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
逆向爱好者 count > EtwpMaxPmcCounter这一个必须成立是不是弄错了
对,是<,所以得把EtwpMaxPmcCounter弄大一下
2024-4-24 10:55
0
雪    币: 1684
活跃值: (2203)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
牛皮
2024-4-25 09:39
0
雪    币: 45
活跃值: (2695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
mark
2024-4-25 10:26
0
雪    币: 50
活跃值: (181)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
感谢楼主的无私分享
2024-4-25 17:19
0
雪    币: 405
活跃值: (2570)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
这里面坑也不少,还得硬编码。一直用第二版得,反而方便。
2024-4-25 17:30
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
大佬,我是个菜鸟,etwhook 原理大概清楚。我用您这份源码测试,有的时候停止驱动的时候蓝屏了,蓝屏分析是stack_trace_to_syscall 这个函数访问堆栈地址,引发的缺页异常,不知道啥原因。我驱动停止后内存释放了,然后导致的缺页异常吗?
2024-4-26 00:25
0
雪    币: 2272
活跃值: (5451)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
wx_逆逆逆逆 大佬,我是个菜鸟,etwhook 原理大概清楚。我用您这份源码测试,有的时候停止驱动的时候蓝屏了,蓝屏分析是stack_trace_to_syscall 这个函数访问堆栈地址,引发的缺页异常,不知道啥 ...
有dump吗,看看是不是访问堆栈访问超过栈顶了呢? 这个函数irql是2,有可能进程的栈换到磁盘了?
2024-4-26 09:07
0
雪    币: 748
活跃值: (3133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
wowocock 这里面坑也不少,还得硬编码。一直用第二版得,反而方便。
有git的地址吗?
2024-4-26 09:16
0
雪    币: 445
活跃值: (2402)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
22
6
2024-4-26 11:39
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23

有dump文件,太大了 上传不了。可能我正好停止驱动的时候有程序调 api进来,但是我的驱动内存已经没有了,它再跑代码就会蓝屏。您有时间可以帮我看看


2024-4-26 21:32
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
我是hoook的 NtOpenProcess怎么保证api调完才能停止驱动呢,随时都有3环程序在调这个api ,怪我太菜。
2024-4-26 21:39
0
雪    币: 2272
活跃值: (5451)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
25
wx_逆逆逆逆 我是hoook的 NtOpenProcess怎么保证api调完才能停止驱动呢,随时都有3环程序在调这个api [em_5],怪我太菜。
看起来就是你驱动unload的时候,还在hook的NtOpenProcess里面,我觉得可以延迟卸载一下,你先恢复hook,然后驱动sleep 5秒卸载,应该基本上不会蓝屏了,你写完可以提个pr,我pull下
2024-4-27 08:45
0
游客
登录 | 注册 方可回帖
返回