Java安全之Tomcat6 Filter内存马

Java安全之Tomcat6 Filter内存马回顾Tomcat8打法先回顾下之前Tomcat789的打法
这里先抛开 7 8之间的区别, 在8中,最后add到filterchain的都是一个filterconfig对象
ApplicationFilterConfig包含了FilterDef对象
构造方法如下,如果当前filter属性为null会从FilterDef取filter的实例对象
ApplicationFilterConfig(Context context, FilterDef filterDef) throws ClassCastException, ClassNotFoundException, IllegalAccessException, InstantiationException, ServletException, InvocationTargetException, NamingException, IllegalArgumentException, NoSuchMethodException, SecurityException {this.context = context;this.filterDef = filterDef;if (filterDef.getFilter() == null) {this.getFilter();} else {this.filter = filterDef.getFilter();this.getInstanceManager().newInstance(this.filter);this.initFilter();}}FilterDef中存储了filterClass / filterName / filter 属性
public class FilterDef implements Serializable {private static final long serialVersionUID = 1L;private static final StringManager sm;private String description = null;private String displayName = null;private transient Filter filter = null;private String filterClass = null;private String filterName = null;private String largeIcon = null;private final Map<String, String> parameters = new HashMap();private String smallIcon = null;private String asyncSupported = null;public FilterDef() {}再有就是createFilterChain中还涉及到filterMap

Java安全之Tomcat6 Filter内存马

文章插图
FilterMap里主要存放urlpatterner和filterName的映射
public class FilterMap extends XmlEncodingBase implements Serializable {private static final long serialVersionUID = 1L;public static final int ERROR = 1;public static final int FORWARD = 2;public static final int INCLUDE = 4;public static final int REQUEST = 8;public static final int ASYNC = 16;private static final int NOT_SET = 0;private int dispatcherMapping = 0;private String filterName = null;private String[] servletNames = new String[0];private boolean matchAllUrlPatterns = false;private boolean matchAllServletNames = false;private String[] urlPatterns = new String[0];
  • tomcat8下注入filter内存马流程如下:
  • FilterDef: 设置 setFilter(Filter filter) setFilterName(String filterName) setFilterClass(String filterClass) 这里filterName和filterClass应该不是一个东西,最后调用StandardContext#addFilterDef将该恶意filterdef put到this.filterDefs
  • FilterMap: addURLPattern("/*") setFilterName(String filterName)setDispatcher(DispatcherType.REQUEST.name()),最后调用StandardContext#addFilterMapBefore(filtermap) 添加到this.filterMaps
  • ApplicationFilterConfig: 调用有参构造将FilterDef作为参数传递进去后调有参构造实例化一个ApplicationFilterConfig,最终put进standardcontext的属性里去 。
探索Tomcat6与Tomcat8之间的区别主要看下tomcat6和tomcat8之间createFilterChain不相同的地方 看到ApplicationFilterFactory#createFilterChain
跟进getFilter
Java安全之Tomcat6 Filter内存马

文章插图
主要代码如下:
所以这里构造filterDef的时候filterClass为evilfilter的全类名即可
Java安全之Tomcat6 Filter内存马

文章插图
再来看下FilterDef 可以发现确实在Tomcat6下面没有filter这个属性了
Java安全之Tomcat6 Filter内存马

文章插图
所以一个很大的区别就是在

经验总结扩展阅读