概述
虽然有一些博客文章讨论开发攻击性驱动程序和Rootkit,但我发现真正讨论反Rootkit规避技术的,只有与游戏作弊相关的文章。在花了一些时间开发我的Rootkit Banshee之后,我开始对反Rootkit、它们的检测机制以及各种规避方法产生了兴趣。
为了有一个透明的环境来测试我的Rootkit规避能力,我开发了一个小型反Rootkit工具叫unKover,它实现了一些检测Rootkit的技术,特别是那些手动映射到内存中的。
手动映射驱动程序
如果你在开发Rootkit或攻击性驱动程序,很可能你在开发机器上启用了testsigning。但在真实环境中,启用testsigning通常不是最好的选择。如果你没有有效证书,就必须手动映射驱动程序。
KDMAPPER
最知名的驱动映射工具是kdmapper,它利用Intel的易受攻击的iqvw64e.sys驱动来将任意驱动写入内核。手动映射的过程类似于反射式PE注入:
- 将节写入内存
- 解析导入
- 应用重定位
- 擦除镜像头以实现隐蔽
- 调用驱动的入口点
检测1:查询设备对象
通常,驱动程序通过IOCTL进行通信,需要在对象管理器中注册设备对象。反Rootkit可以检查所有设备对象,判断其内核内存中的镜像是否有有效的模块支持。
核心思路:遍历\Driver目录,获取每个驱动对象,检查DriverInit地址是否在已加载模块的地址空间内。
检测2:通过APC检测无后备系统线程
如果Rootkit使用共享内存或命名管道进行通信,虽然不需要注册设备对象,但会有一个持续轮询的系统线程。反Rootkit可以通过向所有系统线程排队APC来检测。
APC回调中调用RtlCaptureStackBackTrace展开调用栈,检查每个帧的地址是否指向无后备内存——如果是,就找到了潜在的Rootkit线程。
规避方法
- 栈欺骗(Stack Spoofing)
- 通过DKOM修改KTHREAD对象,将
ApcQueueable位设为0,禁止APC排队 - 但KTHREAD是未文档化结构,不同Windows版本差异很大
检测3:不可屏蔽中断(NMI)
NMI是硬件驱动中断,不能被屏蔽。使用HalSendNmi向CPU核心发送NMI,中断当前运行的线程,在NMI回调中捕获调用栈并分析。
虽然不如APC方法可靠(因为需要"碰巧"在Rootkit线程运行时捕获),但定期发送NMI最终会捕获到可疑线程。
驱动"踩踏"(Driver Stomping)
类似于用户态的模块踩踏,将Rootkit加载到合法驱动程序之上,伪装成由磁盘上的模块支持。但这会带来新的检测指标——内存中的驱动与磁盘上的驱动不同。
总结
这次实验让我学到了很多关于潜在检测向量的知识。我相信EDR产品在涉及内核组件时会非常谨慎,因为这对系统稳定性构成重大风险。我计划花一些时间逆向常见的反Rootkit驱动,了解它们实现了什么样的检测。
