安全矩阵

 找回密码
 立即注册
搜索
查看: 1001|回复: 0

CS二开记录

[复制链接]

215

主题

215

帖子

701

积分

高级会员

Rank: 4

积分
701
发表于 2023-9-9 09:50:12 | 显示全部楼层 |阅读模式
本帖最后由 alyssa 于 2023-9-9 09:58 编辑

CS二开记录  
         
相关jar包反编译我在上一篇文章有提到过
         
         
各个版本的官方解密key:
4.0 1be5be52c6255c33558e8a1cb667cb06
4.1 80e32a742060b884419ba0c171c9aa76
4.2 b20d487addd4713418f2d5a3ae02a7a0
4.3 3a4425490f389aeec312bdd758ad2b99
4.4 5e98194a01c6b48fa582a6a9fcbb92d6
证书认证流程  
         
cobaltstrike.auth认证密钥文件,rsa加密,解密内容:
         
final byte[] decrypt = {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};
         
每更新一个版本,对应的长度+17,key增加17位。
aggressor/Aggressor.class中License.checkLicenseGUI(new Authorization());开始license认证:
         
CobaltStrike4.4源码修改方法  
         
新建工程引入逆向源码与原有jar包  1、打开IntelliJ IDEA并新建项目  
         
创建后在项目下新建立两个文件夹decompiled_src 和lib

decompiled_src:
就将上面反编译出来的cobaltstrike.jar解压到decompiled_src
lib:
将原版cobaltstrike.jar 拷贝到 lib
完成后
选择file->project Structure->Modules->Dependencies->Library-Java
选lib文件夹里刚拷贝过去的jar包
勾上
然后file->project Structure->Artifacts—>jar—>from modules with dependencies 去新建一个Main Class
Main Class 可以在 Lib->cobaltstrike.jar->META-INF->MENIFEST.MF中找到
复制aggressor.Aggressor然后填上去
然后在decompiled_src中找到已经反编译完的aggressor主类,右键选择Refactor ->Copy File(直接复制也行)
之后记得把Lib->cobaltstrike.jar->META-INF->MENIFEST.MF的内容全部拷贝覆盖src->->META-INF->MENIFEST.MF不然编译完成后运行会报错
添加代码尝试JOptionPane.showMessageDialog(null, "Hello world");
运行前记得加运行配置
-XXarallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC


2、修改源码并重新打包  
将要修改的源码连同其对应的路径,一起复制到MyCobaltStrike的src下,如我们计划修改aggressor下的Aggressor.java(入口类导出时必须包含).
入口类:为整个程序的主类,是整个程序开始运行的地方,可以通过MANIFEST.MF文件中的Main-Class了解.



导出修改后的jar包
【文件】–>【项目结构】–>【工件】–>【+】–>【JAR】–>【来自具有依赖项的模块】–>【从模块创建JAR】–>【选择主类】–>【JAR】–>【来自具有依赖项的模块】–>【选择主类Aggressor】–>【确认】
【构建】–>【构建工件】
至此代码修改完成.
         
破解CS(jar点击或者运行直接打开)  
参照:
https://ucasers.cn/%E5%AF%B9cobaltstrike4.4%E7%9A%84%E7%AE%80%E5%8D%95%E9%AD%94%E6%94%B9/#title-3
https://www.iculture.cc/forum-post/14036
方法一硬编码key  
对AuthCrypto().decrypt进行RSA解密后赋值的参数写死:

中间4.0、4.1、4.2的key是没有用到的可以随便写,最后一组写4.3泄露出来的key,4.4同理。
或者Authorization()函数都删掉,几个判断值写死,例如4.4的Authorization():
  1. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    public Authorization() {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        try {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            this.watermark=999999;</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            this.validto="forever";</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            this.valid = true;</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            final byte[] bytes = {94, -104, 25, 74, 1, -58, -76, -113, -91, -126, -90, -87, -4, -69, -110, -42};</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            MudgeSanity.systemDetail("valid to", "perpetual");</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            MudgeSanity.systemDetail("id", this.watermark + "");</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            SleevedResource.Setup(bytes);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        }</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        catch (Exception ex2) {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">            MudgeSanity.logException("auth file parsing", ex2, false);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        }</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">}</font></font></div>
复制代码


那个Authorization函数最好再修改下,建议把读取cobaltstrike.auth文件的代码全部注释掉。接下来就是注释掉common/Stater.java里面的initializeStarter函数内容和common/Stater2.java里面的initialize函数内容,并且注释掉common/Helper.java里面的startHelper函数除返回真以外的所有内容。
剩下的把beacon中途退出的暗桩也去掉,即把beacon/BeaconData.java文件中的shouldPad函数里面的this.shouldPad值改成恒为false。
TIPS:也许会遇到编译错误,一般按照ideaj的提示自动进行修改或者对比其他反编译结果修改即可!后不赘述。
OK了,可以先简单测试一下能不能进行远控,基本是没什么问题了。

方法二自己生成证书  
生成代码可参考:https://xz.aliyun.com/t/8557#toc-4
  1. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import java.io.*;import java.security.*;</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">public class RSAKeyPairGenerator {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    private PrivateKey privateKey;</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    private PublicKey publicKey;</font></font></div>
  2. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    public RSAKeyPairGenerator() throws NoSuchAlgorithmException {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        keyGen.initialize(2048);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        KeyPair pair = keyGen.generateKeyPair();</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        this.privateKey = pair.getPrivate();</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        this.publicKey = pair.getPublic();</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    }</font></font></div>
  3. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    // 将byte 写入文件</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    public void byte2File(String path, byte[] data) throws IOException {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        File f = new File(path);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        f.getParentFile().mkdirs();</font></font></div>
  4. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        FileOutputStream fos = new FileOutputStream(f);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        fos.write(data);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        fos.flush();</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        fos.close();</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    }</font></font></div>
  5. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    public PrivateKey getPrivateKey() {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        return privateKey;</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    }</font></font></div>
  6. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    public PublicKey getPublicKey() {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        return publicKey;</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    }</font></font></div>
  7. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    // 加密数据</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    public byte[] encryptPri(byte[] data, PrivateKey privateKey) throws BadPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        cipher.init(Cipher.ENCRYPT_MODE, this.privateKey);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        return cipher.doFinal(data);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    }</font></font></div>
  8. <div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    public static void main(String[] args) throws NoSuchAlgorithmException, IOException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, BadPaddingException {</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        RSAKeyPairGenerator PairGenerator = new RSAKeyPairGenerator();</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        //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 };</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        byte[] data ={-54, -2, -64, -45, 0, 77, 1, -55, -61, 127, 0, 0, 0, 1, 43,</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">                16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">                16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">                16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">                16, 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103};</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        byte[] rsaByte = PairGenerator.encryptPri(data, PairGenerator.getPrivateKey());</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        PairGenerator.byte2File("RSA/cobaltstrike.auth", rsaByte);</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        PairGenerator.byte2File("RSA/authkey.private", PairGenerator.getPrivateKey().getEncoded());</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">        PairGenerator.byte2File("RSA/authkey.pub", PairGenerator.getPublicKey().getEncoded());</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">    }</font></font></div><div align="left"><font face="Calibri"><font style="font-size: 10.5pt">}</font></font></div>
复制代码

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

Javaagent方式
破解工具可参考:https://github.com/Twi1ight/CSAgent
破解的核心还是需要cs对应版本的key


去除暗桩影响正常使用的口  
beacon/BeaconData中将shouldPad方法的值固定为false:
相比之前的this.shouldPad的exit,又在common/Helper增加.class判断,注释即可:

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

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

代码修改  
BeaconPayload中修改异或数值为新:
随便一个10进制数字即可,后面dll中改成对应的16进制数字。



dll修改  
使用CrackSleeve把dll进行解密:https://github.com/ca3tie1/CrackSleeve/
将cobaltstrike.jar和CrackSleeve.java放一起
编译(javac -encoding UTF-8 -classpath cobaltstrike.jar CrackSleeve.java)
解密文件(java -classpath cobaltstrike.jar;./ CrackSleeve decode) # windows命令行执行
Alt+T进行关键字搜索:2Eh




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


需要修改的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脚本解密出来,同理也可躲避空间搜索引擎的识别:

除了修改异或值的方式,也可以


4.3修改  32位dll  
地址位:10009FBB
6A 00 修改为6A 09(00修改为任意)
64位dll  
地址位:000000001800186C3
beacon.x64.dll里面的指令是xor edx, edx,修改为mov edx, esi
4.4修改  32位dll  
地址位:1000A0B9
6A 00 修改为6A 09(00修改为任意)
64位dll  
地址位:000000018001879B
beacon.x64.dll里面的指令是xor edx, edx,修改为mov edx, esi
使用重新加密:java -classpath cobaltstrike.jar;./ CrackSleeve encode
cs修复错误路径泄漏stage  
源头:
方法就是对uri加个/判断就可以了,不是/开头就响应到404:
也就是在cloudstrike/WebServer.java里面的_serve函数中合适位置加上对uri开头字符的判断。
4.4修改  
4.3修改  
增加用户名加密显示  
为了避免在Event Log中泄漏totp密码或者登录cs的名称,对name字段进行md5加盐显示,修改后如下:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 09:29 , Processed in 0.018393 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表