- ETW事件
- 内核回调
- 过滤驱动程序
如果我们执行对kernel32!VirtualAlloc()的正常调用 , 调用堆栈可能如下所示:
文章插图
图片
在这种情况下,对VirtualAlloc()的调用是由ManualSyscall!mAIn+0x53启动的 。按照调用的顺序,调用堆栈的相关部分如下:
- ManualSyscall!main+0x53
- KERNELBASE!VirtualAlloc+0x48
- ntdll!NtAllocateVirtualMemory+0x14
- nt!KiSystemServiceCopyEnd+0x25
现在让我们看看进行直接系统调用时的调用堆栈:
文章插图
图片
调用堆栈的相关部分按顺序如下:
- ManualSyscall!direct_syscall+0xa
- nt!KiSystemServiceCopyEnd+0x25
嗯,在像linux这样的系统上 , 应用程序直接发起系统调用是完全正常的 。但请记住我提到过Windows版本之间系统调用号会发生变化吗?结果,编写依赖于直接系统调用的Windows软件是非常不切实际的 。由于ntdll已经为您实现了每个系统调用,几乎没有理由进行手动系统调用 。除非你正在编写绕过EDR钩子的恶意软件 。你是在写用于绕过EDR钩子的恶意软件吗?
由于直接系统调用是恶意活动的强有力指标,更复杂的EDR系统将记录源自于ntdll之外的系统调用的检测情况 。说实话,你仍然可以在很多时候逃脱检测 , 但这有什么乐趣呢?
4.间接系统调用
大多数EDR在Nt函数的开头写入它们的钩子 , 覆盖SSN但保留系统调用指令不变 。这使我们能够利用ntdll已经提供的系统调用指令,而不是引入我们自己的 。我们只需自己设置r10和eax寄存器,然后跳转到被挂钩的ntdll函数内的系统调用指令(位于EDR钩子之后) 。
文章插图
图片
注意:我们并不严格需要test或jnz指令,它们只是为了向后兼容 。一些古老的CPU不支持syscall指令,而是使用int 0x2e 。test指令检查系统调用是否启用,如果没有启用,则回退到软中断 。如果我们希望支持这些系统,我们可以自己执行检查,然后根据需要跳转到int 0x2e指令(也位于Nt函数内) 。
就像直接系统调用一样,我们仍然需要系统调用号放入eax寄存器,但我们可以使用在直接系统调用部分详细介绍的所有相同技术 。
通过这种方式设置系统调用将给我们一个类似以下的调用堆栈:
文章插图
图片
正如你所看到的 , 调用堆栈现在看起来好像是来自ntdll!NtAllocateVirtualMemory()而不是我们的可执行文件,因为从技术上讲确实是这样的 。
我们可能会遇到的一个问题是,如果EDR钩子或覆盖了Nt调用中的syscall指令的部分 。我从未见过这种情况发生 , 但理论上可能会发生 。在这种情况下,我们可以跳转到另一个未被挂钩的Nt函数内的syscall指令 。这仍然可以绕过仅验证调用名称是否来自ntdll的EDR,但对于检查内核函数是否与来自ntdll的函数相匹配的这种检查通常都会失败 。
更大的问题是 , 如果EDR检查的不仅仅是第一个返回地址 。不仅仅是系统调用的来源,还有执行系统调用的函数是谁调用的 。如果我们正在从位于动态分配内存中的某个shellcode进行间接系统调用,那么EDR将会察觉到 。来自于有效PE节(exe或DLL内存)之外的调用是相当可疑的 。
此外,由于函数被EDR挂钩,EDR的钩子预期会出现在调用堆栈中 。实际上,我并不确定哪些EDR,如果有的话,会检查这一点 。但是,正如你在这里看到的 , 从调用堆栈中很明显我们绕过了EDR的钩子 。
推荐阅读
- 《未成年人网络保护条例》正式施行 《蛋仔派对》成网易“未成年人模式”试点产品
- 王者荣耀觉醒装备合成,王者荣耀觉醒模式怎么开
- 电脑上怎么查看宽带密码,华为手机怎么查电脑的宽带用户名和密码
- 华为手机如何调整单手操作模式
- 海贼无双4怎么添加2p,海贼无双3怎么双人玩双人模式加入方法
- win0电脑如何添加用户帐户
- 华为如何移除管控中心,华为平板如何解除管控模式
- 赛博朋克2077是什么意思,赛博朋克2077直播模式什么意思
- 手机怎么退出开发者选项,手机怎么把开发者模式选项关闭呢
- 手机屏幕太大单手不好操作怎么办?教你一键改成小屏模式,真实用