CVE-2020-9484 Apache Tomcat Session反序列化代码执行漏洞

前言

好久没有更新过博客了,这半年时间其实我也整理了比较多的分析笔记,但是由于和工作的重合度比较大(很多作为工作的成果)所以暂时就不放到博客里了,挑一些水的先发出来

正文

昨天晚看了一下CVE-2020-9484的分析,这个漏洞利用起来比较简单,但是可能利用场景较少。 漏洞有两个限制:

  1. 需要开启tomcat的session持久化机制(FileStore模式)
  2. 可以上传一个.session结尾的文件,并且可以知道上传后文件的路径

Tomcat支持session持久化的机制,为了在Tomcat挂掉之后session不会丢失,引入了持久化机制,Tomcat的自带的session持久化支持两种模式,一种是保存到文件中,另一种是连接JDBC,保存到数据库中,分别对应

需要开启session的持久化存储模式。在tomcat的config/context.xml中配置,directory配置的是session存储的路径 这次的漏洞出在使用FileStore存储读取session的时候,直接利用sessionid去读取文件。 处理逻辑也比较简单,入口在org.apache.catalina.session.PersistentManagerBase#loadSessionFromStore 跟进org.apache.catalina.session.FileStore#load img 这个load方法的功能: 从String类型的JESSIONID —–> 读取文件 ——> 返回Session,从文件读取到的FileInputStream—–> Session 这里面肯定是存在一个反序列的过程。只要我们可以控制FileInputStream,那么这个反序列化的过程就被我们控制了,可能就可以造成RCE。 这个文件可以被控制吗?跟进file方法,参数id是攻击者可以控制的,可以看到这里没有任何过滤,直接将id拼接进路径中,我们可以利用这个点使用../穿越路径来控制读取任意的文件,另外测试的时候发现,对于不是合法session的文件,如果是在签名声明的directory下,会被自动删除。所以这里需要利用../上传到另一个目录 控制文件之后,跟进到org.apache.catalina.session.StoreBase#getObjectInputStream方法,这个方法用来构建ObjectStream,其中比较关键的点: 这里使用的是ContextClassLoader,可以加载到当前应用的依赖,接下来再跟进,最终就到了反序列化的触发点 img 一直跟进org.apache.catalina.session.StandardSession#doReadObject,这里可以看到调用ObjectInputStream的readObject方法触发反序列化。 攻击流程: 具体攻击流程比较简单,上传ysoserial生成的gadget的payload到穿越的文件夹下,这里上传filename.session到和配置的session同一级目录,然后JESSIONID=../filename(不需要包含.session后缀,tomcat会自动为我们拼接),之后带着Cookie访问网站既可以触发 补充: 可以联想到,在JDK<1.7.40的时候,是存在文件截断漏洞的,是否可以利用这一点来摆脱后缀名的限制? 我更换了JDK1.7尝试了一下,发现不可行,原因是tomcat并不接受cookie中存在控制字符 img 注意点: 关于需不需要拿到context.xml配置的session directory,我们最后填在session中的路径就是相对于这个dirctory的路径,所以拿不拿到这个路径影响不大,实际情况主要取决于我们可以得到怎么样的上传文件之后的路径。 修补方案:修改了file方法,对于拼接完的文件进行了判断,是否是处在我们配置的session目录中,避免了目录穿越。 img