diff --git a/jmg-cli/pom.xml b/jmg-cli/pom.xml
new file mode 100644
index 0000000..72e0028
--- /dev/null
+++ b/jmg-cli/pom.xml
@@ -0,0 +1,64 @@
+
+
+ 4.0.0
+
+ jmg
+ java-memshell-generator
+ 1.0.8
+
+
+ jmg-cli
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+
+ org.jline
+ jline
+ 3.21.0
+
+
+ jmg
+ jmg-sdk
+ ${parent.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.6.0
+
+
+ jar-with-dependencies
+
+
+
+ jmg.cli.CLIApp
+
+
+ false
+ ../releases
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jmg-cli/src/main/java/jmg/cli/CLIApp.java b/jmg-cli/src/main/java/jmg/cli/CLIApp.java
new file mode 100644
index 0000000..998690f
--- /dev/null
+++ b/jmg-cli/src/main/java/jmg/cli/CLIApp.java
@@ -0,0 +1,9 @@
+package jmg.cli;
+
+public class CLIApp {
+ public static void main(String[] args) throws Throwable {
+ Console console = new Console();
+ console.init();
+ console.run();
+ }
+}
diff --git a/jmg-cli/src/main/java/jmg/cli/Console.java b/jmg-cli/src/main/java/jmg/cli/Console.java
new file mode 100644
index 0000000..332ef45
--- /dev/null
+++ b/jmg-cli/src/main/java/jmg/cli/Console.java
@@ -0,0 +1,234 @@
+package jmg.cli;
+
+import jmg.core.config.AbstractConfig;
+import jmg.core.config.Constants;
+import jmg.sdk.jMGenerator;
+import jmg.sdk.util.SDKResultUtil;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReaderBuilder;
+import org.jline.reader.impl.completer.StringsCompleter;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.TerminalBuilder;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+public class Console {
+
+ private static AbstractConfig config = new AbstractConfig();
+ private static final List SERVER_TYPES = Arrays.asList(
+ Constants.SERVER_TOMCAT,
+ Constants.SERVER_SPRING_MVC,
+ Constants.SERVER_JETTY,
+ Constants.SERVER_RESIN,
+ Constants.SERVER_WEBLOGIC,
+ Constants.SERVER_WEBSPHERE,
+ Constants.SERVER_UNDERTOW,
+ Constants.SERVER_GLASSFISH,
+ Constants.SERVER_JBOSS);
+ private static final List TOOL_TYPES = Arrays.asList(
+ Constants.TOOL_GODZILLA,
+ Constants.TOOL_BEHINDER,
+ Constants.TOOL_ANTSWORD,
+ Constants.TOOL_SUO5,
+ Constants.TOOL_NEOREGEORG);
+
+ private static final List SHELL_TYPES = Arrays.asList(
+ Constants.SHELL_LISTENER,
+ Constants.SHELL_FILTER,
+ Constants.SHELL_INTERCEPTOR);
+
+ private static final List FORMAT_TYPES = Arrays.asList(
+ Constants.FORMAT_BASE64,
+ Constants.FORMAT_BCEL,
+ Constants.FORMAT_BIGINTEGER,
+ Constants.FORMAT_CLASS,
+ Constants.FORMAT_JAR,
+ Constants.FORMAT_JAR_AGENT,
+ Constants.FORMAT_JSP);
+
+ private static final List GADGET_TYPES = Arrays.asList(
+ Constants.GADGET_NONE,
+ Constants.GADGET_JDK_TRANSLET,
+ Constants.GADGET_XALAN_TRANSLET,
+ Constants.GADGET_FJ_GROOVY,
+ Constants.GADGET_SNAKEYAML);
+
+
+ public void init() {
+ System.out.println(String.format("Welcome to jMG %s !", Constants.JMG_VERSION));
+ config = new AbstractConfig() {{
+ // 设置工具类型
+ setToolType(Constants.TOOL_GODZILLA);
+ // 设置中间件 or 框架
+ setServerType(Constants.SERVER_TOMCAT);
+ // 设置内存马类型
+ setShellType(Constants.SHELL_LISTENER);
+ // 设置输出格式为 BASE64
+ setOutputFormat(Constants.FORMAT_BASE64);
+ // 设置漏洞利用封装,默认不启用
+ setGadgetType(Constants.GADGET_NONE);
+ // 初始化基础配置
+ build();
+ }};
+
+ }
+
+ public void run() throws Throwable {
+ List commands = Arrays.asList("help", "list", "use", "set", "show", "generate", "info", "exit");
+ Terminal terminal = TerminalBuilder.builder().build();
+ LineReader lineReader = LineReaderBuilder.builder()
+ .terminal(terminal)
+ .completer(new StringsCompleter(commands))
+ .build();
+
+ String prompt = "jmg > ";
+ String line;
+ while (true) {
+ line = lineReader.readLine(prompt);
+ String[] parts = line.trim().split("\\s+");
+ String command = parts[0];
+ String argument1 = parts.length > 1 ? parts[1] : null;
+ String argument2 = parts.length > 2 ? parts[2] : null;
+ switch (command) {
+ case "help":
+ help();
+ break;
+ case "list":
+ list(argument1);
+ break;
+ case "use":
+ use(argument1, argument2);
+ break;
+ case "set":
+ set(argument1, argument2);
+ break;
+ case "get":
+ get(argument1);
+ break;
+ case "generate":
+ generate();
+ break;
+ case "info":
+ info();
+ break;
+ case "exit":
+ System.out.println("Bye!");
+ return;
+ default:
+ System.out.println("Unknown command: " + line);
+ }
+ }
+ }
+
+ public static void help() {
+ String[][] helpMessages = {
+ {"help", "help message", "帮助信息"},
+ {"list [type]", "list toolTypes/serverTypes/formatTypes/shellTypes", "支持的工具类型/中间件|框架/组件类型/输出格式"},
+ {"use ", "choose toolType/serverType/formatType/shellType", "选择工具类型/中间件|框架/组件类型/输出格式"},
+ {"set ", "set pass/key/headerName/headerValue/urlPattern/...", "设置密码/密钥/请求头名称/请求头值/请求路径[/*]/..."},
+ {"get ", "get or ", "查看配置"},
+ {"generate", "generate payload", "生成载荷"},
+ {"info", "connect info", "连接信息"},
+ {"exit", "exit jmg", "退出"}
+ };
+
+ for (String[] message : helpMessages) {
+ System.out.println(String.format("%-20s %-50s %-40s", message[0], message[1], message[2]));
+ }
+ }
+
+
+ public static void list(String argument1) {
+ if ("serverTypes".equalsIgnoreCase(argument1)) {
+ System.out.println("Servers: " + SERVER_TYPES);
+ } else if ("toolTypes".equalsIgnoreCase(argument1)) {
+ System.out.println("Tools: " + TOOL_TYPES);
+ } else if ("shellTypes".equalsIgnoreCase(argument1)) {
+ System.out.println("Shells: " + SHELL_TYPES);
+ } else if ("formatTypes".equalsIgnoreCase(argument1)) {
+ System.out.println("Formats: " + FORMAT_TYPES);
+ } else if ("gadgetTypes".equalsIgnoreCase(argument1)) {
+ System.out.println("Gadgets: " + GADGET_TYPES);
+ } else {
+ System.out.println("Unknown type: " + argument1);
+ }
+ }
+
+ public static void get(String argument1) {
+ try {
+ String methodName = "get" + argument1.substring(0, 1).toUpperCase() + argument1.substring(1);
+ Method method = config.getClass().getMethod(methodName);
+ System.out.println(argument1 + " : " + method.invoke(config));
+ } catch (NoSuchMethodException e) {
+ System.out.println("Unknown type: " + argument1);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ System.out.println("Error getting value for type: " + argument1);
+ }
+ }
+
+ public static void use(String argument1, String argument2) {
+ if ("serverType".equalsIgnoreCase(argument1)) {
+ if (!SERVER_TYPES.contains(argument2)) {
+ System.out.println("Unsupported server type: " + argument2);
+ return;
+ }
+ set("serverType", argument2);
+ } else if ("toolType".equalsIgnoreCase(argument1)) {
+ if (!TOOL_TYPES.contains(argument2)) {
+ System.out.println("Unsupported tool type: " + argument2);
+ return;
+ }
+ set("toolType", argument2);
+ } else if ("shellType".equalsIgnoreCase(argument1)) {
+ if (!SHELL_TYPES.contains(argument2)) {
+ System.out.println("Unsupported shell type: " + argument2);
+ return;
+ }
+ set("shellType", argument2);
+ } else if ("formatType".equalsIgnoreCase(argument1)) {
+ if (!FORMAT_TYPES.contains(argument2)) {
+ System.out.println("Unsupported format type: " + argument2);
+ return;
+ }
+ set("outputFormat", argument2);
+ } else if ("gadgetType".equalsIgnoreCase(argument1)) {
+ if (!GADGET_TYPES.contains(argument2)) {
+ System.out.println("Unsupported gadget type: " + argument2);
+ return;
+ }
+ set("gadgetType", argument2);
+ } else {
+ System.out.println("Unknown type: " + argument1);
+ }
+ }
+
+ public static void set(String argument1, String argument2) {
+ try {
+ String methodName = "set" + argument1.substring(0, 1).toUpperCase() + argument1.substring(1);
+ Method method = config.getClass().getMethod(methodName, String.class);
+ method.invoke(config, argument2);
+ System.out.println(argument1 + " : " + argument2);
+ } catch (NoSuchMethodException e) {
+ System.out.println("Unknown key: " + argument1);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ System.out.println("Error setting value for key: " + argument1);
+ }
+ }
+
+ public static void generate() throws Throwable {
+ // 更新配置
+ config.build();
+ jMGenerator generator = new jMGenerator(config);
+ generator.genPayload();
+ generator.printPayload();
+ }
+
+ public static void info() throws Throwable {
+ // 连接信息
+ SDKResultUtil.printBasicInfo(config);
+ SDKResultUtil.printDebugInfo(config);
+ }
+}
\ No newline at end of file