反序列化漏洞

反序列化漏洞

1、概述

序列化是让Java对象脱离Java运行环境的一种手段,可以有效的实现多平台之间的通信、对象持久化存储。
反序列化漏洞_第1张图片
Java 序列化是指把 Java 对象转换为字节序列的过程,便于保存在内存、文件、数据库中,ObjectOutputStream类的 writeObject() 方法可以实现序列化。反序列化是指把字节序列恢复为 Java 对象的过程,ObjectInputStream 类的 readObject() 方法用于反序列化。

条件:
类必须实现反序列化接口,同时设置serialVersionUID以便适用不同jvm环境。
可通过SerializationDumper这个工具来查看其存储格式,主要包括Magi头:0xaced,TC_OBJECT:0x73,TC_CLASS:0x72,serialVersionUID,newHandle

示例:
反序列化漏洞_第2张图片
代码功能:
将String对象obj1序列化后写入object文件,后反序列化得到对象obj2。

Object文件中的内容:
反序列化漏洞_第3张图片
Ac ed 00 05是java序列化内容的特征,编码后是rO0ABQ==

使用场景:
• http参数,cookie,sesion,存储方式可能是base64(rO0),压缩后的base64(H4sl),MII等
• Servlets HTTP,Sockets,Session管理器 包含的协议就包括JMX,RMI,JMS,JNDI等(\xac\xed)
• xml Xstream,XMLDecoder等(HTTP Body:Content-Type:application/xml)
• json(Jackson,fastjson) http请求中包含

2、漏洞成因

序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。

漏洞案例:
反序列化漏洞_第4张图片
反序列化漏洞_第5张图片
Test.class中MyObject类有一个共有属性name,myObj实例化后将myObj.name赋值为了“hi”,然后序列话写入object:
反序列化漏洞_第6张图片
漏洞发生在反序列化过程,MyObject类实现了Serializable接口,并重写了readObject()函数(从源输入流中读取字节序列,反序列化成对象),这里定制的行为是打开计算器:
反序列化漏洞_第7张图片
攻击时序图:
反序列化漏洞_第8张图片

3、Weblogic反序列化漏洞汇总

历史漏洞:
反序列化漏洞_第9张图片

3.1 CVE-2015-4852 Commons Collections

概述:
借用Java反序列化和Apache Commons Collections这一基础类库实现远程命令执行。这个漏洞横扫WebLogic、WebSphere、JBoss、Jenkins、OpenNMS的最新版。

漏洞出现在WLS Security组件,允许远程攻击者执行任意命令。攻击者通过向TCP端口7001发送T3协议流量,其中包含精心构造的序列化Java对象利用此漏洞。

(T3 协议在 WebLogic Server 和其他 Java 程序,包括客户端及其他 WebLogic Server 实例间传输数据)

漏洞分析:
Apache Commons Collections是一个扩展了Java标准库里的Collection结构的第三方基础库,实现了一个TransformedMap类,该类是对Java标准数据结构Map接口的一个扩展。该类可以在一个元素被加入到集合内时,自动对该元素进行特定的修饰变换,具体的变换逻辑由Transformer类定义,Transformer在TransformedMap实例化时作为参数传入。(可控变量)
反序列化漏洞_第10张图片
如果某个可序列化的类重写了readObject()方法,并且在readObject()中对Map类型的变量进行了键值修改操作,并且这个Map变量是可控的,就可以实现我们的攻击目标了。
于是找到了这个类:AnnotationInvocationHandler。该类的代码如下(反序列化)

我们可以实例化一个AnnotationInvocationHandler类,将其成员变量memberValues赋值为精心构造的恶意TransformedMap对象。然后将其序列化,提交给未做安全检测的Java应用。Java应用在进行反序列化操作时,则会触发TransformedMap的变换函数,执行预设的命令。

分析:https://security.tencent.com/index.php/blog/msg/97
Poc:https://github.com/fjserna/CVE-2015-7547

修复办法:
http://www.oracle.com/technetwork/topics/security/alert-cve-2015-4852-2763333.html
https://blogs.oracle.com/security/entry/security_alert_cve_2015_4852

3.2 CVE-2016-0638

漏洞位置,在readExternal位置:
反序列化漏洞_第11张图片
补丁,加了一个FilteringObjectInputStream过滤接口:
反序列化漏洞_第12张图片

3.3 CVE-2017-3248

根据JRMPListener来构造的,从补丁也可以看出,在resolveClass和resolveProxyClass都设置了黑名单。
反序列化漏洞_第13张图片

3.4 CVE-2017-3506&CVE-2017-10271

概述:
CVE-2017-10271 是3506的绕过。
漏洞在WLS-WebServices这个组件中,基于WLS wsat模块,核心就是XMLDecoder的反序列化漏洞,Java 调用XMLDecoder解析XML文件的时候,存在命令执行漏洞。
当前市面上挖矿主力军。

案例:
xmldecoder.xml:
反序列化漏洞_第14张图片
利用Java的XMLDecoder解析这个xml文件:
反序列化漏洞_第15张图片
漏洞分析:
漏洞出现在wls-wsat.war中,此组件使用了weblogic自带的webservices处理程序来处理SOAP请求,在weblogic.wsee.jaxws.workcontext.WorkContextServerTube
类中获取XML数据传递给XMLDecoder来解析。
反序列化漏洞_第16张图片
实例化了WorkContextXmlInputAdapter类,并且将获取到的XML格式的序列化数据传递到此类的构造方法中,最后通过XMLDecoder来进行反序列化操作。
在这里插入图片描述
漏洞复现:
抓包:
反序列化漏洞_第17张图片
工具:

java -jar WebLogic_Wls-Wsat_RCE_Exp.jar http://192.168.43.100:7001 test.jsp

反序列化漏洞_第18张图片
反序列化漏洞_第19张图片
修复:
1、建议不要用JDK中的XmlDeocder类,寻求其它更安全的xml解析工具类,考虑是否删除WLS-WebServices组件
2、官方修复:补丁限定了object,new,method,void,array等字段,限定了不能生成java 实例

参考:
https://github.com/Tom4t0/Tom4t0.github.io/blob/29314ca531f23e9e245bad9516c5d4e4c63756f2/_posts/2017-12-22-WebLogic%20WLS-WebServices%E7%BB%84%E4%BB%B6%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90.md
3.5 CVE-2018-2628

影响版本:
Oracle WebLogic Server10.3.6.0
Oracle WebLogic Server12.2.1.2
Oracle WebLogic Server12.2.1.3
Oracle WebLogic Server12.1.3.0
反序列化漏洞_第20张图片
漏洞分析:
1.反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2.RMI
RMI是Remote Method Invocation的简称,是J2SE的一部分,能够让程序员开发出基于Java的分布式应用。一个RMI对象是一个远程Java对象,可以从另一个Java虚拟机上(甚至跨过网络)调用它的方法,可以像调用本地Java对象的方法一样调用远程对象的方法,使分布在不同的JVM中的对象的外表和行为都像本地对象一样。
RMI传输过程都使用序列化和反序列化,如果RMI服务端端口对外开发,并且服务端使用了像Apache Commons Collections这类库,那么会导致远程命令执行。
RMI依赖于Java远程消息交换协议JRMP(Java Remote Messaging Protocol),该协议为java定制,要求服务端与客户端都为java编写。

3.绕过黑名单
Weblogic 中InboundMsgAbbrev 的resolveProxyClass处理rmi接口类型,因为只判断了java.rmi.registry.Registry ,找一个其他的rmi接口绕过,比如java.rmi.activation.Activator为 RMI 对象激活提供支持。
在这里插入图片描述
复现过程:
首先服务端监听ysoserial,上面的反射代码被集成到了ysoserial工具中的CommonsCollections 的payload中,最终依然是sun.reflect.annotation.AnnotationInvocationHandler。
攻击端生成payload,接口用java.rmi.registry.Registry

4、漏洞挖掘

基本手段:
从可控数据的反序列化或间接的反序列化接口入手,在此基础上尝试构造序列化对象。

首先拿到一个Java应用,需要找到一个接受外部输入的序列化对象的接收点,即反序列化漏洞的触发点。我们可以通过审计源码中对反序列化函数的调用(例如readObject())来寻找,也可以直接通过对应用交互流量进行抓包,查看流量中是否包含java序列化数据来判断,java序列化数据的特征为以标记(ac ed 00 05)开头。

确定了反序列化输入点后,再考察应用的Class Path中是否包含Apache Commons Collections库(ysoserial所支持的其他库亦可),如果是,就可以使用ysoserial来生成反序列化的payload,指定库名和想要执行的命令即可:

通过先前找到的传入对象方式进行对象注入,数据中载入payload,触发受影响应用中ObjectInputStream的反序列化操作,随后通过反射调用Runtime.getRunTime.exec即可完成利用。

5、防御手段

5.1 weblogic防御

• 过滤T3协议,限定可连接的IP
• 设置Nginx反向代理,实现t3协议和http协议隔离
• JEP290(JDK8u121,7u131,6u141),这个机制主要是在每层反序列化过程中都加了一层黑名单处理

5.2 原生反序列化防御

• 不要反序列化不可信的数据
• 给反序列数据加密签名,并确保解密在反序列之前
• 给反序列化接口添加认证授权
• 反序列化服务只允许监听在本地或者开启相应防火墙
• 升级第三方库
• 升级JDK,JEP290

你可能感兴趣的:(网络安全,java,web安全,反序列化)