7

[原创]魔改cobalstrike免杀:三板斧再锤卡巴

 3 years ago
source link: https://bbs.pediy.com/thread-267619.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
[原创]魔改cobalstrike免杀:三板斧再锤卡巴-编程技术-看雪论坛-安全社区|安全招聘|bbs.pediy.com

一、 概述
这次我们一起来探究如何规避卡巴的内存扫描,使得cobalstrike的beacon能够存活,主要原理就是:在beacon 发送完心跳包sleep,对自身的内存属性进行修改去除可执行属性和相关加密,其实现的方式有以下三种:
1、VEH Hook
2、SMC
3、InlineHook
下面会详细讲述各种方法。同时感谢BGWill师傅的文章,让我拓宽了见识。

相关代码已上传到项目中:
https://github.com/mai1zhi2/CobaltstrikeSource/

二、 前置操作
在项目使用了自定义资源,并把beacon放在项目的资源中,然后通过解析自身的pe结构找到自身的资源,从而进行加载,beacon放在资源可以自己异或加密,放在bmp图片后也是可以的:

三、VEH Hook
VEH Hook是基于windows异常的一种Hook,所以这里要介绍下windows异常处理机制。在windows中,当程序执行过程中发生异常时,系统内核的异常处理过程(nt!KiDispatchException)便开始工作。当在没有内核调试器存在且异常程序没有调试的情况下,windows系统就会把异常处理过程转交给用户层的异常处理过程(ntdll!RtlDispatchException),用户层会查找异常程序中是否安装了VEH、SHE、TopLevelExceptionHandler等异常处理过程,如果已安装则交给其处理。
所以,我们需要先在beacon端安装相应的异常处理过程,然后在发送心跳包时硬编码写下int3断点指令,当程序执行到int3就会触发异常,就会在windows用户态触发相应的处理过程,VEH->SHE->TopLevelExceptionHandler。在这里我们使用int 3+VEH Hook,因为VEH是全局的、基于进程、优先级高。

先找到发送心跳包处:

然后在对应pe文件中找到相应的位置,硬编码上int 3即CC:

然后安装VectoredHandler过程,当程序执行到断定时产生异常,该异常会被VectoredHandler所捕获:

VectoredHandler()如下,在函数中我们需要判断发生异常的地址是否与预期一致,里面的context结构体有详细的栈、寄存器信息:

Win10 x64执行效果:

Win7 x86执行效果:

执行任务时内存属性:

内存中的断点位置:

Sleep时的内存属性:

四、SMC
SMC(Self-Modifying Code),即能修改自身代码,对自己的代码进行打内存补丁。在beacon中,我们需要对心跳包的sleep()进行打补丁,将其修改我们自定义的MySleep()。
这里需要注意的操作有,
1)因为CS的beacon是反射注入的,其反射注入的函数会对其进行重定位,所以我们需要对其pe的重定位数据进行修改,否则,在打内存补丁后,又被反射注入函数进行重定位,MySleep的函数地址就会出错。这也是不能使用IineHook Call IAT的原因。
经过pe下数两行半等一系列数手指操作,找到需要修改的重定位数据:

2)自定义的MySleep()函数是stdcall的,不然栈会不平衡:

在Mysleep()中,需要找到反射注入dll所申请的内存区域,所以要从栈上找到返回地址,再去进行相应的判断,应该也能使用egg hunter在内存中捞出所在区域。

3)修改资源中心跳包的sleep()函数地址:

Win10 x64执行效果:

Win7 x86执行效果:

Sleep时的内存属性:

五、Inline Hook
Inline Hook是直接修改指令的Hook,使得程序转移了所执行的流程,转移的方式也各异,主要有jmp xxxxxxxx、push xxxxxxxx/retn、mov eax,xxxxxxxx/jmp eax、call HookAddr(输入表地址)、HotPatch Hook。使用Inline Hook要注意几个问题:
1、是当Hook操作时的线程安全问题,可以先暂停所有线程,再进行Hook操作,最后恢复线程去避免,而IAT Hook相当于原子操作,不存在这问题。因为我们这里是先Hook sleep(),再进行反射注入,所以也不存在这问题。
2、Detour函数重入,造成无限递归
3、Detour函数的线程安全问题,避免使用全局变量,若使用则要上锁。

这里我们稍改了下教主的框架,没有使用微软的InlineHook框架。
这里先定义代替Sleep()函数的自定义函数,也即是Detour():

里面的OriginalSleep函数是一条跳转回去执行系统的Sleep()通道,里面需要恢复原来的指令,及绕过自己安装的Hook:

获取到需要Hook函数的地址并记录,通过LoadLibrary()、GetProcAddress()获得系统Sleep()函数的地址,这里有个地方需要注意,或许因为编译版本不同,后面可能是FF25 Jmp或E9 call 或者其他,这里debug编译的是FF25 Jmp,我们需要获取到Jmp后面地址所指向的值,该值才是真正系统Sleep()函数位置:

在系统Sleep()地址上,写入自己的跳转代码,一个E9 Jmp跳到先前自定义好的Sleep():

可以看到系统的Sleep()函数已经被Hook了:

一个Jmp跳转到我们自定义的MySleep()中:

其中有个E8 4E ED FF FF 这个Call是跳转回OriginalSleep函数,即跳转回去执行系统的Sleep()通道:

OriginalSleep函数中一个Jmp,绕过了Hook,执行回系统的Sleep()函数:

至此InlineHook完成。

Win10 x64执行效果:

六、小结
这次我们通过相关Hook的方式,达到修改内存中Beacon的属性和数据等目的,但操作起来还是有点繁琐。谢谢大家观看,下次我们再继续深究。

参考:
https://xz.aliyun.com/t/9399#toc-1
加密与解密

第五届安全开发者峰会(SDC 2021)议题征集正式开启!

最后于 2021-5-15 10:42 被快乐鸡哥编辑 ,原因:

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK