0x00 前言
最近内存马技术如火如荼,频繁利用于攻防渗透领域。
本文就先学习一下Tomcat的基础架构和运行逻辑,为之后Tomcat的几种内存马打下基础。
0x01 Java Web 三大件
在讲Tomcat之前,先讲解一下 Java Web 三大件:Servlet,Filter,Listener。
当Tomcat收到请求后,请求会依次通过 Listener -> Filter -> Servlet。
Servlet
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
Servlet工作流程
客户端发起一个http请求(以GET类型为例)
Servlet容器收到该请求,并根据该请求的信息,将其封装成HttpServletRequest和HttpServletResponse 对象
Servlet容器调用HttpServlet的init()方法,该方法只在第一次请求被调用
Servlet容器调用service()方法,该方法根据请求类型调用相应的方法,这里是调用doGet方法
业务逻辑处理完成之后,将结果返回给Servlet容器,然后容器将结果返回给客户端
容器关闭时,会调用destory方法
最后由JVM进行垃圾回收
根据上面的流程,不难理解Servlet接口所定义的几种方法:
1 | package jakarta.servlet; |
Servlet生命周期
1)服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始化方法init(ServletConfig conf)。
2)servlet对象去处理所有客户端请求,在service(ServletRequest req,ServletResponse res)方法中执行
3)服务器关闭时,销毁这个servlet对象,执行destroy()方法。
4)由JVM进行垃圾回收。
多提一嘴,Servelt会处理jsp文件,那么如果上传恶意的jsp小马,就可以拉Java内存马这头大马,俗称“小马拉大马”。
Filter
filter 也称之为过滤器,是对 Servlet 技术的一个强补充,其主要功能是在 HttpServletRequest 到达 Servlet 之前,拦截客户的 HttpServletRequest ,根据需要检查 HttpServletRequest,也可以修改 HttpServletRequest 头和数据;在 HttpServletResponse 到达客户端之前,拦截 HttpServletResponse ,根据需要检查 HttpServletResponse,也可以修改 HttpServletResponse 头和数据。
Filter程序是一个实现了特殊接口的Java类,与Servlet类似,也是由Servlet容器进行调用和执行的。
Filter工作流程
filter链:当多个filter同时存在的时候,组成了filter链。web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter。当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法,通过判断FilterChain中是否还有filter决定后面是否还调用filter。
- 在web.xml注册一个Filter来对某个Servelt程序进行拦截处理,该Filter可以决定是否将请求继续传递给Servlet程序,以及对请求和响应消息是否进行修改
- 当Servelt容器开始调用某个Servelt程序时,如果发现已经注册了一个拦截该Servelt的Filter,那么Servelt容器不再调用Servelt的service方法,而是调用Filter的doFilter方法,再由该方法判断是否激活service方法。
- 但在Filter.doFilter方法中不能直接调用Servlet的service方法,而是调用FilterChain.doFilter方法来激活目标 Servlet的service方法,FilterChain对象是通过Filter.doFilter方法的参数传递进来的。
- 在Filter.doFilter方法中调用FilterChain.doFilter方法的语句前后增加某些程序代码,就可以在Servlet进行响应前后实现某些特殊功能。
- 如果在Filter.doFilter方法中没有调用FilterChain.doFilter方法,则目标Servlet的service方法不会被执行,这样通过Filter就可以阻止某些非法的访问请求。
Filter的生命周期
与servlet一样,Filter的创建和销毁也由web容器负责。web应用程序启动时,web服务器将创建Filter的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
Listener
Java Web 开发中的监听器(Listener)就是 Application、Session 和 Request 三大对象创建、销毁或者往其中添加、修改、删除属性时自动执行代码的功能组件。
- ServletContextListener:对Servlet上下文的创建和销毁进行监听
- ServletContextAttributeListener:监听Servlet上下文属性的添加、删除和替换
- HttpSessionListener:对Session的创建和销毁进行监听。Session的销毁有两种情况,一个中Session超时,还有一种是通过调用 Session 对象的 invalidate() 方法使 session 失效
- HttpSessionAttributeListener:对 Session 对象中属性的添加、删除和替换进行监听
- ServletRequestListener:对请求对象的初始化和销毁进行监听;
- ServletRequestAttributeListener:对请求对象属性的添加、删除和替换进行监听
用途:
可以使用监听器监听客户端的请求、服务端的操作等。通过监听器,可以自动出发一些动作,比如监听在线的用户数量,统计网站访问量、网站访问监控等。
这里也有插入内存马的思路,如果我们写了一个filter插在FilterChain的最前面,那么恶意的filter就会最先执行。
0x02 Tomcat
Tomcat概述
Tomcat是什么
Tomcat是java应用服务器(动态解析,如 JSP),也是Web服务器,比较不稳定,但是业务能力比较强。
Tomcat主要功能
tomcat作为一个 Web 服务器,实现了两个非常核心的功能:
- Http 服务器功能:进行 Socket 通信(基于 TCP/IP),解析 HTTP 报文
- Servlet 容器功能:加载和管理 Servlet,由 Servlet 具体负责处理 Request 请求
Tomcat中实现Http服务器功能的是连接器(Connector),实现Servlet容器功能的是容器(Container)。
Server
Server代表整个tomcat服务器,一个Tomcat只有一个Server 。Server中包含至少一个Service组件,用于提供具体服务。Service
Service是Server内部的组件,一个Server可以包括多个Service。它将若干个Connector组件绑定到一个ContainerConnector
连接器,是Service的核心组件之一,一个Service可以有多个Connector,主要连接客户端请求,用于接受请求并将请求封装成Request 和Response,然后交给Container进行处理,Container处理完之后再交给Connector返回给客户端。
Container
负责处理用户的 servlet 请求
Connector连接器
连接器主要完成以下三个核心功能:
- socket通信,也就是网络编程
- 解析处理应用层协议,封装成一个Request对象
- 将Request转换为ServletRequest,将Response转换为ServletResponse
三个功能分别对应三个组件EndPoint、Processor、Adapter:
- Endpoint 负责提供请求字节流给Processor
- Processor 负责提供 Tomcat 定义的 Request 对象给 Adapter
- Adapter 负责提供标准的 ServletRequest 对象给 Servlet 容器。
Endpoint与Processor有一个组合名称为ProtocolHandler
Container容器
Container组件又称作Catalina,其是Tomcat的核心。在Container中,有4种容器,分别是Engine、Host、Context、Wrapper,这四种容器是父子关系。
四种容器的作用:
- Engine
表示整个 Catalina 的 Servlet 引擎,用来管理多个虚拟站点,一个 Service 最多只能有一个 Engine,但是一个引擎可包含多个 Host - Host
代表一个虚拟主机,或者说一个站点,可以给 Tomcat 配置多个虚拟主机地址,而一个虚拟主机下可包含多个 Context - Context
表示一个 Web 应用程序,每一个Context都有唯一的path,一个Web应用可包含多个 Wrapper - Wrapper
表示一个Servlet,负责管理整个 Servlet 的生命周期,包括装载、初始化、资源回收等
如下图,a.com和b.com分别对应着两个Host:
Tomcat的类加载机制
由于Tomcat中有多个WebApp,同时要确保之间相互隔离,所以 Tomcat 的类加载机制也不是传统的双亲委派机制。
每个WebApp用一个独有的ClassLoader实例来优先处理加载。它首先尝试自己加载某个类,如果找不到再交给父类加载器,其目的是优先加载WEB应用自己定义的类。
同时为了防止WEB应用自己的类覆盖JRE的核心类,在本地WEB应用目录下查找之前,先使用 ExtClassLoader(使用双亲委托机制)去加载,这样既打破了双亲委托,同时也能安全加载类。
0x03 Reference
JavaSec/5.内存马学习/Tomcat/Tomcat介绍/Tomcat介绍.md at main · Y4tacker/JavaSec