Skip to content

Commit a1bab09

Browse files
committed
feat: support servletNameFilter for WebLogicFilterProbe
1 parent 3de0700 commit a1bab09

File tree

4 files changed

+100
-53
lines changed

4 files changed

+100
-53
lines changed

generator/src/main/java/com/reajason/javaweb/probe/payload/filter/WebLogicFilterProbe.java

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,45 +15,78 @@ public class WebLogicFilterProbe {
1515

1616
@Override
1717
public String toString() {
18-
String msg = "";
18+
StringBuilder msg = new StringBuilder();
1919
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
2020
Set<Object> contexts = null;
2121
try {
2222
contexts = getContext();
2323
} catch (Throwable throwable) {
24-
msg += "context error: " + getErrorMessage(throwable);
24+
msg.append("context error: ").append(getErrorMessage(throwable));
2525
}
2626
if (contexts == null || contexts.isEmpty()) {
27-
msg += "context not found\n";
27+
msg.append("context not found\n");
2828
} else {
2929
for (Object context : contexts) {
3030
String contextRoot = getContextRoot(context);
31-
List<Map<String, String>> filters = collectFiltersData(context);
32-
allFiltersData.put(contextRoot, filters);
31+
try {
32+
List<Map<String, String>> filters = collectFiltersData(context);
33+
allFiltersData.put(contextRoot, filters);
34+
} catch (Throwable e) {
35+
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
36+
}
3337
}
34-
msg += formatFiltersData(allFiltersData);
38+
msg.append(formatFiltersData(allFiltersData));
3539
}
36-
return msg;
40+
return msg.toString();
3741
}
3842

39-
private List<Map<String, String>> collectFiltersData(Object context) {
40-
List<Map<String, String>> result = new ArrayList<>();
41-
try {
42-
Object filterManager = getFieldValue(context, "filterManager");
43-
Map<String, Object> filters = (Map<String, Object>) getFieldValue(filterManager, "filters");
44-
List<Object> filterPatternList = (ArrayList<Object>) getFieldValue(filterManager, "filterPatternList");
45-
if (filterPatternList == null || filterPatternList.isEmpty()) {
46-
return Collections.emptyList();
43+
@SuppressWarnings("unchecked")
44+
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
45+
46+
Object filterManager = getFieldValue(context, "filterManager");
47+
Map<String, Object> filters = (Map<String, Object>) getFieldValue(filterManager, "filters");
48+
List<Object> filterPatternList = (ArrayList<Object>) getFieldValue(filterManager, "filterPatternList");
49+
List<Object> filterServletList = (ArrayList<Object>) getFieldValue(filterManager, "filterServletList");
50+
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
51+
for (Object filterInfo : filterPatternList) {
52+
Object urlMap = getFieldValue(filterInfo, "map");
53+
String filterName = (String) getFieldValue(filterInfo, "filterName");
54+
if (filterName == null) {
55+
// WebLogic 10.3.6
56+
Object[] mapValues = (Object[]) invokeMethod(urlMap, "values", null, null);
57+
filterName = ((String) mapValues[0]);
4758
}
48-
for (Object filterInfo : filterPatternList) {
49-
Map<String, String> info = new HashMap<>();
50-
Object urlMap = getFieldValue(filterInfo, "map");
51-
String filterName = (String) getFieldValue(filterInfo, "filterName");
52-
if (filterName == null) {
59+
if (aggregatedData.get(filterName) == null) {
60+
Object filterWrapper = filters.get(filterName);
61+
String filterClassName = null;
62+
try {
63+
filterClassName = (String) getFieldValue(filterWrapper, "filterClassName");
64+
} catch (NoSuchFieldException e) {
5365
// WebLogic 10.3.6
54-
Object[] mapValues = (Object[]) invokeMethod(urlMap, "values", null, null);
55-
filterName = ((String) mapValues[0]);
66+
filterClassName = (String) getFieldValue(filterWrapper, "filterclass");
5667
}
68+
if (filterClassName == null) {
69+
Object filter = getFieldValue(filterWrapper, "filter");
70+
if (filter != null) {
71+
filterClassName = filter.getClass().getName();
72+
}
73+
}
74+
Map<String, Object> info = new HashMap<>();
75+
info.put("filterName", filterName);
76+
info.put("filterClass", filterClassName);
77+
info.put("urlPatterns", new LinkedHashSet<String>());
78+
info.put("servletNames", new LinkedHashSet<String>());
79+
aggregatedData.put(filterName, info);
80+
}
81+
Map<String, Object> info = aggregatedData.get(filterName);
82+
String[] urlPatterns = (String[]) invokeMethod(urlMap, "keys", null, null);
83+
if (urlPatterns != null) {
84+
((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urlPatterns));
85+
}
86+
}
87+
for (Object filterInfo : filterServletList) {
88+
String filterName = (String) getFieldValue(filterInfo, "filterName");
89+
if (aggregatedData.get(filterName) == null) {
5790
Object filterWrapper = filters.get(filterName);
5891
String filterClassName = null;
5992
try {
@@ -68,14 +101,29 @@ private List<Map<String, String>> collectFiltersData(Object context) {
68101
filterClassName = filter.getClass().getName();
69102
}
70103
}
104+
Map<String, Object> info = new HashMap<>();
71105
info.put("filterName", filterName);
72106
info.put("filterClass", filterClassName);
73-
String[] urlPatterns = (String[]) invokeMethod(urlMap, "keys", null, null);
74-
info.put("urlPatterns", Arrays.toString(urlPatterns));
75-
result.add(info);
107+
info.put("urlPatterns", new LinkedHashSet<String>());
108+
info.put("servletNames", new LinkedHashSet<String>());
109+
aggregatedData.put(filterName, info);
76110
}
77-
} catch (Exception e) {
78-
e.printStackTrace();
111+
Map<String, Object> info = aggregatedData.get(filterName);
112+
String servletName = (String) getFieldValue(filterInfo, "servletName");
113+
if (servletName != null) {
114+
((Set<String>) info.get("servletNames")).add(servletName);
115+
}
116+
}
117+
List<Map<String, String>> result = new ArrayList<>();
118+
for (Map<String, Object> entry : aggregatedData.values()) {
119+
Map<String, String> finalInfo = new HashMap<>();
120+
finalInfo.put("filterName", (String) entry.get("filterName"));
121+
finalInfo.put("filterClass", (String) entry.get("filterClass"));
122+
Set<?> urls = (Set<?>) entry.get("urlPatterns");
123+
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
124+
Set<?> servletNames = (Set<?>) entry.get("servletNames");
125+
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
126+
result.add(finalInfo);
79127
}
80128
return result;
81129
}
@@ -96,6 +144,7 @@ private String formatFiltersData(Map<String, List<Map<String, String>>> allFilte
96144
appendIfPresent(output, "", info.get("filterName"), "");
97145
appendIfPresent(output, " -> ", info.get("filterClass"), "");
98146
appendIfPresent(output, " -> URL:", info.get("urlPatterns"), "");
147+
appendIfPresent(output, " -> Servlet:", info.get("servletNames"), "");
99148
output.append("\n");
100149
}
101150
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import com.reajason.javaweb.Server;
44
import com.reajason.javaweb.integration.ProbeAssertion;
5+
import com.reajason.javaweb.integration.ShellAssertion;
56
import com.reajason.javaweb.integration.VulTool;
67
import com.reajason.javaweb.integration.probe.DetectionTool;
8+
import com.reajason.javaweb.memshell.MemShellResult;
79
import com.reajason.javaweb.memshell.ShellTool;
810
import com.reajason.javaweb.memshell.ShellType;
911
import com.reajason.javaweb.packer.Packers;
12+
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
1013
import com.reajason.javaweb.utils.CommonUtil;
1114
import lombok.SneakyThrows;
1215
import lombok.extern.slf4j.Slf4j;
@@ -87,21 +90,17 @@ void testBytecodeReqParamResponseBody() {
8790
@Test
8891
void testFilterProbe() {
8992
String url = getUrlFromWebLogic(container);
90-
String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe());
91-
System.out.println(data);
92-
assertThat(data, anyOf(
93-
containsString("Context: ")
94-
));
93+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic));
94+
ShellAssertion.assertFilterProbeIsRight(data);
9595
}
9696

9797
@Test
9898
void testFilterFirstInject() {
9999
String url = getUrlFromWebLogic(container);
100-
shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container);
101-
String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe());
102-
log.info(data);
100+
MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container);
101+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic));
103102
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
104103
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
105-
assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.WebLogic))));
104+
assertEquals(filterName, memShellResult.getShellClassName());
106105
}
107106
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import com.reajason.javaweb.Server;
44
import com.reajason.javaweb.integration.ProbeAssertion;
5+
import com.reajason.javaweb.integration.ShellAssertion;
56
import com.reajason.javaweb.integration.VulTool;
67
import com.reajason.javaweb.integration.probe.DetectionTool;
8+
import com.reajason.javaweb.memshell.MemShellResult;
79
import com.reajason.javaweb.memshell.ShellTool;
810
import com.reajason.javaweb.memshell.ShellType;
911
import com.reajason.javaweb.packer.Packers;
12+
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
1013
import com.reajason.javaweb.utils.CommonUtil;
1114
import lombok.SneakyThrows;
1215
import lombok.extern.slf4j.Slf4j;
@@ -87,20 +90,17 @@ void testBytecodeReqParamResponseBody() {
8790
@Test
8891
void testFilterProbe() {
8992
String url = getUrlFromWebLogic(container);
90-
String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe());
91-
System.out.println(data);
92-
assertThat(data, anyOf(
93-
containsString("Context: ")
94-
));
93+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic));
94+
ShellAssertion.assertFilterProbeIsRight(data);
9595
}
9696

9797
@Test
9898
void testFilterFirstInject() {
9999
String url = getUrlFromWebLogic(container);
100-
shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container);
101-
String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe());
100+
MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container);
101+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic));
102102
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
103103
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
104-
assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.WebLogic))));
104+
assertEquals(filterName, memShellResult.getShellClassName());
105105
}
106106
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import com.reajason.javaweb.Server;
44
import com.reajason.javaweb.integration.ProbeAssertion;
5+
import com.reajason.javaweb.integration.ShellAssertion;
56
import com.reajason.javaweb.integration.VulTool;
67
import com.reajason.javaweb.integration.probe.DetectionTool;
8+
import com.reajason.javaweb.memshell.MemShellResult;
79
import com.reajason.javaweb.memshell.ShellTool;
810
import com.reajason.javaweb.memshell.ShellType;
911
import com.reajason.javaweb.packer.Packers;
12+
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
1013
import com.reajason.javaweb.utils.CommonUtil;
1114
import lombok.SneakyThrows;
1215
import lombok.extern.slf4j.Slf4j;
@@ -81,21 +84,17 @@ void testBytecodeReqParamResponseBody() {
8184
@Test
8285
void testFilterProbe() {
8386
String url = getUrlFromWebLogic(container);
84-
String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe());
85-
log.info(data);
86-
assertThat(data, anyOf(
87-
containsString("Context: ")
88-
));
87+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic));
88+
ShellAssertion.assertFilterProbeIsRight(data);
8989
}
9090

9191
@Test
9292
void testFilterFirstInject() {
9393
String url = getUrlFromWebLogic(container);
94-
shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container);
95-
String data = VulTool.post(url + "/b64", DetectionTool.getWebLogicFilterProbe());
96-
log.info(data);
94+
MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container);
95+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic));
9796
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
9897
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
99-
assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.WebLogic))));
98+
assertEquals(filterName, memShellResult.getShellClassName());
10099
}
101100
}

0 commit comments

Comments
 (0)