几个Syscall项目的学习记录
字数 1733 2025-08-20 18:17:41
系统调用(Syscall)绕过技术详解
1. 系统调用基础概念
系统调用(Syscall)是一种绕过EDR(终端检测与响应)用户态hook的技术,它通过获取系统调用号并构造syscall stub的汇编指令直接进入内核态API调用,从而避免用户态hook的检测。
基本syscall stub汇编代码
mov r10, rcx ; 将rcx值移动到r10
mov eax, [系统调用号] ; 将系统调用号存入eax
syscall ; 执行系统调用
ret ; 返回
2. 主要Syscall项目分析
2.1 HellsGate
项目地址: https://github.com/am0nsec/HellsGate
技术特点
-
系统调用号获取方式:
- 遍历PEB(进程环境块)找到ntdll
- 遍历ntdll的导出表找到目标函数
- 通过匹配syscall stub特征字节码定位系统调用号
-
特征匹配代码:
if (*((PBYTE)pFunctionAddress + cw) == 0x4c &&
*((PBYTE)pFunctionAddress + 1 + cw) == 0x8b &&
*((PBYTE)pFunctionAddress + 2 + cw) == 0xd1 &&
*((PBYTE)pFunctionAddress + 3 + cw) == 0xb8 &&
*((PBYTE)pFunctionAddress + 6 + cw) == 0x00 &&
*((PBYTE)pFunctionAddress + 7 + cw) == 0x00) {
// 提取系统调用号
}
- 直接系统调用实现:
HellDescent PROC
mov r10, rcx
mov eax, wSystemCall
syscall
ret
HellDescent ENDP
2.2 SysWhispers2
项目地址: https://github.com/jthuraisamy/SysWhispers2
技术特点
-
系统调用号获取方式:
- 解析PEB获取ntdll
- 获取所有Zw开头导出函数的地址
- 对地址排序,序号即为系统调用号
-
间接系统调用实现:
- 随机获取ntdll中syscall指令地址
- 跳转到该地址执行syscall指令
- 使调用栈看起来来自ntdll
-
关键汇编代码:
WhisperMain PROC
pop rax
mov [rsp + 8], rcx ; 保存寄存器
; ... 省略其他寄存器保存
mov ecx, currentHash
call SW2_GetSyscallNumber ; 获取系统调用号
mov dword ptr [syscallNumber], eax
xor rcx, rcx
call SW2_GetRandomSyscallAddress ; 获取随机syscall地址
mov qword ptr [syscallAddress], rax
; ... 省略寄存器恢复
call qword ptr [syscallAddress] ; 调用随机syscall指令
ret
WhisperMain ENDP
2.3 FreshyCalls
项目地址: https://github.com/crummie5/FreshyCalls
技术特点
-
系统调用号获取方式:
- 与SysWhispers2类似,按地址顺序填充map结构
- 使用C++模板实现通用调用
-
间接系统调用实现:
- 构造trampoline跳板
- 使用mini shellcode实现间接跳转
- 跳转到ntdll中的syscall指令
-
关键mini shellcode:
push r13
push r14
mov r14, rdx ; syscall指令地址
mov r13, rcx ; 系统调用号
; ... 参数处理
lea r11, [rip+0x0C]
call r11
; ...
mov rax, r13 ; 系统调用号
mov r10, rcx
jmp r14 ; 跳转到syscall指令
2.4 PIG-Syscall
项目地址: https://github.com/evilashz/PigSyscall
技术特点
-
系统调用号获取方式:
- 通过异常目录表而非导出表获取
- 函数名称加密存储
-
增强的安全措施:
- 对syscall stub进行加密
- 使用时动态解密
- 使用Exchange邮件编码算法加解密
-
加密的stub示例:
unsigned char encrypted_masked_syscall_stub[] = {
0xd3, 0xab, 0xd3, 0x89, 0xc9, 0xb0, 0x73, 0xc9, 0xb0, 0x6c,
// ... 其他加密字节
};
2.5 HWSyscalls
项目地址: https://github.com/ShorSec/HWSyscalls
技术特点
-
系统调用号获取方式:
- 使用HalosGate方法(匹配相邻函数stub)
- 避免因hook导致获取失败
-
硬件断点技术:
- 初始化时设置硬件断点
- 通过异常处理实现间接调用
- 彻底处理调用堆栈问题
-
关键流程:
- 初始化时设置断点在PrepareSyscall
- 第一次断点获取目标函数地址
- 第二次断点实现间接系统调用
- 使用Gadget(ADD RSP,68;RET)返回
3. 技术对比与演进
| 技术 | 调用方式 | 系统调用号获取 | 反检测特性 |
|---|---|---|---|
| HellsGate | 直接调用 | 导出表特征匹配 | 无 |
| SysWhispers2 | 间接调用 | 地址排序 | 随机syscall地址 |
| FreshyCalls | 间接调用 | 地址排序 | mini shellcode |
| PIG-Syscall | 间接调用 | 异常目录表 | stub加密 |
| HWSyscalls | 硬件断点 | HalosGate方法 | 完整调用栈伪造 |
4. 防御与检测
-
常见检测方法:
- 检查syscall指令调用来源(非ntdll)
- 检查syscall stub硬编码特征
- 检查系统调用号获取方式
- 调用栈完整性检查
-
绕过策略演进:
- 从直接调用到间接调用
- 从固定调用到随机调用
- 从明文stub到加密stub
- 从软件实现到硬件辅助
5. 总结
系统调用绕过技术从最初的直接调用发展到现在的多种高级间接调用方式,不断演进以绕过安全产品的检测。理解这些技术的原理和实现方式,对于攻防双方都具有重要意义。未来的发展方向可能会更加注重调用链的完整性和隐蔽性,以及与硬件特性的深度结合。