it's enough for intranet penetration. let's teach you how to crack cobaltstrike 3.12

Posted by fierce at 2020-03-04

Cobaltstrike is a commercial remote control software with intranet penetration. It supports custom script expansion and has very powerful functions. Some time ago, some kind-hearted people on GitHub released the trial version of cobaltstrike 3.12, then lz1y quickly released the cracked version, plus xor64.bin (there is no such file in the trial version) provided by enthusiastic elder brother, a more perfect and latest available version was born. Let's take a look at how the latest trial version is perfectly cracked.

The main body code of cobaltstrike (hereinafter referred to as CS) is developed in Java, which is relatively friendly in reverse. Using JD GUI to decompile cobaltstry.jar file, you can see that the code has almost no anti cracking. There is no confusion about Java source. But when viewing the source code of decompilation, there are many problems / / internal error / /. Here I recommend a Java decompilation tool Luyten, which can decompile almost 100% to obtain the cobaltstrip.jar source code.

// INTERNAL ERROR // luyten

The license processing logic of CS is in the common / file:

common/ package common;
import aggressor.*;
import javax.swing.*;
import java.awt.*;public class License{    private static long life;    private static long today;    private static long start;    private static long difference;        private static long getTimeSinceStart() {        final Prefs options = Prefs.getPreferences(); = System.currentTimeMillis();        License.start = options.getLongNumber("", 0L);        if (License.start == 0L) {            options.set("", + "");  ;            License.start =;        }        return License.difference = ( - License.start) / 86400000L;    }        public static void checkLicenseGUI(final Authorization auth) {        getTimeSinceStart();        if (License.difference > || - License.start < 0L) {            JOptionPane.showMessageDialog(null, "Your Cobalt Strike trial is now expired.\nPlease purchase a license and use the\nsoftware update feature to continue.\n\nFor details, visit:\n", null, 0);            System.exit(0);        }        else {            final long left = - License.difference;            String form = left + " day";            if (left != 1L) {                form += "s";            }            CommonUtils.print_warn("This is a trial version of Cobalt Strike. You have " + form + " left of your trial. If you purchased Cobalt Strike. Run the Update program and enter your license.");            CommonUtils.print_trial("WARNING! This trial is *built* to get caught by standard defenses. The licensed product does not have these restrictions. See:");            JOptionPane.showMessageDialog(null, "This is a trial version of Cobalt Strike.\nYou have " + form + " left of your trial.\n\nIf you purchased Cobalt Strike. Run the\nUpdate program and enter your license.", null, 1);        }    }        public static boolean isTrial() {        return true;    }        public static void checkLicenseConsole(final Authorization auth) {        getTimeSinceStart();        if (License.difference > || - License.start < 0L) {            CommonUtils.print_error("Your Cobalt Strike trial is now expired. Please purchase a license and use the software update feature to continue. For details, visit:");            System.exit(0);        }        else {            final long left = - License.difference;            String form = left + " day";            if (left != 1L) {                form += "s";            }            CommonUtils.print_warn("This is a trial version of Cobalt Strike. You have " + form + " left of your trial. If you purchased Cobalt Strike. Run the Update program and enter your license.");            CommonUtils.print_trial("WARNING! This trial is *built* to get caught by standard defenses. The licensed product does not have these restrictions. See:");        }    }        static { = 21L; = 0L;        License.start = 0L;        License.difference = 0L;    }}

The code logic is very clear. Here we have two directions for patch:

Modify unlimited extended trial

Modify the return value of istrial() and forge it into the official version


Because the trial version and the official version of CS have different processing logic in many places, after modifying the return value of istrial(), we need to modify all places that call the istrial() function to adjust the code. In addition, the trial version of CS leaves some fingerprint features and restrictions, and we also need to remove the corresponding feature code.

isTrial() isTrial()

Modify repackage

Now that we know the idea of cracking, let's see how to modify the source code and recompile it. In Java programming, we can use jar tools to package a series of. Class files into jar packages for other Java programs. We can also modify the contents of the. Class file in the jar package and recompile the package. For example, modify example.class in demo.jar and recompile as follows:


1. Use JD GUI, Luyten and other tools to decompile the class in demo.jar package into the source code, and extract the from it

2. Execute jar xvf demo.jar and unzip demo.jar to get the sub files of the jar package (note that it will unzip to the current directory), and place the file in the same directory as the example.class file

3. Execute Java C-CP a.jar; b.jar; c.jar to recompile (or javac-cp demo.jar example. Java) to get a new example.class file. Among them, a.jar, b.jar and c.jar are dependent packages. Generally, they directly depend on a demo.jar package that was originally decompressed.

4. Make sure that the compiled example.class replaces the original example.class file (you can view it through JD GUI decompilation)

5. Execute Jar - UVF demo.jar COM / some / path / example.class to update demo.jar package

When updating the class file in the jar package, the new class file directory path needs to be consistent with the original package path. For example, after modifying and recompiling, the command to update the jar package is as follows: 17:16 KINGX modified_java_files >jar -uvf cobaltstrike-with-xor64.jar aggressor/AggressorClient*.class 正在添加: aggressor/AggressorClient$1.class(输入 = 650) (输出 = 403)(压缩了 38%) 正在添加: aggressor/AggressorClient$2.class(输入 = 1263) (输出 = 704)(压缩了 44%) 正在添加: aggressor/AggressorClient.class(输入 = 11115) (输出 = 5196)(压缩了 53%)

Possible problems

When the modified java file is recompiled to a class file, it may encounter many strange errors. Sometimes it is due to the error of the decompiled source code. At this time, we can use Luyten, JAD, JD GUI and other decompiler tools together, try to restore the correct source code, and then recompile. For example:, JAD aggressor / aggressorclient *. Class and Luyten decompiled the source code are different.

jad aggressor/AggressorClient*.class luyten

Tips: the - at the beginning of the line in the following code snippet represents deletion, + represents addition

Patch trial version

Modify the common.license, remove the checklicensegui(), checklicenseconsole() function bodies, and modify the istrial() return value to false

Modify main program title

Aggressor. Aggressorclient, modify gettitle() function

Release the limit of the same kind of listener

A team server can only listen to one listener by default. You can remove the limitation by modifying the code.

Aggressor.dialogs.listenerdialog, remove the following code:

...else if (Listener.isEgressBeacon(payload) && DataUtils.isBeaconDefined(this.datal) && !name.equals(DataUtils.getEgressBeaconListener(this.datal))) {    DialogUtils.showError("You may only define one egress Beacon per team server.\nThere are a few things I need to sort before you can\nput multiple Beacon HTTP/DNS listeners on one server.\nSpin up a new team server and add your listener there.");}...

Removing fingerprint features of EICAR back door

There are several EICAR characters in the trial version: x5o! P% @ AP [4 \ pzx54 (P ^) 7CC) 7} $eicar-standard-antivirus-test-file! $H + h *, all of which need to be cleaned up:



Modify the pad() function:

-  result.append("5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*\u0000");+  result.append("123\u0000");


-  $eicar = 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'+  $eicar = '' -  c2profile.addCommand(".http-get.server", "!header", "X-Malware: X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");-  c2profile.addCommand(".http-post.server", "!header", "X-Malware: X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");-  c2profile.addCommand(".http-stager.server", "!header", "X-Malware: X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");-  c2profile.addCommand(".stage.transform-x86", "append", "X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");-  c2profile.addCommand(".stage.transform-x64", "append", "X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");


Since the return value of license. Istrial() has been changed to false, the following section will not be affected.

if (License.isTrial()) {    packer.addString("X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");    CommonUtils.print_trial("Added EICAR string to " + s);}

Add xor64.bin

When a payload is generated, xorencode() in common.artifactutils is called for encoding:

public static byte[] _XorEncode(final byte[] data, final String arch) {    AssertUtils.TestArch(arch);    if ("x86".equals(arch)) {        final byte[] decoder = XorStub();        final byte[] payload = XorEncoder.encode(data);        return CommonUtils.join(decoder, payload);    }    if ("x64".equals(arch)) {        final byte[] decoder = CommonUtils.readResource("resources/xor64.bin");        final byte[] payload = XorEncoder.encode(data);        return CommonUtils.join(decoder, payload);    }    return new byte[0];}public static byte[] XorEncode(final byte[] data, final String arch) {    if (License.isTrial()) {        CommonUtils.print_trial("Disabled " + arch + " payload stage encoding.");        return data;    }    AssertUtils.Test(data.length > 16384, "XorEncode used on a stager (or some other small thing)");    return _XorEncode(data, arch);}

There is no payload stage encoding in the trial version, so xor.bin/xor64.bin file is not included in the trial version package. If there are two files, they can be added to resources / xor.bin and resources / xor64.bin. There is an enthusiastic elder brother on GitHub who provides xor64 generation script: xor64

payload stage encoding resources/xor.bin resources/xor64.bin

Modify the source code one by one, recompile and update it to cobaltstry.jar package, and then copy and replace the original jar package.