Tomcat 的 4 类容器组件:
Engine、Host 、Context 、 Wrapper:
- Engine(org.apache.catalina.core.StandardEngine):最大的容器组件,可以容纳多个 Host。
- Host(org.apache.catalina.core.StandardHost):一个 Host 代表一个虚拟主机,一个Host可以包含多个 Context。
- Context(org.apache.catalina.core.StandardContext):一个 Context 代表一个 Web 应用,其下可以包含多个 Wrapper。
- Wrapper(org.apache.catalina.core.StandardWrapper):一个 Wrapper 代表一个 Servlet(重点 :上文提到的动态注册Servlet组件的内存马技术,想要动态的去注册Servlet组件实现过程中的关键之一就是如何获取Wrapper对像,再往上也就是如何获取到Context对象,从而掌握整个Web应用)。
Servlet的三大基础组件:
Servlet、Filter 、Listener :
请求 → Listener → Filter → Servlet
- Servlet: 最基础的控制层组件,用于动态处理前端传递过来的请求,每一个Servlet都可以理解成运行在服务器上的一个java程序;生命周期:从Tomcat的Web容器启动开始,到服务器停止调用其destroy()结束;驻留在内存里面
- Filter:过滤器,过滤一些非法请求或不当请求,一个Web应用中一般是一个filterChain链式调用其doFilter()方法,存在一个顺序问题。
- Listener:监听器,以ServletRequestListener为例,ServletRequestListener主要用于监听ServletRequest对象的创建和销毁,一个ServletRequest可以注册多个ServletRequestListener接口(都有request来都会触发这个)。
Context对象获取
对于Tomcat来说,一个Web应用中的Context组件为org.apache.catalina.core.StandardContext对象,前文也有提到我们在实现通过动态注册Servlet组件的内存马技术的时候,其中一个关键点就是怎么获取器Context对象,而该对象就是StandContext对象。那么我们可以通过哪些途径得到StandContext对象那呢?
有requet对象的时候
Tomcat中Web应用中获取的request.getServletContext是ApplicationContextFacade对象。该对象对ApplicationContext进行了封装,而ApplicationContext实例中又包含了StandardContext实例,所以当request存在的时候我们可以通过反射来获取StandardContext对象
没有request对象的时候
1、不存在request的时候从currentThread中的ContextClassLoader中获取(适用Tomcat 8,9)
2、ThreadLocal中获取
3、从MBean中获取
内存马的分类
根据内存马的实现技术来分类将内存马分为三类:
基于动态添加Servlet组件的内存马
servlet
- 1、首先通过反射,从request中获取Tomcat中控制Web应用的Context(StandardContext对象),上文中有提到获取StandardContext获取的方式,这里因为是jsp来实现的,所以可以直接拿到request,所以就利用上文提到的第一种方法,通过反射即可获取到Tomcat下的StrandardContext对象,下面也是同理。
- 2、注册一个Servlet对象并重写其Service方法,在其中实现命令执行并通过response返回
- 3、创建Wrapper对象并利用各个船舰的Servlet来初始化
- 4、为Wrapper添加路由映射
filter
- 1、首先通过反射,从request中获取Tomcat中控制Web应用的Context(StandardContext对象)
- 2、利用获取的上下文StandardContext对象获取filterconfigs对象
- 3、创建一个恶意Filter对象并重写其doFilter方法,在其中实现命令执行并通过response返回,最后filterChain传入后面的filter
- 4、创建FilterDef对象并利用刚刚创建的Filter对象来初始化,并新建一个FilterMap对象,为创建的FilterDef对象添加URL映射
- 5、利用创建FilterConfig对象并使用刚刚创建的FilterDef对象初始化,最后将其加入FilterConfigs里面,等待filterChain.dofilter调用
Listener
- 首先通过反射,从request中获取Tomcat中控制Web应用的Context(StandardContext对象)
- 创建一个ServletRequestListener对象并重写其requestDestroyed方法,在其中实现命令执行并通过response回显.
- 将创建的ServletRequestListener对象通过StandardContext添加到事件监听中去
基于动态添加框架组件的内存马
这里说到的框架有很多,spring、springboot、weblogic等
基于Javaagent和Javassist技术的内存马
PREVIOUSDubbo