前一段时间在玩WBGlIl大佬以前发的一篇过卡巴的思路(虽然现在不过了),但是在研究的时候发现如果我们我们在没有CS的特性基础下直接看这篇文章,或者说你去魔改他的脚本是不太可能的,刚好就来普及一下这个CS的一些简单特性!(如有说错,请大佬们纠正)
1.Stagless已成标配
为什么说Stagless已成标配呢? 我们分别来准备两个🐎(一个stage 一个stagless)(无C2Profile)
我们分别来用Process Hacker去看看他的内存
如果我们是通过Stage的shellcode上线的话,他会用Stagler去拉取stagless形成反射dll!!!
这个拉取的行为就是一个特征,所以我们一般都是不会用stage的shellcode而是通过采用Stageless的shellcode去进行上线!!!!
2.CS的命令执行
1.Fork && Run
还记得我们平时去Shell whoami 吗,其实这是一个极度危险的操作(虽然目前360不会因为你shell whoami 就把你杀了)
我们通过Process Hacker 去看看他的过程(systeminfo)
新开一个cmd,然后通过Pipe在cmd运行这个命令,运行的结果再回传给我们自己的beacon,这个其实也算有点灾难,不过也要看你的进程链了!
2.Execute-Assembly && Process Hollowing
execute-assembly是CS的大名鼎鼎的内存加载,设计的初心是不想让我们的文件落地,防止静态被扫描,但是它的原理和Process Hollowing差不多,直接掏空一个进程,然后塞我们自己的程序进去(这就是一个非常危险的操作)
就算这里我采用白加黑的操作都是直接死掉了(远程线程注入)
而且execute-assembly只能对.net的程序进行加载,如果对方是有Defender的话,你还要考虑AMSI,所以就诞生了Inject-Assembly !!! 但是执行完之后内存会非常难看(很多RWX的内存)
3.BOF && Inline-Execute
那么有无办法拯救这只CS呢 ??? 有! 就是通过BOF去进行执行 !!
我们把我们的whoami进行BOF化(其实这里白加黑的话直接shell也是不会杀的)
我们也可以通过Inline-execute去执行,和BOF的效果是一样的!!
其实它的原理就是在本程序通过起线程通过WindowsAPI去执行命令(在本程序),这样就不会有太多的对其他的进程进行操作(更加OPSEC) ,当然他的缺点就是如果命令执行奔溃了,那么你的Beacon也会掉,一会用WBG大佬的脚本来演示一下就知道了!!!
3.VEH免杀脚本的优略
这里的脚本就是直接复制WBG大佬的脚本上线的了!!!
CS上线原理如下 (不配C2 Profile)
不管你是正常跑stageless 还是跑stage 的上线都是可以的,在跑起来ShellCode之后,首先他会去用VirtualAlloc进行内存申请,然后再将反射dll和loader的产物复制到这块内存(真正重要的也是这块内存)
那么VEH的免杀原理是什么呢 ??? 大致是这样的
首先对VirtualAlloc,Sleep进行HOOK,当我们要跑shellcode进行VirtualAlloc的时候,VirtualAlloc的第三块地址被我们拿到,然后Sleep的时候我们在自实现的Sleep里面改这个第三块内存为RW,当我们Sleep结束,要跑起来的时候,执行了一块RW内存,抛0xc005,VEH异常处理捕获,然后改这块内存为RWX,在执行完命令之后再去sleep又把他改成RW,循环往复,这样在杀软看起来是一块RW内存就不会去扫描。
:::就是这样的
那么当今来说他的劣势是什么呢????
1.BOF执行导致内存修改无效
我们上面说到了他是Hook了VirtualAlloc的,如果我们用BOF执行whoami呢 ? ??
我们知道他是在本地进行VirtualAlloc的对吧,问题就在这里了,一旦VirtualAlloc之后它的地址就不是我们CS的第三块内存的地址了!!! 这就是一个很致命的问题!
我们来演示一下:
首先我们上线一个Beacon,这是没有问题的,这时候我们用Bof去执行一下whoami
也是成功执行,但是问题就来了,我们再去看它的内存地址
他重新分配了一块内存,然后后续的改内存属性都变成了在这块内存而不是在我们的cs真正发挥作用的第三块内存了,我们用ProcessHacker去看看
可以看见我们真正的那块需要被隐藏的地址还是RWX
但是我们刚才执行的命令那块内存确实被改成了RW,但是这块内存也已经被清空了!
可能作者当时写这篇文章的时候,是想着我们都用shell 执行的,并无考虑到我们的BOF存在。
所以我个人看法
- 改变Hook的时机,或者说一开始不用VirtualAlloc(虽然好像这个并没有什么作用)
- 在VirtualAlloc之后进行Unhook,这样后续不论是shell 还是BOF 执行命令我们都不会出现上面的修改内存无效!
2.可以配合加密
我们上面是对内存进行了动态的RWX ---> RW --- > RWX 这样的修改,以前的杀软可能会不扫描这块内存,但是现在应该是会了(卡巴会的)! 所以我们可以在触发异常 , sleep 的时候分别对内存进行解密和加密,这样这块内存就 既是RW 又被加密了 !
通过这种手法,也是能轻松的免杀火绒的内存扫描的!!!