帆软报表历史漏洞分析(二)
字数 4411
更新时间 2026-03-24 15:13:25
帆软报表FineReport历史漏洞分析(二) 教学文档
1. 前言
本文档基于对帆软FineReport历史漏洞的系统性分析撰写,旨在提供详尽的技术教学。主要内容涵盖/remote/design/channel反序列化漏洞、FineVis插件任意文件写入漏洞的深度分析,并列举V8/V9版本的部分老漏洞。上一篇文章已分析路由结构与SQL注入类漏洞,本文为续篇。
2. 弱口令漏洞
2.1 影响版本
多个版本存在此问题。
2.2 漏洞分析
帆软报表系统存在默认内置用户。在实际环境中,以管理员身份登录后,可以在后台用户管理页面查看到这些内置用户。攻击者可以任意挑选一个默认用户,使用密码123456尝试登录,有很大概率成功进入后台系统。
2.3 官方修复方案
删除系统默认的内置用户,或对所有内置用户的密码进行强制性手动修改。
3. /remote/design/channel 反序列化漏洞
3.1 影响版本
- V10版本:可前台利用,全版本均受影响。
- V11版本:只能后台利用(需登录认证)。影响版本包括
<=11.0.32,存在可用的反序列化利用链。
3.2 漏洞分析
3.2.1 反序列化点
- 漏洞路由:
/remote/design/channel。 - 对应类:
com.fr.third.activemq.transport.WsTransport#onMessage。 - 关键差异:
- V10版本:
onMessage方法中无任何身份校验逻辑,直接处理序列化数据,支持前台未授权利用。 - V11版本:
onMessage方法中增加了validate鉴权校验,因此只能在已登录后台的上下文中利用。
- V10版本:
- 反序列化触发:数据流最终进入
com.fr.workspace.WorkContext#handleMessage->handleMessage,此处是核心反序列化点。序列化数据作为请求体,被SafeInvocationSerializer处理,并且外层经过了Gzip压缩。
3.2.2 反序列化利用链分析
由于帆软的第三方依赖包位于com/fr/third目录下,包名与常规不同,导致常规的序列化利用链生成工具无法直接使用,需要手动构造。以下分析几条关键利用链:
3.2.2.1 黑名单对比
通过对比不同版本的黑名单文件,可以推断出被修复的利用链。黑名单文件位置为/com/fr/serialization/blacklist.txt。文档作者通过脚本对比了10.0.19、11.0.28、11.5.5、11.5.8等版本的黑名单差异。
3.2.2.2 Hibernate链
- 利用链:
HashMap+TypedValue+TemplatesImpl - 触发原理:利用Hibernate依赖中
TypedValue#hashCode方法调用Getter的特性,链式调用至TemplatesImpl#getOutputProperties,最终实现代码执行。 - 修复情况:此链被修复得最早,目前基本已无法利用。
3.2.2.3 TreeBag链
- 利用链:
TreeBag+ClassComparator+VersionComparator+POJONode - 触发原理:
TreeBag#readObject触发compare方法,经过一系列Comparator调用,最终通过POJONode#toString触发Getter,并利用java.security.SignedObject#getObject进行二次反序列化。 - 调用栈:
org.apache.commons.collections.bag.TreeBag#readObject -> java.util.TreeMap#put -> java.util.TreeMap#compare -> com.fr.base.ClassComparator#compare -> org.freehep.util.VersionComparator#compare -> com.fr.third.fasterxml.jackson.databind.node.POJONode#toString -> java.security.SignedObject#getObject - 修复情况:
- V10版本在
10.0.19(2024.3.19发布)中修复。 - V11版本在
11.0.28(2024.7.17发布)中修复。
- V10版本在
3.2.2.4 TextAndMnemonicHashMap链
- 利用链:
HashMap+HashTable+UIDefaults$TextAndMnemonicHashMap+JSONArray+DruidXADataSource+HSQL+ 二次反序列化/JNDI - 触发原理:利用帆软自有的
com.fr.json.JSONArray#toString方法,该方法内部调用writeValueAsString,可触发Getter。链构造中,触发DruidXADataSource#getXAConnection()方法建立JDBC连接,利用帆软内置的HSQL驱动,在JDBC连接字符串中调用任意public static方法,从而实现二次反序列化或JNDI注入。 - 修复情况:V10全版本未修复;V11在
11.0.28版本中修复。
3.2.2.5 ImmutableSetMultimap链
- 利用链:
ImmutableSetMultimap+UsingToStringOrdering+JSONArray - 触发原理:通过
ImmutableSetMultimap#readObject触发Arrays.sort,进而调用UsingToStringOrdering#compare,再触发JSONArray#toString,后续可衔接DruidXADataSource及HSQL的利用链。 - 修复情况:V11在
11.0.32版本(2025.3.31发布)中修复。
3.3 V11版本后台鉴权绕过分析
V11版本需要在请求头中附带有效的token才能通过validate校验。token可通过模拟“远程设计”功能的登录流程获取。
- 获取密钥:访问
/webroot/decision/remote/design/check接口,获取encryptionKey。 - 加密密码:使用获取的
encryptionKey,通过AES/ECB模式对用户密码进行加密(PKCS5/PKCS7填充),并Base64编码。 - 获取Token:向
/webroot/decision/remote/design/verify接口发起POST请求,提交用户名和加密后的密码,并在请求头中设置transEncryptLevel: 1,成功后会返回JWT格式的token。 - 利用:在向
/remote/design/channel接口发送反序列化Payload时,在请求头中加入username和token字段即可。
3.4 官方修复机制
- 反序列化过滤的核心在
com.fr.serialization.SerializerHelper类。其safeDeserialize等方法最终会调用自定义的CustomObjectInputStream。 CustomObjectInputStream在其静态代码块中加载blacklist.txt黑名单,并在resolveClass方法中进行类名过滤,从而实现漏洞防护。
4. FineVis插件任意文件写入漏洞
4.1 影响版本
受影响的FineVis插件版本。
4.2 POC(Proof of Concept)
漏洞利用需要按顺序发送三个HTTP请求:
- 注册模板:
POST /webroot/decision/view/duchamp/theme/item/copy,参数id和sourceID可任意指定。 - 上传恶意文件:
POST /webroot/decision/view/duchamp/theme/attach,通过id关联模板,通过attachID标记附件,并通过metadata参数中的name字段进行路径穿越(如../../../../test.jsp),实现任意文件写入。 - 应用附件到模板:
POST /webroot/decision/view/duchamp/theme/resource2template,触发将上传的附件内容写入到name字段指定的路径。
4.3 漏洞分析
- 第一步:
DuchampThemeRequestService#copy方法,用于创建或复制一个主题模板,将id与模板配置关联。 - 第二步:
DuchampThemeRequestService#uploadAttachImage方法,根据id找到模板,将上传的文件内容与attachID关联,并存储文件元数据(包含可控的写入路径name)。 - 第三步:
DuchampThemeRequestService#applyThemeResource2Tpl->DuchampThemeRequestHelper#applyThemeResource2Tpl方法,根据模板ID和附件ID,取出文件内容,并根据元数据中的name路径写入服务器磁盘,从而完成任意文件写入。
4.4 官方修复
在FineVis插件的最新版本(如4.7.1)中,uploadAttachImage和applyThemeResource2Tpl这两个关键方法已被直接删除,从而彻底修复了漏洞。
5. V8/V9老版本漏洞列举
由于版本较旧,以下仅作列举,不保证所有Payload在特定环境下有效:
local_install文件上传漏洞:V8版本存在,可通过特定接口上传恶意文件。op=chart&cmd=get_geo_json任意文件读取+fr_log命令执行:V8版本漏洞,利用参数可实现文件读取,并可能进一步导致命令执行。- 任意文件覆盖漏洞:V9版本存在,通过
/WebReport/ReportServer?op=svginit&cmd=design_save_svg&filePath=接口,利用路径穿越覆盖服务器文件,写入Webshell。
6. 附录与参考
- 官方安全公告:https://help.fanruan.com/finereport/doc-view-4833.html
- 远程设计文档:https://help.fanruan.com/finereport/doc-view-1388.html
- 本文涉及的工具与代码仓库:https://github.com/1diot9/MyJavaSecStudy
- 黑名单对比结果:https://github.com/1diot9/MyJavaSecStudy/tree/main/CodeAudit/帆软报表FineReport/blacklist
相似文章
相似文章