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