mirror of
https://gitee.com/pengzhile/atlassian-agent.git
synced 2023-02-28 12:37:36 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1095be6b25 | ||
|
|
d5b9b974d7 | ||
|
|
65c05e4215 |
@@ -1,4 +1,4 @@
|
||||
# Atlassian Agent
|
||||
# Atlassian Agent v1.3.1
|
||||
|
||||
#### Support (almost any version, include 8.0):
|
||||
* JIRA Software [FAQ](doc/JIRA_FAQ.md)
|
||||
@@ -55,8 +55,8 @@
|
||||
### 使用KeyGen
|
||||
* 你得确认已经配置好agent,参考上面说明。
|
||||
* 当你试着执行`java -jar /path/to/atlassian-agent.jar`时应该可以看到输出的KeyGen参数帮助。
|
||||
* 请仔细看看每个参数的作用,特别是`-p`参数的取值范围。
|
||||
* 第三方插件将其`应用密钥/插件关键字`作为`-p`参数。如:`-p com.gliffy.integration.confluence`
|
||||
* 请仔细看看每个参数的作用,特别是`-p`参数的取值范围。`-p`参数内容最好用引号包住,否则可能影响参数解析。
|
||||
* 第三方插件将其`应用密钥/插件关键字`作为`-p`参数。如:`-p 'com.gliffy.integration.confluence'`
|
||||
* 在Atlassian服务安装时你应该能看到类似:`AAAA-BBBB-CCCC-DDDD`的server id,请留意。
|
||||
* 提供了正确的参数运行KeyGen会在终端输出计算好的激活码。
|
||||
* 将生成的激活码复制出来去激活你要使用的服务。
|
||||
|
||||
@@ -5,7 +5,6 @@ import io.zhile.crack.atlassian.license.LicenseProperty;
|
||||
import io.zhile.crack.atlassian.license.products.*;
|
||||
import org.apache.commons.cli.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -15,6 +14,7 @@ import java.util.Map;
|
||||
* @link https://zhile.io
|
||||
*/
|
||||
public class Usage {
|
||||
private static final String VERSION = "v1.3.1";
|
||||
private static final Options OPTIONS = new Options();
|
||||
private static final Map<String, String> PRODUCTS = new HashMap<>(16);
|
||||
private static final String PRODUCTS_DESC;
|
||||
@@ -32,6 +32,7 @@ public class Usage {
|
||||
PRODUCTS.put("jc", "JIRA Core");
|
||||
PRODUCTS.put("portfolio", "Portfolio plugin for JIRA");
|
||||
PRODUCTS.put("jsd", "JIRA Service Desk");
|
||||
PRODUCTS.put("jsm", "JIRA Service Management");
|
||||
PRODUCTS.put("training", "Training plugin for JIRA");
|
||||
PRODUCTS.put("capture", "Capture plugin for JIRA");
|
||||
PRODUCTS.put("*", "Third party plugin key, looks like: com.foo.bar");
|
||||
@@ -50,7 +51,7 @@ public class Usage {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String usage = "\n====================================================\n" +
|
||||
"======= Atlassian Crack Agent =======\n" +
|
||||
"======= Atlassian Crack Agent " + VERSION + " =======\n" +
|
||||
"======= https://zhile.io =======\n" +
|
||||
"======= QQ Group: 30347511 =======\n" +
|
||||
"====================================================\n\n";
|
||||
@@ -142,6 +143,7 @@ public class Usage {
|
||||
property = new Portfolio(contactName, contactEMail, serverID, organisation, dataCenter);
|
||||
break;
|
||||
case "jsd":
|
||||
case "jsm":
|
||||
property = new JIRAServiceDesk(contactName, contactEMail, serverID, organisation, dataCenter);
|
||||
break;
|
||||
case "training":
|
||||
|
||||
@@ -4,8 +4,8 @@ import java.lang.instrument.Instrumentation;
|
||||
|
||||
/**
|
||||
* @author pengzhile
|
||||
* @link https://zhile.io
|
||||
* @version 1.0
|
||||
* @link https://zhile.io
|
||||
*/
|
||||
public class Agent {
|
||||
public static void premain(String args, Instrumentation inst) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package io.zhile.crack.atlassian.agent;
|
||||
|
||||
import javassist.*;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtConstructor;
|
||||
import javassist.CtField;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.IllegalClassFormatException;
|
||||
@@ -8,8 +11,8 @@ import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* @author pengzhile
|
||||
* @link https://zhile.io
|
||||
* @version 1.0
|
||||
* @link https://zhile.io
|
||||
*/
|
||||
public class KeyTransformer implements ClassFileTransformer {
|
||||
private static final String CN_KEY_SPEC = "java/security/spec/EncodedKeySpec";
|
||||
@@ -47,11 +50,11 @@ public class KeyTransformer implements ClassFileTransformer {
|
||||
throw new RuntimeException(e1);
|
||||
}
|
||||
}
|
||||
|
||||
cc.addField(CtField.make("private static final byte[] __h_ok=" + b64f + "(\"MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAIvfweZvmGo5otwawI3no7Udanxal3hX2haw962KL/nHQrnC4FG2PvUFf34OecSK1KtHDPQoSQ+DHrfdf6vKUJphw0Kn3gXm4LS8VK/LrY7on/wh2iUobS2XlhuIqEc5mLAUu9Hd+1qxsQkQ50d0lzKrnDqPsM0WA9htkdJJw2nS\");", cc));
|
||||
cc.addField(CtField.make("private static final byte[] __h_ok1=" + b64f + "(\"MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAIvfweZvmGo5otwawI3no7Udanxal3hX2haw962KL/nHQrnC4FG2PvUFf34OecSK1KtHDPQoSQ+DHrfdf6vKUJphw0Kn3gXm4LS8VK/LrY7on/wh2iUobS2XlhuIqEc5mLAUu9Hd+1qxsQkQ50d0lzKrnDqPsM0WA9htkdJJw2nS\");", cc));
|
||||
cc.addField(CtField.make("private static final byte[] __h_ok2=" + b64f + "(\"MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGALZHuJwQzgGnYm/X9BkMcewYQnWjMIGWHd9Yom5Qw7cVIdiZkqpiSzSKurO/WAHHLN31obg7NgGkitWUysECRE3zuJVbKGhx9xjVMnP6z5SwI89vB7Gn7UWxoCvT0JZgcMyQobXeVBtM9J3EgzkdDx/+Dck7uz/l1y+HDNdRzW00=\");", cc));
|
||||
cc.addField(CtField.make("private static final byte[] __h_nk=" + b64f + "(\"MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAO0DidNibJHhtgxAnM9NszURYU25CVLAlwFdOWhiUkjrjOY459ObRZDVd35hQmN/cCLkDox7y2InJE6PDWfbx9BsgPmPvH75yKgPs3B8pClQVkgIpJp08R59hoZabYuvm7mxCyDGTl2lbrOi0a3j4vM5OoCWKQjIEZ28OpjTyCr3\");", cc));
|
||||
CtConstructor cm = cc.getConstructor("([B)V");
|
||||
cm.insertBefore("if(Arrays.equals($1,__h_ok)){$1=__h_nk;System.out.println(\"============================== agent working ==============================\");}");
|
||||
cm.insertBefore("if(Arrays.equals($1,__h_ok1)||Arrays.equals($1,__h_ok2)){$1=__h_nk;System.out.println(\"============================== agent working ==============================\");}");
|
||||
|
||||
return cc.toBytecode();
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -6,7 +6,10 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.*;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Signature;
|
||||
import java.security.spec.EncodedKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
@@ -32,7 +35,7 @@ public class Encoder {
|
||||
}
|
||||
}
|
||||
|
||||
public static String encode(String licenseText) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
|
||||
public static String encode(String licenseText) throws Exception {
|
||||
byte[] licenseData = zipText(licenseText.getBytes());
|
||||
byte[] text = new byte[licenseData.length + 5];
|
||||
text[0] = 13; // license prefix
|
||||
@@ -42,11 +45,15 @@ public class Encoder {
|
||||
text[4] = 15;
|
||||
System.arraycopy(licenseData, 0, text, 5, licenseData.length);
|
||||
|
||||
return packLicense(text, sign(text));
|
||||
}
|
||||
|
||||
public static byte[] sign(byte[] bytes) throws Exception {
|
||||
Signature signature = Signature.getInstance("SHA1withDSA");
|
||||
signature.initSign(PRIVATE_KEY);
|
||||
signature.update(text);
|
||||
signature.update(bytes);
|
||||
|
||||
return packLicense(text, signature.sign());
|
||||
return signature.sign();
|
||||
}
|
||||
|
||||
private static byte[] zipText(byte[] licenseText) throws IOException {
|
||||
|
||||
@@ -2,8 +2,8 @@ package io.zhile.crack.atlassian.license;
|
||||
|
||||
/**
|
||||
* @author pengzhile
|
||||
* @link https://zhile.io
|
||||
* @version 1.0
|
||||
* @link https://zhile.io
|
||||
*/
|
||||
public enum LicenseEdition {
|
||||
BASIC,
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package io.zhile.crack.atlassian.license;
|
||||
|
||||
import io.zhile.crack.atlassian.keygen.Encoder;
|
||||
import io.zhile.crack.atlassian.utils.Base64;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* @author pengzhile
|
||||
@@ -53,7 +58,8 @@ abstract public class LicenseProperty {
|
||||
setOrganisation(organisation);
|
||||
setDataCenter(dataCenter);
|
||||
|
||||
data.put("licenseVersion", "2");
|
||||
setLicenseVersion("2");
|
||||
setKeyVersion("1600708331");
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
@@ -120,6 +126,14 @@ abstract public class LicenseProperty {
|
||||
data.put("PurchaseDate", new SimpleDateFormat("yyyy-MM-dd").format(purchaseDate));
|
||||
}
|
||||
|
||||
public void setLicenseVersion(String version) {
|
||||
data.put("licenseVersion", version);
|
||||
}
|
||||
|
||||
public void setKeyVersion(String version) {
|
||||
data.put("keyVersion", version);
|
||||
}
|
||||
|
||||
public void setDataCenter(boolean dataCenter) {
|
||||
if (dataCenter) {
|
||||
data.put(productProperty("DataCenter"), "true");
|
||||
@@ -134,11 +148,74 @@ abstract public class LicenseProperty {
|
||||
return getProductName() + "." + property;
|
||||
}
|
||||
|
||||
protected void setLicenseHash() {
|
||||
data.remove("licenseHash");
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String key : new TreeSet<>(data.keySet())) {
|
||||
String val = data.get(key);
|
||||
if (val == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append(escape(key, true)).append("=").append(escape(val, false)).append("\n");
|
||||
}
|
||||
|
||||
try {
|
||||
data.put("licenseHash", Base64.encode(Encoder.sign(sb.toString().getBytes(StandardCharsets.UTF_8))));
|
||||
} catch (Exception e) {
|
||||
// never
|
||||
}
|
||||
}
|
||||
|
||||
protected String escape(String str, boolean isKey) {
|
||||
int len = str.length();
|
||||
StringBuilder sb = new StringBuilder(len * 2);
|
||||
|
||||
for (int index = 0; index < len; ++index) {
|
||||
char c = str.charAt(index);
|
||||
switch (c) {
|
||||
case '\t':
|
||||
sb.append("\\t");
|
||||
break;
|
||||
case '\n':
|
||||
sb.append("\\n");
|
||||
break;
|
||||
case '\f':
|
||||
sb.append("\\f");
|
||||
break;
|
||||
case '\r':
|
||||
sb.append("\\r");
|
||||
break;
|
||||
case ' ':
|
||||
if (index == 0 || isKey) {
|
||||
sb.append('\\');
|
||||
}
|
||||
|
||||
sb.append(' ');
|
||||
break;
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
default:
|
||||
if ("=: \t\r\n\f#!".indexOf(c) != -1) {
|
||||
sb.append('\\');
|
||||
}
|
||||
|
||||
sb.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuilder sb = new StringBuilder("#");
|
||||
sb.append(date.toString());
|
||||
|
||||
setLicenseHash();
|
||||
for (Map.Entry<String, String> entry : data.entrySet()) {
|
||||
if (entry.getValue() == null) {
|
||||
continue;
|
||||
|
||||
@@ -2,8 +2,8 @@ package io.zhile.crack.atlassian.license;
|
||||
|
||||
/**
|
||||
* @author pengzhile
|
||||
* @link https://zhile.io
|
||||
* @version 1.0
|
||||
* @link https://zhile.io
|
||||
*/
|
||||
public enum LicenseType {
|
||||
ACADEMIC,
|
||||
|
||||
@@ -4,8 +4,8 @@ import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
/**
|
||||
* @author pengzhile
|
||||
* @link https://zhile.io
|
||||
* @version 1.0
|
||||
* @link https://zhile.io
|
||||
*/
|
||||
public class Base64 {
|
||||
public static byte[] decode(String val) {
|
||||
|
||||
Reference in New Issue
Block a user