水洞之Apache Jackrabbit-CVE-2023-37895

漏洞概述

Apache Jackrabbit是一个强大的开源内容存储库,实现了Java的内容存储库规范(JSR-170和JSR-283)。Apache Jackrabbit webapp/standalone多个版本中存在Java 对象反序列化漏洞,由于使用的commons-beanutils 组件中存在一个可通过 RMI 远程执行代码的类,可通过构造恶意序列化数据,并发送到目标系统上的 RMI 服务端口(默认为1099端口)或发送到RMI-over-HTTP路径(默认使用路径“/rmi”),当目标系统反序列化该数据时可能导致远程代码执行。

漏洞分析

在漏洞概述中说到,在路径/rmi中,会引起RMI远程代码执行,通过web.xml找到/rmi路由对应的Servlet

<servlet>
  <servlet-name>RMI</servlet-name>
  <servlet-class>org.apache.jackrabbit.servlet.remote.RemoteBindingServlet</servlet-class>
</servlet>

对应的类为org.apache.jackrabbit.servlet.remote.RemoteBindingServlet,只有doGet方法

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();
}

先调用getRemoteRepository获取Repository

protected RemoteRepository getRemoteRepository() throws ServletException {
    if (remote == null) {
        try {
            RemoteAdapterFactory factory = getRemoteAdapterFactory();
            remote = factory.getRemoteRepository(new ServletRepository(this));
        } catch (RemoteException e) {
            throw new ServletException(
                    "Failed to create the remote repository reference", e);
        }
    }
    return remote;
}

在获取Repository的同时,调用了getRemoteAdapterFactory去获取Factory,然后调用Factory的getRemoteRepository方法,会返回一个ServerRepository对象

public ServerRepository(
        Repository repository, RemoteAdapterFactory factory)
        throws RemoteException {
    super(factory);
    this.repository = repository;
}

然后返回给客户端这个远程获取到的类

image-20230823082740125

客户端拿到这个Repository后,可以调用其中的login方法

image-20230823083032295

此时的remote是RemoteRepository类,也是就会调用服务端的login方法

image-20230823083443644

ClientRepositorylogin当中存在一个Credentials,实现了Serializable接口

image-20230823083105655

Credentials接口的实现类之一SimpleCredentials存在一个attributes属性,是一个HashMap

image-20230823083913535

该项目自带commons-beanutils1.9.4,我们可以用cb链来打。

Exp

把cb链生成的PriorityQueue类作为Attribute属性封装成SimpleCredentials,在反序列化的时候,会先反序列化SimpleCredentials里的Attribute,也就是HashMap,然后反序列化HashMap中的PriorityQueue,即可触发RCE。