反序列化漏洞的末日?JEP290机制研究

本文探讨了JEP290为Java引入的反序列化过滤机制,特别是针对RMI远程调用的影响。JEP290不仅提供了黑名单和白名单功能,还增强了对RMI导出对象的验证,有效地提升了系统的安全性。
0x00 前言
先说一下JEP290这个增强建议本身其实在2016年就提出来了,本身是针对JAVA 9的一个新特性,但是随后官方突然决定向下引进该增强机制,分别对JDK 6,7,8进行了支持:
当时pwntester大神还专门发了个推标庆祝了一下:

所以官方从8u121,7u13,6u141分别支持了这个JEP。
我为什么现在才来说这个case,因为最近测一个RMI的漏洞过程中,发现居然默认情况下把反序列化给拦截掉了,看了异常信息,发现是JDK本身造成的。后来才知道,原来这个java 9 的特性早就移植到6,7,8了。因此打算着重讨论下这个新的机制对RMI序列化的影响。

0x01 JEP290介绍
JEP290主要描述了这么几个机制:
(1)提供一个限制反序列化类的机制,白名单或者黑名单
(2)限制反序列化的深度和复杂度
(3)为RMI远程调用对象提供了一个验证类的机制
(4)定义一个可配置的过滤机制,比如可以通过配置properties文件的形式来定义过滤器
实际上就是为了给用户提供一个更加简单有效并且可配置的过滤机制,以及对RMI导出对象执行检查。
其核心实际上就是提供了一个名为ObjectInputFilter的接口,用户在进行反序列化操作的时候,将filter设置给ObjectInputStream对象。这里就是用的setInternalObjectInputFilter方法:

每当进行一次反序列化操作时,底层就会根据filter中的内容来进行判断,从而防止恶意的类进行反序列化操作。此外,还可以限制反序列化数据的信息,比如数组的长度、字节流长度、字节流深度以及使用引用的个数等。filter返回accept,reject或者undecided几个状态,然后用户根据状态进行决策。
而对于RMI来说,主要是导出远程对象前,先要执行过滤器逻辑,然后才进行接下来的动作,即对反序列化过程执行检查。
此外,还提供了两种可配置过滤器的方式:
(1)通过设置jdk.serialFilter这个System.property
(2)直接通过conf/security/java.properties文件进行配置

具体规则方面的内容可以直接参考原始链接:


0x02 RMI的过滤机制
RMI这个就不多介绍了,给出一张原理图:

RMI将网络通信的部分进行了抽象,这部分逻辑对于用户来说是透明的,其实是通过动态代理机制来实现的,通过Stub和Skel这两个代理对象,完成了对远程对象的调用。
扯远了,我们还是看看RMI中新加入的过滤机制。
首先先要复现该问题,自己写一个RMI Server,然后启动起来。之后,写一个RMI Client,调用bind方法将恶意的类发送给Server。结果直接抛出异常:

同时Server的控制台打印出来错误日志:

可以看到,是在处理远程对象代理的时候,没有通过filter的校验从而报错。
我使用的是8u131进行调试,直接来到RegistryImpl_Skel类中的46行代码,这里就是导出远程对象:

readObject正是在执行反序列化操作,单步跟进,就来到了ObjectInputStream的readObject方法中,调用的是readObject0方法:

接下来是readOrdinaryObject-> radClassDesc->readProxyDesc,然后获取里面的接口并调用filterCheck方法一个个检查,最后再对对象本身进行一次检查:

来到filterCheck方法中:

可以看到这里调用了ObjectInputStream中的serialFilter属性的checkInput方法,最后真正检查的是RegistryImpl.registryFilter方法,针对远程对象的检查条件如下:
return String.class != var2 && 
!Number.class.isAssignableFrom(var2) && 
!Remote.class.isAssignableFrom(var2) && 
!Proxy.class.isAssignableFrom(var2) && 
!UnicastRef.class.isAssignableFrom(var2) && !RMIClientSocketFactory.class.isAssignableFrom(var2) && !RMIServerSocketFactory.class.isAssignableFrom(var2) && !ActivationID.class.isAssignableFrom(var2) && 
!UID.class.isAssignableFrom(var2) ? Status.REJECTED : Status.ALLOWED;
可以看到直接把AnnotationInvocationHandler给禁用掉了,所以这个方法肯定是要返回REJECTED状态了,因此直接就抛了异常出来。

0x03 思考
ObjectInputFilter的引入是给了用户一个非常方便并且很官方的反序列化过滤机制,因此用好它可以很方便的写出过滤代码,思考一下反序列化刚出现的那会儿,还得自己去编码实现过滤机制,稍有不慎就会出问题。但是有了Filter机制,并不代表一定不会出问题,原因是开发者使用黑名单机制还是有可能漏掉一些lib或者有新的gadgets出现。所以以后反序列化漏洞还是可以玩一段时间,毕竟底层开发者技术跟进需要时间。
最后说一句,RMI这种粗暴的过滤我实在保留意见,因为可能会让很多基于RMI的程序面临兼容性问题。

<think>嗯,用户现在询问的是如何防御WebLogic反序列化漏洞攻击。之前的历史对话已经详细讨论了如何判断攻击是否成功,现在用户显然想转向防护措施。从引用的材料来看,这些漏洞主要涉及T3/IIOP协议、wls9-async组件和黑名单绕过机制[^1][^3][^5],所以防御方案需要针对性解决这些问题。 用户可能是个运维工程师或安全人员,正面临实际防护需求。ta特意强调"参考站内引用",说明需要权威解决方案而非泛泛而谈。值得注意的是,引用[2]提到WebLogic反序列化漏洞频发是因为"存在较多反序列化类和触发途径",这提示防御必须多管齐下。 防御方案应该覆盖三个层面:首先是补丁管理,因为引用[4]明确列出受影响的WebLogic版本;其次是协议控制,引用[3][^4]都指出T3/IIOP协议是主要攻击向量;最后是纵深防御,引用[2]强调黑名单机制容易被绕过,需要白名单等补充措施。 技术细节上要特别注意:wls9-async组件在引用[5]被确认为默认启用危险组件,必须优先处理;引用[4]提到的CVE-2023-21839表明即使新版本也存在风险,说明补丁不能一劳永逸;引用[1]提到的反序列化原理则暗示需要监控ObjectInputStream的使用。 用户没有说明环境是测试还是生产,所以方案需包含操作风险提示。另外考虑到ta之前关注过攻击验证,防御措施里可以加入"如何验证防护有效性"的建议,比如用旧版工具测试T3协议是否真正关闭。</think>防御WebLogic反序列化漏洞攻击需采取分层防护策略,结合补丁管理、协议控制和运行防护等手段。以下是关键防御措施: --- ### 一、基础防护:补丁与配置加固 1. **及安装官方补丁** - 定期检查Oracle官方安全公告,优先修复高危漏洞(如CVE-2023-21839、CVE-2019-2890)[^4][^3] - **操作示例**: ```bash # 下载官方补丁(示例) wget https://updates.oracle.com/ARULink/PatchDetails/process_form?patch_num=12345678 ``` 2. **禁用高风险协议** - 关闭非必需的T3/IIOP协议(主要攻击向量)[^4]: ```xml <!-- 修改config.xml --> <protocol>t3</protocol> <enabled>false</enabled> ``` - 通过控制台操作: `Admin Console → Environment → Servers → [Server] → Protocols → Disable T3` 3. **移除危险组件** - 删除易受攻击的组件(如`wls9-async.war`)[^5]: ```bash rm $DOMAIN_HOME/servers/AdminServer/tmp/_WL_internal/wls9-async/* ``` --- ### 二、纵深防御:运行防护 1. **启用反序列化过滤器** - 配置`FilterConfig.properties`文件,强制使用白名单机制: ```properties # 限制允许反序列化的类 java.util.ArrayList=ALLOWED java.lang.String=ALLOWED *.*=REJECTED # 默认拒绝所有 ``` - 启动参数添加:`-Djava.security.manager -Djava.security.policy=filter.policy` 2. **部署RASP防护** - 使用应用层防护工具(如OpenRASP)实拦截恶意行为: ```yaml # 配置规则示例(检测恶意ObjectInputStream) - hook: java/lang/ObjectInputStream.resolveClass action: block conditions: - class_exists: ysoserial.PayloadObject ``` 3. **网络层隔离** - 通过防火墙限制WebLogic端口(7001)的访问源: ```bash # 只允许管理IP访问 iptables -A INPUT -p tcp --dport 7001 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 7001 -j DROP ``` --- ### 三、持续监控与响应 1. **日志审计** - 监控`AdminServer.log`中的反序列化异常: ```bash grep "DeserializationException" $DOMAIN_HOME/servers/*/logs/*.log ``` - 告警关键词:`ClassCastException`, `InvalidObjectException` 2. **文件完整性校验** - 定期检查核心文件哈希值: ```bash # 生成基准哈希 sha256sum $ORACLE_HOME/wlserver/server/lib/weblogic.jar > baseline.sha256 # 定期对比 sha256sum -c baseline.sha256 ``` 3. **最小权限原则** - WebLogic进程以非root用户运行: ```bash chown -R weblogic:weblogic $DOMAIN_HOME ``` --- ### 四、防御效果验证 1. **漏洞扫描工具** - 使用Nmap检测漏洞状态: ```bash nmap -sV --script=weblogic-vuln-cve-2023-21839 <target_ip> ``` 2. **模拟攻击测试** - 通过ysoserial发送无害payload验证防护: ```bash java -jar ysoserial.jar CommonsCollections1 "id" | curl -X POST --data-binary @- http://target:7001/_async/ ``` - **预期结果**:返回`403 Forbidden`或拦截日志 > **关键提示**:防御需覆盖**开发-部署-运行**全生命周期,补丁更新是最有效手段[^2][^4]。对于无法停机的系统,至少需禁用T3协议并启用反序列化过滤器[^3]。 --- ### 防御框架对比 | 措施 | 实施难度 | 防护效果 | 适用场景 | |---------------------|----------|----------|------------------| | 协议禁用 | ★☆☆☆☆ | ★★★★☆ | 所有版本 | | 反序列化过滤器 | ★★★☆☆ | ★★★★★ | WebLogic 10.3.6+ | | RASP运行防护 | ★★★★☆ | ★★★★★ | 关键业务系统 | | 网络隔离 | ★★☆☆☆ | ★★★☆☆ | 云环境/物理服务器| ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值