内存马初探-Filter
Tomcat简介
tomcat其实质上就是一个大点的servlet容器,那什么是容器呢,我觉得其实就是一个类。在tomcat中各个容器之间嵌套。而这些容器都是有生命周期的java类,都继承了共同的接口Lifecycle,所以Lifecycle就是这些容器的顶层接口。下面来谈谈存在哪些容器。
容器
- init()方法:初始化容器组件,它必须在启动容器之前调用。它会创建许多对象。
- start():启动容器,比如启动一个Server。
- stop():停止执行
- destroy():销毁这个容器。
- Server容器:一个StandardServer类实例就表示一个Server容器
- Service容器:一个StandardService类实例就表示一个Service容器
- Engine容器:一个StandardEngine类实例就表示一个Engine容器。
- Host容器:一个StandardHost类实例就表示一个Host容器。
- Context容器:一个StandardContext类实例就表示一个Context容器。
- Wrapper容器:一个StandardWrapper类实例就表示一个Wrapper容器。
这些容器全都是从上到下嵌套,需要注意的是这些容器虽然存在父子关系,但是它们的java类并没有父子。
/**
* Add a child Container, only if the proposed child is an implementation
* of Context.
*
* @param child Child container to be added
*/
@Override
public void addChild(Container child) {
child.addLifecycleListener(new MemoryLeakTrackingListener());
if (!(child instanceof Context))//这里说明Host容器的子容器只能是Context容器
throw new IllegalArgumentException
(sm.getString("standardHost.notContext"));
super.addChild(child);
}
一个Host容器中可以有多个Wrapper容器。
/**
* Add a child Container, only if the proposed child is an implementation
* of Wrapper.
*
* @param child Child container to be added
*
* @exception IllegalArgumentException if the proposed container is
* not an implementation of Wrapper
*/
@Override
public void addChild(Container child) {
// Global JspServlet
Wrapper oldJspServlet = null;
if (!(child instanceof Wrapper)) {
//这里说明Context容器的子容器只能是Wrapper容器。
throw new IllegalArgumentException
(sm.getString("standardContext.notWrapper"));
}
//这里删除了部分代码
}
内存马简单介绍
类型
- servlet-api
- filter型
- servlet型
- listener型
- 指定框架,如spring
- 字节码增强型
- 任意JSP文件隐藏
在Tomcat中我们对Servlet进行访问的时候会先通过Filter,如下图所示。
因此我们只要中Filter中插入恶意代码,就可以进行命令执行,形成一个内存马。
Filter:自定义Filter的实现,需要实现javax.servlet.Filter下的init()、doFilter()、destroy()三个方法。
- 启动时调用init()方法
- 工作时调用doFilter()
- 销毁时调用destroy()
在tomcat中ServletContext的实现是ApplicationContext。在Web应用中,获取的ServletContext实际上是ApplicationContextFacade的对象,对ApplicationContext进行了封装,而ApplicationContext实例中又包含了StandardContext实例,。
Filter注册流程
我们自己写一个Filter然后下断点,然后跟进createFilterChain。
filterChain.setServlet(servlet);
filterChain.setSupport(((StandardWrapper)wrapper).getInstanceSupport());
StandardContext context = (StandardContext)wrapper.getParent();
FilterMap[] filterMaps = context.findFilterMaps();
if (filterMaps != null && filterMaps.length != 0) {
String servletName = wrapper.getName();
int i;
ApplicationFilterConfig filterConfig;
boolean isCometFilter;
for(i = 0; i < filterMaps.length; ++i) {
if (this.matchDispatcher(filterMaps[i], dispatcher) && this.matchFiltersURL(filterMaps[i], requestPath)) {
filterConfig = (ApplicationFilterConfig)context.findFilterConfig(filterMaps[i].getFilterName());
if (filterConfig != null) {
isCometFilter = false;
if (comet) {
try {
isCometFilter = filterConfig.getFilter() instanceof CometFilter;
} catch (Exception var18) {
Throwable t = ExceptionUtils.unwrapInvocationTargetException(var18);
ExceptionUtils.handleThrowable(t);