Skip to content

Commit 1166036

Browse files
committed
feat: support servletNameFilter for GlassFishFilterProbe
1 parent 90b9116 commit 1166036

37 files changed

Lines changed: 172 additions & 161 deletions

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

Lines changed: 67 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,85 +10,101 @@
1010
* @author ReaJason
1111
*/
1212
public class GlassFishFilterProbe {
13+
1314
@Override
1415
public String toString() {
15-
String msg = "";
16+
StringBuilder msg = new StringBuilder();
1617
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
1718
Set<Object> contexts = null;
1819
try {
1920
contexts = getContext();
2021
} catch (Throwable throwable) {
21-
msg += "context error: " + getErrorMessage(throwable);
22+
msg.append("context error: ").append(getErrorMessage(throwable));
2223
}
2324
if (contexts == null || contexts.isEmpty()) {
24-
msg += "context not found\n";
25+
msg.append("context not found\n");
2526
} else {
2627
for (Object context : contexts) {
2728
String contextRoot = getContextRoot(context);
28-
List<Map<String, String>> filters = collectFiltersData(context);
29-
allFiltersData.put(contextRoot, filters);
29+
try {
30+
List<Map<String, String>> filters = collectFiltersData(context);
31+
allFiltersData.put(contextRoot, filters);
32+
} catch (Throwable e) {
33+
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
34+
}
3035
}
31-
msg += formatFiltersData(allFiltersData);
36+
msg.append(formatFiltersData(allFiltersData));
3237
}
33-
return msg;
38+
return msg.toString();
3439
}
3540

36-
private List<Map<String, String>> collectFiltersData(Object context) {
41+
@SuppressWarnings("unchecked")
42+
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
3743
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
3844

39-
try {
40-
List filterMaps = (List) invokeMethod(context, "findFilterMaps");
41-
if (filterMaps == null || filterMaps.isEmpty()) return Collections.emptyList();
42-
43-
Object[] filterDefs = (Object[]) invokeMethod(context, "findFilterDefs");
44-
for (Object fm : filterMaps) {
45-
String name = (String) invokeMethod(fm, "getFilterName");
46-
if (name == null) continue;
47-
if (!aggregatedData.containsKey(name)) {
48-
String filterClass = "N/A";
49-
if (filterDefs != null) {
50-
for (Object def : filterDefs) {
51-
if (!name.equals(invokeMethod(def, "getFilterName"))) continue;
52-
Class<?> cls = (Class<?>) invokeMethod(def, "getFilterClass");
53-
if (cls == null) {
54-
Object config = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
55-
Object filter = config != null ? invokeMethod(config, "getFilter") : null;
56-
if (filter != null) filterClass = filter.getClass().getName();
57-
}
58-
if (cls != null) filterClass = cls.getName();
59-
break;
60-
}
61-
}
62-
Map<String, Object> info = new HashMap<>();
63-
info.put("filterName", name);
64-
info.put("filterClass", filterClass);
65-
info.put("urlPatterns", new LinkedHashSet<String>());
66-
info.put("servletNames", new LinkedHashSet<String>());
67-
aggregatedData.put(name, info);
68-
}
69-
Map<String, Object> info = aggregatedData.get(name);
70-
String[] urls = null;
71-
try {
72-
urls = (String[]) invokeMethod(fm, "getURLPatterns");
73-
} catch (Exception e) {
45+
List filterMaps = (List) invokeMethod(context, "findFilterMaps");
46+
if (filterMaps == null || filterMaps.isEmpty()) return Collections.emptyList();
47+
48+
Object[] filterDefs = (Object[]) invokeMethod(context, "findFilterDefs");
49+
50+
for (Object fm : filterMaps) {
51+
String name = (String) invokeMethod(fm, "getFilterName");
52+
if (name == null) continue;
53+
if (!aggregatedData.containsKey(name)) {
54+
String filterClass = "N/A";
55+
if (filterDefs != null) {
56+
Object filterDef = invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{name});
7457
try {
75-
Object urlPattern = invokeMethod(fm, "getURLPattern");
76-
if (urlPattern instanceof String) {
77-
urls = new String[] { (String) urlPattern };
78-
}
79-
} catch (Exception ignored) {
58+
filterClass = (String) invokeMethod(filterDef, "getFilterClass");
59+
} catch (Throwable throwable) {
60+
filterClass = (String) invokeMethod(filterDef, "getFilterClassName");
8061
}
62+
if (filterClass == null) {
63+
Object filterConfig = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
64+
Object filter = invokeMethod(filterConfig, "getFilter");
65+
if (filter != null) filterClass = filter.getClass().getName();
66+
}
67+
}
68+
Map<String, Object> info = new HashMap<>();
69+
info.put("filterName", name);
70+
info.put("filterClass", filterClass);
71+
info.put("urlPatterns", new LinkedHashSet<String>());
72+
info.put("servletNames", new LinkedHashSet<String>());
73+
aggregatedData.put(name, info);
74+
}
75+
Map<String, Object> info = aggregatedData.get(name);
76+
String[] urls = null;
77+
try {
78+
urls = (String[]) invokeMethod(fm, "getURLPatterns");
79+
} catch (Exception e) {
80+
// Tomcat 5
81+
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
82+
if (urlPattern != null) {
83+
urls = new String[]{urlPattern};
8184
}
82-
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
8385
}
84-
} catch (Exception ignored) {}
86+
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
87+
String[] servletNames = null;
88+
try {
89+
servletNames = (String[]) invokeMethod(fm, "getServletNames");
90+
} catch (Exception e) {
91+
// Tomcat 5
92+
String servletName = (String) invokeMethod(fm, "getServletName");
93+
if (servletName != null) {
94+
servletNames = new String[]{servletName};
95+
}
96+
}
97+
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
98+
}
8599
List<Map<String, String>> result = new ArrayList<>();
86100
for (Map<String, Object> entry : aggregatedData.values()) {
87101
Map<String, String> finalInfo = new HashMap<>();
88102
finalInfo.put("filterName", (String) entry.get("filterName"));
89103
finalInfo.put("filterClass", (String) entry.get("filterClass"));
90104
Set<?> urls = (Set<?>) entry.get("urlPatterns");
91105
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
106+
Set<?> servletNames = (Set<?>) entry.get("servletNames");
107+
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
92108
result.add(finalInfo);
93109
}
94110
return result;
@@ -111,6 +127,7 @@ private String formatFiltersData(Map<String, List<Map<String, String>>> allFilte
111127
appendIfPresent(output, "", info.get("filterName"), "");
112128
appendIfPresent(output, " -> ", info.get("filterClass"), "");
113129
appendIfPresent(output, " -> URL:", info.get("urlPatterns"), "");
130+
appendIfPresent(output, " -> Servlet:", info.get("servletNames"), "");
114131
output.append("\n");
115132
}
116133
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,21 @@ private List<Map<String, String>> collectFiltersData(Object context) throws Exce
7474
urls = (String[]) invokeMethod(fm, "getURLPatterns");
7575
} catch (Exception e) {
7676
// Tomcat 5
77-
urls = new String[]{(String) invokeMethod(fm, "getURLPattern")};
77+
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
78+
if (urlPattern != null) {
79+
urls = new String[]{urlPattern};
80+
}
7881
}
7982
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
8083
String[] servletNames = null;
8184
try {
8285
servletNames = (String[]) invokeMethod(fm, "getServletNames");
8386
} catch (Exception e) {
8487
// Tomcat 5
85-
servletNames = new String[]{(String) invokeMethod(fm, "getServletName")};
88+
String servletName = (String) invokeMethod(fm, "getServletName");
89+
if (servletName != null) {
90+
servletNames = new String[]{servletName};
91+
}
8692
}
8793
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
8894
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/DetectionTool.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,6 @@ public static String getServerDetection() {
3535
return getBase64Class(ServerProbe.class);
3636
}
3737

38-
public static String getTomcatFilterProbe() {
39-
return getBase64Class(TomcatFilterProbe.class);
40-
}
41-
42-
public static String getJettyFilterProbe() {
43-
return getBase64Class(JettyFilterProbe.class);
44-
}
45-
4638
public static String getResinFilterProbe() {
4739
return getBase64Class(ResinFilterProbe.class);
4840
}
@@ -51,10 +43,6 @@ public static String getUndertowFilterProbe() {
5143
return getBase64Class(UndertowFilterProbe.class);
5244
}
5345

54-
public static String getGlassFishFilterProbe() {
55-
return getBase64Class(GlassFishFilterProbe.class);
56-
}
57-
5846
public static String getApusicFilterProbe() {
5947
return getBase64Class(ApusicFilterProbe.class);
6048
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish3ContainerTest.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;
@@ -94,20 +97,17 @@ void testBytecodeReqParamResponseBody() {
9497
@Test
9598
void testFilterProbe() {
9699
String url = getUrl(container);
97-
String data = VulTool.post(url + "/b64", DetectionTool.getGlassFishFilterProbe());
98-
System.out.println(data);
99-
assertThat(data, anyOf(
100-
containsString("EmptyFilter")
101-
));
100+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
101+
ShellAssertion.assertFilterProbeIsRight(data);
102102
}
103103

104104
@Test
105105
void testFilterFirstInject() {
106106
String url = getUrl(container);
107-
shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
108-
String data = VulTool.post(url + "/b64", DetectionTool.getGlassFishFilterProbe());
107+
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
108+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
109109
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
110110
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
111-
assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.GlassFish))));
111+
assertEquals(filterName, memShellResult.getShellClassName());
112112
}
113113
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish4ContainerTest.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;
@@ -94,20 +97,17 @@ void testBytecodeReqParamResponseBody() {
9497
@Test
9598
void testFilterProbe() {
9699
String url = getUrl(container);
97-
String data = VulTool.post(url + "/b64", DetectionTool.getGlassFishFilterProbe());
98-
System.out.println(data);
99-
assertThat(data, anyOf(
100-
containsString("EmptyFilter")
101-
));
100+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
101+
ShellAssertion.assertFilterProbeIsRight(data);
102102
}
103103

104104
@Test
105105
void testFilterFirstInject() {
106106
String url = getUrl(container);
107-
shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
108-
String data = VulTool.post(url + "/b64", DetectionTool.getGlassFishFilterProbe());
107+
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
108+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
109109
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
110110
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
111-
assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.GlassFish))));
111+
assertEquals(filterName, memShellResult.getShellClassName());
112112
}
113113
}

integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish501ContainerTest.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 = getUrl(container);
90-
String data = VulTool.post(url + "/b64", DetectionTool.getGlassFishFilterProbe());
91-
System.out.println(data);
92-
assertThat(data, anyOf(
93-
containsString("EmptyFilter")
94-
));
93+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
94+
ShellAssertion.assertFilterProbeIsRight(data);
9595
}
9696

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

integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish510ContainerTest.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;
@@ -88,20 +91,17 @@ void testBytecodeReqParamResponseBody() {
8891
@Test
8992
void testFilterProbe() {
9093
String url = getUrl(container);
91-
String data = VulTool.post(url + "/b64", DetectionTool.getGlassFishFilterProbe());
92-
System.out.println(data);
93-
assertThat(data, anyOf(
94-
containsString("EmptyFilter")
95-
));
94+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
95+
ShellAssertion.assertFilterProbeIsRight(data);
9696
}
9797

9898
@Test
9999
void testFilterFirstInject() {
100100
String url = getUrl(container);
101-
shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
102-
String data = VulTool.post(url + "/b64", DetectionTool.getGlassFishFilterProbe());
101+
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
102+
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
103103
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
104104
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
105-
assertThat(filterName, anyOf(startsWith(CommonUtil.getWebPackageNameForServer(Server.GlassFish))));
105+
assertEquals(filterName, memShellResult.getShellClassName());
106106
}
107107
}

0 commit comments

Comments
 (0)