剖析Java内存马1
前文
内存马是一种仅在内存中执行,不写入硬盘的恶意程序,其能够隐蔽地进行攻击,同时躲避常规的病毒检测手段。是当今攻防模式下常见的攻击形式,最常见的就是java内存马,常分为以下几个部分:传统web型、spring系列框架型、中间件型、其他内存马、Agent型内存马等,常见的四个类型为:Listener型、Filter型、Servlet型以及Agent型,本文主要深度剖析一下前三种类型
Servlet
我们先了解一下Servlet容器架构。Tomcat 设计了 4 种容器,分别是 Engine、Host、Context 和 Wrapper,这4种容器不是相互独立的关系,而是父子关系,逐层包含,如下图所示:

一个Service最多只能有一个Engine,Engine表示引擎,用来管理多个虚拟主机的;Host代表就是一个虚拟主机,可以给Tomcat配置多个虚拟主机,一个虚拟主机下面可以部署多个Web应用;一个Context就表示一个Web应用,Web应用中会有多个Servlet,Wrapper就表示一个Servlet。这一点可以从Tomcat的配置文件server.xml中看出来
1 |
|
如果说我们要访问ht tps://xxxx:8080/user/list,那tomcat是如何实现请求定位到具体的servlet的呢?为此tomcat设计了Mapper,其中保存了容器组件与访问路径的映射关系,步骤为:
1 |
|
我们先设计一个简单的Servlet(tomcat9.0.96)
Main.java

HelloServlet.java


我们在org.apache.catalina.core.StandardWrapper#setServletClass处打断点进行调试

并追踪它的上层调用位置,我们可以发现为org.apache.catalina.startup.ContextConfig#configureContext


追踪configureContext,查看代码


概括一下上述的代码,也就是servlet初始化的六步
1 |
|
那servlet是如何进行装载的呢,我们在org.apache.catalina.core.StandardWrapper#loadServlet这里打下断点进行调试,重点关注一下startInternal

可以清晰看到,装载的顺序为:Listener、Filter、Servlet

并且我们可以发现,调用了org.apache.catalina.core.StandardContext#loadOnStartup,跟进该方法

先创建一个TreeMap,然后遍历传入的Container数组,将每个Servlet的loadOnStartup值作为键,将对应的Wrapper对象存储在相应的列表中;如果这个loadOnStartup值是负数,除非你请求访问它,否则就不会加载;如果是非负数,那么就按照这个loadOnStartup的升序的顺序来加载,这就是servlet装载流程
Filter
同理,我们先了解一下Filter容器,Filter容器是用于对请求和响应进行过滤和处理的,我用PPT潦草画个图

filter可以理解为一道门,客户端的请求在经过filter会经过servlet,那么如果我们动态创建一个filter并且将其放在最前面,我们的filter就会最先执行,当我们在filter中添加恶意代码,就可以实现命令执行,从而形成内存马。先写个简单的Filter(tomcat9.0.96)

效果就是跑起来后,控制台输出Filter初始化start,当我们访问/test正确路由的时候,控制台继续输出Filter路由成功访问,当我们结束tomcat的时候,会触发destroy方法,从而输出Filter已结束

我们在上面的demo中的doFilter函数这里下断点进行调试,并跟进org.apache.catalina.core.StandardWrapperValve#invoke


继续跟进变量filterChain,找到定义处的代码:
1 |
|

查看createFilterChain方法

代码有点长,不再一一截了,直接粘过来
1 |
|
这段代码是用于创建过滤器链的静态方法,它的主要功能是根据请求、包装器和Servlet的状态,构建一个包含适当过滤器的ApplicationFilterChain对象,首先检查是否为空值,如果传入的Servlet为null,直接返回null,表示没有可处理的请求,然后检查请求是否是Request的实例,如果是,则根据安全设置或已存在的过滤器链进行创建,然后将Servlet和异步支持设置到过滤器链中,再从wrapper中获取StandardContext,并查找相关的过滤器映射,再通过循环检查过滤器映射,根据请求的调度类型和路径进行过滤器的匹配,于此同时使用matchDispatcher和matchFiltersURL等方法来检查过滤器是否适用于当前请求,在所有匹配的过滤器都添加后,返回构建好的过滤器链
回过头来,再跟进刚才的filterChain.doFilter方法(org.apache.catalina.core.ApplicationFilterChain#doFilter)

可以看到调用了internalDoFilter方法,跟进该方法可以发现会依次拿到filterConfig和filter

但要是想打入内存马,也就是要动态地创建一个Filter,刚才我们发现在createFilterChain那个函数里面有两个关键点:org.apache.catalina.core.StandardContext#findFilterMaps和org.apache.catalina.core.StandardContext#findFilterConfig


二者的实现代码


这样一来,查找到现有的context,然后往里面插入我们自定义的恶意过滤器映射和过滤器配置,就可以实现动态添加过滤器了,但是如何添加filterMap和filterConfig? 尝试搜索addFilterMap关键词,发现StandardContext中有两个相关的方法

addFilterMap是在一组映射末尾添加新的我们自定义的新映射;而addFilterMapBefore则会自动把我们创建的filterMap自动排到第一位,而且addFilterMapBefore函数中第一步是先执行validateFilterMap这个函数,继续跟进

filterName和filterDef,必须对应得到,因此我们需要自定义filterDef并把它加入到filterDefs,这就需要用到addFilterDef方法

当我们继续去看filterConfig如何添加时,通过搜索,发现找不到类似上面的addFilterConfig这种,但是有filterStart和filterStop这两个方法


ok, 也就是说,只能通过反射的方法去获取相关属性并添加进去
Listener
我们最后再来说一下Listenner,还是先看看我用PPT画的潦草图

Listener是最先被加载的,所以动态注册一个恶意的Listener,就又可以形成一种内存马了。常见的listener有:ServletContextListener、ServletRequestListener、HttpSessionListener、HttpSessionAttributeListener。其中,ServletRequestListener是最适合做内存马的,利用条件很低:只要访问服务就可触发
我们先写一个简单的Listener(tomcat9.0.96)


我们在如下图所示的两个地方打断点进行调试

通过上图,可以看到org.apache.catalina.core.StandardContext#listenerStart方法的调用,跟进查看代码,可以发现主要干两个事情:一是通过findApplicationListeners找到这些Listerner的名字;二是实例化这些listener

接着就是分类放置,我们的ServletRequestListener被放在了eventListeners里面,分类放置之后,还做了一个动作:eventListeners.addAll(Arrays.asList(getApplicationEventListeners()));

Arrays.asList就是将数组转换为列表;eventListeners.addAll就是将括号里面的内容添加到之前实例化的监听器列表eventListeners中。至于括号里面的这个getApplicationEventListeners方法,我们跟进查看代码

就是把applicationEventListenersList转换成一个包含任意类型对象的数组,我们完全可以使其变成包含各种类型的应用程序事件监听器的数组,从而进行利用。而Listener可以有两个来源,一是根据web.xml文件或者@WebListener注解实例化得到的Listener;二就是applicationEventListenersList中的Listener,如果想打内存马的话,前者肯定不合适,更适合开发人员使用,因此我们需要找找有没有类似之前我们用到的addFilterConfig这种函数,通过查找,找到了一个方法叫addApplicationEventListener,在StandardContext.java里面

跟进该方法,查看代码,正好符合我们利用内存马的需求
1 |
|
【参考文章】
https://blog.nowcoder.net/n/0c4b545949344aa0b313f22df9ac2c09
https://www.maishuren.top/archives/tomcat-zhong-servlet-rong-qi-de-she-ji-yuan-li
https://mp.weixin.qq.com/s/hdqwsYtBN_IpaH2DGZLPoA