漏洞分析: 帆软反序列化RCE漏洞分析_V20220812
本文仅用于技术讨论与研究,文中的实现方法切勿应用在任何违法场景。如因涉嫌违法造成的一切不良影响,本文作者概不负责。
0x00 前言
朋友发给我一起看看的洞,我也搞 JAVA
的系统搞得少,一起看了下,成功复现,在这里记录一下。
0x01 漏洞简介
帆软官网通告: https://help.fanruan.com/finereport/doc-view-4833.html
0x02 漏洞影响
影响 2022-08-12 之前的 FineReport10.0/11.0
、FineBI5.1
系列
经测试 FineBI5.1.10
可以成功,FineBI5.1.18
无法成功,下载到的最新版 FineReport10.0
也无法成功,但历史版本应该可以成功。
0x03 环境搭建
安装包下载
本文使用的环境是 FineBI5.1.10
官网可以下载到安装包:https://www.finebi.com/product/download
注册一个账号即可获取免费注册码
调试环境搭建
安装完后,IDEA
直接打开整个项目,一股脑导入所有的 jar
包
接下来设置调试选项
复制红框中的参数,然后打开 E:\FineBI5.1\bin\finebi.vmoptions
,并将该参数插入到最后一行,重启 FineBI.exe
,IDEA
打开 debug
即可开始调试。
0x04 漏洞分析
根据漏洞通告,直接找到 webroot/decision/remote/design/channel
接口所在的包,位置如下:
1 |
|
此处将所有的输入都放入 WorkContext.handleMessage
,跟进后如下
1 |
|
继续跟进 messageListener.handleMessage
1 |
|
这里就能看到与反序列化有关的 this.deserializeInvocation
,参数 var1
是我们的输入,var2
用来存放结果
看到这一句
1 |
|
这里涉及到三个类的处理,依次来看,我们首先看到 InvocationSerializer.getDefault()
1 |
|
这里直接返回 DEFAULT
,是在 23 行定义的常量,直接是获取实例化的 InvocationSerializer()
,可以直接看构造函数,最后执行的是 SerializerSummaryAdaptor.get()
获取完后直接将得到的值或对象赋值给 this.paramSerializer
,但是这个变量在后面反序列化执行中并不涉及,因此就不细讲了。
因此我们此处获取的是 InvocationSerializer()
的实例化对象,之后传入 GZipSerializerWrapper.wrap()
进行封装,看代码
1 |
|
这里直接返回 GZipSerializerWrapper(var0)
实例化对象,然后是将传进来的 var1
也就是前面提到的 InvocationSerializer()
实例化对象赋值给 this.serializer
好了,接下来执行 SerializerHelper.deserialize()
1 |
|
这时候的 var1
已经处理过,不再是 null
,可以跳过 if
语句,然后使用 ByteArrayInputStream
将字节数组转换为输入流,最后进行反序列化,调用首先调用 GZipSerializerWrapper
的 deserialize
函数
注意到这里的 deserialize
方法,反序列化时,会先将传入的值进行 gzip
解压,然后再反序列化,这点一定得牢记。
然后调用 this.serializer
的 deserialize
,前面讲过 this.serializer
是实例化的 InvocationSerializer()
,因此调用 InvocationSerializer()
的 deserialize
这里就调用了 JDKSerializer.CustomObjectInputStream(var1)
,看到代码
1 |
|
这个 CustomObjectInputStream
类继承了 ObjectInputStream
,最后调用 readObject
方法进行反序列化,由于内容可控,因此造成了反序列化漏洞。
0x05 漏洞复现
这里可以利用 CB
链的不使用 common-connections
版本进行攻击,直接借助 su18
大佬的 ysuserial
工具生成 payload
,选中的链子是 CommonsBeanutils1183NOCC
简单写个 exp
提交数据
这个 exp
参考的大佬的,链接在最下方有,在他的基础上,增加了 gzip
压缩,以及删除了 headers
,这个 headers
在此处可以使用,但是在 FineBI5.1.18
或者 FineReport10.0.19
会导致数据无法 POST
成功(这里让我调了挺久,最后通过 wireshark
抓包才查出来问题)
1 |
|
0x06 修复
FineBI5.1.10
成功后,我又去看了 FineBI5.1.18
,利用没有成功。我这里使用 FineReport10.0
,代码几乎一致
FineReport10.0
的代码中存在这样一段,对反序列化的数据进行了黑名单过滤
1 |
|
黑名单位置
1 |
|