Castiel's Blog

CobaltStrike4.0无Hook蛮力Cracked License思路

CobaltStrike4.0无Hook蛮力Cracked License思路
2020-03-22 · 9 min read
工具 CobaltStrike

0x00 前言

前两天一早起来就看到CoolCat师傅发布CobaltStrike4.0 Cracked,并附上了破解思路(点这里)。随后跟师傅要了一份原版的来也准备自己动手破解玩玩儿,经过两天折腾,在CoolCat师傅思路的基础上实现了蛮力绕过Liccense。昨晚写好了破解工具,今天上午就发现师傅们各显神通,纷纷给出了各种思路和方法。其中Frost Blue 零队微信公众发布一篇Cobaltstrike 4破-解之 我自己给我自己颁发license的文章,后面提到HMAC的思路和本文思路大同小异,但未给出具体的实现方式,本文算是做个补充,不到之处望师傅们多指正。该文章是直接对cobaltstrike.auth的加解密下手,其中对AuthCrypto部分的分析思路值得学习和借鉴,而我则是想直接绕过cobaltstrike.auth的部分来实现蛮力Cracked。

0x01 初探License

在拿到原版之前都有耳闻说是最新版的CobaltStrike的认证算法有所改变,而且看了CoolCat师傅的文章后也纳闷CoolCat师傅为何没有尝试直接蛮力破解,后来师傅告诉我实际上他也尝试过蛮力破解,但没成功,最后直接用流出的正版秘钥搞了。强迫症和好奇心推动下我决定还是尝试尝试蛮力破解方法。直接用jd-gui载入cobaltstrike.jar包直奔common/Authorization.class去,粗略看了一下整体代码和3.14版本差不多,然后就直接按照我上篇文章的思路来(点这里),注释掉Authorization构造函数的全部内容,把watermarkvalidtovalid写死在构造函数中(发现新版少了licensekey域)。简单测试下都能正常启动teamserver和GUI,等我把exit暗桩一并改了编译好测试的时候悲剧了,连接teamserver后报错,如下图:
在这里插入图片描述
跟了下common.SleevedResource.readResource的代码发现是要读取文件,再看下调用位置c2profile.Preview.getPE
在这里插入图片描述
发现是要读取resources/beacon.dll,第一反应是查看了下jar包里对应是否存在该资源,发现没有,还以为是因为不存在该资源的原因。但仔细一想也不对,如果不存在该资源那正版的怎么能正常运行呢?而且我自始至终至修改了Authorization和exit暗桩所在的BeaconData类。再仔细想和BeaconData的关系应该不大,可能问题还是出在修改了Authorization的原因,得搞清楚去读取这个dll和license有啥关系 才行,于是继续返回去仔细看了下Authorization的代码才发现问题之所在。
在这里插入图片描述
发现Authorization比之前版本多了个DataParser用于解析解密cobaltstrike.auth后的数据的类,这部分的分析请参考上文提到Frost Blue 零队微信公众发布的文章,这里重点在后面的SleevedResource.Setup(arrayOfByte);。在解析解密后的cobaltstrike.auth数据之后传了参数arrayOfByteSleevedResource.Setup方法。

0x02 SleeveSecurity

跟进SleevedResource.Setup发现调用SleevedResource类的构造函数并将该byte数组传递给了dns.SleeveSecurityregisterKey方法,继续跟进该方法:
在这里插入图片描述
实话,Java渣渣刚的我刚看这部分的SHA-256HmacSHA256确实有点懵逼,刚看到MAC这个词还以为是MAC地址呢。后来百度了下才知道是Message Authentication Code,HMAC则是密钥相关的哈希运算消息认证码。但这里的重点是搞清楚了的,那就是使用传递过来的byte数组内容做key,使用加密算法生成keyhash_key。搞清楚了这个再反过来看看SleevedResource中的readResource方法:
在这里插入图片描述
这里经过CommonUtils.strrep替换之后实际上是读取jar包中sleeve目录下的文件,然后使用SleeveSecuritydecrypt方法进行解密,如下图:
在这里插入图片描述
这里把读取到的dll文件分成两部分,主体部分(长度0至总长度-16)和veriKey部分(最后16位)。然后就用到了上文提到的hash_key,用它来对dll文件主体做doFinal操作(我也搞不懂是解密加密了。。)得到一个32位的字符串,然后取前16位与veriKey比对,比对通过后在把dll文件主体内容使用上文的key来解密。至此也就搞清楚了为啥我直接使用蛮力破解后连接teamserver会报错了,因为我没有使用SleevedResource.Setup(arrayOfByte);注册keyhash_key,造成dll文件无法正常解密,所以报错了。

0x03 初试Cracked

搞清楚了问题,我便尝试自己手动SleevedResource.Setup(arrayOfByte);注册keyhash_key,但是这个这个arrayOfByte值填什么好呢 ?我准备尝试一下,直接使用SleevedResource.Setup(null);,改后发现还是继续有报错,但这次报错有所不一样:
在这里插入图片描述
分析发现问题是出在veriKey比对不过,看来自己随便填肯定是不行的。思来想去我决定还是回到CoolCat师傅的思路,使用正版的秘钥来试试,看看SleevedResource.Setup(arrayOfByte);这个注册keyhash_key所用的arryOfByte值到底是什么样的。所以这里直接拿CoolCat师傅公布的byte[]值 替换掉Authorization类中解密cobaltstrike.auth文件后的arrayOfByte2数组,如下图:
在这里插入图片描述
使用正版秘钥后,经过调试发现SleevedResource.Setup(arrayOfByte);这个注册keyhash_key所用的arryOfByte值实际就是arrayOfByte2的后16位({27,-27,-66, 82,-58,37,92,51,85,-114,-118,28,-74,103,-53,6}),而且使用正版秘钥后便能正常连接teamserver了。而且必须用正版的才行,测试上诉内容更改一位都不行。至此我也总算摸清楚新版的这个认证方式了,官方在签发正版的cobaltstrike.auth的时候就生成了一个秘钥或者是key({27,-27,-66, 82,-58,37,92,51,85,-114,-118,28,-74,103,-53,6})一并存放在cobaltstrike.auth文件中,然后再使用该秘钥或者是key 来对sleeve文件夹下的所有dll文件进行加密,所以客户这边必须有正版的秘钥才能正常使用。

疑问?

这里官方在签发cobaltstrike.auth的时候用到的这个秘钥或者是key是否是固定值?如果不是固定值,而是在签发的时候随机生成的话,那就意味着同样是正版在交换了jar文件之后可能就无法正常使用。若是固定值,那这个固定值会不会成为一个指纹特征,毕竟这个值是用来加密sleeve目录下诸如mimikatz-full.x64.dll这类文件,而这类文件使用的时候是要加载到目标内存中执行的。就我个人理解的话这个值应该是一个固定值,否则一人一值的话那加密后应该会影响到整个jar包的hash校验值了。不知这里的理解和分析是否有误,仅供师傅们参考和指正。

0x04 Cracked

有了以上疑问之后我还是觉得能自定义这个秘钥或是key实现蛮力破解是最好不过了。于是在反复研究了整个认证方式和加解密算法之后发现在dns.SleeveSecurity类中对应有encrypt方法,该方法和decrypt是对称的,如下图:
在这里插入图片描述
加密方式也是使用keyhash_key,既然加密方法有了,那就好办了,灵光一闪思路就有了。我可以使用正版的秘钥先把sleeve下的dll文件全部解密一份,然后自定义一个16位的byte值来做key,然后再使用这个key来注册keyhash_key,再调用他的加密方法把刚解出来dll文件再重新加密,这样一来就可以在Authorization类的构造方法中蛮力Cracked了。实测能正常运行,dll文件的使用也没有问题,如下图
在这里插入图片描述
这里为了方便写了个小工具,用来解密和加密文件(点这里下载 https://github.com/ca3tie1/CrackSleeve)。

使用方法

  1. 将cobaltstrike.jar和CrackSleeve.java放一起
  2. 编译(javac -encoding UTF-8 -classpath cobaltstrike.jar CrackSleeve.java)
  3. 解密文件(java -classpath cobaltstrike.jar;./ CrackSleeve decode)
  4. 自定义16位字符串加密文件(java -classpath cobaltstrike.jar;./ CrackSleeve encode CustomizeString)
  5. 将解密后的sleeve文件夹替换jar包中的文件夹
  6. Authorization类中便可以自定义蛮力Cracked了,如下图:
在这里插入图片描述

0x05 总结

整体思路和个过程大致如此,不到之处师傅们多多指正。这里的关键是在于要嫖到一个正版的秘钥,这里还是需要感谢CoolCat师傅以及其他无私奉献的师傅们。其他x64无法上线的问题请参考ssooking师傅和CoolCat师傅的文章。
参考链接:
https://www.cnblogs.com/ssooking/p/12535998.html
https://blog.gzsec.org/post/Patch-Cobalt-Strike-4.0/
https://blog.gzsec.org/post/patch-cobalt-strike-40-stage-x64-bugs/