分析破解方法cobaltstrike.auth:各版本官方解密key去除暗桩从Hook看破解思路
今天想练习Java的时候
想用cs4.4进行操作
后来发现cs4.4二开的以后,打不开了
记录一下破解流程和cs4.4的暗桩
LN师傅曾说过CS4.4
v4.4加入了混淆,加大了分析难度,不敢保证理解所有逻辑v4.4加入了循环完整性校验,大家知道前几个版本所谓的exit暗装其实就是cobaltstrike.jar整个包的完整性校验。在4.4中加强了校验,增加了里面class文件的完整性校验,那什么是循环完整性校验呢?举个例子有a.class b.class c.class d.class,a.class中有b.class的完整性校验,b.class中有c.class的完整性校验,以此类推,因此你动了一个class都会引起校验失败。要破解非常麻烦。
分析从入口处aggressor/Aggressor.class中发现License.checkLicenseGUI(new Authorization());从此开始进行license认证
在License.checkLicenseGUI中isValid,isPerpetual,isAlmostExpired分别对授权证书的正确性和授权是否有效以及授权是否过期进行判断
而在Authorization类中
主管liscense
则是对cobaltstrike.auth进行处理,读取文件内容,调用AuthCrypto.decrypt对内容进行cobaltstrike.auth解密操作
在这里进行RSA解密后赋值的参数写死,也就是Var4写死进行破解
中间4.0、4.1、4.2的key是没有用到的可以随便写,最后一组写4.3泄露出来的key,4.4同理。
也可以吧Authorization()函数都删掉,几个判断值写死,例如4.4的Authorization()
public Authorization() { try { this.watermark=999999; this.validto="forever"; this.valid = true; final byte[] bytes = {94, -104, 25, 74, 1, -58, -76, -113, -91, -126, -90, -87, -4, -69, -110, -42}; MudgeSanity.systemDetail("valid to", "perpetual"); MudgeSanity.systemDetail("id", this.watermark + ""); SleevedResource.Setup(bytes); } catch (Exception ex2) { MudgeSanity.logException("auth file parsing", ex2, false); }}
AuthCrypto()中的构造函数生成了RSA/ECB/PKCS1Padding的cpier
故得知authpub.key是rsa加密的
调用了函数A(),A函数中对resources/authkey.pub进行了md5判断,再获取RSA的公钥
加取公钥并验证哈希
往下看到decrypt函数
decrypt()中调用A函数对cobaltstrike.auth文件内容用公钥进行RSA解密赋值给数组var2再用DataParser做转换赋值给var3
将解密好得数据交给dataParser处理了一下
readInt()方法获取var3的前四位进行文件头判断(-889274181为3.x版本;-889274157为4.x版本)赋值给var4。
如果你用了老旧的cobaltstrike.auth版本给新的,就会提示pre-4.0 authorization file. Run update to get new file或者bad header
再从var3中readShort()获取两位作为长度赋值给var5,
再var6 = var3.readBytes(var5)获取该长度内容赋值给var6并返回
在Authorization类中
得到的arrayOfByte2数组是去除前六位之后的内容,继续对arrayOfByte2数组进行处理,先获取四个数字赋值给var6再获取4个数字赋值给watermark再获取一个数字赋值给var7,判断var7小于43,判断i是否等于29999999,在common/ListenerConfig中判断watermark为0时候会增加杀毒检测水印:
去除前6位后,再去除var6、watermark、var7这9位,剩余的为4.0到4.3以来的key,为:16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20结构
byte b2 = dataParser.readByte(); //获取1位,即16byte[] arrayOfByte3 = dataParser.readBytes(b2); //获取16位,为4.0的keybyte b3 = dataParser.readByte(); //获取1位,即16byte[] arrayOfByte4 = dataParser.readBytes(b3); //获取16位,为4.1的keybyte b4 = dataParser.readByte(); //获取1位,即16byte[] arrayOfByte5 = dataParser.readBytes(b4); //获取16位,为4.2的keybyte b5 = dataParser.readByte(); //获取1位,即16byte[] arrayOfByte6 = dataParser.readBytes(b5); //获取16位,为4.3的key赋值给arrayOfByte6
在Authorization类中调用SleevedResource.Setup方法对arrayOfByte6进行处理。在SleevedResource中把key设定为AES、HmacSHA256解密的秘钥,在A中的this.A.decrypt(var3);进行解密调用,解密的内容为/sleeve/中的dll文件:
在SleeveSecurity中设定AES、HmacSHA256解密的秘钥,使用传入的值计算一个长度为256的摘要,再取0-16作为AES的密钥,取16-32作为HmacSHA256的密钥
如果得不到对应的key,就无法对sleeve文件夹中的dll进行解密,连接服务端时候会提示[Sleeve] Bad HMAC的错误提示
所以完成破解的关键部分是对应版本的key
破解方法Javaagent原理:https://www.cnblogs.com/rickiyang/p/11368932.html破解工具可参考:https://github.com/Twi1ight/CSAgent破解的核心还是需要cs对应版本的key
Twi1ight师傅还是进行了很细心的汉化
cobaltstrike.auth:认证密钥文件,rsa加密,解密内容4.3
-54, -2, -64, -45, //文件头0, 77, //后续长度 1, -55, -61, 127, //证书时间限制29999999(永久)0, 0, 0, 1, //watermark(水印)43, //版本16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 16, 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103
每更新一个版本,对应的长度+17,key增加17位:4.4
-54, -2, -64, -45, //文件头0, 94, //后续长度 1, -55, -61, 127, //证书时间限制29999999(永久)0, 0, 0, 1, //watermark(水印)44, //版本16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 16, 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103,16, 94, -104, 25, 74, 1, -58, -76, -113, -91, -126, -90, -87, -4, -69, -110, -42
各版本官方解密key4.0 1be5be52c6255c33558e8a1cb667cb064.1 80e32a742060b884419ba0c171c9aa764.2 b20d487addd4713418f2d5a3ae02a7a04.3 3a4425490f389aeec312bdd758ad2b994.4 5e98194a01c6b48fa582a6a9fcbb92d6
去除暗桩当你二开cs4.4的时候,即使破解了也会启动不起来因为暗桩的存在
beacon/BeaconData中将shouldPad方法的值固定为false:
相比之前的this.shouldPad的exit,cs4.4又在common/Helper增加.class判断,注释即可
在common/Starter中增加.class判断,注释即可:
在common/Starter2中增加.class判断,注释即可:
这时候我们发现改动版的并没有出现不启动的现象
从Hook看破解思路
https://github.com/keven1z/DHook
已知破解CS需要修改common/Authorization中的以下参数:
validto 证书有效期valid 证书有效性watermark 证书是否授权,也是一个CS水印
以及调用common/SleevedResource.Setup传入密钥即可转换一下我们解密key的格式
未破解版本
server 访问端口:8081 server心跳监听端口: 7070
创建我们要hook的应用
点击新增,新增应用(此应用与即将hook的服务器绑定),填写应用名称即可。
以agent的形式启动应用
点击获取agent,自动下载对应应用的agent,将-javaagent:[path]/dHook.jar加入待hook的java应用中启动
如以下Tomcat应用,在catalina.bat中加入set CATALINA_OPTS=”-javaagent:../dHook.jar”,启动Tomcat
agent启动成功会看到如上标志,并且可以在页面看到状态变为1.
添加hook点点击编辑Hook。进入以下页面
点击新增,新增Hook点,界面如下: 参数解释
className
类的全路径,以/分割,示例:com/keven1z/Test
method
方法名,示例:test1
desc
方法描述,示例:(Ljava/lang/String;)Ljava/lang/String;
修改返回值
待修改的返回值
方法执行前
定义所Hook的方法执行前操作,主要为两个操作:1. 静态方法调用 2. 修改当前类中属性值
方法执行后
定义所Hook的方法执行后操作,主要为两个操作:1. 静态方法调用 2. 修改当前类中属性值
classMapagent所捕获的Hook的所有类名
导出配置
将会导出hook点的信息的json文件
导出agent
将会导出包含hook点的agent,该agent不与服务端绑定,去除了多余的api调用,仅作用hook点的修改,体积很小。
首先我们将检验几个参数给”板正”
发现我们可以正常启动了
然后我们再输入解密的key
再导出我们破解的Agent
现在我们就可以正常用CS上线玩耍了