CobaltStrike4.7 license验证分析

之前群里发了一个CobaltStrike4.7过期的auth,用的话需要把时间改一下才可以用。就想着分析一下CobaltStrike的验证方法,能不能绕过时间限制。

对于CobaltStrike的client来说,其jar包是没有混淆的,直接解出来就能看代码,下面从client入手分析分析看CobaltStrike是如何验证auth的。

分析:

直接使用过期auth执行会提示license is expired。

对java调试也不太懂,但是既然没混淆,直接用jadx打开搜字符串即可。

GUI和Console的验证从代码实现上来说应该都是用一样的方法,所以只需要重点关注一个即可。

点进去后发现代码的执行流程是:

1.读取cobaltstrike.auth文件

2.然后对文件内容进行decrypt

  • 2.1decrypt里有一个RSA生成公钥的操作,读取了资源文件夹里的authkey.pub文件并通过md5校验文件
  • 2.2然后对auth文件的byte[]进行一些操作

A是cipher,init可能是初始化某种方法,参数2是上面生成的publickey,那么猜测这里可能是加密或者解密相关的操作,对java不熟,看了一下JDK的文档发现init的第一个参数是操作模式

对应模式的值如下,这里的值为2,猜测应该是DECRYPT_MODE

  • 2.3 对解密出来的数据进行判断,首先判断int大小的字节是否是-889274181或-889274157

分别对应的十六进制为CAFEC0BB和CAFEC0D3,相当于对auth的头部进行了判断,然后读一个Short后返回

  • 2.4 接着读两个Int,第一个Int在下面有一个判断,如果是29999999的话,validto=forever,猜测可能是时间校验,并且时间可以是永久有效。第二个Int从变量名watermark上可以看出来是水印,通常是为了追溯购买用户用的。
  • 2.5 然后读取一个Byte,并判断是否<47,根据下面的错误信息来看这里是版本号判断。
  • 2.6 然后读取一个byte,并跳过读取到的字节数,该操作有六次
  • 2.7 然后读取一个Int,值用来做循环的范围,返回的字符串变量为watermarkHash,猜测是用来验证水印hash的,所以水印的值不能随便改。
  • 2.8 继续两个字节数读取跳过
  • 2.9 读取一个byte,然后获取到一个字节数组,该字节数组用作SleevedResource.Setup

到这里大致的流程都知道了,拿过期的auth解密来对照的看一看。

解密后的HEX如下:

cafec0d300ca00035e9f175065ea2f101be5be52c6255c33558e8a1cb667cb061080e32a742060b884419ba0c171c9aa7610b20d487addd4713418f2d5a3ae02a7a0103a4425490f389aeec312bdd758ad2b99105e98194a01c6b48fa582a6a9fcbb92d610f38eb3d1a335b252b58bc2acde81b542000000186964767955614d444b7562575734544c3369506a42773d3d10b9aa33080a5a90313ef19dc0627d2ea11c7335396c35697131656a5a334f51642f7367764e61673d3d7190d668108638b511e05b557bf970c418356d44f4

按照上面分析的字段来拆解

cafec0d3    auth头
00ca        读取一个short返回,0xca = 202 这个刚好是解密后字节序列的大小
00035e9f    = 220831 看样子这个就是时间了
175065ea    = 391144938 水印
2f          = 47 版本号
六次读取byte并跳过的操作,0x10 = 16 
10
1be5be52c6255c33558e8a1cb667cb06
10
80e32a742060b884419ba0c171c9aa76
10
b20d487addd4713418f2d5a3ae02a7a0
10
3a4425490f389aeec312bdd758ad2b99
10
5e98194a01c6b48fa582a6a9fcbb92d6
10
f38eb3d1a335b252b58bc2acde81b542
00000018    = 24 用作水印hash的循环
6964767955614d444b7562575734544c3369506a42773d3d    水印hash
下面又有两次的读取byte并跳过
10
b9aa33080a5a90313ef19dc0627d2ea1
1c
7335396c35697131656a5a334f51642f7367764e61673d3d7190d668
读取byte,获取的值读取bytes用作SleevedResource.Setup
10
8638b511e05b557bf970c418356d44f4

不过auth是RSA生成的,我们只有公钥没有私钥,所以只能了解auth的结构是什么,并没有办法自己伪造。

Client绕过:

对于绕过来说,一种方法是暴力破解,即修改java的字节码将验证跳转流程改为不验证直接跳转然后替换回去,再找到各种验证文件完整性的地方修改CRC验证即可,但是CobaltStrike做文件校验的地方非常多,所以这种方法需要修改很多地方,非常麻烦。

另一种方法即是下面使用的方法,通过替换加解密的密钥,让CobaltStrike加载通过我们自己公私钥生成的auth文件。

通过上面的分析我们知道,auth的时间是可以无限有效的,下面是我们将要伪造的auth文件,主要就是将validto改成29999999

CAFEC0D3
00CA
01C9C37F = 29999999
175065EA
2F
10
1BE5BE52C6255C33558E8A1CB667CB06
10
80E32A742060B884419BA0C171C9AA76
10
B20D487ADDD4713418F2D5A3AE02A7A0
10
3A4425490F389AEEC312BDD758AD2B99
10
5E98194A01C6B48FA582A6A9FCBB92D6
10
F38EB3D1A335B252B58BC2ACDE81B542
00000018
6964767955614D444B7562575734544C3369506A42773D3D
10
B9AA33080A5A90313EF19DC0627D2EA1
1C
7335396C35697131656A5A334F51642F7367764E61673D3D7190D668
10
8638B511E05B557BF970C418356D44F4

然后使用java生成公私密钥对

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair pair = keyGen.generateKeyPair();
        this.privateKey = pair.getPrivate();
        this.publicKey = pair.getPublic();
        //生成的密钥对写入文件
        PairGenerator.WriteFile("MyAuthkey.private", PairGenerator.getPrivateKey().getEncoded());
        PairGenerator.WriteFile("MyAuthkey.pub", PairGenerator.getPublicKey().getEncoded());
        //然后对我们伪造的auth文件进行加密
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, this.privateKey);
        cipher.doFinal(data);

因为client中的authkey.pub有hash校验,所以我们使用修改类加载的方法(这里图省事使用的是老外的代码)

public class Hook {
    public static void premain(String str, Instrumentation instrumentation) {
        System.out.println("Hook starting...");
        instrumentation.addTransformer(new Transformer());
    }
}

public class Transformer implements ClassFileTransformer {
    public byte[] transform(ClassLoader classLoader, String str, Class cls, ProtectionDomain protectionDomain, byte[] bArr) throws IllegalClassFormatException {
        if (str.equals("sun/management/VMManagementImpl")) {
            System.out.println("Applying Patch #1");
            bArr = Base64.getDecoder().decode("yv66vgAAADQBFQEAH3N1bi9tYW5hZ2VtZW50L1ZNTWFuYWdlbWVudEltcGwHAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAbc3VuL21hbmFnZW1lbnQvVk1NYW5hZ2VtZW50BwAFAQAGPGluaXQ+AQADKClWAQAEQ29kZQwABwAICgAEAAoBAAZ2bUFyZ3MBABBMamF2YS91dGlsL0xpc3Q7DAAMAA0JAAIADgEACXBlcmZJbnN0cgEAMUxzdW4vbWFuYWdlbWVudC9jb3VudGVyL3BlcmYvUGVyZkluc3RydW1lbnRhdGlvbjsMABAAEQkAAgASAQAKbm9QZXJmRGF0YQEAAVoMABQAFQkAAgAWAQALZ2V0VmVyc2lvbjABABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEAGWluaXRPcHRpb25hbFN1cHBvcnRGaWVsZHMBACRpc0NvbXBpbGF0aW9uVGltZU1vbml0b3JpbmdTdXBwb3J0ZWQBAAMoKVoBABljb21wVGltZU1vbml0b3JpbmdTdXBwb3J0DAAdABUJAAIAHgEAJWlzVGhyZWFkQ29udGVudGlvbk1vbml0b3JpbmdTdXBwb3J0ZWQBACF0aHJlYWRDb250ZW50aW9uTW9uaXRvcmluZ1N1cHBvcnQMACEAFQkAAgAiAQAfaXNDdXJyZW50VGhyZWFkQ3B1VGltZVN1cHBvcnRlZAEAG2N1cnJlbnRUaHJlYWRDcHVUaW1lU3VwcG9ydAwAJQAVCQACACYBAB1pc090aGVyVGhyZWFkQ3B1VGltZVN1cHBvcnRlZAEAGW90aGVyVGhyZWFkQ3B1VGltZVN1cHBvcnQMACkAFQkAAgAqAQAYaXNCb290Q2xhc3NQYXRoU3VwcG9ydGVkAQAUYm9vdENsYXNzUGF0aFN1cHBvcnQMAC0AFQkAAgAuAQAdaXNPYmplY3RNb25pdG9yVXNhZ2VTdXBwb3J0ZWQBABlvYmplY3RNb25pdG9yVXNhZ2VTdXBwb3J0DAAxABUJAAIAMgEAHGlzU3luY2hyb25pemVyVXNhZ2VTdXBwb3J0ZWQBABhzeW5jaHJvbml6ZXJVc2FnZVN1cHBvcnQMADUAFQkAAgA2AQAgaXNUaHJlYWRBbGxvY2F0ZWRNZW1vcnlTdXBwb3J0ZWQBABx0aHJlYWRBbGxvY2F0ZWRNZW1vcnlTdXBwb3J0DAA5ABUJAAIAOgEAGWlzR2NOb3RpZmljYXRpb25TdXBwb3J0ZWQBABVnY05vdGlmaWNhdGlvblN1cHBvcnQMAD0AFQkAAgA+AQAjaXNSZW1vdGVEaWFnbm9zdGljQ29tbWFuZHNTdXBwb3J0ZWQBAB9yZW1vdGVEaWFnbm9zdGljQ29tbWFuZHNTdXBwb3J0DABBABUJAAIAQgEAI2lzVGhyZWFkQ29udGVudGlvbk1vbml0b3JpbmdFbmFibGVkAQAWaXNUaHJlYWRDcHVUaW1lRW5hYmxlZAEAHmlzVGhyZWFkQWxsb2NhdGVkTWVtb3J5RW5hYmxlZAEAE2dldExvYWRlZENsYXNzQ291bnQBAAMoKUkBABJnZXRUb3RhbENsYXNzQ291bnQBAAMoKUoMAEkASgoAAgBLAQAVZ2V0VW5sb2FkZWRDbGFzc0NvdW50DABNAEoKAAIATgEAD2dldFZlcmJvc2VDbGFzcwEADGdldFZlcmJvc2VHQwEAFGdldE1hbmFnZW1lbnRWZXJzaW9uAQAHdmVyc2lvbgEAEkxqYXZhL2xhbmcvU3RyaW5nOwwAUwBUCQACAFUBAAdnZXRWbUlkAQAdamF2YS9uZXQvVW5rbm93bkhvc3RFeGNlcHRpb24HAFgBABBqYXZhL2xhbmcvU3RyaW5nBwBaAQANU3RhY2tNYXBUYWJsZQEADGdldFByb2Nlc3NJZAwAXQBICgACAF4BAAlsb2NhbGhvc3QIAGABABRqYXZhL25ldC9JbmV0QWRkcmVzcwcAYgEADGdldExvY2FsSG9zdAEAGCgpTGphdmEvbmV0L0luZXRBZGRyZXNzOwwAZABlCgBjAGYBAAtnZXRIb3N0TmFtZQwAaAAZCgBjAGkBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgcAawoAbAAKAQAGYXBwZW5kAQAcKEkpTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwwAbgBvCgBsAHABAAFACAByAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7DABuAHQKAGwAdQEACHRvU3RyaW5nDAB3ABkKAGwAeAEACWdldFZtTmFtZQEADGphdmEudm0ubmFtZQgAewEAEGphdmEvbGFuZy9TeXN0ZW0HAH0BAAtnZXRQcm9wZXJ0eQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7DAB/AIAKAH4AgQEAC2dldFZtVmVuZG9yAQAOamF2YS52bS52ZW5kb3IIAIQBAAxnZXRWbVZlcnNpb24BAA9qYXZhLnZtLnZlcnNpb24IAIcBAA1nZXRWbVNwZWNOYW1lAQAaamF2YS52bS5zcGVjaWZpY2F0aW9uLm5hbWUIAIoBAA9nZXRWbVNwZWNWZW5kb3IBABxqYXZhLnZtLnNwZWNpZmljYXRpb24udmVuZG9yCACNAQAQZ2V0Vm1TcGVjVmVyc2lvbgEAHWphdmEudm0uc3BlY2lmaWNhdGlvbi52ZXJzaW9uCACQAQAMZ2V0Q2xhc3NQYXRoAQAPamF2YS5jbGFzcy5wYXRoCACTAQAOZ2V0TGlicmFyeVBhdGgBABFqYXZhLmxpYnJhcnkucGF0aAgAlgEAEGdldEJvb3RDbGFzc1BhdGgBACVzdW4vc2VjdXJpdHkvYWN0aW9uL0dldFByb3BlcnR5QWN0aW9uBwCZAQATc3VuLmJvb3QuY2xhc3MucGF0aAgAmwEAFShMamF2YS9sYW5nL1N0cmluZzspVgwABwCdCgCaAJ4BAB5qYXZhL3NlY3VyaXR5L0FjY2Vzc0NvbnRyb2xsZXIHAKABAAxkb1ByaXZpbGVnZWQBADQoTGphdmEvc2VjdXJpdHkvUHJpdmlsZWdlZEFjdGlvbjspTGphdmEvbGFuZy9PYmplY3Q7DACiAKMKAKEApAEACWdldFVwdGltZQEACmdldFVwdGltZTAMAKcASgoAAgCoAQAOZ2V0Vm1Bcmd1bWVudHMBABIoKUxqYXZhL3V0aWwvTGlzdDsBAAlTaWduYXR1cmUBACYoKUxqYXZhL3V0aWwvTGlzdDxMamF2YS9sYW5nL1N0cmluZzs+OwEAE2phdmEvdXRpbC9BcnJheUxpc3QHAK4KAK8ACgEAEy1YWDorQWdncmVzc2l2ZUhlYXAIALEBAA5qYXZhL3V0aWwvTGlzdAcAswEAA2FkZAEAFShMamF2YS9sYW5nL09iamVjdDspWgwAtQC2CwC0ALcBABItWFg6K1VzZVBhcmFsbGVsR0MIALkBAA9nZXRWbUFyZ3VtZW50czABABUoKVtMamF2YS9sYW5nL1N0cmluZzsBAA5nZXRTdGFydHVwVGltZQEAFmdldEF2YWlsYWJsZVByb2Nlc3NvcnMBAA9nZXRDb21waWxlck5hbWUBACFzdW4vbWFuYWdlbWVudC9WTU1hbmFnZW1lbnRJbXBsJDEHAMABACQoTHN1bi9tYW5hZ2VtZW50L1ZNTWFuYWdlbWVudEltcGw7KVYMAAcAwgoAwQDDAQATZ2V0VG90YWxDb21waWxlVGltZQEAE2dldFRvdGFsVGhyZWFkQ291bnQBABJnZXRMaXZlVGhyZWFkQ291bnQBABJnZXRQZWFrVGhyZWFkQ291bnQBABRnZXREYWVtb25UaHJlYWRDb3VudAEACWdldE9zTmFtZQEAB29zLm5hbWUIAMsBAAlnZXRPc0FyY2gBAAdvcy5hcmNoCADOAQAMZ2V0T3NWZXJzaW9uAQAKb3MudmVyc2lvbggA0QEAEWdldFNhZmVwb2ludENvdW50AQAVZ2V0VG90YWxTYWZlcG9pbnRUaW1lAQAUZ2V0U2FmZXBvaW50U3luY1RpbWUBACFnZXRUb3RhbEFwcGxpY2F0aW9uTm9uU3RvcHBlZFRpbWUBABJnZXRMb2FkZWRDbGFzc1NpemUBABRnZXRVbmxvYWRlZENsYXNzU2l6ZQEAE2dldENsYXNzTG9hZGluZ1RpbWUBABFnZXRNZXRob2REYXRhU2l6ZQEAGGdldEluaXRpYWxpemVkQ2xhc3NDb3VudAEAGmdldENsYXNzSW5pdGlhbGl6YXRpb25UaW1lAQAYZ2V0Q2xhc3NWZXJpZmljYXRpb25UaW1lAQAWZ2V0UGVyZkluc3RydW1lbnRhdGlvbgEAMygpTHN1bi9tYW5hZ2VtZW50L2NvdW50ZXIvcGVyZi9QZXJmSW5zdHJ1bWVudGF0aW9uOwEAImphdmEvbGFuZy9JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24HAOABABNqYXZhL2lvL0lPRXhjZXB0aW9uBwDiAQANc3VuL21pc2MvUGVyZgcA5AEAE2phdmEvbmlvL0J5dGVCdWZmZXIHAOYBABtzdW4vbWlzYy9QZXJmJEdldFBlcmZBY3Rpb24HAOgKAOkACgEAAXIIAOsBAAZhdHRhY2gBACooSUxqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9u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");
        }
        if (str.equals("common/AuthCrypto")) {
            System.out.println("Applying Patch #2");
            bArr = Base64.getDecoder().decode("yv66vgAAADQApAoALwBHCQAuAEgJAC4ASQgASgoASwBMCQAuAE0KAC4ATgcATwgAUAgAUQoAUgBTBwBUCgBVAFYIAFcKAFgAWQoADABaCgAMAFsIAFwIAF0KAAwAXgoAXwBgCABhCgAMAGIKAGMAZAcAZQoAGQBmCABnCgBoAGkKAGgAaggAawgAbAoALgBtBwBuCgAhAGYKACEAbwoAIQBwA8r+wLsIAHEDyv7A0wgAcgoAIQBzCgAhAHQKAAgAdQoASwB2CgBLAHcHAHgHAHkBAAFBAQAVTGphdmF4L2NyeXB0by9DaXBoZXI7AQABQwEAE0xqYXZhL3NlY3VyaXR5L0tleTsBAAFCAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEADVN0YWNrTWFwVGFibGUHAHgHAE8HAHoBAAVlcnJvcgEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHZGVjcnlwdAEABihbQilbQgcAbgcAeQcAewEAClNvdXJjZUZpbGUBAA9BdXRoQ3J5cHRvLmphdmEMADYANwwAMgAzDAA0ADUBABRSU0EvRUNCL1BLQ1MxUGFkZGluZwcAfAwAfQB+DAAwADEMADAANwEAE2phdmEvbGFuZy9FeGNlcHRpb24BABtDb3VsZCBub3QgaW5pdGlhbGl6ZSBjcnlwdG8BAA9BdXRoQ3J5cHRvIGluaXQHAH8MAIAAgQEAEmNvbW1vbi9Db21tb25VdGlscwcAggwAgwCEAQAVcmVzb3VyY2VzL2F1dGhrZXkucHViBwCFDACGAIcMAIgAiQwAigBBAQATcmVzb3VyY2VzL3VDYXJlLnB1YgEAIDhiYjRkZjAwYzEyMDg4MWExOTQ1YTQzZTJiYjIzNzllDACLAIwHAI0MAI4AjwEAGkludmFsaWQgYXV0aG9yaXphdGlvbiBmaWxlDACQAJEHAJIMAJMAlAEAJWphdmEvc2VjdXJpdHkvc3BlYy9YNTA5RW5jb2RlZEtleVNwZWMMADYAlQEAA1JTQQcAlgwAfQCXDACYAJkBACFDb3VsZCBub3QgZGVzZXJpYWxpemUgYXV0aHB1Yi5rZXkBABthdXRocHViLmtleSBkZXNlcmlhbGl6YXRpb24MADAAQQEAEWNvbW1vbi9EYXRhUGFyc2VyDACaADcMAJsAnAEANnByZS00LjAgYXV0aG9yaXphdGlvbiBmaWxlLiBSdW4gdXBkYXRlIHRvIGdldCBuZXcgZmlsZQEACmJhZCBoZWFkZXIMAJ0AnAwAngCfDACgAD8MAKEAogwAowBBAQARY29tbW9uL0F1dGhDcnlwdG8BABBqYXZhL2xhbmcvT2JqZWN0AQACW0IBABNqYXZhL2xhbmcvVGhyb3dhYmxlAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBABJjb21tb24vTXVkZ2VTYW5pdHkBAAxsb2dFeGNlcHRpb24BACsoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9UaHJvd2FibGU7WilWAQAPamF2YS9sYW5nL0NsYXNzAQAOZ2V0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyAQATZ2V0UmVzb3VyY2VBc1N0cmVhbQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvaW8vSW5wdXRTdHJlYW07AQAHcmVhZEFsbAEAGShMamF2YS9pby9JbnB1dFN0cmVhbTspW0IBAANNRDUBAAV0b0hleAEAFihbQilMamF2YS9sYW5nL1N0cmluZzsBABBqYXZhL2xhbmcvU3RyaW5nAQAGZXF1YWxzAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQALcHJpbnRfZXJyb3IBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABBqYXZhL2xhbmcvU3lzdGVtAQAEZXhpdAEABChJKVYBAAUoW0IpVgEAGGphdmEvc2VjdXJpdHkvS2V5RmFjdG9yeQEALihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvc2VjdXJpdHkvS2V5RmFjdG9yeTsBAA5nZW5lcmF0ZVB1YmxpYwEANyhMamF2YS9zZWN1cml0eS9zcGVjL0tleVNwZWM7KUxqYXZhL3NlY3VyaXR5L1B1YmxpY0tleTsBAANiaWcBAAdyZWFkSW50AQADKClJAQAJcmVhZFNob3J0AQAJcmVhZEJ5dGVzAQAFKEkpW0IBAApnZXRNZXNzYWdlAQAEaW5pdAEAFyhJTGphdmEvc2VjdXJpdHkvS2V5OylWAQAHZG9GaW5hbAAxAC4ALwAAAAMAAgAwADEAAAACADIAMwAAAAIANAA1AAAABQABADYANwABADgAAACHAAMAAgAAAC0qtwABKgG1AAIqAbUAAyoSBLgABbUABiq3AAenABFMKhIJtQADEgorA7gAC7EAAQAOABsAHgAIAAIAOQAAACoACgAAABAABAAMAAkADgAOABIAFwATABsAFwAeABQAHwAVACUAFgAsABgAOgAAABAAAv8AHgABBwA7AAEHADwNAAIAMAA3AAEAOAAAANUAAwAFAAAAYhIMtgANEg62AA+4ABBMK7gAEU0SDLYADRIStgAPuAAQTBITLLgAFLYAFZoADBIWuAAXA7gAGLsAGVkrtwAaThIbuAAcOgQqGQQttgAdtQACpwARTCoSHrUAAxIfKwO4AAuxAAEAAABQAFMACAACADkAAAA6AA4AAAAcAA4AHQATAB8AIQAiAC0AIwAyACQANgAmAD8AJwBGACgAUAAsAFMAKQBUACoAWgArAGEALQA6AAAAGQAD/QA2BwA9BwA9/wAcAAEHADsAAQcAPA0AAQA+AD8AAQA4AAAAHQABAAEAAAAFKrQAA7AAAAABADkAAAAGAAEAAAAwAAQAQABBAAEAOAAAAP0AAwAGAAAAXCortwAgTSy+mgAFLLC7ACFZLLcAIk4ttgAjLbYAJDYEFQQSJaAADSoSJrUAAwO8CLAVBBInnwANKhIotQADA7wIsC22ACk2BS0VBbYAKrBOKi22ACu1AAMDvAiwAAQABgAMAE8ACAANADAATwAIADEAQQBPAAgAQgBOAE8ACAACADkAAABGABEAAAA0AAYANgALADcADQA4ABYAOQAaADoAIAA7ACcAPAAtAD0AMQA/ADgAQAA+AEEAQgBDAEgARABPAEUAUABGAFgARwA6AAAAIwAE/AANBwA9/QAjBwBCARD/AAwAAwcAOwcAPQcAPQABBwA8AAIAMABBAAEAOAAAANEAAwAFAAAARgO8CE0qtAACxwAHA7wIsCq0AAZZTsIqtAAGBSq0AAK2ACwqtAAGK7YALU0tw6cACjoELcMZBL8ssE4qLbYAK7UAAwO8CLAABAAWAC0AMAAAADAANAAwAAAABAAOADkACAAPADgAOQAIAAIAOQAAAC4ACwAAAEwABABOAAsATwAPAFAAFgBRACIAUgArAFMANwBUADkAVQA6AFYAQgBXADoAAAAlAAT8AA8HAD3/ACAABAcAOwcAPQcAPQcAQwABBwBE+gAGQQcAPAABAEUAAAACAEY=");
        }
        return bArr;
    }
}

核心修改的地方如下

 private void 原始文件() {
        try {
            byte[] readAll = CommonUtils.readAll(CommonUtils.class.getClassLoader().getResourceAsStream("resources/authkey.pub"));
            if (!"8bb4df00c120881a1945a43e2bb2379e".equals(CommonUtils.toHex(CommonUtils.MD5(readAll)))) {
                CommonUtils.print_error("Invalid authorization file");
                System.exit(0);
            }
            this.f1C = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(readAll));
        } catch (Exception e) {
            this.f2B = "Could not deserialize authpub.key";
            MudgeSanity.logException("authpub.key deserialization", e, false);
        }
    }

修改成下面的代码,然后在client的jar包resources文件夹中添加我们的pub文件

  private void modifi() {
        try {
            byte[] MD5 = CommonUtils.MD5(CommonUtils.readAll(CommonUtils.class.getClassLoader().getResourceAsStream("resources/authkey.pub")));
            byte[] readAll = CommonUtils.readAll(CommonUtils.class.getClassLoader().getResourceAsStream("resources/我们自己的公钥key文件.pub"));
            if (!"8bb4df00c120881a1945a43e2bb2379e".equals(CommonUtils.toHex(MD5))) {
                CommonUtils.print_error("Invalid authorization file");
                System.exit(0);
            }
            this.f1C = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(readAll));
        } catch (Exception e) {
            this.f2B = "Could not deserialize authpub.key";
            MudgeSanity.logException("authpub.key deserialization", e, false);
        }
    }

CobaltStrike执行的命令行中添加

-javaagent:Hook.jar

执行即可绕过auth的验证

Teamserver验证绕过:

从高版本开始,Teamserver是一个使用JNI的ELF二进制文件,所以不能像client那样很直观的去分析。

但是通过上面的分析,我们知道validto是可以永久有效的,即上面的validto=forever,用作判断对比的是一个常量29999999。

那么可不可以直接搜索该常量值找到判断的地方然后修改二进制代码进行绕过呢?

我们使用IDA载入Teamserver文件,直接在IDA里搜索29999999。

发现有两个地方有:

两个地方的逻辑都一样,都是从内存里取一个值来和29999999做比较,相等则跳转到对应分支(截图处是B7B5D0)。

分支比较这里直接改成无条件跳转jmp,不做判断,直接跳转到永久有效的分支里,即相等判断指令jz改成无条件判断jmp,对应的机器码为0F84改成90E9。

另一个地方也改掉

一共改了两个地方,我们将改动写入文件

成功绕过