mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
fix: wrong jetty handler will disrupt service
This commit is contained in:
+11
@@ -3,6 +3,7 @@ package com.reajason.javaweb.memshell.generator.processors;
|
|||||||
import com.reajason.javaweb.GenerationException;
|
import com.reajason.javaweb.GenerationException;
|
||||||
import com.reajason.javaweb.asm.ClassRenameUtils;
|
import com.reajason.javaweb.asm.ClassRenameUtils;
|
||||||
import com.reajason.javaweb.asm.ClassSuperClassUtils;
|
import com.reajason.javaweb.asm.ClassSuperClassUtils;
|
||||||
|
import com.reajason.javaweb.asm.MethodUtils;
|
||||||
import com.reajason.javaweb.memshell.ServerFactory;
|
import com.reajason.javaweb.memshell.ServerFactory;
|
||||||
import com.reajason.javaweb.memshell.ShellType;
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
@@ -31,13 +32,23 @@ public class JettyHandlerPostProcessor implements Processor<byte[]> {
|
|||||||
switch (serverVersion) {
|
switch (serverVersion) {
|
||||||
case "6":
|
case "6":
|
||||||
superClassName = "org/mortbay/jetty/handler/AbstractHandler";
|
superClassName = "org/mortbay/jetty/handler/AbstractHandler";
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;Lorg/eclipse/jetty/util/Callback;)Z");
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Lorg/eclipse/jetty/server/Request;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V");
|
||||||
bytes = ClassRenameUtils.relocateClass(bytes, "org/eclipse/jetty/server", "org/mortbay/jetty");
|
bytes = ClassRenameUtils.relocateClass(bytes, "org/eclipse/jetty/server", "org/mortbay/jetty");
|
||||||
break;
|
break;
|
||||||
case "7+":
|
case "7+":
|
||||||
superClassName = "org/eclipse/jetty/server/handler/AbstractHandler";
|
superClassName = "org/eclipse/jetty/server/handler/AbstractHandler";
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;Lorg/eclipse/jetty/util/Callback;)Z");
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;I)V");
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;I)V");
|
||||||
break;
|
break;
|
||||||
case "12":
|
case "12":
|
||||||
superClassName = "org/eclipse/jetty/server/Handler$Abstract";
|
superClassName = "org/eclipse/jetty/server/Handler$Abstract";
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/Object;Ljava/lang/Object;)Z");
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;I)V");
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;I)V");
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Lorg/eclipse/jetty/server/Request;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V");
|
||||||
|
bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Lorg/eclipse/jetty/server/Request;Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;)V");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
@@ -59,6 +59,7 @@ public class JettyHandlerInjector {
|
|||||||
if (handler.getClass().isAssignableFrom(nextHandler.getClass())) {
|
if (handler.getClass().isAssignableFrom(nextHandler.getClass())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
validateHandler(handler);
|
||||||
setFieldValue(handler, "nextHandler", nextHandler);
|
setFieldValue(handler, "nextHandler", nextHandler);
|
||||||
setFieldValue(handler, "_server", server);
|
setFieldValue(handler, "_server", server);
|
||||||
|
|
||||||
@@ -77,6 +78,20 @@ public class JettyHandlerInjector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validateHandler(Object shell) throws Exception {
|
||||||
|
Class<?> handlerClass = shell.getClass().getSuperclass();
|
||||||
|
Method rightHandleMethod = null;
|
||||||
|
for (Method method : handlerClass.getMethods()) {
|
||||||
|
if (method.getName().equals("handle")) {
|
||||||
|
rightHandleMethod = method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shell.getClass().getMethod(
|
||||||
|
"handle",
|
||||||
|
rightHandleMethod.getParameterTypes()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return msg;
|
return msg;
|
||||||
|
|||||||
+1
-1
@@ -85,6 +85,6 @@ public class Jetty12ee10ContainerTest {
|
|||||||
ShellType.JAKARTA_HANDLER})
|
ShellType.JAKARTA_HANDLER})
|
||||||
void testProbeInject(String shellType) {
|
void testProbeInject(String shellType) {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17);
|
ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -86,6 +86,6 @@ public class Jetty12ee11ContainerTest {
|
|||||||
ShellType.JAKARTA_HANDLER})
|
ShellType.JAKARTA_HANDLER})
|
||||||
void testProbeInject(String shellType) {
|
void testProbeInject(String shellType) {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17);
|
ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -83,6 +83,6 @@ public class Jetty12ee8ContainerTest {
|
|||||||
ShellType.HANDLER,})
|
ShellType.HANDLER,})
|
||||||
void testProbeInject(String shellType) {
|
void testProbeInject(String shellType) {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17);
|
ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -85,6 +85,6 @@ public class Jetty12ee9ContainerTest {
|
|||||||
ShellType.JAKARTA_HANDLER})
|
ShellType.JAKARTA_HANDLER})
|
||||||
void testProbeInject(String shellType) {
|
void testProbeInject(String shellType) {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17);
|
ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.reajason.javaweb.asm;
|
||||||
|
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/12/7
|
||||||
|
*/
|
||||||
|
public class MethodUtils {
|
||||||
|
|
||||||
|
public static byte[] removeMethod(byte[] bytes, String methodName) {
|
||||||
|
ClassReader cr = new ClassReader(bytes);
|
||||||
|
ClassWriter cw = new ClassWriter(0);
|
||||||
|
RemoveMethodAdapter adapter = new RemoveMethodAdapter(cw, methodName);
|
||||||
|
cr.accept(adapter, 0);
|
||||||
|
return cw.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] removeMethodByMethodDescriptor(byte[] bytes, String methodName, String methodDescriptor) {
|
||||||
|
ClassReader cr = new ClassReader(bytes);
|
||||||
|
ClassWriter cw = new ClassWriter(0);
|
||||||
|
RemoveMethodAdapter adapter = new RemoveMethodAdapter(cw, methodName, methodDescriptor);
|
||||||
|
cr.accept(adapter, 0);
|
||||||
|
return cw.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class RemoveMethodAdapter extends ClassVisitor {
|
||||||
|
private String methodName;
|
||||||
|
private String methodDescriptor;
|
||||||
|
|
||||||
|
public RemoveMethodAdapter(ClassVisitor cv, String methodName) {
|
||||||
|
super(Opcodes.ASM9, cv);
|
||||||
|
this.methodName = methodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoveMethodAdapter(ClassVisitor cv, String methodName, String methodDescriptor) {
|
||||||
|
super(Opcodes.ASM9, cv);
|
||||||
|
this.methodName = methodName;
|
||||||
|
this.methodDescriptor = methodDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(
|
||||||
|
int access, String name, String descriptor,
|
||||||
|
String signature, String[] exceptions) {
|
||||||
|
if (methodDescriptor != null) {
|
||||||
|
if (methodDescriptor.equals(descriptor) && methodName.equals(name)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (methodName.equals(name)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user