0%
毅种循环

模块 65 - Syscalls - SysWhispers

恶意软件开发课程 - Syscalls - SysWhispers


模块 65 - Syscalls - SysWhispers#

Syscalls - SysWhispers#

简介#

SysWhispers 是一款通过 直接系统调用 (Direct Syscalls) 来绕过 Syscalls 挂钩监控的强大工具。SysWhispers 经历了多个版本的迭代,每个版本都有其独特的功能。本模块将深入探讨各版本之间的区别以及它们的工作原理。

SysWhispers (初代)#

SysWhispers 可以为 64 位系统生成头文件和汇编(ASM)文件,从而实现直接系统调用。它支持从 Windows XP 到 Windows 10 20H2 的操作系统。

初代的局限性在于:由于 系统服务号 (SSN) 会随着 Windows 的每次更新而改变,开发者必须针对不同的 Windows 版本手动指定支持范围。例如,Windows 10 1903 的 SSN 可能与 1909 版本完全不同。

💡 初学者提示:运行时适配

为了保证兼容性,SysWhispers 生成的代码会在程序运行时先检查当前系统的具体版本,然后根据版本号手动选择正确的 SSN。

核心原理:解析 PEB#

SysWhispers 生成的汇编代码会通过解析 PEB (进程环境块) 来确定操作系统版本。PEB 中有三个关键成员:

  • OSBuildNumber (构建号)
  • OSMajorVersion (主版本号)
  • OSMinorVersion (次版本号)

生成的汇编代码本质上是一系列复杂的 ifelse if 判断。一旦确定了版本,代码就会跳转到对应的 SSN 赋值语句,最后执行 syscall 指令。

SysWhispers2#

SysWhispers2 在初代的基础上进行了重大改进。它不再需要用户手动指定 Windows 版本,也不再硬编码庞大的查询表。

其核心创新在于采用了一种名为 根据系统调用地址排序 (Sorting By System Call Address) 的技术。

排序技术原理#

  1. 找到所有以 Zw 开头的系统调用。
  2. 将它们的地址存入一个数组。
  3. 按地址从低到高进行升序排序。
  4. 排序后的索引值,就是该系统调用对应的 SSN

这种方法使得代码变得极其精简,因为 SSN 是在运行时通过简单的计算得出的,而不是靠查表。

SysWhispers3#

SysWhispers2 虽然解决了 SSN 的兼容性问题,但它依然是在我们自己的代码段(.text)中执行 syscall 指令。

[!WARNING] 现代高级 EDR 会监控“系统调用是从哪里发起的”。如果它发现 syscall 指令不是来自 ntdll.dll 的地址空间,而是一个可疑的内存区域,就会判定为恶意行为。

SysWhispers3 引入了以下进阶功能:

  1. 间接系统调用 (Indirect Syscalls):它不再直接在 ASM 内部写 syscall 指令,而是在执行前先在 ntdll.dll 内部搜索一个合法的 syscall 指令地址,然后通过 jmp 跳转过去执行。这样在 EDR 看来,调用依然发生在“合规”的 ntdll 内部。
  2. 随机跳板 (Jumper Randomized):为了进一步迷惑搜索,它可以随机跳转到任何一个系统调用的 syscall 指令处。例如,你明明在调用分配内存的函数,但跳板却借用了 NtTestAlert 里的 syscall 指令。

代码对比示例 (SysWhispers2 vs SysWhispers3)#

在 SysWhispers3 生成的代码中,你会看到它调用了两个核心辅助函数:

  • SW3_GetSyscallNumber:获取索引(即 SSN)。
  • SW3_GetRandomSyscallAddress:在 ntdll 中随机找一个合法的系统调用指令地址作为出口。
; SysWhispers3 伪代码示例
NtMapViewOfSection PROC
    ; ... 保存寄存器 ...
    call SW3_GetRandomSyscallAddress ; 获取 ntdll 里的随机 syscall 地址存入 r15
    call SW3_GetSyscallNumber        ; 获取 SSN 存入 eax
    ; ... 恢复寄存器 ...
    mov r10, rcx
    jmp r15                          ; 不再直接 syscall,而是跳入 ntdll 执行
NtMapViewOfSection ENDP
asm

🎯 总结#

在本模块中,我们学习了:

  1. 工具演进:理解了从硬编码查表到动态地址排序的技术跨越。
  2. 态势感知绕过:学会了如何应对 EDR 对“非法系统调用入口点”的检测。
  3. 极致兼容性:理解了排序算法为何能让我们的一份 Payload 运行在所有 Windows 版本上。

📚 下一步学习

下一个模块将介绍 Syscalls - Hell’s Gate。我们将学习一种纯 C 实现的“地狱之门”技术,看看如何在没有任何开源工具辅助的情况下,纯靠代码逻辑在内存中“挖掘”出隐藏的系统调用!