cobaltstrike4.4_cdf
2022-4-12 13:47:37 Author: github.com(查看原文) 阅读量:886 收藏

cobaltstrike4.4\4.3版本破解、去除checksum8特征、bypass BeaconEye、修复错误路径泄漏stage、增加totp双因子验证

此工具以及文章内容仅限于安全研究,用户承担因使用此工具以及文章内容而导致的所有法律和相关责任!作者不承担任何法律责任! 如您在使用本工具以及文章内容的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任,否则,请您不要安装并使用本工具。您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。在使用本工具进行安全研究时,您应确保该行为符合法律法规,并且已经取得了足够的授权。请勿对非授权目标使用该工具。

请认真核对相应版本jar包hash:

image-20220330150032475

image-20220330150148108

证书认证流程(4.3为例)

各个版本的官方解密key:

4.0 1be5be52c6255c33558e8a1cb667cb06
4.1 80e32a742060b884419ba0c171c9aa76
4.2 b20d487addd4713418f2d5a3ae02a7a0
4.3 3a4425490f389aeec312bdd758ad2b99
4.4 5e98194a01c6b48fa582a6a9fcbb92d6

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位。

aggressor/Aggressor.class中License.checkLicenseGUI(new Authorization());开始license认证:

image-20211101142121856

License.checkLicenseGUIisValidisPerpetualisExpiredisAlmostExpired对授权是否有效、授权是否过期进行判断:

image-20211101142738431

Authorization类中是cobaltstrike.auth文件的处理,读取文件内容,调用AuthCrypto().decrypt对内容进行处理:

image-20211101143829398

AuthCrypto()中构造函数中调用load(),load()函数中对resources/authkey.pub进行md5判断,再获取了RSA的公钥:

image-20211101144809625

decrypt()中调用_decrypt对cobaltstrike.auth文件内容用公钥进行RSA解密赋值给数组var2,再用DataParser做转换赋值给var3,readInt()方法获取var3的前四位进行文件头判断(-889274181为3.x版本;-889274157为4.x版本)。再从var3中readShort()获取两位作为长度赋值给var5,再var6 = var3.readBytes(var5)获取该长度内容赋值给var6并返回:

image-20211101145153818

Authorization类中得到的arrayOfByte2数组是去除前六位之后的内容,继续对arrayOfByte2数组进行处理,先获取四个数字赋值给i,再获取4个数字赋值给watermark,再获取一个数字赋值给b1,判断b1小于43,判断i是否等于29999999,在common/ListenerConfig中判断watermark为0时候会增加杀毒检测水印:

image-20211101152338045

image-20211101152000407

去除前6位后,再去除i、watermark、b1这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位,即16
            byte[] arrayOfByte3 = dataParser.readBytes(b2);		//获取16位,为4.0的key
            byte b3 = dataParser.readByte();	//获取1位,即16
            byte[] arrayOfByte4 = dataParser.readBytes(b3);		//获取16位,为4.1的key
            byte b4 = dataParser.readByte();	//获取1位,即16
            byte[] arrayOfByte5 = dataParser.readBytes(b4);		//获取16位,为4.2的key
            byte b5 = dataParser.readByte();	//获取1位,即16
            byte[] arrayOfByte6 = dataParser.readBytes(b5);		//获取16位,为4.3的key赋值给arrayOfByte6

在Authorization类中调用SleevedResource.Setup方法对arrayOfByte6进行处理。在SleevedResource中把key设定为AES、HmacSHA256解密的秘钥,在_readResource中的this.data.decrypt(arrayOfByte1);进行解密调用,解密的内容为/sleeve/中的dll文件:

image-20211101153935202

在SleeveSecurity中设定AES、HmacSHA256解密的秘钥,使用传入的值计算一个长度为256的摘要,再取0-16作为AES的密钥,取16-32作为HmacSHA256的密钥

image-20211101154127243

如果得不到对应的key,就无法对sleeve文件夹中的dll进行解密,连接服务端时候会提示[Sleeve] Bad HMAC的错误提示:

image-20211101160942103

hmac解密部分可参考:Cobaltstrike 4破解之 我自己给我自己颁发license

所以完成破解的关键是对应cs版本的key。

破解方式

方法一硬编码key

对AuthCrypto().decrypt进行RSA解密后赋值的参数写死:

image-20211101164639914

中间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);
        }
    }

方法二自己生成证书

生成代码可参考:https://xz.aliyun.com/t/8557#toc-4

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

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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
                16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
                16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
                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());
    }
}

将生成的authkey.pub放入src/resources/,将生成的cobaltstrike.auth放到打包好的jar包同目录,修改common/AuthCrypto.load()函数中md5数为authkey.pub的值:

image-20211101180149632

Javaagent方式

Javaagent原理:https://www.cnblogs.com/rickiyang/p/11368932.html

破解工具可参考:https://github.com/Twi1ight/CSAgent

破解的核心还是需要cs对应版本的key

去除暗桩

beacon/BeaconData中将shouldPad方法的值固定为false:

image-20211101180447451

4.4新暗桩

(之前以4.3为例进行License认证分析,换成4.4后发现运行退出,存在新的暗桩)

相比之前的this.shouldPad的exit,又在common/Helper增加.class判断,注释即可:

image-20211119153406737

在common/Starter中增加.class判断,注释即可:

image-20211119153558224

在common/Starter2中增加.class判断,注释即可:

image-20211119153636952

去掉这三处又可以团体运动了。

checksum8特征就不细说了,为了避免被nmap和空间搜索引擎扫描出来还是有必要改改的。

代码修改

BeaconPayload中修改异或数值为新:

随便一个10进制数字即可,后面dll中改成对应的16进制数字。

image-20211108114054512

dll修改

使用CrackSleeve把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) # windows命令行执行

Alt+T进行关键字搜索:2Eh

image-20211107222017434

image-20211107222039265

直接修改xor的值,先Change byte找到2E修改,再Apply pathes to input file保存。(别忘记保存)

image-20211107222223636

需要修改的dll:beacon.dll、beacon.x64.dll、dnsb.dll、dnsb.x64.dll、pivot.dll、pivot.x64.dll、extc2.dll、extc2.x64.dll

再CrackSleeve加密dll,最后,把encode目录下的dll,放到idea项目目录中重新编译打包。

进行测试uri地址虽说仍旧可以请求到,但内容已经无法用nmap脚本解密出来,同理也可躲避空间搜索引擎的识别:

image-20211107233719344

除了修改异或值的方式,也可以https://mp.weixin.qq.com/s?__biz=MzA3MDY2NjMxMA==&mid=2247484641&idx=1&sn=014f6c4ad5343e3f5034c33dffa66f26&chksm=9f3815c8a84f9cde1c7493ff29cfc89c0474fec48ede52be618727e7b9a5ab321c4743e1a44c&mpshare=1&scene=23&srcid=1202NA46yt71CvD3BMGKS10c&sharer_sharetime=1606892728447&sharer_shareid=ff83fe2fe7db7fcd8a1fcbc183d841c4#rd 改掉checksum8算法,但是只能固定uri访问了,需要配合profile才能使用,而且每次改uri还要重新打包,方法各有利弊吧。

去beaconeye特征修改思路来源于https://www.t00ls.cc/articles-63215.html,以4.3和4.4为例需要进行修改的字节如下。

使用CrackSleeve把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) # windows命令行执行

4.3 key 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103 4.4 key 94, -104, 25, 74, 1, -58, -76, -113, -91, -126, -90, -87, -4, -69, -110, -42

4.3修改

32位dll

地址位:10009FBB

6A 00 修改为6A 09(00修改为任意)

image-20211111165257545

64位dll

地址位:000000001800186C3

beacon.x64.dll里面的指令是xor edx, edx,修改为mov edx, esi

image-20211111165321033

4.4修改

32位dll

地址位:1000A0B9

6A 00 修改为6A 09(00修改为任意)

image-20211112104322791

64位dll

地址位:000000018001879B

beacon.x64.dll里面的指令是xor edx, edx,修改为mov edx, esi

image-20211112105408975

使用重新加密:java -classpath cobaltstrike.jar;./ CrackSleeve encode

image-20211111173148579

image-20211112124415835

源头:https://mp.weixin.qq.com/s?__biz=Mzg2NjQ2NzU3Ng==&mid=2247489846&idx=1&sn=181c223cab4bce4e06def94604166348&chksm=ce4b32a1f93cbbb70e63e589d0da6323a8d2d4539c8aa0ef57d4005976dda6d73caeddebcac3&mpshare=1&scene=1&srcid=0308x6zXAxyDR8lv27V2O9yn&sharer_sharetime=1647358883801&sharer_shareid=15e69d4f532774f3e596a31efa4ef72b#rd

image-20220330111308258

方法就是对uri加个/判断就可以了,不是/开头就响应到404:

4.4修改

image-20220330111413985

4.3修改

image-20220330125957143

为了避免在Event Log中泄漏totp密码或者登录cs的名称,对name字段进行md5加盐显示,修改后如下:

image-20220330112745362

增加了TOTP双因素验证,加强登录,防止爆破密码被掏。

teamserver端,teamserver输出中增加了个totp二维码链接:

image-20220407112543322

(删除nohup.out前记得复制出来QR code,每次启动teamserver会生成新的QR code所以每次启动teamserver都需要重新扫码)

浏览器打开(需翻墙)用谷歌Authenticator或者TOTP 验证器扫二维码,或者复制出secret%3D后的密钥,配置到验证器中也可:

image-20220407112054716

connect端,host、port、password和以前依旧,user中,后六位为totp的动态数字即可连接:

image-20220407111813265

没有填写或填写错误totp动态数字会提示:

image-20220407113709140

注:某些时候没手机,可以用浏览器的totp功能的插件或者python简单弄个totp代码即可。


文章来源: https://github.com/y35uishere/cobaltstrike4.4_cdf
如有侵权请联系:admin#unsafe.sh