目录
0x00 前言
0x01 SpringBoot框架介绍
1、SpringBoot实现简单的 GET、POST 请求
2、SpringBoot 实现数据库操作
0x02 JDBC&Mybatis注入
0、环境及靶场介绍 - Hello-Java-Sec
1、JDBC 注入
2、Mybatis 注入
3、代码审计案例 - inxedu 后台 MyBatis 注入
0x00 前言
希望和各位大佬一起学习,如果文章内容有错请多多指正,谢谢!
个人博客链接:CH4SER的个人BLOG – Welcome To Ch4ser's Blog
0x01 SpringBoot框架介绍
1、SpringBoot实现简单的 GET、POST 请求
创建一个SpringBoot的项目,左侧选择 Spring Initializr,Server URL默认是 start.spring.io,可换成阿里云的 start.aliyun.com 更快,设置完成点击 Next
阿里云默认选择 2.6.13 的 SpringBoot 稳定版本,这里 Dependencies 勾选 Web - Spring Web 以测试简单的 GET、POST 请求,然后点击 Finish 即可
创建好的项目里,SpringBootTestDemoApplication 是整个的入口点,而 demos.web 可以直接删除
创建一个 IndexController,测试 GET、POST 方法(新建一个 controller 文件夹)
1、路由映射
@RequestMapping、@GetMapping、@PostMapping
2、参数传递
@RequestParam
3、数据响应
@RestController、@Controller
(@RestController注解相当于 @ResponseBody+@Controller 合在一起用的效果)
以下只截取部分测试结果:(有参数 GET 方式、有参数 POST 方式)
2、SpringBoot 实现数据库操作
创建一个新的 Spring 项目,Dependencies 勾选 Web - Spring Web、SQL - Mybatis Framework 和 MySQL Driver,用以测试数据库功能
创建完成后,可以看到 pom.xml 里面已经自动导入了 Dependency 信息
然后配置数据库的连接信息,默认的配置文件是 application.properties,在 resources 文件夹下面,将其后缀改为 .yml 然后进行配置,这里我使用 PHPStudy 开启的 MySQL(5.7.26版本)
创建一个 User 类,用于操作数据库数据,设置好 get、set、toString 方法(新建一个 entity 文件夹)
创建一个 UserMapper(创建的时候选择 “接口” ),定义了 findAll 和 findByID 两个方法(新建一个 mapper 文件夹)
创建一个 GetStuController,调用 findAll 和 findByID 两个方法(新建一个 controller 文件夹)
访问 http://localhost:8080/getallstu,测试结果如下:
访问 http://localhost:8080/getbyid,测试结果如下:
0x02 JDBC&Mybatis注入
0、环境及靶场介绍 - Hello-Java-Sec
环境:JDK 1.8、MYSQL 5.7.26
靶场:Hello-Java-Sec
Github地址:https://github.com/j3ers3/Hello-Java-Sec
1、JDBC 注入
JDBC 有两个方法执行 SQL 语句,分别是 PrepareStatement 和 Statement。
下面展示漏洞代码:
- 以下为采用 Statement 方法拼接 SQL 语句,导致 SQL 注入
- 以下为使用 PrepareStatement 预编译,但却采取拼接的方式构造 SQL,此时进行预编译也无用
- 以下为使用 JDBCTemplate,JDBCTemplate 是 Spring 对 JDBC 的封装,如果使用拼接语句便会产生注入
下面展示安全代码:
- 以下为采用黑名单过滤危险字符,同时也容易误伤(次方案)
- 以下为使用 PrepareStatement 预编译,使用?作为占位符,进行参数化查询
- 以下为使用 ESAPI 安全框架,ESAPI 是一个免费、开源的、网页应用程序安全控件库,它使程序员能够更容易写出更低风险的程序
- 以下为强制数据类型,强制转为数值型,SQL 语句无法拼接字符串,因此不存在注入
2、Mybatis 注入
MyBatis 支持两种参数符号,一种是 #,另一种是 $,# 使用预编译,$ 使用拼接 SQL。
Mybatis 框架下易产生 SQL 注入漏洞的情况主要分为以下三种。
- order by 注入
漏洞成因为:由于使用 #{} 会将对象转成字符串,形成 "order by 'user' desc" 导致报错(SQL 规定 order by 的字段名不能是字符),因此很多开发会采用 ${} 来解决,从而造成 SQL 注入
正确的写法应为:使用排序映射
- 搜索框 like 注入
漏洞成因为:模糊搜索时,直接使用 '%#{q}%' 会报错,部分开发图方便直接改成 '%${q}%' 从而造成注入
正确的写法应为:使用 # 号并使用 concat 连接
- in 之后多个参数的注入
漏洞成因为:在这种需求场景下使用 # 同样会报错,于是部分开发图方便就把 # 号改成了 $ 从而造成注入
正确的写法应为:使用 foreach 遍历
3、代码审计案例 - inxedu 后台 MyBatis 注入
环境:JDK 1.8、MYSQL 5.2.17
Inxedu 介绍:因酷时代 Inxedu 在线教育系统 V2.0.6 是一个开源的网校项目
项目搭建:
IDEA 打开 inxedu 项目,选择 Maven Project,然后修改数据库配置(project.properties),并导入相关 .sql 文件执行
然后设置 Tomcat 启动,注意修改对应端口为前面设置的 82
在 Deployment 里设置 Application context 为 /,和配置文件里的项目路径保持一致
代码审计:
首先看一下该项目用了什么组件,在 External Libraries 里发现其使用了 Mybatis
根据之前的分析,我们知道 Mybatis 下的 SQL 注入有 3 种,分别为 order by 注入、搜索框 like 注入、in 之后多个参数的注入,根据其漏洞代码的特征去项目里面搜索:
- order by 注入,其漏洞代码特征为 ${
- 搜索框 like 注入,其漏洞代码特征为 %${
- in 之后多个参数的注入,其漏洞代码特征为 (${
这里以 in 之后多个参数的注入为例,搜索结果如下,定位到 ArticleMapper.xml(全局搜索快捷键 ctrl+shift+f)
得到 id 值为 deleteArticleByIds,然后搜索该 id 继续定位,看哪里调用了它
搜索结果如下,定位到 AdminArticleController.java
根据路由信息 @RequestMapping 得知,此功能点大概率为后台文章删除操作
进入网站后台(默认账号密码 admin 111111)
测试文章删除功能点是否存在 SQL 注入,随便删除一篇文章,然后抓包
新建一个 txt 写入请求然后让 SQLMap 跑(不然 SQLMap 进不了后台),测试结果为存在 SQL 注入