[工具]Cobalt Strike4.3 破解日记
最新生活太难了,继续下去会有点自闭,所以趁着4.3出来还没多久,休闲一下换换情绪。
-
4.3的验证方式其实相较于4.0来说并没有发生多大的变化,只是在其中加入了一些垃圾数据而已。按需更改就好了,趁着这次把之前4.0没有分析明白的
cobaltstrike.auth
文件和整个验证流程好好理一理。 - 原版的话网上也挺多的,这里就不放了。
- 这里使用的不是最快速的方法,把这当成厕所读物就好了
- 还是回顾了一下零队的《Cobaltstrike 4破解之 我自己给我自己颁发license》链接 / ca3tie1师傅的《CobaltStrike4.0无Hook蛮力Cracked License思路》链接
准备工作
- 请去参考4.0破解日记
验证过程
common/Authorization.java :12-28
读取加密的cobaltstrike.auth
文件,实例化common/AuthCrypto
后进行解密工作的准备- 读取
resources/authkey.pub
取出公钥common/AuthCrypto.java
并且从构造器我们可以得知他的加密方式是RSA/ECB/PKCS1Padding
需要注意的是Padding方式 - 然后简单的验证一下公钥的MD5是否对应,提取公钥。
- 回到
common/Authorization.java :31
开始解密,此时我们再去common/AuthCrypto.java : 47
观察函数public byte[] decrypt(byte[] var1)
此时真正的解密在protected byte[] _decrypt(byte[] var1)
保护函数中,而解密的公共函数中还有验证cobaltstrike.auth
的文件魔术头,转换方法在零队的文章中已经解释得很清楚了,这里就不再赘述了。 计算过程: -889274157
原 | 反 | 补 | 十进制 |
---|---|---|---|
1100 1010 | 0011 0101 | 0011 0110 | -54 |
1111 1110 | 0000 0001 | 0000 0010 | -2 |
1100 0000 | 0011 1111 | 0100 0000 | -64 |
1101 0011 | 0010 1100 | 0010 1101 | -45 |
最后计算出来前四个bytes是
byte[] header = {-54, -2, -64, -45};
- 代码中使用的是步进读取的方式操作的文件,所以我们要分清楚每个操作读了多少个字节 (从
common/DataParser.java
能得知)readInt() 4个字节 readByte() 1个字节 readShort() 2个字节 readBytes(int n) n个字节
这里要注意的是代码line 64-65中还使用readShort()
获取了剩下需要读取的数据长度,所以后面我们要删除垃圾操作/数据的时候需要更改此处 最后回到common/Authorization.java
,接下来就是真正的校验环节了,我们需要关注的是他的所有读取操作- 一 line: 36 首先把解密后的
raw
文件使用DataParser
封装,方便读取。 - 二 line: 38 读取过期时间,如果是29999999就是永久,转换方法和文件头一样
- 三 line: 39 读取水印值,具体是哪来干嘛的我也不太清楚,只知道如果值为0的话会帮你添加EICAR指纹,这里设置一个非0数值即可
- 四 line: 40 读取版本号进行简单的版本校验,这里设置一个大于等于43的值即可
- 五 line: 46-51 其实是一个读取垃圾值的操作,简单来说就是读取一个字节作为接下来的读取长度,然后读取垃圾值后扔掉 循环3次,我嫌麻烦就直接删掉了
- 六 line: 52 读取sleeve keygen key的长度
- 七 line: 53 根据长度读取sleeve keygen key
- 八 line: 54-60 时间校验,根据步骤二中读出的值做判断
- 九 其实到此为止已经完成了校验过程了,后续的sleeve keygen过程就没有再过多研究了,只是大概知道是生成解密各类dll/bin的key seed,有机会二开的时候再看看吧
- 一 line: 36 首先把解密后的
文件解释
- common/AuthCrypto.java 公钥相关的操作,比如读取公钥、解密
CobaltStrike.auth
、校验文件头等 - common/Authorization.java 主要的校验代码,解密过后的
CobaltStrike.auth
中数据就在这检查 - resources/authkey.pub 公钥匙,要求padding为PKCS#1
- cobaltstrike.auth 经过私钥签名加密的校验信息,文件结构如下:
header | length | expire time | Version | 垃圾数据x3 | sleeve keygen key |
---|---|---|---|---|---|
文件魔术头 | length of rest data | 过期时间 29999999为永久 | 版本号 | 垃圾数据x3 | 最关键的sleeve keygen key |
4个字节 | 2个字节 | 4个字节 | 1个字节 | (1个字节的长度+对应长度的垃圾数据)x3 | 1个字节的长度+对应的key长度(这里为1+16个字节) |
开始破解:
我们需要修改的东西为
- 使用网上已有的破解版获得authkey.pub和CobaltStrike.auth(如果新版本出来没有的话可以去尝试申请试用版获得)
- 使用openssl解密CobaltStike.auth,获得sleeve keygen key (这里哭一下当初找的破解版的CobaltStrike.auth作者把文件头校验和长度校验直接删掉了,在理清文件结构的时候踩了不少坑)
- 计算正确的header
- 计算正确的文件长度
- 填充各类校验字节,如时间/水印/版本/垃圾字符
- 重新生成公私钥
- 把重新写好的CobaltStrike.auth用私钥签名(使用openssl的时候注意参数是-sign 不是-encrypt,这里也踩了一个坑<-其实是密码学没学好,sign有两种形式,一个是直接把文件用私钥加密,一种是计算文件摘要并用私钥加密,这里我们使用第一种)
- 计算公钥的MD5并更改,扔进去
- 把CobaltStrike.auth扔进去
- 重新build jar,开始愉快的使用
命令相关:
生成公私钥(这里要注意的是使用2048bit和PKCS#1)
openssl genrsa -out pk.pem 2048
导出公钥
openssl rsa -in pk.pem -pubout -out pub.pem
签名
openssl rsautl -sign -inkey pk.pem -in cs4.3-plain.auth -out cobaltstrike.auth
检查签名
openssl rsautl -verify -pubin -inkey pub.pem -in cobaltstrike.auth
~
打完收工,最后提供一份我的cobaltstrike.auth文件内容(删了垃圾数据的)
c= [0xCA,0xFE,0xC0,0xD3,0x00,0x1A,0x01,0xC9,0xC3,0x7F,0x19,0x69,0xA0,0x8D,0x2B,0x10,0x3A,0x44,0x25,0x49,0x0F,0x38,0x9A,0xEE,0xC3,0x12,0xBD,0xD7,0x58,0xAD,0x2B,0x99]
with open('cs4.3-plain.auth','w+') as f:
for s in c:
f.write(chr(s))
神清气爽 继续搬砖去了。。。。
Did you like the post? Subscribe to the feed.