只有10个端口地址,怎么在清单外挖到 SQL 注入漏洞?
原创
添柴不加火
添柴不加火
希泽Sec
2026年11月5日 15:17
山东
去阅读
DEEP OCEAN
只有10个端口地址,怎么在清单外挖到 SQL 注入漏洞?
导读 · CONTENTS
01前言
02分析前端代码
03先做鉴权基线
01
前言
PREFACE
给你一张清单,上面只有 10 个「域名 + 端口」,不告诉你是什么系统、用了什么技术、有什么功能。很多人拿到手就挨个打开首页、点开扫描器,扫一圈没发现东西,就觉得这系统挺安全。其实很多时候,不是没漏洞,是你连真正要测的资产都没找全。最近一次测试就是这个开局,最后真正的 SQL 注入漏洞就是在清单里没有的地址上。
02
分析前端代码
ANALYSIS
刚开始10个入口跑一遍,得到的东西无非是:Server 头、框架痕迹、登录页标题,能分出“这是个 Java 系统”“这是个若依”“这是个 nginx 默认页”,仅此而已。然后就开始分析前端JS,其中一个 Vue 前端站点,Vite 构建的 \_app.config.js 里,明确标注了真实 API 路径前缀,如果没发现它,后面所有接口探测都会命中 404,最后只会得出“这站没东西”的结果。而关键点在另一个站点的 JS 包里,把 3.67MB 的 bundle 文件下载下来结果里出现了一个其他端口的后端地址,路径前缀为 /jeecg-boot。而这个端口,根本不在提供的 10 个入口清单里。
03
先做鉴权基线
SECTION
确认了新的后端地址,也通过响应特征判断出是 JeecgBoot 框架,先别急着挂扫描器。我先做了一件事:建立鉴权基线。什么是鉴权基线?就是先搞清楚这套系统的默认规则:哪些接口本来就是公开的,哪些必须带凭证才能访问。没有这条基线,根本分不清“这是未授权漏洞”还是“接口设计就是如此”。我从 Swagger 文档里扒了 106 个接口,一个一个的发起请求,最终结果:
POINT 164 个接口返回 401(鉴权生效)
POINT 27 个接口返回 200(均为登录、验证码类公开接口)
POINT 3其余接口连接失败
JeecgBoot 内置了积木报表(JimuReport)组件,默认路径为 /jmreport/\\。基线测试时就注意到一个反常现象:/sys/\\ 下的接口全部返回 401,但 /jmreport/\\路径的响应形态完全不同。顺着路径测试到 queryFieldBySql 接口,构造最简单的查询请求:
CODE
POST /jeecg-boot/jmreport/queryFieldBySql
{\"sql\":\"select 1 as a\"}
响应直接返回 200,success:true,全程没有任何身份校验。
那为什么会出现这个问题?积木报表的定位是报表设计器,设计初衷就是允许用户在浏览器端自由编写 SQL 查询数据,因此接口天然不带鉴权 —— 它的安全假设是自身运行在已认证的内网环境中,而 JeecgBoot 将其集成打包时,没有把 /jmreport/\\ 路径纳入 Shiro 鉴权链,一个默认内网使用的组件,被直接暴露在公网,就成了一个零门槛的任意 SQL 执行点。
04
转换测试手法
TESTING
确认 SQL 可执行后,首先用最直接的时间盲注做验证:
POINT 1正常查询耗时 0.4~0.8 秒
POINT 2执行 sleep(2) 耗时约 4.4 秒
POINT 3执行 sleep(5) 耗时约 10.4 秒
延迟时长与 sleep 参数基本呈 2 倍线性关系,这不是测量误差,反而暴露了底层的 SQL 包装逻辑:
CODE
select
count(0)
from
(<用户输入SQL>)
tmp\_count
子查询被执行了两次,因此 sleep 时间也翻倍了,同时时间盲注会因为网络抖动而影响最终结果。这时候转变了一下思路:把条件为真和条件为假的完整响应报文逐字节对比,一对比就发现了现成的判定依据:
POINT 1条件为真:result字段中包含fieldList 数组
POINT 2条件为假:result 为空对象
布尔盲注这不就来了吗老规矩,点到为止,SQL 注入仅验证到库名、数据库版本即可。
如果觉得有用,欢迎点赞、在看、转发三连。
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论