本帖最后由 00006666 于 2025-7-29 10:38 编辑
以下内容为转载 原文地址
The problem with direct syscalls
Direct syscalls have been the go to for bypassing user mode hooks for over a decade. I actually first experimented with this method myself way back in 2012. Unfortunately, much work has been done to try and prevent this kind of bypass. The most common detection is by having the EDR’s kernel mode driver inspect the callstack.
Although the EDR can no longer hook a lot of places in the kernel, it can use monitoring functionality provided by the operating system, such as:
ETW events
Kernel Callbacks
Filter Drivers
If we perform a manual syscall, and somewhere along the way the kernel function we call hits any of the above, the EDR could take the opportunity to inspect the callstack of our thread. By unwinding the call stack and inspecting return addresses, the EDR can see the entire chain of function calls that led to this syscall.
If we were to perform a normal call to, say, kernel32!VirtualAlloc(), the callstack may look like so:
The callstack of a call to VirtualAlloc().
In this case the call to VirtualAlloc() is initiated by ManualSyscall!main+0x53. The relevant parts of the callstack in order of call are:
ManualSyscall!main+0x53
KERNELBASE!VirtualAlloc+0x48
ntdll!NtAllocateVirtualMemory+0x14
nt!KiSystemServiceCopyEnd+0x25
This tells us (or the EDR) that the executable (ManualSyscall.exe) called VirtualAlloc(), which called NtAllocateVirtualMemory(), which then performed a system call to transition into kernel mode.
Now let’s look at the call stack when we do a direct syscall:
the callstack for a direct syscall to NtAllocateVirtualMemory().
The relevant parts of this callstack in order are:
ManualSyscall!direct_syscall+0xa
nt!KiSystemServiceCopyEnd+0x25
Here it’s clear the kernel transition was triggered by code inside ManualSyscall.exe and not ntdll. But, what’s the problem with this?
Well, on systems like linux it’s completely normal for application to initiate system calls directly. But remember that I mentioned system call ids change between Windows versions? As a result it’s highly impractical to write Windows software that relies on direct system calls. Due to the fact ntdll already implements every system call for you, there’s almost no reason to do a manual syscall. Unless, of course, you’re writing malware to bypass EDR hooks. Are you writing malware to bypass EDR hooks?
所以目前所有具备ETW来源的栈回溯检测技术的杀软和EDR产品都能相对轻松的检测syscall,当然恶意软件也可能使用栈欺骗技术来绕过检测。
栈回溯技术的介绍可以参考Elastic发布的文章
https://mp.weixin.qq.com/s/Tf98bQs9UX0cP0dts8BQ3Q
|