RMI Bypass Jep290(Jdk8u231) 反序列化漏洞

来源:scanv2020.07.24

一 漏洞概述

RMI(Java Remote Method Invocation)是Java远程方法调用,是一种允许一个JVM上的object调用另一个JVM上object方法的机制,在Java RMI的通信过程中存在反序列化漏洞,攻击者能够利用该漏洞造成代码执行,漏洞等级为高危。

随着RMI的进一步发展,RMI上的反序列化攻击手段正逐渐增多,该类漏洞最近正受到愈加广泛的关注。

在JDK8u231之前的JDK版本,能够让注册中心反序列化UnicastRef这个类,该类可以发起一个JRMP连接到恶意服务端上,从而在DGC层造成一个反序列化,因为DGC层的filter是在反序列化之后进行设置的,没有起到实际作用,在JDK8u231进行了修复,在DGC层反序列化之前就为InputStream设置了filter,来过滤传入的序列化数据,提高安全性。

二 影响版本

JDK<=8u231

三 复现过程

1.需要一个向服务端发起JRMP连接的UnicastRef,这里ysoserial有相关代码,并且在LocateRegistry.getRegistry里也有相应代码。

2.创建RemoteObjectInvocationHandler的代理类,ssf是RMIServerSocketFactory类型。

3.将ssf的值设置成创建的代理类,但是由于是private类型,所以需要用反射来赋值。

然后我们利用Server端进行bind,让注册中心反序列化这个UnicastRemoteObject对象,不过序列化的时候出现了问题,在调用RegistryImpl_Stub.bind的时候,进行writeObject的时候。 

如果enableReplace为true。 

检测我们要序列化的obj,是否实现Remote/RemoteStub,由于UnicastRemoteObject实现了Remote,没有实现RemoteStub,于是会进入判断,就会替换我们的obj,以至于反序列化的时候不能还原我们构造的类。 

所以,需要把enableReplace改为false。这里可以自己实现重写RegistryImpl_Stub,将bind方法进行修改,在序列化之前,通过反射,把enableReplace值进行修改。

4.恶意服务端只需要利用ysoserial.exploit.JRMPListener开启,监听到来自客户端的请求之后,就会向客户端发送byte值2,并序列化恶意类,最终让客户端反序列化恶意类。

四 影响范围

根据 ZoomEye 网络空间搜索引擎对关键字 “RMI” 进行搜索,共得到 455,773 条 IP 历史记录,主要分布在韩国等国家。

五 修复建议

建议受影响用户及时将JDK升级到最新版本

下载地址为:https://www.oracle.com/java/technologies/javase-downloads.html

六 时间线

知道创宇发布漏洞情报时间:2020年7月24日

七 相关链接

TRINHS RMI:https://mogwailabs.de/blog/2020/02/an-trinhs-rmi-registry-bypass/

ZoomEye 网络空间搜索引擎:https://www.zoomeye.org/searchResult/report?q=app%3A%22RMI%22

热门文章

关注知道创宇云安全

获取安全动态