Windows系统调用免杀的过去和未来
字数 2635 2025-09-23 19:27:46
Windows系统调用免杀技术深度解析
一、系统调用基础概念
1.1 核心组件:ntoskrnl.exe
ntoskrnl.exe是Windows操作系统内核的核心组件,负责:
- 维护系统服务描述符表(SSDT)
- 响应系统调用指令(int 2Eh/sysenter/syscall)
1.2 系统调用存根(syscall stub)
系统调用存根是用户空间与内核交互的桥梁,主要功能:
- 将系统调用号放入特定寄存器(EAX/RAX)
- 执行触发系统调用的指令(int 0x2E/syscall)
- 系统调用号(SSN)用于索引SSDT中的函数指针
1.3 _KUSER_SHARED_DATA结构
用户态和内核态共享的数据结构:
- 用户态地址:0x7ffe0000(只读)
- 内核态地址:0xffdf0000(可写)
- 包含SystemCall字段(偏移0x300),存储KiFastSystemCall地址
1.4 MSR寄存器
x86/x64架构中的专用寄存器:
- sysenter使用:
- IA32_SYSENTER_CS:内核代码段选择
- IA32_SYSENTER_EIP:内核入口点
- IA32_SYSENTER_ESP:内核栈指针
- syscall使用:
- IA32_LSTAR:64位内核入口点
- IA32_STAR:指定内核/用户态CS/SS
二、系统调用流程
2.1 传统中断调用(INT 2E)
- CPU执行INT 2E指令触发软中断
- 通过IDT找到KiSystemService
- 保存完整寄存器形成完整陷阱帧
- 定位SSDT表并索引服务函数
2.2 快速系统调用(SYSCALL/SYSENTER)
- CPU执行sysenter/syscall指令
- 直接跳转到MSR指定地址(KiFastCallEntry)
- 只保存关键寄存器形成精简陷阱帧
- 执行KiSystemService核心逻辑
2.3 Zw与Nt函数区别
- 用户态下功能相同
- 内核态下:
- Zw*函数:设置Previous Mode为内核模式,绕过参数检查
- Nt*函数:继承调用者模式,执行严格参数检查
三、系统调用免杀技术演进
3.1 早期技术:地狱之门(HellsGate)
核心思想:动态获取系统调用号
实现步骤:
- 通过PEB获取ntdll基址
- 解析ntdll导出表
- 计算函数名哈希匹配目标函数
- 扫描函数代码查找系统调用号模式:
- x64模式:0x4C 0x8B 0xD1 0xB8(MOV R10, RCX; MOV EAX, SSN)
- 直接使用syscall指令调用
局限性:
- 被Hook函数无法正确获取SSN
- syscall指令硬编码易被检测
3.2 改进技术:HalosGate
核心思想:通过相邻函数推算SSN
实现方法:
- 定位目标函数附近未被Hook的函数
- 获取其SSN并加减偏移量
- 得到目标函数的SSN
3.3 改进技术:TartarusGate
增强功能:
- 更精确的Hook检测(检查0xE9跳转指令)
- 添加NOP指令混淆syscall特征
3.4 ntdll unhook技术
实现思路:
- 从磁盘重新加载ntdll.dll
- 修复节表、重定位表
- 调整内存属性
- 获得干净的ntdll副本
局限性:无法绕过ring0的SSDT Hook监控
四、现代系统调用免杀技术
4.1 彩蛋猎人(egg hunters)
核心思想:运行时替换syscall指令
实现方法:
- 使用DB伪指令定义特殊字节序列(如"r00vr00v")
- 程序加载后搜索并替换为syscall指令
- 绕过静态检测
优化方向:
- 替换部分DB指令为实际指令
- 增加彩蛋长度提高精确度
4.2 随机跳转间接系统调用
实现步骤(以SysWhispers3为例):
- 枚举ntdll中所有Zw*函数
- 构建函数哈希-地址列表
- 随机选择干净的syscall指令地址
- 构造调用链:
- 获取随机syscall地址→RAX→R11
- 获取SSN→EAX
- JMP R11实现间接调用
优势:回调RIP指向ntdll,绕过来源检测
4.3 VEH间接系统调用
核心技术(HWSyscalls项目):
- 硬件断点:在Dr0寄存器设置断点地址
- VEH处理:注册异常处理函数构造syscall
- 栈空间伪造:利用kernel32/kernelbase的ret gadget
- SSN获取:改进版HalosGate算法
调用流程:
- 调用PrepareSyscall触发硬件断点
- VEH处理函数接管执行
- 构造mov r10, rcx + mov eax, SSN
- 跳转到干净的syscall指令地址
五、系统调用免杀关键问题与解决方案
| 问题 | 解决方案 |
|---|---|
| 系统调用号获取 | HellsGate动态解析、HalosGate相邻函数推算 |
| syscall指令检测 | egg hunters运行时替换、间接跳转调用 |
| 调用来源验证 | 随机跳转使RIP指向ntdll、VEH异常处理 |
| 参数检查绕过 | 使用Zw*函数设置Previous Mode为内核模式 |
| ETW检测 | 禁用ETW或混淆线程堆栈 |
六、实战建议
- 基础掌握:深入理解HellsGate实现原理
- 技术组合:结合多种技术(如egg hunters+随机跳转)
- 环境适配:根据目标EDR能力选择适当方案
- 持续进化:关注新技术如HWSyscalls的硬件断点应用
- 隐蔽性优化:添加反调试、堆栈混淆等辅助技术
七、参考资源
- HellsGate项目:https://github.com/am0nsec/HellsGate
- HalosGate技术解析:https://blog.sektor7.net/
- SysWhispers3:https://github.com/klezVirus/SysWhispers3
- HWSyscalls项目:https://github.com/Sh0ckFR/HWSyscalls
- Windows异常处理机制:https://blog.csdn.net/qq_41988448/article/details/112467210
通过系统性地理解和应用这些技术,可以有效绕过现代AV/EDR对系统调用的监控,实现更高隐蔽性的恶意代码执行。