Java RMI反序列化/JEP290相关

RMI

远程过程调用 (Remote Procedure Call)是一种服务器-客户端模式,
Java的RMI(Remote Method Invocation)是一种RPC实现。
其基本思想是程序员可以像本地那样,与远程对象进行交互。

步骤:

1、创建一个接口IRemoteService,继承自java.rmi.Remote;
2、S端创建一个类IRemoteServiceImpl,实现该接口,并且继承自java.rmi.server.UnicastRemoteObject;
3、S端在某端口(1099)注册该Naming服务,并将新建的对象(Skeleton)与该服务绑定;
4、C端通过网络连接(lookup)到该服务,得到C端的对象(Stub)通过网络调用服务端对象(Skeleton)的方法。

RMI安全问题

RMI基于Java的序列化/反序列化实现,使其成为反序列漏洞利用的一个攻击面。

原理

攻击者输入恶意序列化对象,使得RMI服务端反序列化攻击者指定的对象;
如果攻击者指定的对象实现了自定义的readObject()方法,则在反序列化过程中可以借此实现一些副作用(比如执行任意代码)。

利用条件

RMI服务端classloader可以找到(存在于classpath中)一个或多个类,能在反序列化过程中实现攻击者的意图。通常把能实现这个的类叫做gadget,或者当通过多个类组合起来实现的叫做gadget chain

Ysoserial

是一个预装了多个gadgets的反序列化漏洞利用工具。

JEP 290

这篇文章A First Look Into Java’s New Serialization Filtering
对JEP 290做了解读。
认为

在Java反序列化漏洞广受诟病的背景下,Oracle拿出了出了它自己的起码之力:JEP 290,提供了一种反序列化过滤的机制。这个机制确实是在朝正确的方向上走。但它不能完全解决问题,也不适合企业生产环境。

因为这种黑名单/白名单的过滤机制只有配置得当,才能有效过滤掉恶意的反序列化攻击。

JEP 290引入了三种过滤机制:

一、进程级过滤器(Process-wide Filter),也叫全局过滤器(Global Filter)

这种过滤方式的工作方式是:
启动Java应用时添加命令行参数(后面有例子)

-Djdk.serialFilter=<白名单类1>;<白名单类2>;!<黑名单类>

或者设置Java系统属性(Java 6,7,8)
$JAVA_HOME/jre/lib/security/java.security(官方的是错的)
或者启动Java应用时设置

-Djava.security.properties=<黑白名单配置文件名>

基于白名单的进程级过滤器虽然是有效的,但是由于是白名单,程序员得找出某应用所有需要被反序列化调用的类,所以一般较难实现。不需要程序员手动修改应用程序级别的代码,因为这个机制已经内置在加入JEP 290的JDK代码(java.io.ObjectInputStream)中。
PS:对于RMI反序列化,如果加入了全局过滤器,当然没有办法绕过这个全局过滤器。

二、自定义过滤器(Custom filters)

可以覆盖进程级过滤器!
当程序员很明确知道他想要反序列化的类是在哪个具体的包下,或者具体的类。需要程序员手动修改应用程序级别的代码。
通过代码:

ObjectInputFilter filesOnlyFilter = ObjectInputFilter.Config.createFilter("de.mogwailabs.Example;!*");

表示只接受
de.mogwailabs.Example
这个包下的类,其他的类都会被拒绝。
PS: 对于RMI反序列化,我们不关心这个,因为我们无法修改服务端代码。

三、内置过滤器(Built-in Filters)

//TODO

关于java.security文件

这个文件在jre目录下,
Java 6、7、8的是在这个目录下:

$JAVA_HOME/jre/lib/security/java.security

看一下不同的JDK有没有JEP 290有什么区别:
在这里插入图片描述
具体看一下这个有JEP 290的jdk1.8.0_112的java.security文件有什么东西。
首先有全局过滤器,即

jdk.serialFilter

这个值,不过需要程序员自行配置。
在这里插入图片描述

另外有RMI相关的,有一个内置的黑名单:
在这里插入图片描述
Github有人写了一个常用的黑名单,配置JEP 290机制使用:
以下有一些黑名单类集合(过滤掉ysoserial中的gadgets):
https://github.com/mogwailabs/deserialization-filter-blacklists/blob/master/blacklist-filter.properties
在这里插入图片描述
在以下JDK版本之上

  • Java 8 - 8u121
  • Java 7 - 7u131
  • Java 6 - 6u141

可以使用以下方式来进行进程级(Process-wide)的黑名单过滤,操作方法:

java -Djava.security.properties=blacklist-filter.properties -jar application.jar

后JEP 290时代

ATTACKING JAVA RMI SERVICES AFTER JEP 290
这篇文章其实人家也没说绕过JEP 290的机制。人家标题说的就是XXX after jep 290,即"后JEP 290时代的Java RMI漏洞利用方式",从头到尾没说绕过的事,也在开篇承认了如果在JEP 290机制下使用了全局过滤,那还是没问题的。
在这里插入图片描述
翻译过来是:如果没有配置全局过滤器,我们还是可以在应用程序级别下功夫利用反序列化漏洞的。

以最近的Dubbo反序列漏洞为例,比如我们用CommonsCollections4这个gadget生成了payload,不管是使用JDK 112还是JDK 131启动dubbo-samples-http,都可以被反序列化成功。原因在于JEP 290只是引入了一种机制,要么使用进程级的过滤器,要么各个应用自己加上自己应用级的过滤器。
而且对于JDK 112,即便加上了这个参数

-Djava.security.properties=/Users/caiqiqi/GitProjects/JavaSer/JEP290/blacklist-filter.properties

在这里插入图片描述
启动后,依然可以被反序列化成功。
反序列化成功HTTP响应结果是:
在这里插入图片描述
而当使用带JEP290的JDK 131启动时,
在这里插入图片描述
未能命令执行。HTTP返回响应:
在这里插入图片描述
报错信息是:

java.io.InvalidClassException: filter status: REJECTED

对比一下:
在这里插入图片描述
从打印出的调试信息也可以看出JEP 290修改了java.io.ObjectInputStream类,增加了过滤对待反序列化对象的类检查的逻辑(推测的,待看具体代码)。

RMI反序列化漏洞环境

环境来源:
https://github.com/mogwailabs/rmi-deserialization
环境包括服务端和客户端。且两端持有相同的接口:
IBSidesService.java

package de.mogwailabs.BSidesRMIService;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IBSidesService extends Remote {

   boolean register(String ticketID) throws RemoteException;
   void visitTalk(String talkname) throws RemoteException;
   void poke(Object attende) throws RemoteException;
}

在这里插入图片描述
为了环境更加真实,这里没有将服务端和客户端放到同一个节点上。服务端代码BSidesMucRmiService放到ubuntu-server虚拟机里:
使用maven编译依赖并打包:

mvn clean compile assembly:single

成功打包成jar之后,会在默认端口1099启动RMI服务:

java -jar ./target/BSidesRMIService-0.1-jar-with-dependencies.jar

在这里插入图片描述
使用nmap扫描1099端口,可以得到34725这个新的端口,然后第二次使用nmap扫描,可以获取到远程RMI服务的一些信息。
在这里插入图片描述
然后编译客户端。由于客户端有ysoserial的payload,需要带上ysoserial作为classpath:

javac -cp /Users/caiqiqi/Downloads/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar *.java

在这里插入图片描述

漏洞利用:

java -cp .:/Users/caiqiqi/Downloads/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar de.mogwailabs.BSidesRMIService.AttackClient 127.0.0.1  1099 "touch /tmp/test_rmi"

JDK 1.8.0_112
在这里插入图片描述
可以成功
在这里插入图片描述
在这里插入图片描述

参考

发布了592 篇原创文章 · 获赞 97 · 访问量 97万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章