吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 16441|回复: 54
收起左侧

[PC样本分析] 魔改CobaltStrike:协议全剖析

  [复制链接]
mai1zhi2 发表于 2021-4-25 16:57
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 mai1zhi2 于 2021-4-25 20:29 编辑

一、概述

这次文章将较详细介绍下CobaltStrike 4.1的agressor端登录teamserver端的通讯和beacon端与teamserver端通讯,包括元数据、心跳包、执行任务等数据传输。帖子写到一半IDEA授权就掉了,所以就拖到现在才写完,附项目地址:https://github.com/mai1zhi2/CobaltstrikeSource/

二、aggressor端登录teamserver端的通讯分析
2.1、agressor客户端发送密码登录teamserver端进行验证:
运行Teamserver端,首先会创建SecureServerSocket对象,然后循环调用acceptAndAuthenticate()接受认证信息:
图片1.png
点击connet按钮后:Aggressor端首先在dialogAction()方法获得相应的登录信息:
图片2.png
然后传入host、port创建安全套接字:
图片3.png
  SecureSocket的构造方法中设置了相关的socket属性, 调用createSocket()传入要连接的ip地址和port:
图片4.png
agressor端调用完createSocket()后,teamserver端acceptAndAuthenticate()会接受到信息,其中跟入authenticate(Socket var1, String var2, String var3)方法负责处理接受到的信息:
图片5.png
跟入该方法,当var4没读取到足够的字符就一直阻塞:
图片6.png
Aggressor端构建完SecureSocket对象后,调用其authenticate(string var1)方法,并传入登录的密码,该方法主要通过密码构造相应的数据包,其数据包先传入48879这个数值(标志),然后再传密码的长度,接着传入密码的内容,最后以0x41进行填充:
图片7.png
数据包var3内容:
图片8.png
当var3.flush()调用向server端发送数据,teamserver的authenticate(Socket var1, Stringvar2, String var3)方法就会停止阻塞,接受到相应的数据并对密码进行判断:
[attach]2275158[/attach
]若密码相等则发送51966标志数给aggressor端:
图片10.png
然后返回执行PostAuthentication对象实现的clientAuthenticated():
图片11.png
图片12.png
新建线程,等待后续接受aggressor端所发送的信息:
图片13.png
aggressor端接受到后进行判断:
图片14.png
至此teamserver端校验aggressor端密码完毕。
2.2、aggressor.authenticate消息类型传输:
接着Aggressor端再通过SecureSocket对象构造出TeamSocket对象:
图片15.png
图片16.png
传入TeamSocket对象来创建TeamQueue对象,其中TeamReader与TeamWriter均为TeamQueue的内部类,均实现Runnable接口负责与TeamServer通信:
图片17.png
图片18.png
然后调用TeamQueue的call()方法,把消息类型aggressor.authenticate、用户名、密码、版本信息均传入,再把请求通过TeamWriter属性发送给teamserver端:
图片19.png
图片20.png
图片21.png
图片22.png
图片23.png

TeamServer端收到aggressor的aggressor.authenticate类型请求数据包:
图片24.png

跟入process(),先比较数据包的类型,再判断版本号,接着校验密码和是否重复登录,最后向aggressor回复success:
图片25.png

最后新建名为write for nickname的线程向各个客户端回复消息:
图片26.png
Aggressor端收到Success回复:
图片27.png

2.3、aggressor. metadata消息类型传输:

Aggressor端继续向teamserver端发送:aggressor.metadata类型请求
: 图片28.png

TeamServer端收到aggressor.metadata请求后,调用process()方法:
图片29.png

继续跟入process(),该函数主要用hashmap存放相关的数据,最后向aggressor端返回了aggressor.matedata类型和hashmap数据:
图片30.png

图片31.png

aggressor客户端接收teamserver端返回的aggressor.matedata类型和hashmap数据:
图片32.png

跟入processread()函数,函数主要获取消息包中数据类型和数据:
图片33.png

再跟入result(),可见该函数负责处理从teamserver端返回的aggressor.authenticate和aggressor.metadata类型的信息:
图片34.png

传入metadata数据hashmapvar2来构造AggressorClient对象,跟入该对象的构造方法:
图片35.png

继续跟入setup()方法,该方法主要是注册各类Bridge对象,储存teamserver端返回的metadata,加载插件框,以及发送aggressor.ready给teamserver告知其准备完。
图片36.png
最后调用该对象的showTime(),至此显示出主界面,后续同步相关数据:
图片37.png
下面图是360空间测绘的,顺手帮他们改了图中的小错误:
图片38.png
至此,我们知道了cs的agressor端登录teamserver端通讯方式,所以可以进行相应简单的修改来规避cs登录爆破:
1、 teamserver端避免使用默认的端口号50050。
2、 如果修改48879这个标识数,需要修改的地方有三个,涉及到修改aggressor端:SecureSocket的authenticate方法:
图片39.png       

AsymmetricCrypto的decrypt()方法
图片40.png

       SecureServerSocket的authenticate方法
图片41.png   
三、beacon端与teamserver端第一次数据包通信(元数据)

我们先生成不分段的后门beacon.exe,因为不分段的beacon更好调,其通信过程都一样的。当启动teamserver后,会把cobaltstrike.beacon_keys反序列化为Keyparis对象:
图片42.png

然后把该对象传入AsymmetricCrypto构造函数中,并把publickey和privatekey保存为AsymmetricCrypto对象中相应的属性:
图片43.png

所反序列化出来的公私钥:
图片44.png
图片45.png

公钥会在后门生成时放进去,但不是在上述的函数中,详见之前发的后门生成的帖子。而私钥则是为后续通信做加解密处理准备的。 下面我们继续操作:先直接上x32dbg,createthread()下断,查看线程调转的地方再相应下断,然后执行到反射dll,再等所导出的解析函数解析完dll后,再通过导入表搜相关的通信函数,因为这次文章主要是协议分析,相关中间的相关功能先省略掉,有必要再从栈回溯查看相关的函数调用,然后我们看到相关的通信函数:winnet的HttpOpenRequestA、HttpSendRequestA、InternetCloseHandle、InternetopenA等,还有ws2_32的socket、send、recv、accept等,通过观察ws2_32用的是select网络模型,则先排除掉:
图片46.png
所以从winnet的相关api下断入手,
图片47.png

程序先在InternetOpen()函数断下,传入相关的agent信息:
图片48.png

接着InternetConnect()函数,传入相关的url:192.168.202.1和port:80
图片49.png
httpopenRequestA()函数,get请求,uri为/pixel.gif
图片50.png
httpSendRequest()发送请求,注意cookie的值经过编码:
图片51.png
Wireshark所捕捉到的数据包:
图片52.png

可见cookie对应的数据经过编码或加密的,我们往上翻找到相应的函数sub_1000783E(),跟进该函数,可见函数有16个不同的case,当发送第一个数据包(元数据)时先后走case7和case3,case7只是复制操作:
图片53.png

Case3是自实现的base64:
图片54.png
图片55.png

根据所编码的内容&unk_100398A8 继续找相应的赋值和加密操作sub_1000671C(),在该函数中,收集受害者主机的代码页、时间戳、程序id等信息并生成hash值:
图片56.png

生成hash:
图片57.png

最后调用sub_1000969e()函数,对收集的信息进行rsa加密:
图片58.png

用来加密的RSA公钥:
图片59.png

RSA加密前所收集的数据内容:
图片60.png
被RSA加密后的数据内容:
图片61.png

至此,beacon.exe端第一次发包(元数据)分析完,流程总结为以下:收集数据->RSA加密->base64编码


下面开始分析Teamserver端接受beacon.exe元数据的请求:
图片62.png

跟入_server(),该函数经过Useragent等判断后,先把url、method等相关参数传入webservice.serve()进行构造相关响应头并返回,其中MalleableHook实现了相关的webservice接口,跟入MalleableHook.serve():
图片63.png

在该方法中调用了GetHandler.serve()并把相应参数传入,继续跟入,该函数中先解析出相应的URI、method等:
图片64.png
我们先跟入BeaconHTTP.this.c2profile.recover()函数,在该函数中先将cookie数据拿出来:
图片65.png

然后再进行base64解码:
图片66.png

解码完成后,会判断解码后数据的长度,接着传入被加密的数据到process_beacon_metadata()进行解析,继续跟入:
图片67.png

跟入decrypt(),首先把反序列化处RSA私钥,然后对原数据解密,接着判断标志数是否为48879,如果不相等则解密失败,然后再判断数据长度,如果大于117则失败:
图片68.png

回到process_beacon_metadata(),解密完后先读取前16字节备用,然后用16-20字节判断windowscharts:
图片69.png

把ip、windowscharts、listen地址、截取后的元数据传入到BeaconEntry()的构造方法进行解析:
图片70.png 跟入该方法,方法中先跳过前20字节,然后获取到id、pid、port、系统位数、受害者ip等信息:
图片71.png
图片72.png

图片73.png

构造完后返回到process_beacon_metadata()函数,再传入元数据中hash值给registerkey()该函数是注册AESkey和HmacSHA256key的,对传入的hash值进行一次sha256,然后前一半作为AESkey,后一半作为hmacSHA256key:
图片74.png

最后构造response数据包返回给beacon.exe:
图片75.png

图片76.png

图片77.png

图片78.png

四、beacon端与teamserver端心跳包通信:

心跳包和发送元数据包的流程是相一致的,都是先复制加密后的数据再base64编码最后拼接cookie,只是没有再走sub_1000671C()函数获取元数据了,只是走sub_100024F4()发送数据,数据的内容也是与元数据相一致的。
图片79.png


五、beacon端与teamserver端执行所需任务的通信

下面介绍Beacon.exe接受teamserver端的任务数据传输:
5.1、teamserver端怎么发送任务给beacon的?

当每次心跳结束后,teamserver端都会把相应的任务加入响应包中发送给Beacon.exe
图片80.png

首先会根据beaconEntry的id号获取到任务队列中的data和socks:
图片81.png

图片82.png

然后把beaconEntry的id号和data数据传入encrypt()函数进行加密,跟入encrypt()函数,函数中先通过beaconEntry的id号拿到AESkey和hmackey:
图片83.png

获取当前系统时间/1000、data长度、data数据并将其写入var3,然后进行aes加密,密钥为beaconenrty中保存好的:
图片84.png

对其加密后的数据进行hmac:
图片85.png

将hmac前16字节拼到加密后的数据后,并返回:
图片86.png

最后发送给beacon.exe:
图片87.png

5.2、      beacon怎么处理teamserver端的响应包?
InternetReadFile()读取到响应的内容
图片88.png

然后在sub_1000c901中进行相关的自己实现的sha256验证:
图片89.png

当验证通过后调用sub_1000c5b1进行解密,我们来看下解密的流程,显而易见这是一个aes_cbc解密的流程,先解密再异或,v4是加密的内容,v18是解密后存储空间,后面是context:
图片90.png

图片91.png

Context内容:
图片92.png

解密后内容:
图片93.png

Iv为abcdefghijklmnop:
图片94.png

解密后的内容:
图片95.png

后面解析解密后的数据,先获得时间戳,再获得数据长度,最后获得数据内容:
图片96.png



5.3、beacon执行完任务怎么发送数据给teamserver端?

当beacon执行完相关任务后,调用sub_10001345()函数把数据内容加密:
图片97.png

然后经过长度和数据类型等拼接后,调用1000C170()也是进行AES_CBC的加密:
图片98.png

最后把加密完的数据调用1000C901()进行sha256的校验,校验值补在后面:
图片99.png
发送数据:
图片100.png





5.4、teamserver端怎么处理beacon端执行后返回的数据?
接收数据的方式与元数据一致的,先在BeaconHTTP.server()获得beacon和id和post数据:
图片101.png

然后把id和数据传入process_beacon_data()处理,在该函数中调用process_beacon_callback():

图片102.png

调用Decrypt()来解密数据,解密流程也是先对除了后面16的数据进行sha256验证,验证通过过再进行解密:
图片103.png
把解密出来的数据传入process_beacon_callback_decrypted()函数进行解析:
图片104.png
六、关于流量检测
这次我们一起剖析了CobalStrike的通信协议,可见其通信协议是可靠的,RSA传输AES的密钥,AES的密钥加密后续通信,这也是c2的常规通信手法了。但为什么能被天眼所探测出呢?如果在配置好profile和证书的情况下,天眼还是能检测到流量通信,不妨一试删除默认的.cobaltstrike.beacon_keys,
图片105.png

这个文件是可以删掉的,删掉后会重新生成新的,但改文件保管着RSA的公私钥,所以要注意的是一旦删掉后原来的链接会丢失。同样也可以使用ExternalC2规避。
图片9.png

免费评分

参与人数 43吾爱币 +40 热心值 +39 收起 理由
flygg + 1 谢谢@Thanks!
HideMyEye + 1 我很赞同!
JPK + 1 用心讨论,共获提升!
L1ngFeng + 1 + 1 我很赞同!
yixi + 1 + 1 谢谢@Thanks!
submarine1620 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
SnowSec + 1 + 1 我很赞同!
mfl6 + 1 + 1 热心回复!
无名氏wyw + 1 我很赞同!
azcolf + 1 + 1 热心回复!
siuhoapdou + 1 + 1 谢谢@Thanks!
jokin1999 + 1 + 1 谢谢@Thanks!
d3d + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
eziolei + 1 + 1 感谢您的宝贵建议,我们会努力争取做得更好!
自强 + 1 + 1 太强了,感谢分享
10JQKA + 1 谢谢@Thanks!
奈何不得 + 1 + 1 热心回复!
从小到大cxd + 1 + 1 感谢大佬
rekaytang + 1 + 1 我很赞同!
努力加载中 + 1 + 1 谢谢@Thanks!
lookerJ + 1 + 1 谢谢@Thanks!
小脚jio + 1 + 1 我很赞同!
chuxia12 + 1 我很赞同!
victos + 1 + 1 谢谢@Thanks!
pdcba + 1 + 1 谢谢@Thanks!
fengbolee + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
crazycannon + 1 + 1 谢谢@Thanks!
aaa661179 + 1 + 1 热心回复!
独行风云 + 1 + 1 用心讨论,共获提升!
wabc666 + 1 + 1 我很赞同!
gaosld + 1 + 1 谢谢@Thanks!
白影33 + 2 + 1 用心讨论,共获提升!
che_shen + 1 鼓励转贴优秀软件安全工具和文档!
凤凰御令 + 1 + 1 谢谢@Thanks!
aze1990 + 1 我很赞同!
雪流星 + 1 + 1 我很赞同!
点灯小子 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
looooooc + 1 + 1 鸡哥太强了
Insurance + 1 + 1 我很赞同!
salcvc + 1 + 1 用心讨论,共获提升!
夏寒 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
zydx + 1 + 1 鼓励转贴优秀软件安全工具和文档!
星辰丿 + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

梦呓233 发表于 2021-4-28 21:19
chenyumiao 发表于 2021-4-27 09:02
软件不错,我自己目前就在用这个版本,去官网看了,最新对应这个版本号

你确定最新不是4.3?
zlsxhc 发表于 2021-4-27 06:04
月清晖 发表于 2021-4-27 08:54
虽然看不懂,但是看起来很牛皮!谢谢楼主分享!
chenyumiao 发表于 2021-4-27 09:02
软件不错,我自己目前就在用这个版本,去官网看了,最新对应这个版本号
canarys2008 发表于 2021-4-28 16:50
谢谢分享,太牛了!
N0th1ng 发表于 2021-4-28 18:23
大佬牛!虽然看不懂(╯︵╰)
wangxd 发表于 2021-4-29 10:00
虽然看不懂,但是看起来很牛皮!谢谢楼主分享!
L1ngFeng 发表于 2021-4-29 18:37
学到了 cs 协议有点东西的
头像被屏蔽
tl;dr 发表于 2021-4-29 21:37
谢谢大佬
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 12:04

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表