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
可以成功
参考
- 2019年3月BSides会议上的Exploiting Java RMI services in 2019议题PPT
- ATTACKING JAVA RMI SERVICES AFTER JEP 290
- RMI漏洞的另一种利用方式
- A First Look Into Java’s New Serialization Filtering
- JDK approach to address deserialization Vulnerability
- Oracle官方关于Serialization Filtering的详细说明
- 反序列化漏洞的末日?JEP290机制研究
Java RMI反序列化/JEP290相关相关推荐
- java rmi反序列化漏洞 简介
目录 一.RMI简介 二.RMI示例 三.漏洞复现 四.漏洞分析 1.为什么这里的badAttributeValueExpException对象是通过反射构造,而不是直接声明? 2.为什么不直接将ba ...
- Java RMI服务远程方法调用漏洞
JAVA RMI 反序列化远程命令执行漏洞 漏洞资料 背景 原理 Payload构造 搭建本地测试环境 开启包含第三方库的RMI服务 测试RMI客户端 攻击测试 升级版攻击 Weblogic Comm ...
- java rmi漏洞工具_学生会私房菜【20200924】Weblogic WLS核心组件反序列化命令执行突破(CVE20182628)漏洞复现...
学生会私房菜 学生会私房菜是通过学生会信箱收集同学们的来稿,挑选其中的优质文档,不定期进行文档推送的主题. 本期文档内容为:Weblogic WLS核心组件反序列化命令执行突破(CVE-2018-26 ...
- Java RMI 介绍
一.Java RMI 概览 Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机 ...
- rmi反序列化导致rce漏洞修复_RMI反序列化漏洞分析
原创:Xman21合天智汇 一.RMI简介 首先看一下RMI在wikipedia上的描述: Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Ja ...
- Java RMI学习与解读(二)
写在前面# 接上篇文章,这篇主要是跟着看下整个RMI过程中的源码并对其做简单的分析 RMI源码分析# 还是先回顾下RMI流程: 创建远程对象接口(RemoteInterface) 创建远程对象类(Re ...
- rmi 反序列化漏洞_java反序列化漏洞—被低估的破坏之王
[IT168 资讯]IT168 资讯]近日,2015年最为被低估的,具有巨大破坏力的漏洞浮出水面.在FoxGlove Security安全团队的@breenmachine 发布一篇博客中介绍了该漏洞在 ...
- 学习笔记-java代码审计-反序列化
Java代码审计-反序列化 0x00 漏洞挖掘 业务代码 简单来说,找readObject/readUnshared就好了 protected void doPost(HttpServletReque ...
- Apache JMeter rmi 反序列化 cve-2018-1297
漏洞描述 Severity: Important Vendor: The Apache Software Foundation Versions Affected: JMeter 2.X, 3.X D ...
最新文章
- 帮AI体检看病一条龙服务,阿里发布“AI安全诊断大师”
- 深度学习环境配置指南!(Windows、Mac、Ubuntu全讲解)
- Java排序算法之——希尔排序
- UVa 11388 - GCD LCM
- 【python】xsspider零碎知识点
- 移动前端开发基础与优化
- boost::pool模块实现验证是否 malloc/free 宏一切仍然正常的测试程序)
- 产品经理思维模型:文化母体、品牌寄生、超级符号
- Epoll例子的使用
- conda命令增删查环境
- 20191011:冒泡排序的改良版--Shaker排序
- Shell脚本学习-阶段二十九-运维使用的
- python执行mysql存储过程_Mysql学习---使用Python执行存储过程
- RN开发系列<8>--Redux(1)入门篇
- vs2015 professional 密钥
- Windows又又又更新?Win 12开发将于下个月开始
- 29.Go异常处理-recover
- java基础复习之不死神兔
- Firefox火狐浏览器主页被360篡改了
- chrome扩展程序安装_如何从Chrome网上应用店外部安装扩展程序