0
点赞
收藏
分享

微信扫一扫

Tomcat Filter 类型内存马与查杀学习

以 Filter 型内存⻢为例

在进⼊正题之前,先说两个东⻄

java 特性 -- 反射

java 的四⼤特性是,封装,继承,多态,反射,其中灵魂是反射。

Tomcat Filter 类型内存马与查杀学习_免杀马


这张图正常new⼀个对象的时候,逻辑过程是,把class⽂件加载到 jvm 中,之后才能产⽣ class 对象,但是利⽤反射机制的话,就能够直接在 jvm 中调⽤已经加载好的 class ⽂件,从⽽实现去new⼀个对象。简单的反射获取对象的⽅法有以下⼏种:

类名.class,如:com.anbai.sec.classloader.TestHelloWorld.class 
Class.forName("com.anbai.sec.classloader.TestHelloWorld") 
classLoader.loadClass("com.anbai.sec.classloader.TestHelloWorld")

常在连接数据库的时候这么用

Class.forName("com.mysql.jdbc.Driver")

①获取⽬标类型的Class对象

②通过Class对象分别获取Constructor类对象、Method类对象&Field类对象

③通过Constructor类对象、Method类对象&Field类对象分别获取类的构造函数、⽅法 &属性的具体信息,并进⾏后续操作

Tomcat 热加载

上⾯说到,根据双亲委派机制,那么什么是双亲委派机制呢?

Tomcat Filter 类型内存马与查杀学习_免杀马_02

Tomcat Filter 类型内存马与查杀学习_免杀马_03

所以在分析某些类的时候,要按照对应Tomcat⾥⾯去分析。

流程分析

filter也称之为过滤器,过滤器实际上就是对web资源进⾏拦截,做⼀些过滤,权限鉴别等处理后再交给下⼀个过滤器或servlet处理,通常都是⽤来拦截request进⾏处理的,也可以对返回的response进⾏拦截处理。

Tomcat Filter 类型内存马与查杀学习_java_04

当多个filter同时存在的时候,组成了filter链。web服务器根据Filter在web.xml⽂件中的注册顺序,决定先调⽤哪个Filter。第⼀个 Filter的doFilter⽅法被调⽤时,web服务器会创建⼀个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的 doFilter方法,则 web 服务器会检查FilterChain对象中是否还有 filter 如果有则调⽤第2个filter 如果没有则调⽤⽬标资源。如果我们动态创建⼀个filter并且将其放在最前⾯,filter就会最先执⾏,当在filter中添加恶意代码,就会进⾏命令执⾏,这样也就成为了⼀个内存Webshell。

Filter生命周期

public void init(FilterConfig filterConfig) throws ServletException   //初始化 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, Serv
letException;   //拦截请求 
public void destroy();  //销毁

Filter 对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在 Web 容器卸载Filter对象之前被调⽤。该⽅法在Filter的⽣命周期中仅执⾏⼀次。在这个⽅法中,可以释放过滤器使⽤的资源。我们可以通过动态注册的⽅法去注册⼀个Filter。

Filter 类的介绍

FilterDefs:存放FilterDef的数组 ,FilterDef中存储着我们过滤器名,过滤器实例等基本信息

FilterConfigs:存放 filterConfig 的数组,在FilterConfig 中主要存放FilterDef和Filter对象等信息

FilterMaps:存放FilterMap的数组,在FilterMap中主要存放了FilterName和对应的URLPattern

FilterChain:过滤器链,该对象上的doFilter方法能依次调⽤链上的Filter

ApplicationFilterChain:调⽤过滤器链

ApplicationFilterConfig:获取过滤器

ApplicationFilterFactory:组装过滤器链

WebXml:存放web.xml中内容的类

ContextConfig:Web应⽤的上下⽂配置类

StandardContext:Context接⼝的标准实现类,⼀个Context代表⼀个 Web应⽤,其下可以包含多个Wrapper

StandardWrapperValve:⼀个 Wrapper的标准实现类,⼀个 Wrapper代表⼀个Servlet

那什么是 Context,wrapper?

Servlet是java最基本的应⽤,而Tomcat是⼀个⼤的Servlet容器,tomcat主要由connector连接器和容器组成。(这四个容器的关系如下),是父子关系,不是平行关系

Tomcat Filter 类型内存马与查杀学习_类对象_05

和Servlet的方式不同,Filter不能通过注解去配置,必须在web.xml进⾏配置。

<?xml version="1.0"encoding="UTF-8"?> 
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 
version="4.0"> 
    <filter> 
        <filter-name>filterDemo</filter-name> 
        <filter-class>FilterDemo</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>filterDemo</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
    <filter> 
        <filter-name>filterDemo2</filter-name> 
        <filter-class>FilterDemo2</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>filterDemo2</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
</web-app>

这⾥写了两FilterDemo,代码基本相同,主要是为了展示这个Filter过滤链。

   import javax.servlet.*; 
import java.io.IOException; 
public class FilterDemo2 implements Filter { 
    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
        System.out.println("第⼀个Filter 初始化创建"); 
    } 
    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
throws IOException, ServletException { 
System out println("第⼀个Filter执⾏过滤操作");  
filterChain.doFilter(servletRequest,servletResponse); 
    } 
    @Override 
    public void destroy() { 
    } 
}

Tomcat Filter 类型内存马与查杀学习_免杀马_06

Tomcat是这样将我们⾃定义的filter调⽤的。

Tomcat Filter 类型内存马与查杀学习_免杀马_07

1. 根据请求的URL从FilterMaps中找出与之URL对应的Filter名称

2. 根据Filter名称去FilterConfigs中寻找对应名称的FilterConfig

3. 找到对应的FilterConfig之后添加到FilterChain中,并且返回FilterChain

4. filterChain 中调⽤internalDoFilter遍历获取chain中的FilterConfig,然后从FilterConfig中获取Filter,然后调⽤Filter的doFilter⽅法

举报

相关推荐

0 条评论