CobaltStrike 4.3 破解及Sleeve相关问题

0x00 前言

此篇文章为了记录在破解CobaltStrike 4.3 中遇到的一些问题及最终解决方式。

破解目标

  • 自行签发auth 文件
  • 对资源解密,方便二次发开
  • 使用官方原版自行破解,更放心

关于Cobalt Strike 4.3 的破解我个人认为可以分为两步,一是Authorization,二是SleevedResource

其中这里坑比较大的是sleeve

0x01 反编译

这里我使用jd-gui Save All Sources 导出反编译后的源码

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3f0c8713-0ea0-4283-a322-92f6d61f6ae3/Untitled.png

新建Idea项目-导入原版cobaltstrike.jar和反编译的源码。结构如下

https://maka8ka.github.io/images/CobaltStrike-2021-0501/Untitled.png

lib中使用原版

Reserve_Cobalt_src中存放反编译源码

破解第三步:

修改文件→项目结构如下

https://maka8ka.github.io/images/CobaltStrike-2021-0501/Untitled%201.png

https://maka8ka.github.io/images/CobaltStrike-2021-0501/Untitled%202.png

修改运行配置

https://maka8ka.github.io/images/CobaltStrike-2021-0501/Untitled%203.png

破解第四步

从反编译源码中获取如下java源文件放入src目录,目录对应好

https://maka8ka.github.io/images/CobaltStrike-2021-0501/Untitled%204.png

(上面的直接抄 maka8ka老哥的作业 ,懒得截图了)

就此,环境算是搭建好了,我们现在来修改几个认证的地方和暗桩

0x02 破解认证

  1. 修改 src/common/AuthCrypto.java 中对公钥md5的验证

1.png

这里我把"!"删掉了,跳出如果公钥md5不匹配,退出的问题(后期生成自己的RSA不用在算公钥的md5了)

  1. 修改src/common/Authorization.java 验证

2.png

watchmark 改为1 vaild 改为true

3.修改 src/beacon/BeaconData.java 修复自动退出beacon的问题

3.png

到这里 Authorization 基本已经搞完了,我们来生成自己的RSA并替换公钥

0x03 生成RSA及Sleeve解密

如果这里我们用maka8ka老哥提供的脚本,欸,你就会发现,CS gui 可以正常运行,Teamserver 可以正常运行,但是一连接,欸,就不行了。

Untitled.png

根据TeamServer 报错[Sleeve] Bad HMAC on 208928 byte message from resource 这里查了一下,就是在解密SleevedResource的时候,密钥错误,导致dll文件无法正常解密,所以报错了,解密Sleeve的Key 存在于CobaltStrike.auth 文件中,具体的文件组成可以参考rcoil.me 大佬的文章

将 .auth 文件读取成 byte[],处理之后得出 26 位的 byte[],将其拆分为:

4位 -> 经过有符号转换 int,结果为29999999 -> 用于判断是否永久有效(是否为发行版)
4位 -> 经过有符号转换 int,结果不为 0 即可 -> 水印
1位 -> 该 byte 值必须是大于 40 且小于 128 -> 判断认证是否适合 4.x
1位 -> 该 byte 值必须是 16 -> key 的长度
16位 -> 该 key 理论上无法逆推

要注意的是:处理 .auth 文件的时候,还需要判断文件头...,因此还需要填充文件头,但按照分析下来,是 4 个字节,但在实测过程中,发现是 6 个字节
因此 .auth 文件的必要数据是 32 位 -> 6 + 4 + 4 + 1 + 1 + 16

所以说,我们如果要解密dll的话,需要一个正版auth文件,并解密出Sleeve 解密的byte data

这里,我在Authorization 第77行 SleevedResource.Setup(arrayOfByte6); 下一个断点,开启IDEA debug

4.png

这里的话,就解析到一个bytes[] 来解密dll,下面我给大家提供一个按照大佬脚本修改好后的,CobaltStrike 4.3 RSA Key 生成的脚本

package KeyGen;

import common.CommonUtils;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.security.*;
import java.util.Base64;

public class RSAKeyPairGenerator {
    private PrivateKey privateKey;
    private PublicKey publicKey;

    public RSAKeyPairGenerator() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair pair = keyGen.generateKeyPair();
        this.privateKey = pair.getPrivate();
        this.publicKey = pair.getPublic();
    }

    // 将byte 写入文件
    public void byte2File(String path, byte[] data) throws IOException {
        File f = new File(path);
        f.getParentFile().mkdirs();

        FileOutputStream fos = new FileOutputStream(f);
        fos.write(data);
        fos.flush();
        fos.close();
    }

    public PrivateKey getPrivateKey() {
        return privateKey;
    }

    public PublicKey getPublicKey() {
        return publicKey;
    }

    // 加密数据
    public byte[] encryptPri(byte[] data, PrivateKey privateKey) throws BadPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, this.privateKey);
        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, IOException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, BadPaddingException {
        RSAKeyPairGenerator PairGenerator = new RSAKeyPairGenerator();
        //byte[] data = {-54, -2, -64, -45, 0, 77, 1, -55, -61, 127, 0, 0, 0, 1, 43, 16, 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103 };
        byte[] data ={-54, -2, -64, -45, 0, 77, 1, -55, -61, 127, 0, 0, 0, 1, 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};
        byte[] rsaByte = PairGenerator.encryptPri(data, PairGenerator.getPrivateKey());
        PairGenerator.byte2File("RSA/cobaltstrike.auth", rsaByte);
        PairGenerator.byte2File("RSA/authkey.private", PairGenerator.getPrivateKey().getEncoded());
        PairGenerator.byte2File("RSA/authkey.pub", PairGenerator.getPublicKey().getEncoded());
    }
}

其中,byte类型的 data 比较重要,这关系到后续CS能否正常运行,以上想法可能存在错误,欢迎各位师傅指正

本文链接:

https://f4x.me/archives/50.html
1 + 9 =
4 评论
    HelenChrome 92Windows 10
    2021年08月13日 回复

    都1202年了还用CS?

      杨如画Chrome 92Windows 10
      2021年08月14日 回复

      @Helen 八嘎

    粉丝Chrome 92Windows 7
    2021年10月06日 回复

    这个生成代码怎么编译 编译报错那

    CobaltStrike 4.3 RSA Key 生成的脚本

      杨如画Chrome 94OSX
      2021年10月16日 回复

      @粉丝 如果报的是程序包common不存在 ,把最开始那个引用注释掉就好