From 729dd8d166cf2758732daa304eb4b852ba9a1a3c Mon Sep 17 00:00:00 2001 From: ReaJason Date: Sun, 11 Jan 2026 10:51:47 +0800 Subject: [PATCH] feat: support servletNameFilter for WebLogicFilterProbe --- .../payload/filter/WebLogicFilterProbe.java | 107 +++++++++++++----- .../weblogic/WebLogic1036ContainerTest.java | 17 ++- .../weblogic/WebLogic12214ContainerTest.java | 16 +-- .../weblogic/WebLogic14110ContainerTest.java | 17 ++- 4 files changed, 102 insertions(+), 55 deletions(-) diff --git a/generator/src/main/java/com/reajason/javaweb/probe/payload/filter/WebLogicFilterProbe.java b/generator/src/main/java/com/reajason/javaweb/probe/payload/filter/WebLogicFilterProbe.java index ab020c87..ec058900 100644 --- a/generator/src/main/java/com/reajason/javaweb/probe/payload/filter/WebLogicFilterProbe.java +++ b/generator/src/main/java/com/reajason/javaweb/probe/payload/filter/WebLogicFilterProbe.java @@ -15,45 +15,48 @@ public class WebLogicFilterProbe { @Override public String toString() { - String msg = ""; + StringBuilder msg = new StringBuilder(); Map>> allFiltersData = new LinkedHashMap>>(); Set contexts = null; try { contexts = getContext(); } catch (Throwable throwable) { - msg += "context error: " + getErrorMessage(throwable); + msg.append("context error: ").append(getErrorMessage(throwable)); } if (contexts == null || contexts.isEmpty()) { - msg += "context not found\n"; + msg.append("context not found\n"); } else { for (Object context : contexts) { String contextRoot = getContextRoot(context); - List> filters = collectFiltersData(context); - allFiltersData.put(contextRoot, filters); + try { + List> filters = collectFiltersData(context); + allFiltersData.put(contextRoot, filters); + } catch (Throwable e) { + msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n"); + } } - msg += formatFiltersData(allFiltersData); + msg.append(formatFiltersData(allFiltersData)); } - return msg; + return msg.toString(); } - private List> collectFiltersData(Object context) { - List> result = new ArrayList<>(); - try { - Object filterManager = getFieldValue(context, "filterManager"); - Map filters = (Map) getFieldValue(filterManager, "filters"); - List filterPatternList = (ArrayList) getFieldValue(filterManager, "filterPatternList"); - if (filterPatternList == null || filterPatternList.isEmpty()) { - return Collections.emptyList(); + @SuppressWarnings("unchecked") + private List> collectFiltersData(Object context) throws Exception { + + Object filterManager = getFieldValue(context, "filterManager"); + Map filters = (Map) getFieldValue(filterManager, "filters"); + List filterPatternList = (ArrayList) getFieldValue(filterManager, "filterPatternList"); + List filterServletList = (ArrayList) getFieldValue(filterManager, "filterServletList"); + Map> aggregatedData = new LinkedHashMap<>(); + for (Object filterInfo : filterPatternList) { + Object urlMap = getFieldValue(filterInfo, "map"); + String filterName = (String) getFieldValue(filterInfo, "filterName"); + if (filterName == null) { + // WebLogic 10.3.6 + Object[] mapValues = (Object[]) invokeMethod(urlMap, "values", null, null); + filterName = ((String) mapValues[0]); } - for (Object filterInfo : filterPatternList) { - Map info = new HashMap<>(); - Object urlMap = getFieldValue(filterInfo, "map"); - String filterName = (String) getFieldValue(filterInfo, "filterName"); - if (filterName == null) { - // WebLogic 10.3.6 - Object[] mapValues = (Object[]) invokeMethod(urlMap, "values", null, null); - filterName = ((String) mapValues[0]); - } + if (aggregatedData.get(filterName) == null) { Object filterWrapper = filters.get(filterName); String filterClassName = null; try { @@ -68,14 +71,59 @@ public class WebLogicFilterProbe { filterClassName = filter.getClass().getName(); } } + Map info = new HashMap<>(); info.put("filterName", filterName); info.put("filterClass", filterClassName); - String[] urlPatterns = (String[]) invokeMethod(urlMap, "keys", null, null); - info.put("urlPatterns", Arrays.toString(urlPatterns)); - result.add(info); + info.put("urlPatterns", new LinkedHashSet()); + info.put("servletNames", new LinkedHashSet()); + aggregatedData.put(filterName, info); } - } catch (Exception e) { - e.printStackTrace(); + Map info = aggregatedData.get(filterName); + String[] urlPatterns = (String[]) invokeMethod(urlMap, "keys", null, null); + if (urlPatterns != null) { + ((Set) info.get("urlPatterns")).addAll(Arrays.asList(urlPatterns)); + } + } + for (Object filterInfo : filterServletList) { + String filterName = (String) getFieldValue(filterInfo, "filterName"); + if (aggregatedData.get(filterName) == null) { + Object filterWrapper = filters.get(filterName); + String filterClassName = null; + try { + filterClassName = (String) getFieldValue(filterWrapper, "filterClassName"); + } catch (NoSuchFieldException e) { + // WebLogic 10.3.6 + filterClassName = (String) getFieldValue(filterWrapper, "filterclass"); + } + if (filterClassName == null) { + Object filter = getFieldValue(filterWrapper, "filter"); + if (filter != null) { + filterClassName = filter.getClass().getName(); + } + } + Map info = new HashMap<>(); + info.put("filterName", filterName); + info.put("filterClass", filterClassName); + info.put("urlPatterns", new LinkedHashSet()); + info.put("servletNames", new LinkedHashSet()); + aggregatedData.put(filterName, info); + } + Map info = aggregatedData.get(filterName); + String servletName = (String) getFieldValue(filterInfo, "servletName"); + if (servletName != null) { + ((Set) info.get("servletNames")).add(servletName); + } + } + List> result = new ArrayList<>(); + for (Map entry : aggregatedData.values()) { + Map finalInfo = new HashMap<>(); + finalInfo.put("filterName", (String) entry.get("filterName")); + finalInfo.put("filterClass", (String) entry.get("filterClass")); + Set urls = (Set) entry.get("urlPatterns"); + finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString()); + Set servletNames = (Set) entry.get("servletNames"); + finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString()); + result.add(finalInfo); } return result; } @@ -96,6 +144,7 @@ public class WebLogicFilterProbe { appendIfPresent(output, "", info.get("filterName"), ""); appendIfPresent(output, " -> ", info.get("filterClass"), ""); appendIfPresent(output, " -> URL:", info.get("urlPatterns"), ""); + appendIfPresent(output, " -> Servlet:", info.get("servletNames"), ""); output.append("\n"); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java index 89ec2501..0a9b0a37 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java @@ -2,11 +2,14 @@ package com.reajason.javaweb.integration.probe.weblogic; import com.reajason.javaweb.Server; import com.reajason.javaweb.integration.ProbeAssertion; +import com.reajason.javaweb.integration.ShellAssertion; import com.reajason.javaweb.integration.VulTool; import com.reajason.javaweb.integration.probe.DetectionTool; +import com.reajason.javaweb.memshell.MemShellResult; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; +import com.reajason.javaweb.probe.payload.FilterProbeFactory; import com.reajason.javaweb.utils.CommonUtil; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -87,21 +90,17 @@ public class WebLogic1036ContainerTest { @Test void testFilterProbe() { String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe()); - System.out.println(data); - assertThat(data, anyOf( - containsString("Context: ") - )); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); + ShellAssertion.assertFilterProbeIsRight(data); } @Test void testFilterFirstInject() { String url = getUrlFromWebLogic(container); - shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe()); - log.info(data); + MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); List filter = ProbeAssertion.getFiltersForContext(data, "/app"); String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.WebLogic)))); + assertEquals(filterName, memShellResult.getShellClassName()); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java index 286fdcd0..ed5dcd79 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java @@ -2,11 +2,14 @@ package com.reajason.javaweb.integration.probe.weblogic; import com.reajason.javaweb.Server; import com.reajason.javaweb.integration.ProbeAssertion; +import com.reajason.javaweb.integration.ShellAssertion; import com.reajason.javaweb.integration.VulTool; import com.reajason.javaweb.integration.probe.DetectionTool; +import com.reajason.javaweb.memshell.MemShellResult; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; +import com.reajason.javaweb.probe.payload.FilterProbeFactory; import com.reajason.javaweb.utils.CommonUtil; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -87,20 +90,17 @@ public class WebLogic12214ContainerTest { @Test void testFilterProbe() { String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe()); - System.out.println(data); - assertThat(data, anyOf( - containsString("Context: ") - )); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); + ShellAssertion.assertFilterProbeIsRight(data); } @Test void testFilterFirstInject() { String url = getUrlFromWebLogic(container); - shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe()); + MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); List filter = ProbeAssertion.getFiltersForContext(data, "/app"); String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.WebLogic)))); + assertEquals(filterName, memShellResult.getShellClassName()); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java index ff58da12..15497c48 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java @@ -2,11 +2,14 @@ package com.reajason.javaweb.integration.probe.weblogic; import com.reajason.javaweb.Server; import com.reajason.javaweb.integration.ProbeAssertion; +import com.reajason.javaweb.integration.ShellAssertion; import com.reajason.javaweb.integration.VulTool; import com.reajason.javaweb.integration.probe.DetectionTool; +import com.reajason.javaweb.memshell.MemShellResult; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; +import com.reajason.javaweb.probe.payload.FilterProbeFactory; import com.reajason.javaweb.utils.CommonUtil; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -81,21 +84,17 @@ public class WebLogic14110ContainerTest { @Test void testFilterProbe() { String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe()); - log.info(data); - assertThat(data, anyOf( - containsString("Context: ") - )); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); + ShellAssertion.assertFilterProbeIsRight(data); } @Test void testFilterFirstInject() { String url = getUrlFromWebLogic(container); - shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe()); - log.info(data); + MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); List filter = ProbeAssertion.getFiltersForContext(data, "/app"); String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.WebLogic)))); + assertEquals(filterName, memShellResult.getShellClassName()); } }