原理:
Servlet 有自己的过滤器 filter , 可以通过自定义的过滤器,来对用户的请求进行拦截等操作。

经过filter 之后才会刀Servlet ,如果我们动态创建一个 filter 并且将其放在最前面,我们的filter 就会最先被执行,当我们在filter 中添加恶意代码,就会进行命令执行,这样也就成为了一个内存webshell,所以就需要我们想办法在最前方注册一个恶意的filter 并执行。
提前说一下大致的注册流程,通过request对象获取StandardContext对象,然后设置一下三个变量
- 存放每个filter 的类位置: org.apache.catalina.core.StandardContext#filterDefs
- 存放每个filter的url 映射: org.apache.catalina.core.StandardContext#filterMaps
- 存放每个filter的配置,构建 filterChain 用到的变量 org.apache.catalina.core.StandardContext#filterConfigs
filter的注册、运行主要涉及以上三个变量。
filter 的注解初始化
跟踪一下filter 的 注解 是如何初始化的,看看把 filter 的相关信息存放到什么位置。
在Servlet 中,写Filter 有两种方式,一种是把filte配置写到 web.xml中,一种就是写注解:
@WebFilter("/*")
写web.xml:

两种方式皆可,我这里是 直接写禁了 web.xml 了
大致流程图:

运行后成功触发:

每一次 访问都会经过filter 再到达 servlet。
再来看看我们后面会要用到的几个类:
- FilterDefs:存放FilterDef的数组 ,FilterDef 中存储着我们过滤器名,过滤器实例,作用 url 等基本信息
- FilterConfigs:存放filterConfig的数组,在 FilterConfig 中主要存放 FilterDef 和 Filter对象等信息
- FilterMaps:存放FilterMap的数组,在 FilterMap 中主要存放了 FilterName 和 对应的URLPattern
- FilterChain:过滤器链,该对象上的 doFilter 方法能依次调用链上的 Filter
- WebXml:存放 web.xml 中内容的类
- ContextConfig:Web应用的上下文配置类
- StandardContext:Context接口的标准实现类,一个 Context 代表一个 Web 应用,其下可以包含多个 Wrapper
- StandardWrapperValve:一个 Wrapper 的标准实现类,一个 Wrapper 代表一个Servlet
调用栈:

分析一下 Tomcat 中是如何 将我们自定义的filter 进行设置并调用的:
分析:
可以看到再 StandarWrapperValve#invoke 中 ,通过createFilterChain 方法获得了 一个 ApplicationFilterChain 类型的 filterchain ,其中包含了 filters 有两个值 ,而第一个值就包含了我们传入的自定义filter :


跟进 createFilterChain() ,看看他是如何获取我们的自定义的Filter过滤器 获取了request请求,在通过该申请获取了filterChain

再往下看,context获取了一个StandardContext()对象,接着用context获取了filterMaps()主要就是filtername和path


之后经过循环 逐一将 filterMaps 的值传入 filterConfig,最后通过 addFilter 将其传入 filterChain 中

跟进 addFilter() ,他会将 其值都添加到 filters中:

之后回到最初的StandardWrapperValve#invoke

本文深入探讨了如何利用JAVA中的filter创建内存马,详细解析了filter的初始化过程,包括如何通过StandardContext修改filterConfigs、filterDefs和filterMaps。通过动态注册恶意filter,可以在请求处理过程中执行任意代码,实现内存webshell。文章还介绍了如何获取ServletContext并转化为StandardContext,以及构造payload的过程。
578

被折叠的 条评论
为什么被折叠?



