Contents
0x00 前言
本章主要是对Cobalt Stike中的Payload生成和Beacon在内存中是如何加载并且执行命令和相关通信行为的分析,在前文初探Beacon中提到CS提供两种Payload的方式,分阶段和不分阶段,这里我们将会对两种方式都进行说明
0x01 Stage Payload流程
首先是分阶段的Payload生成,这里我们不妨定位到Aggressor
中,该部分主要负责构建CobaltStrike的GUI功能,定位到Aggressor/dialogs/WindowsExecutableDialog
类中,该类主要负责CS中Windows Executable
这个会话框的action
主要有三个方法:dialogAction、dialogResult、show

该方法调用
getPayloadStager
获取对应系统版本的shellcode,不妨继续跟进,最终调用GenericStager抽象类
中的generate
方法,以Listener为http为例,跟进到GenericHTTPStager
的generate中:


并且定位到了这个模板文件在resources\httpstager64.bin
,相关文件后续在进行分析
到这里整个的Stager HTTP的shellcode已经就生成了,随后会进行一个回调处理,也就是刚刚的第二个方法:dialogResult
这一部分实际上准备封装成EXE可执行文件进行存储,我们主要是关注patchArtifact
相关函数


我们跟进到这个_patchArtifact
方法中:

这里可以看到通过生成随机数var6和shellcode逐字节异或加密,再往后走可以看到寻找到1024个A所在的位置(需要替换为shellcode)的位置,将异或后的shellcode写入,最终生成完整的PE文件


最后我们来看下Patch前后的相关比较:

0x02 Stageless Payload流程
这里我们定位到WindowsExecutableStageDialog
文件中,其类结构和Stage相似,我们直接来分析dialigResult这个回调方法:


最后调用exportBeaconStageHTTP,并且传递了Listener的Port和IP:

并且其中加载了资源文件beacon.x64.dll
文件

大致流程就是读取Beacon.dll,解密完成进行修补然后使用相同的方法将其嵌入到PE中。
注意:4.x与3.x不同的是多了一个资源解密,在3.x时所有资源都是放在resources文件夹内,在4.x后Cobalt Strike将加密的资源都放在了sleeve文件夹内,还有一些不同的是,无阶段payload生成增加了powershell和raw两种格式。
0x03 Beacon加载分析
这里通过对Stager的动态调试分析Beacon的相关行为
前置分析

main中包含两个函数,我们这里先来查看第二个函数,跟进:

可以看到这里对buffer进行初始化,最终的格式形如:
%c%c%c%c%c%c%c%c%cMSSE-%d-server
其实后续分析会发现是Pipe管道,然后调用
CreateThread
,我们跟进所调用的这个函数:sub_401713
先前格式化的Buffer名称,被用于创建命名管道,然后将lpBuffer中的值写入到管道中

回到sub_401840
最后return了一个函数,我们跟进这个函数sub_4017E2:


这里实际上做了两件事,先将写入到管道的数据读出来,然后调用
sub_40158E
方法,这个方法实际上就是通过unk_403008
进行异或解密,期间先调用VirtualAlloc
申请一段内存,然后解密完成后调用VirtualProtect
来使得该段内存空间为可读可写可执行,最后调用CreateThread
创建一个线程去执行shellcode

在动态调式的过程中我们也能够清楚知道:

分析到这里之后我们后面就是要分析解密完成后的shellcode
Shellcode分析
根据分析,我们定位到Shellcode,这里的图为借用

首先调用LoadLibrary加载wininet.dll,其中rbp所指向的函数为寻找加密哈希所对应的函数
紧接着调用InternetConnectW连接先前CobaltStrike Listener中配置的IP

InternetConnectW返回的句柄,传入到HttpOpenRequestW中,对应的url为C2zn

使用HttpSendRequestA发送请求,并设置请求头

通过InternetReadFile循环读取C2的数据,并写入到用VirtualAlloc申请的内存中,读取完毕后,跳转到写入数据所在的地址并执行
在MSF和CS中基本都是通过判断Win Api的Hash比较来调用,而非直接调用,大致的流程就是不断遍历导出表,计算函数hash,判断跟传入的hash是否一致,如果一致则调用
0x04 总结
本文主要是分析Payload的生成,包括Stager和Unstager的相关差异和修补过程以及Beacon加载后的相关操作,包括Hash调用Win函数等进行分析,主要是为了更深层的熟悉Cobalt Stike,为后续的深度免杀和相关检测打下基础
参考文章:
https://www.anquanke.com/post/id/237127#h3-7
https://wbglil.gitbook.io/cobalt-strike/cobalt-strike-yuan-li-jie-shao/untitled-5