Tomcat CVE-2022-29885

四月中旬,我向Apache Tomcat发送了三份拒绝服务漏洞的报告:

  • 第一份:利用条件极高的DoS,因此不被认可
  • 第二份:已确认并分配CVE-2022-29885
  • 第三份:官方正在审核中

随便写一下CVE-2022-29885的内容,官方对此漏洞定义只是低危

目前官方没有给出修复代码,仅认为是文档的问题,降低了对EncryptInterceptor的安全描述

Tomcat集群之间的通讯需要配置NioReceiver

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
  <Channel className="org.apache.catalina.tribes.group.GroupChannel">
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
      address="0.0.0.0"
      port="5000"
      selectorTimeout="100"
      maxThreads="6"/>
  </Channel>
</Cluster>

以上是不安全的配置,在这种情况下黑客自己建立的Tomcat节点可以打集群中的目标并RCE,由于ClassLoader的限制仅7U218U20Gadget生效:

正如作者师傅所说:Tomcat集群管理中并没有注册和管理中心,子节点加入集群不需要进行校验,所以黑客可以伪装Tomcat节点对集群其他节点进行攻击

官方其实考虑到了这种问题:Tomcat Cluster

文档的意思简单概括:请确保Tomcat集群拥有安全的网络环境,并且Tomcat的EncryptInterceptor配置可以提供安全性,于是想到从这一点入手

安全的集群配置应该如下

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
  <Channel className="org.apache.catalina.tribes.group.GroupChannel">
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
      address="0.0.0.0"
      port="5000"
      selectorTimeout="100"
      maxThreads="6"/>
    <Interceptor className="org.apache.catalina.tribes.group.interceptors.EncryptInterceptor"
       encryptionAlgorithm="AES/CBC/PKCS5Padding"
       encryptionKey="YOUR_KEY(LENGTH:32)"/>
  </Channel>
</Cluster>

在Tomcat收到消息后,反序列化数据前,执行该类的messageReceived方法验证

    @Override
    public void messageReceived(ChannelMessage msg) {
        try {
            byte[] data = msg.getMessage().getBytes();
            // 对数据进行解密
            data = encryptionManager.decrypt(data);
            XByteBuffer xbb = msg.getMessage();
            xbb.clear();
            xbb.append(data, 0, data.length);
            // 进行反序列化数据等步骤
            super.messageReceived(msg);
        } catch (GeneralSecurityException gse) {
            log.error(sm.getString("encryptInterceptor.decrypt.failed"), gse);
        }
    }

如果黑客不知道目标AES加密的KEY将会导致抛出异常,无法进行反序列化,以防止RCE

因此有两种可能造成拒绝服务漏洞的情况:

  • 调用decrypt对字节数组进行解密时触发
  • 调用xbb.append初始化数据时候触发

最终的POC就不放出了,并且这也不是什么有意义的洞,没有必要过多关注

危害:

  • 一般情况下Tomcat不会暴漏集群通讯端口,如果仅开放8080等web端口是没有危害的
  • 如果打到内网发现Tomcat集群,在不安全配置下且JDK符合低版本可以RCE
  • 如果打到内网发现Tomcat集群且配置安全,在一定条件下可以DoS

虽然是鸡肋垃圾洞,不过也算达成了去年立下的目标:拿下Tomcat和Spring的CVE

下一个目标:挖到不垃圾的洞