关于CS流量行为
首先生成一个payload,在虚拟机中启用wireshark之后直接执行,可以捕获一个完整的流量信息。
上线之后执行 whoami,然后退出
打开 wireshark,过滤对话,通过 C2 地址可以过滤出 Cobalt Strike 的流量。我这里按照传递数据包的大小排序了,可以看到最上面有一个传递 payload (攻击载荷,Beacon)的会话。
随后过滤相关数据包,直接推荐直接使用ip来过滤,防止漏掉会话流
我这里因为执行了sleep 0,所以流量看起来非常不清晰,所以这里我重新抓包分析。
随后加上http协议过滤,可以看到业务流程
首先是checksum8,这个原理来自这两处
metasploit-framework/uri_checksum.rb at master · rapid7/metasploit-framework (github.com)
Cobalt Strike: Using Known Private Keys To Decrypt Traffic – Part 2 – NVISO Labs[
我们可以看到没有检测出我刚刚创建的 payload 存在该特征,但是示例中的URI确实被检测出该特征。而且在另一次实验中获取的该值也符合该设定。所以暂且按下不表。
可以看到这个是符合 CS x64 特征的,而且我确实生成的是该类木马。
从流量中来看,第一个数据包直接传输 CS 的 Beacon,并且没有加密流量,因为 Beacon本身就是需要自解密的。
第二个数据包中就出现了Cookie字段,里面存放的是一段 Base64 之后的数据。这段数据被称之为元数据。
分析元数据的部分参考这篇文章
CS Beacon通信分析 - Cobalt Strike (gitbook.io)
https://wbglil.gitbook.io/cobalt-strike/cobalt-strike-yuan-li-jie-shao/cs-mu-biao-shang-xian-guo-cheng
首先我们反编译cobaltstrike.jar找到 HTTP Beacon每次回连发送元数据请求时使用的方法,Cobalt Strike关于Beacon GET处理的核心代码在BeaconHTTP里。
从代码中分析就可以知道,元数据本质上是 Beacon 本地产生一个 16 byte的数据,该数据做 SHA-256 处理之后,前16位作为AES秘钥,16-32位作为HmacSHA256,用于加解密传递的数据。
元数据本身则通过 RSA 公钥加密,这样 C2 就和 Beacon 完成了秘钥协商,接下来通过检查任务列表中是否存在任务,存在任务则下发任务,Beacon完成任务之后,通过POST返回执行之后的结果。
接下来,我们就需要获取到本地的 RSA 公钥,然后就可以解密并生成 AES 的 key,并以此来解密流量。
首先找到cobaltstrike.beacon_keys文件,然后打开它,可以发现它是一个序列化之后的文件。
同样的从代码中找到解析文件的地方,使用它的方法来获取 key。
(KeyPair) CommonUtils.readObject(file, null));
使用BeaconTool直接解析出公私钥。
darkr4y/geacon: Practice Go programming and implement CobaltStrike's Beacon in Go (github.com)
随后RSA解密元数据,并且按照代码中的格式解析,就可以计算出 AES 的 key 和一些额外信息
接下来,在某个心跳包的回包中,我们就可以发现我们的服务器对受控终端发出了一条指令。
解密就可以看到我们服务器下发的指令
至于%COMSPEC%就是 cmd.exe 的绝对路径。
接下来就可以顺理成章的解密返回数据。
对应的返回数据包
对应的解密数据