前言

找个springboot项目练一练

环境搭建

审计的项目是github上 9.5k start的开源项目 newbee-mall。由于最新版的项目已修复多个漏洞,本文使用的是 Oct 17, 2019 的版本,项目地址 https://github.com/newbee-ltd/newbee-mall/tree/36807c87d13ee9ca08aff75197063b8836d8711d

使用IntelliJ IDEA打开项目文件夹,配置好SDK后IDEA会以maven项目打开并自动下载依赖包。

Spring属性文件路径:/src/main/resources/application.properties,其中可修改端口和mysql数据库地址

1
2
3
server.port=8089
...
spring.datasource.url=jdbc:mysql://localhost:3306/newbee_mall_db?...

配置文件路径:/src/main/java/ltd/newbee/mall/config/NeeBeeMallWebMvcConfigurer.java,其中配置了图片路径

1
2
3
4
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/upload/**").addResourceLocations("file:" + Constants.FILE_UPLOAD_DIC);
registry.addResourceHandler("/goods-img/**").addResourceLocations("file:" + Constants.FILE_UPLOAD_DIC);
}

此时是没有测试数据的,需要将/src/main/resources/upload.zip压缩包中的测试商品数据解压出来,放到任意的目录中。此处作为学习测试使用,可以直接解压在当前路径下,正式系统中一定要存放在非项目路径下。

在文件src/main/java/ltd/newbee/mall/common/Constants.java中,变量FILE_UPLOAD_DIC为当前上传图片路径,将其更改为我们解压upload.zip绝对路径

1
2
3
public class Constants {
//上传文件的默认url前缀,根据部署设置自行修改
public final static String FILE_UPLOAD_DIC = "/some_path/src/main/resources/upload/";

项目结构

整个项目的结构如下

image-20230122190834979

以「保存订单」功能为例,主要的请求流程如下图,参考Java SpringBoot框架代码审计二 - Spring Boot项目结构介绍 | Seikei’s Blog (s31k31.github.io)

request-example

SQLi

这个电商系统使用了mybatis用于数据库连接,可以在mapper里面搜索一下${}变量,如果存在则逆向寻找到参数是否可控

#{}告诉 MyBatis 创建一个预编译语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中。

${} 仅仅是纯粹的 string 替换,在动态 SQL 解析阶段将会进行变量替换,类似于直接替换字符串,会导致SQL注入产生。

image-20230218233638392

所有的匹配项都出现在NewBeeMallGoodsMapper.xml中,在文件开头找到namespace

1
<mapper namespace="ltd.newbee.mall.dao.NewBeeMallGoodsMapper">

继续在NewBeeMallGoodsMapper中找对应的方法

1
2
3
4
List<NewBeeMallGoods> findNewBeeMallGoodsList(PageQueryUtil pageUtil);
List<NewBeeMallGoods> findNewBeeMallGoodsListBySearch(PageQueryUtil pageUtil);
int getTotalNewBeeMallGoodsBySearch(PageQueryUtil pageUtil);
int getTotalNewBeeMallGoods(PageQueryUtil pageUtil);

注入点一

以第一个方法findNewBeeMallGoodsList为例,在项目中查找用法

继续定位到NewBeeMallGoodsServiceImpl,这是service中的接口实现类

image-20230218234352639

继续查找用法,定位到NewBeeMallGoodsController,这里贴出相关代码

1
2
3
4
5
6
7
8
9
@RequestMapping(value = "/goods/list", method = RequestMethod.GET)
@ResponseBody
public Result list(@RequestParam Map<String, Object> params) {
if (StringUtils.isEmpty(params.get("page")) || StringUtils.isEmpty(params.get("limit"))) {
return ResultGenerator.genFailResult("参数异常!");
}
PageQueryUtil pageUtil = new PageQueryUtil(params);
return ResultGenerator.genSuccessResult(newBeeMallGoodsService.getNewBeeMallGoodsPage(pageUtil));
}

需要访问的路由是/admin/goods/list,需要登录管理员,这里是一个后台的sql注入,用测试账号登陆

这是正常的请求

image-20230219001224309

如果要进行sql注入就需要闭合之前的语句

1
and goods_name like CONCAT('%','${goodsName}','%')

最终payload

1
/admin/goods/list?page=1&limit=10&goodsName=1','%') and length(database())>50#

注入点二

前台注入

1
/search?keyword=1','%')) and length(database())>50#

XSS

正常的框架在对xss做限制时,往往是通过Filter或者Interceptor来全局处理。Filter或Interceptor在请求进入Controller前,对请求内容进行处理。这样可以做到统一的字符处理,不用在每个功能点前单独对用户传入的字符进行XSS过滤。

在代码审计中,找XSS漏洞第一件事是先判断程序中是否存在Filter或者Interceptor。

image-20230227135229884

经过检查后可以发现这三个拦截器都没有和xss相关的功能

前端模板使用thymeleaf渲染,可以处理HTML,XML,JavaScript,CSS。thymeleaf有自己的XSS转义方法,thymeleaf模版在对th:text标签进行渲染的时候,默认对特殊字符进行了转义,我们可以在模板搜索一下th:utext,这个标签是不会被转义的

xss-request-path

可以找到两个结果

image-20230227140842395

回头找一下功能点

detail.html模板对应的路由是/goods/detail/,通过id来寻找商品,并且显示详细信息,此处不可控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@GetMapping("/goods/detail/{goodsId}")
public String detailPage(@PathVariable("goodsId") Long goodsId, HttpServletRequest request) {
if (goodsId < 1) {
return "error/error_5xx";
}
NewBeeMallGoods goods = newBeeMallGoodsService.getNewBeeMallGoodsById(goodsId);
if (goods == null) {
return "error/error_404";
}
NewBeeMallGoodsDetailVO goodsDetailVO = new NewBeeMallGoodsDetailVO();
BeanUtil.copyProperties(goods, goodsDetailVO);
goodsDetailVO.setGoodsCarouselList(goods.getGoodsCarousel().split(","));
request.setAttribute("goodsDetail", goodsDetailVO);
return "mall/detail";
}

newbee_mall_goods_edit.html对应的是编辑界面

可以进行xss

Reference

https://github.com/newbee-ltd/newbee-mall

springboot代码审计学习-newbeemall审计 (pankas.top)

Java SpringBoot框架代码审计一 - 前期准备 | Seikei’s Blog (s31k31.github.io)