Cobalt Strike之Payload生成及Beacon加载分析(二)

Cobalt Strike之Payload生成及Beacon加载分析(二)

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

upload_f4c716dd09b5716995ca395d95dc59a3

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

upload_af750163e431c96625b1f066e522797f

upload_a5f61825f280e66e56d48fca0e36de42

并且定位到了这个模板文件在resourceshttpstager64.bin,相关文件后续在进行分析

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

upload_dd7bbd9999600285862c1f61b4d79f52

upload_64d61eff17f4c196528851477cfae32a

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

upload_67ea3301bfbaf79d32f54ed863f977cb

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

upload_449a093bc7303c4762e8342202bdcb50

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

upload_b5b1d9dc24aa023a1d43448adbf93866

0x02 Stageless Payload流程

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

upload_406bf9a3921737d23d2e91bfeb9dd894

upload_464a58a4fb055e25ee83852931292147

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

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

upload_81366584f9700d469e5a491291a9fa3f

大致流程就是读取Beacon.dll,解密完成进行修补然后使用相同的方法将其嵌入到PE中。

注意:4.x与3.x不同的是多了一个资源解密,在3.x时所有资源都是放在resources文件夹内,在4.x后Cobalt Strike将加密的资源都放在了sleeve文件夹内,还有一些不同的是,无阶段payload生成增加了powershell和raw两种格式。

0x03 Beacon加载分析

这里通过对Stager的动态调试分析Beacon的相关行为

前置分析

upload_a850b3b2a21b1ea64137b951506047fd

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

可以看到这里对buffer进行初始化,最终的格式形如:
%c%c%c%c%c%c%c%c%cMSSE-%d-server
其实后续分析会发现是Pipe管道,然后调用CreateThread,我们跟进所调用的这个函数:sub_401713
upload_91ae354083a70d675a4a9ee4a7bb056e

先前格式化的Buffer名称,被用于创建命名管道,然后将lpBuffer中的值写入到管道中
upload_998cf270d7c9d5a5f2a1434b44d89437

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

upload_06caf875ed531bd3a8f16535df85fbf4

upload_6b2f5760f952b06e15cacbb88f0c2770

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

upload_7a881b4475c7569fd63ba149936eb172

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

分析到这里之后我们后面就是要分析解密完成后的shellcode

Shellcode分析

根据分析,我们定位到Shellcode,这里的图为借用

upload_91aa04aad960dfc89c404cc048e800c9

首先调用LoadLibrary加载wininet.dll,其中rbp所指向的函数为寻找加密哈希所对应的函数

紧接着调用InternetConnectW连接先前CobaltStrike Listener中配置的IP

upload_af19709bc821c4194953427da0590e96

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

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

通过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

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇