网站首页 > java教程 正文
翻译:WisFree
预估稿费:170RMB
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
写在前面的话
AMF(Action Message Format)是一种二进制序列化格式,之前主要是Flash应用程序在使用这种格式。近期,Code White发现有多个Java AMF库中存在漏洞,而这些漏洞将导致未经身份验证的远程代码执行。由于AMF目前已经得到了广泛的使用,因此可能会有多家厂商的产品将受到这些漏洞的影响,例如Adobe、Atlassian、HPE、SonicWall和VMware等等。
目前,漏洞相关信息已上报至美国CERT(详情请参考美国CERT VU#307983)
概述
目前,Code White主要对以下几种热门的Java AMF实现:
Flex BlazeDS by Adobe
Flex BlazeDS by Apache
Flamingo AMF Serializer by Exadel (已停更)
GraniteDS (已停更)
WebORB for Java by Midnight Coders
而这些又存在着下面列出的一个或多个漏洞:
XML外部实体注入(XXE)
任意对象创建及属性设置
通过RMI实现Java序列化
漏洞影响
简而言之,任意远程攻击者如果能够欺骗并控制服务器的通信连接,那么他将有可能向目标主机发送能够执行任意代码的序列化Java对象,当该对象在目标主机中进行反序列化之后,恶意代码将会被执行。
前两个漏洞并不是新漏洞,但是目前仍然有很多库存在这样的漏洞。除此之外,研究人员也发现了一种能够将这种设计缺陷转换成Java序列化漏洞的方法。
我们将会对上述漏洞(除了XXE)进行详细描述,如果你想了解关于这个XXE漏洞的详细内容,请参考我们之前所发表的一篇文章《CVE-2015-3269: Apache Flex BlazeDS XXE Vulnerabilty》。
介绍
AMF3(Action Message Format version 3)同样是一种二进制信息编码格式,它也是Flash应用在与后台交互时主要使用的一种数据格式。与JSON类似,它支持不同的数据类型。考虑到向后兼容性,AMF3实际上算是AMF的一种拓展实现,并且引入了新的对象类型。
AMF3对象的新功能可以归结为两种新增加的特性,而这两种新特性(dynamic和externalizable)描述了对象是如何进行序列化操作的:
Dynamic:一个声明了动态特性的类实例;公共变量成员可以在程序运行时动态添加(或删除)到实例中。
Externalizable:实现flash.utils.IExternalizable并完全控制其成员序列化的类实例。
注:具体请参考Adobe官方给出的解释【传送门】。
Dynamic特性
我们可以拿Dynamic特性与JavaBeans的功能进行对比:它允许我们通过类名及属性来创建一个对象。实际上,很多JavaBeans实体目前已经实现了这种技术,例如java.beans.Introspector、Flamingo、Flex BlazeDS和WebORB等等。
但需要注意的是,这种功能将会导致一种可利用的漏洞产生。实际上,Wouter Coekaerts早在2011年就已经将这种存在于AMF实现中的漏洞曝光了,并且还在2016年发布了相应漏洞的利用代码及PoC。
Externalizable特性
我们可以拿Externalizable特性赖于Java的java.io.Externalizable接口进行对比。实际上,很多厂商早就已经将flash.utils.IExternalizable接口的规范进行了调整,其实它与Java的java.io.Externalizable区别不大,这种特性将允许我们可以高效地对实现了java.io.Externalizable接口的类进行重构。
java.io.Externalizable接口定义了两个方法:即readExternal(java.io.ObjectInput)和writeExternal(java.io.ObjectInput),而这两个方法将允许java类完全控制序列化以及反序列化操作。这也就意味着,在程序的运行过程中不存在默认的序列化/反序列化行为以及有效性检测。因此,相对于java.io.Serializable来说,我们使用java.io.Externalizable来实现序列化/反序列化则更加的简单和高效。
将EXTERNALIZABLE.READEXTERNAL转换为OBJECTINPUTSTREAM.READOBJECT
在OpenJDK 8u121中总共有十五个类实现了java.io.Externalizable接口,而其中绝大多数类的任务仅仅是重构一个对象的状态而已。除此之外,实际传递给Externalizable.readExternal(java.io.ObjectInput)方法的java.io.ObjectInput实例也并非java.io.ObjectInputStream的实例。
在这十五个类中,那些与RMI有关的类则吸引了我们的注意。尤其是sun.rmi.server.UnicastRef和sun.rmi.server.UnicastRef2,因为他们会通过sun.rmi.transport.LiveRef.read(ObjectInput, boolean)方法来对sun.rmi.transport.LiveRef对象进行重构。除此之外,这个方法还会重构一个sun.rmi.transport.tcp.TCPEndpoint对象以及一个本地sun.rmi.transport.LiveRef对象,并且在sun.rmi.transport.DGCClient中进行注册。其中,DGCClient负责实现客户端的RMI分布式垃圾回收系统。DGCClient的外部接口为“registerRefs”方法,当一个LiveRef的远程对象需要进入虚拟机系统时,它需要在DGCClient中进行注册。关于DGCClient的更多内容请参考OpenJDK给出的官方文档【传送门】。
根据官方文档中的描述,LiveRef的注册是由一次远程调用完成的,而我们觉得这里将有可能允许我们通过RMI来实现远程代码执行(RCE)!
在对这次调用进行了追踪分析之后,我们发现整个调用过程非常复杂,它涉及到Externalizable.readExternal、sun.rmi.server.UnicastRef/sun.rmi.server.UnicastRef2、ObjectInputStream.readObject以及sun.rmi.transport.StreamRemoteCall.executeCall()等多种对象及方法。
接下来让我们来看看,如果我们通过一个sun.rmi.server.UnicastRef对象来对一条AMF消息进行反序列化的话会出现什么情况,相关代码如下所示(利用了Flex BlazeDS):
为了证实代码能够正常运行,我们首先设置了一个监听器,然后看一看链接是否能够成功建立。
此时,我们成功地与客户端建立了一条通信连接,而且使用的还是Java RMI传输协议。
漏洞利用
实际上,jacob Baines早在2016年就已经将这项技术(反序列化黑名单绕过)公之于众了,但是我并不确定当时他是否知道这种技术同样还会将任意的Externalizable.readExternal对象转换为ObjectInputStream.readObject对象。除此之外,他当时还介绍了一个可以发送任意Payload的JRMP监听器:
厂商产品影响情况
Vendor | Status | Date Notified | Date Updated |
Adobe | Affected | 28 Mar 2017 | 03 Apr 2017 |
Apache Software Foundation | Affected | 28 Mar 2017 | 06 Apr 2017 |
Atlassian | Affected | - | 28 Mar 2017 |
Exadel | Unknown | 28 Mar 2017 | 28 Mar 2017 |
Granite Data Services | Unknown | 16 Mar 2017 | 16 Mar 2017 |
Hewlett Packard Enterprise | Unknown | 28 Mar 2017 | 28 Mar 2017 |
Midnight Coders | Unknown | 16 Mar 2017 | 03 Apr 2017 |
Pivotal | Unknown | 28 Mar 2017 | 28 Mar 2017 |
SonicWall | Unknown | 28 Mar 2017 | 28 Mar 2017 |
VMware | Unknown | 16 Mar 2017 | 16 Mar 2017 |
缓解方案
首先,使用了Adobe或Apache实现的应用程序应该尽快将Apache更新至最新版本(v4.7.3)。其次,Exadel目前已经停止对他的代码库进行维护了,所以使用了Flamingo AMF Serializer的用户不会再收到更新推送了。不过目前对于GraniteDS和WebORB还没有合适的解决方案。
参考资料
http://codewhitesec.blogspot.com/2017/04/amf.html
http://openjdk.java.net/jeps/290
http://www.kb.cert.org/vuls/id/279472
http://www.adobe.com/go/amfspec
https://cwe.mitre.org/data/definitions/502.html
https://cwe.mitre.org/data/definitions/913.html
https://cwe.mitre.org/data/definitions/611.html
其他信息
CVE ID:
CVE-2015-3269、CVE-2016-2340、CVE-2017-5641、CVE-2017-5983、CVE-2017-3199、CVE-2017-3200、CVE-2017-3201、CVE-2017-3202、CVE-2017-3203、CVE-2017-3206、CVE-2017-3207、CVE-2017-3208
公开日期:2017年4月4日
最新更新日期:2017年4月4日
文档版本:73
猜你喜欢
- 2024-11-04 快速处理Kafka反序列化错误(kafka自定义反序列化)
- 2024-11-04 又一个反序列化漏洞,我服了...(反序列化漏洞修复方案)
- 2024-11-04 Java代码示例:如何使用 serialVersionUID处理序列化
- 2024-11-04 Java 序列化机制(java序列化过程)
- 2024-11-04 SpringBoot整合Grpc实现跨语言RPC通讯
- 2024-11-04 php和java及python3.10的序列化和反序列化
- 2024-11-04 Java修炼终极指南:133 避免在反序列化时发生DoS攻击
- 2024-11-04 聊聊fastjson反序列化的那些坑(fastjson反序列化原理)
- 2024-11-04 Java序列化 3 连问,这太难了吧(在线序列化工具)
- 2024-11-04 避免使用Java序列化(serializable 防止序列化)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)