Skip to content

Commit d5c7b73

Browse files
committed
add: 添加对 woodpecker-framework 插件的支持
1 parent ac9c608 commit d5c7b73

15 files changed

+1318
-1
lines changed

jmg-woodpecker/pom.xml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>jmg</groupId>
8+
<artifactId>java-memshell-generator</artifactId>
9+
<version>${project.build.version}</version>
10+
</parent>
11+
12+
<artifactId>jmg-woodpecker</artifactId>
13+
14+
<properties>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
17+
</properties>
18+
<dependencies>
19+
<dependency>
20+
<groupId>jmg</groupId>
21+
<artifactId>jmg-core</artifactId>
22+
<version>${project.build.version}</version>
23+
<scope>compile</scope>
24+
</dependency>
25+
<dependency>
26+
<groupId>jmg</groupId>
27+
<artifactId>jmg-antsword</artifactId>
28+
<version>${project.build.version}</version>
29+
<scope>compile</scope>
30+
</dependency>
31+
<dependency>
32+
<groupId>jmg</groupId>
33+
<artifactId>jmg-behinder</artifactId>
34+
<version>${project.build.version}</version>
35+
<scope>compile</scope>
36+
</dependency>
37+
<dependency>
38+
<groupId>jmg</groupId>
39+
<artifactId>jmg-custom</artifactId>
40+
<version>${project.build.version}</version>
41+
<scope>compile</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>jmg</groupId>
45+
<artifactId>jmg-godzilla</artifactId>
46+
<version>${project.build.version}</version>
47+
<scope>compile</scope>
48+
</dependency>
49+
<dependency>
50+
<groupId>jmg</groupId>
51+
<artifactId>jmg-extender</artifactId>
52+
<version>${project.build.version}</version>
53+
<scope>compile</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>jmg</groupId>
57+
<artifactId>jmg-neoregeorg</artifactId>
58+
<version>${project.build.version}</version>
59+
<scope>compile</scope>
60+
</dependency>
61+
<dependency>
62+
<groupId>jmg</groupId>
63+
<artifactId>jmg-suo5</artifactId>
64+
<version>${project.build.version}</version>
65+
<scope>compile</scope>
66+
</dependency>
67+
</dependencies>
68+
69+
</project>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package me.gv7.woodpecker.helper;
2+
3+
4+
import jmg.antsword.generator.AntSwordGenerator;
5+
import jmg.core.config.AbstractConfig;
6+
import jmg.core.config.Constants;
7+
import jmg.core.generator.InjectorGenerator;
8+
import me.gv7.woodpecker.plugin.IResultOutput;
9+
import me.gv7.woodpecker.plugin.ShellHelperPlugin;
10+
import me.gv7.woodpecker.util.JMGResultUtil;
11+
12+
import java.util.Map;
13+
14+
public class AntSwordHelper extends ShellHelper {
15+
16+
@Override
17+
public String getHelperTabCaption() {
18+
return Constants.TOOL_ANTSWORD;
19+
}
20+
21+
@Override
22+
public void doHelp(Map<String, Object> customArgs, IResultOutput resultOutput) {
23+
try {
24+
AbstractConfig config = initConfig(customArgs);
25+
new AntSwordGenerator().makeShell(config);
26+
new InjectorGenerator().makeInjector(config);
27+
JMGResultUtil.printAntSwordBasicInfo(resultOutput, config);
28+
JMGResultUtil.printResult(resultOutput, config);
29+
JMGResultUtil.printDebugInfo(resultOutput, config);
30+
} catch (Exception e) {
31+
resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e));
32+
}
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package me.gv7.woodpecker.helper;
2+
3+
import jmg.behinder.generator.BehinderGenerator;
4+
import jmg.core.config.AbstractConfig;
5+
import jmg.core.config.Constants;
6+
import jmg.core.generator.InjectorGenerator;
7+
import me.gv7.woodpecker.plugin.IResultOutput;
8+
import me.gv7.woodpecker.plugin.ShellHelperPlugin;
9+
import me.gv7.woodpecker.util.JMGResultUtil;
10+
11+
import java.util.Map;
12+
13+
public class BehinderHelper extends ShellHelper {
14+
15+
16+
@Override
17+
public String getHelperTabCaption() {
18+
return Constants.TOOL_BEHINDER;
19+
}
20+
21+
@Override
22+
public void doHelp(Map<String, Object> customArgs, IResultOutput resultOutput) {
23+
try {
24+
AbstractConfig config = initConfig(customArgs);
25+
new BehinderGenerator().makeShell(config);
26+
new InjectorGenerator().makeInjector(config);
27+
JMGResultUtil.printBehinderBasicInfo(resultOutput, config);
28+
JMGResultUtil.printResult(resultOutput, config);
29+
JMGResultUtil.printDebugInfo(resultOutput, config);
30+
} catch (Exception e) {
31+
resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e));
32+
}
33+
}
34+
}
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
package me.gv7.woodpecker.helper;
2+
3+
import javassist.ClassClassPath;
4+
import javassist.ClassPool;
5+
import javassist.CtClass;
6+
import javassist.NotFoundException;
7+
import jmg.core.config.AbstractConfig;
8+
import jmg.core.config.Constants;
9+
import jmg.core.generator.InjectorGenerator;
10+
import jmg.core.util.ClassNameUtil;
11+
import jmg.core.util.CommonUtil;
12+
import jmg.custom.generator.CustomGenerator;
13+
import me.gv7.woodpecker.plugin.ShellHelperPlugin;
14+
import me.gv7.woodpecker.plugin.*;
15+
import me.gv7.woodpecker.util.JMGResultUtil;
16+
import javax.servlet.Filter;
17+
import javax.servlet.ServletRequestListener;
18+
import java.io.DataInputStream;
19+
import java.io.File;
20+
import java.io.FileInputStream;
21+
import java.io.IOException;
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
import java.util.Map;
25+
26+
public class CustomHelper implements IHelper {
27+
@Override
28+
public String getHelperTabCaption() {
29+
return Constants.TOOL_CUSTOM;
30+
}
31+
32+
@Override
33+
public IArgsUsageBinder getHelperCutomArgs() {
34+
IArgsUsageBinder binder = ShellHelperPlugin.pluginHelper.createArgsUsageBinder();
35+
List<IArg> list = new ArrayList();
36+
37+
IArg server_type = ShellHelperPlugin.pluginHelper.createArg();
38+
server_type.setName("server_type");
39+
server_type.setType(7);
40+
List<String> enumServerType = new ArrayList();
41+
enumServerType.add(Constants.SERVER_TOMCAT);
42+
enumServerType.add(Constants.SERVER_SPRING_MVC);
43+
enumServerType.add(Constants.SERVER_JETTY);
44+
enumServerType.add(Constants.SERVER_RESIN);
45+
enumServerType.add(Constants.SERVER_WEBLOGIC);
46+
enumServerType.add(Constants.SERVER_WEBSPHERE);
47+
enumServerType.add(Constants.SERVER_UNDERTOW);
48+
enumServerType.add(Constants.SERVER_GLASSFISH);
49+
server_type.setEnumValue(enumServerType);
50+
server_type.setDefaultValue(Constants.SERVER_TOMCAT);
51+
server_type.setRequired(true);
52+
server_type.setDescription("自定义中间件");
53+
list.add(server_type);
54+
55+
IArg shell_type = ShellHelperPlugin.pluginHelper.createArg();
56+
shell_type.setName("shell_type");
57+
shell_type.setType(7);
58+
List<String> enumShellType = new ArrayList();
59+
enumShellType.add(Constants.SHELL_LISTENER);
60+
enumShellType.add(Constants.SHELL_FILTER);
61+
enumShellType.add(Constants.SHELL_INTERCEPTOR);
62+
shell_type.setEnumValue(enumShellType);
63+
64+
IArg gadgetType = ShellHelperPlugin.pluginHelper.createArg();
65+
gadgetType.setName("gadget_type");
66+
gadgetType.setType(7);
67+
List<String> enumGadgetType = new ArrayList();
68+
enumGadgetType.add(Constants.GADGET_NONE);
69+
enumGadgetType.add(Constants.GADGET_JDK_TRANSLET);
70+
enumGadgetType.add(Constants.GADGET_XALAN_TRANSLET);
71+
enumGadgetType.add(Constants.GADGET_FJ_GROOVY);
72+
enumGadgetType.add(Constants.GADGET_SNAKEYAML);
73+
gadgetType.setEnumValue(enumGadgetType);
74+
gadgetType.setDefaultValue(Constants.GADGET_NONE);
75+
gadgetType.setRequired(true);
76+
gadgetType.setDescription("自定义利用链");
77+
list.add(gadgetType);
78+
79+
80+
IArg formatType = ShellHelperPlugin.pluginHelper.createArg();
81+
formatType.setName("format_type");
82+
formatType.setType(7);
83+
List<String> enumFormattType = new ArrayList();
84+
enumFormattType.add(Constants.FORMAT_BASE64);
85+
enumFormattType.add(Constants.FORMAT_BIGINTEGER);
86+
enumFormattType.add(Constants.FORMAT_BCEL);
87+
enumFormattType.add(Constants.FORMAT_CLASS);
88+
enumFormattType.add(Constants.FORMAT_JAR);
89+
enumFormattType.add(Constants.FORMAT_JAR_AGENT);
90+
enumFormattType.add(Constants.FORMAT_JSP);
91+
formatType.setEnumValue(enumFormattType);
92+
formatType.setDefaultValue(Constants.FORMAT_BASE64);
93+
formatType.setRequired(true);
94+
formatType.setDescription("自定义输出格式");
95+
list.add(formatType);
96+
97+
IArg class_file_path = ShellHelperPlugin.pluginHelper.createArg();
98+
class_file_path.setName("class_file_path");
99+
class_file_path.setDefaultValue("/tmp/woo.class");
100+
class_file_path.setDescription("自定义内存马文件(.class)");
101+
class_file_path.setRequired(true);
102+
list.add(class_file_path);
103+
104+
IArg injector_class_name = ShellHelperPlugin.pluginHelper.createArg();
105+
injector_class_name.setName("injector_class_name");
106+
injector_class_name.setType(0);
107+
injector_class_name.setRequired(false);
108+
injector_class_name.setDescription("自定义注入器类名");
109+
list.add(injector_class_name);
110+
IArg url_pattern = ShellHelperPlugin.pluginHelper.createArg();
111+
112+
url_pattern.setName("url_pattern");
113+
url_pattern.setType(0);
114+
url_pattern.setDefaultValue("/*");
115+
url_pattern.setRequired(false);
116+
url_pattern.setDescription("自定义请求路径");
117+
list.add(url_pattern);
118+
119+
IArg output_path = ShellHelperPlugin.pluginHelper.createArg();
120+
output_path.setName("output_path");
121+
output_path.setType(0);
122+
output_path.setDefaultValue("workdir");
123+
output_path.setRequired(false);
124+
output_path.setDescription("自定义输出路径");
125+
list.add(output_path);
126+
127+
binder.setArgsList(list);
128+
return binder;
129+
}
130+
131+
@Override
132+
public void doHelp(Map<String, Object> customArgs, IResultOutput resultOutput) {
133+
try {
134+
135+
AbstractConfig config = new AbstractConfig();
136+
config.setToolType(Constants.TOOL_CUSTOM);
137+
config.setServerType((String) customArgs.get("server_type"));
138+
config.setShellType((String) customArgs.get("shell_type"));
139+
config.setOutputFormat((String) customArgs.get("format_type"));
140+
config.setGadgetType((String) customArgs.get("gadget_type"));
141+
if (customArgs.get("url_pattern") != null) config.setUrlPattern((String) customArgs.get("url_pattern"));
142+
if (customArgs.get("shell_class_name") != null)
143+
config.setShellClassName((String) customArgs.get("shell_class_name"));
144+
if (customArgs.get("injector_class_name") != null)
145+
config.setInjectorClassName((String) customArgs.get("injector_class_name"));
146+
if (customArgs.get("output_path") != null) config.setSavePath((String) customArgs.get("output_path"));
147+
if (customArgs.get("class_file_path") != null)
148+
config.setClassFilePath((String) customArgs.get("class_file_path"));
149+
if (config.getInjectorClassName() == null)
150+
config.setInjectorClassName(ClassNameUtil.getRandomInjectorClassName());
151+
if (config.getUrlPattern() == null) config.setUrlPattern("/*");
152+
config.setInjectorSimpleClassName(CommonUtil.getSimpleName(config.getInjectorClassName()));
153+
if (config.getSavePath() == null) config.setSavePath(System.getProperty("user.dir"));
154+
155+
config.setSavePath(CommonUtil.getFileOutputPath(config.getOutputFormat(), config.getInjectorSimpleClassName(), config.getSavePath()));
156+
File f;
157+
try {
158+
f = new File(config.getClassFilePath());
159+
if (!f.exists() || !f.isFile()) {
160+
resultOutput.warningPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(new Throwable("File does not exist or is not a regular file: " + config.getClassFilePath())));
161+
return;
162+
}
163+
ClassPool classPool = ClassPool.getDefault();
164+
classPool.insertClassPath(new ClassClassPath(Filter.class));
165+
classPool.insertClassPath(new ClassClassPath(ServletRequestListener.class));
166+
classPool.makeInterface("org.springframework.web.servlet.AsyncHandlerInterceptor");
167+
classPool.makeInterface("org.springframework.web.servlet.HandlerInterceptor");
168+
String filePath = config.getClassFilePath();
169+
CtClass ctClass = classPool.makeClass(new DataInputStream(new FileInputStream(filePath)));
170+
// Bug: 修复 custom 生成的注入器 shellClassName 为空导致注入失败的问题
171+
config.setShellClassName(ctClass.getName());
172+
if (isFilterClass(ctClass)) {
173+
config.setShellType("Filter");
174+
} else if (isListenerClass(ctClass)) {
175+
config.setShellType("Listener");
176+
} else if (isInterceptorClass(ctClass)) {
177+
config.setShellType("Interceptor");
178+
} else {
179+
resultOutput.warningPrintln(filePath + " is neither a Filter nor a Listener.");
180+
return;
181+
}
182+
183+
} catch (Exception e) {
184+
resultOutput.warningPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(new Throwable("File does not exist or is not a regular file: " + config.getClassFilePath())));
185+
}
186+
new CustomGenerator().makeShell(config);
187+
new InjectorGenerator().makeInjector(config);
188+
JMGResultUtil.printCustomBasicInfo(resultOutput, config);
189+
JMGResultUtil.printResult(resultOutput, config);
190+
} catch (Exception e) {
191+
resultOutput.errorPrintln(ShellHelperPlugin.pluginHelper.getThrowableInfo(e));
192+
}
193+
}
194+
195+
196+
public static boolean isFilterClass(CtClass ctClass) throws NotFoundException, IOException {
197+
CtClass[] interfaces = ctClass.getInterfaces();
198+
CtClass[] var2 = interfaces;
199+
int var3 = interfaces.length;
200+
201+
for (int var4 = 0; var4 < var3; ++var4) {
202+
CtClass intf = var2[var4];
203+
if (intf.getName().equals("javax.servlet.Filter")) {
204+
return true;
205+
}
206+
}
207+
208+
return false;
209+
}
210+
211+
public static boolean isListenerClass(CtClass ctClass) throws NotFoundException, IOException {
212+
CtClass[] interfaces = ctClass.getInterfaces();
213+
CtClass[] var2 = interfaces;
214+
int var3 = interfaces.length;
215+
216+
for (int var4 = 0; var4 < var3; ++var4) {
217+
CtClass intf = var2[var4];
218+
if (intf.getName().equals("javax.servlet.ServletRequestListener")) {
219+
return true;
220+
}
221+
}
222+
223+
return false;
224+
}
225+
226+
public static boolean isInterceptorClass(CtClass ctClass) throws NotFoundException, IOException {
227+
CtClass[] interfaces = ctClass.getInterfaces();
228+
CtClass[] var2 = interfaces;
229+
int var3 = interfaces.length;
230+
231+
for (int var4 = 0; var4 < var3; ++var4) {
232+
CtClass intf = var2[var4];
233+
if (intf.getName().contains("Interceptor")) {
234+
return true;
235+
}
236+
}
237+
238+
return false;
239+
}
240+
}

0 commit comments

Comments
 (0)