如何呢?
Syscall 这种东西,见仁见智,不同的人,不同场景,不同EDR,不同对抗环境,效果不同 。 拿国外的EDR来说,有些EDR坚持使用Hook(与内核的检测机制进行配合),有的也已经放弃了Ring3的Hook.
一个原因就是Ring3的Hook,是可以轻松绕过,但是对于Ring0 的 ETWTI ,就拿这个NtAllocateVirtualMemory的内核函数来说
会去Call EtwTiLogAllocExecVm
在Ring3对抗ETWTI的也有不过更多的还是尝试Bypass,Ring0的一种Disable方法是把IsEnabled清空
下图我把他全部都清空了 ,不过前提,你得进Ring0,选不选则Ring0对抗,那也是见仁见智了。
Syscall
回到主题,syscall,一个很久之前就已经有了的技术,经过多代的演变,玩出了很多新的花样 whisperX, Gate,HWsyscall, AtomLdr .... 目的都是为了绕过用户层挂钩,规避EDR 。 但是,不同的syscall 就会有不同的线程调用栈,当我们进行栈回溯的时候,能看到如下部分调用栈
syscall.ret -> main!func()syscall.ret -> ntdll -> main!func()...
Hwsyscall
然后就有一个项目HwSyscall,效果如下
配合硬件断点,捕获两次Hit,构造Gadget 伪造调用堆栈
并且需要我们去遵循特定的调用形式,比如NtAllocateVirtualMemory
第一次触发:当我们调用Prepaere函数的时候,将DR0设置成这个Nt函数
第二次触发:当我们调用这个函数的时候,抬栈,然后构造一个假的调用栈
Gadgte如下 [ Add RSP ,68 ; RET ]
拷贝参数
判断是否有Hook
如果有Hook,找Syscall的地址,做好Stub 准备之后直指过去Syscall
重新设置在PrePareSyscall 上的断点,以便后续继续使用
最终实现效果如下
Hit && Run
如果说HwSyscall已经不错了,那么Hit && Run 则是在这个基础上的更加完善
比如说上面的调用堆栈,我们正常的去调用 WaitForSingleObject ,调用栈如下
可以看见我们的ZwWaitForSingleObject 返回的是KernelBase!WaitforSinlgeObjectEx
于是Hit && Run 的作者在参考了一系列的文章之后就写了这么一篇博客
也是两次Hit ,然后改变执行流,下面拿的是NtAllocateVirtualMemory
第一次触发 : 当我们去Call NtAllocateVirtualMemory 触发断点
清空断点,保存当前线程上下文
并且重定向执行流到一个调用参数完全无害的VirtualAlloc
第二次触发 : 这时候就是在Syscall 的时候触发了,把刚才保存的线程上下文寄存器以及对应的参数进行替换
然后把RCX给R10(这里不用动EAX,因为我们是syscall 上触发的断点,我们EAX本来就是对应的SSN)
最终的效果如下
Bonus :去Ring0的旅途中你会发现很多好玩的调用栈 :)
参考链接
https://github.com/Dec0ne/HWSyscalls
https://github.com/UmaRex01/Hit-And-Run
https://infosecwriteups.com/hit-and-run-a-novel-syscall-method-for-bypassing-edrs-via-veh-and-call-stack-theft-e2f399d71eeb
圈子介绍
圈子内部致力于红蓝对抗,武器免杀与二开,不定期分享前沿技术文章,经验总结,学习笔记以及自研工具与插件,进圈联系~
圈子已满200余人,目前价格199,学生优惠30
后续升价
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...