java代码审计初试——newbee-mall审计

java代码审计初试——newbee-mall审计

一、介绍

本次审计对象是newbee-mall Version 1.0.0(新蜂商城系统),是一个适合比较基础的朋友练习代码审计的一套系统。采用了 Spring Boot 架构,代码逻辑清晰简单。

下载地址:https://github.com/newbee-ltd/newbee-mall

二、项目搭建

软件名版本
操作系统win10
javajdk1.8_x
审计软件IntelliJ IDEA 2019.3.3 x64
Maven3.6.1
mysql5.7.26
审计目标newbee-mall Version 1.0.0

1、下载newbee-mall Version 1.0.0

使用 IDEA 以 Maven 方式打开该项目即可,会自动加载相关依赖。没有任何报错就是依赖成功加载了

在这里插入图片描述

2、打开 PHPStudy 下的 Mysql 5.7.26 数据库

通打开命令行进入 mysql 数据库,创建名为newbeedb 的数据库,最后导入 newbee-mall\src\main\resources 目录下的newbee_mall_schema.sql 数据,如下命令:

进入mysql:mysql -u root -p (回车后键入密码)

创建数据库:create database newbeedb;

​切换使用数据库:use newbeedb;

导入数据:source 数据文件绝对路径

show tables :查看到下图的表就成功了;

在这里插入图片描述

3、修改系统配置文件信息

访问 src/main/resources/application.properties 配置文件的第 10 ~ 12 行,修改数据库链接信息:
在这里插入图片描述

4、启动项目
在这里插入图片描述

5、访问目标

http://127.0.0.1:28089/,后台地址:

http://127.0.0.1:28089/admin/login,登录账号密码为 admin/123456

在这里插入图片描述

三、漏洞挖掘

(一)、后台SQL注入漏洞

在对该项目进行简单梳理时,发现该项目使用了 Mybatis 持久层框架,可以简单理解成操作数据的第三方依赖。不恰当的使用 Mybatis 拼接 SQL 语句,往往会造成危害严重的 SQL 注入漏洞。在 Mybatis 中有两种常用的拼接 SQL 语句的符号,即 $ 和 # 。

#{} 告诉 MyBatis 创建一个预编译语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在SQL 中会由一个 ? 来标识,并被传递到一个新的预处理语句中,这样可以有效的防止 SQL 注入漏洞。

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

因此,

1、我们可以在项目中全局搜索关键字 ${,查看是否使用了存在风险的拼接方式,共发现四处使用${} 拼接 SQL 语句的地方,如下所示:

在这里插入图片描述

2、双击第一个进入src/main/resources/mapper/NewBeeMallGoodsMapper.xml 第 70 行,如下图所示:

在这里插入图片描述

3、逆向追踪到映射接口

点击左边的小鸟(MybatisX插件)会调到对应的映射接口文件

在这里插入图片描述

简单说明下,在 Mybatis 中 XXXMapper.xml 和 XXXMapper.java 的作用。

xxxmapper.xml :这是映射器(Mapper)文件,用于定义 SQL 查询语句和映射关系。它包含了各种 SQL 语句和对应的参数映射、结果映射等配置信息。xxxmapper.xml 文件中的 SQL 语句可以通过命名空间和标识符来唯一标识,并与 Java 代码中的对应映射器接口关联起来。这个文件通常是使用 XML 格式编写的。

xxxmapper.java :这是映射器接口,用于定义数据访问的方法。映射器接口中的方法通常对应于xxxmapper.xml 文件中定义的 SQL 查询语句。通过映射器接口,Java 代码可以调用数据库操作,而不需要直接编写和管理 SQL 查询语句。MyBatis 会在运行时自动实现这些接口的具体实现。映射器接口通常使用 Java 接口的形式编写。

4、继续逆向追踪

查看谁调用了 NewBeeMallGoodsMapper.java 接口中的findNewBeeMallGoodsList 方法,我们只需键盘按住 Ctrl + 鼠标左键点击该方法即可看到调用关系:
在这里插入图片描述

5、进入 NewBeeMallGoodsServiceImpl.java,

位于src/main/java/ltd/newbee/mall/service/impl/NewBeeMallGoodsServiceImpl.java ,在getNewBeeMallGoodsPage 方法中使用了 goodsMapper.findNewBeeMallGoodsList 方法:
在这里插入图片描述

6、继续逆向追踪,查看谁调用了 getNewBeeMallGoodsPage 方法,

还是只需键盘按住 Ctrl+ 鼠标左键点击该方法即可看到调用关系,直接跳到了 NewBeeMallGoodsController,位于src/main/java/ltd/newbee/mall/controller/admin/NewBeeMallGoodsController.java ,在第134 行使用了 getNewBeeMallGoodsPage 方法

7、分析NewBeeMallGoodsController 中 list 方法代码

首先,点击第 134 行中 pageUtil,该参数来自第 133 行,通过 PageQueryUtil 类创建一个 pageUtil 对象,传入 params 作为参数。PageQueryUtil 是作者自定义的工具类,是用于处理分页相关的操作。

然后,点击 133 行中 params,可以看到该参数来自第 129 行,是一个 Map 对象,可以简单理解为它需要从请求中获取参数。

最后,整理代码信息可以得到接口路径为/goods/list即 (http://127.0.0.1:28089/admin/goods/list),请求为 GET 方法,是个列表功能,根据代码路径来看应该是后台功能,这么看来我们找到了漏洞前端功能点。如下图所示:

在这里插入图片描述

有时 SQL 注入防范代码会在过滤器和拦截器中体现,但查看该项目时,并没有发现相关防护代码。

漏洞利用:

来到后台,从代码注释上大致可以猜到是商品管理功能:
在这里插入图片描述

F12查看这个功能的请求包

在这里插入图片描述

接下来burpsuit抓包拼接漏洞参数(goodsName)
在这里插入图片描述

sqlmap验证存在注入:
在这里插入图片描述

(二)、前台SQL注入漏洞

在这里插入图片描述

来到mapper文件

在这里插入图片描述

逆向追踪来到最终的Controller文件
在这里插入图片描述

可以得到接口路径为 /search 或 /search.html ,请求为 GET 方法,应该是个搜索功能,根据代码路径来看应该是前台功能,这么看来我们找到了漏洞前端功能点,漏洞参数为keyword。

在这里插入图片描述

sqlmap验证:
在这里插入图片描述

(三)、后台权限绕过漏洞

漏洞代码位于:src/main/java/ltd/newbee/mall/interceptor/AdminLoginInterceptor.java 的第 21 ~ 32 行
在这里插入图片描述

这段代码的意思是:

request.getRequestURI()获取路径
if判断:如果路径的开头是以/admin开头 并且Session 中的 loginUser 属性为 null;
if判断成立后,提示需要登录并跳转到后台登录页面中。
这两个条件中,Session 部分我们是没办法操纵的。但 uri.startsWith(“/admin”) 这个条件我们可以搞点小破坏,前面提到了 uri 是使用的 getRequestURI 方法获取的原始路径,那么我们可以找一些特殊字符绕过路径判断,并且不影响整体接口,比如:分号 ; ,正斜杠 / 等等。
最终,构造结构路径为 /;/admin/test 或 ///admin/test ,这样路径就不是以 /admin 开头了,并且该路径不会影响结构访问,实现了权限绕过。
在这里插入图片描述

(四)、越权漏洞

在做这部分代码审计分析时,我们需要改动两处代码,打开注册功能。

第一处,访问 src/main/java/ltd/newbee/mall/controller/mall/PersonalController.java 代码,将注册功能代码注释删除,最终如下图所示:

在这里插入图片描述

第二处,访问 src/main/resources/templates/mall/register.html ,将47行的注册事件按钮的register2()改为register(),如下图所示:

在这里插入图片描述

1、注册两个账号进入用户中心,点击更改个人信息抓包发现userid,可能存在越权漏洞

在这里插入图片描述

在项目中全局搜索接口名 /personal/updateInfo ,最终找到代码位置
src/main/java/ltd/newbee/mall/controller/mall/PersonalController.java
如下图所示:
在这里插入图片描述

第一步:分析第 116 行,通过方法名也可以看出这是更新用户信息的方法,其中传入了 mallUser和 httpSession 参数,而这两个参数来自用户, MallUser mallUser 表示要更新的用户对象,也就是接受用户信息的实体类, HttpSession httpSession 表示当前会话的 HttpSession 对象。我们可以跟进 MallUser 查看,主要定义了以下内容,其中有个 userId,如下图所示:
在这里插入图片描述

第二步:返回到 PersonalController 层,Ctrl 加鼠标左键点击第 116 行的 updateUserInfo 跟进该方法,最终跳转到了 NewBeeMallUserService 层,如下图所示:
在这里插入图片描述

点击左侧按钮,进行跟进到 NewBeeMallUserServiceImpl 层,updateUserInfo 方法具体代码如下

在这里插入图片描述

第三步:分析实现层代码具体做了什么操作。
第 73 行,根据根据用户 ID 主键查询用户信息,跟进 selectByPrimaryKey 通过 MallUserMapper.java接口跳转到 MallUserMapper.xml 映射器代码中。可以看到,通过限制 userId 在tb_newbee_mall_user 表中查询用户信息。也就是说,我的 userId 是 10,则最终查询语句如下,代码如下图所示:

select refid="Base_Column_List"(在上面定义了具体是哪些列) from
tb_newbee_mall_user where user_id = 10;

在这里插入图片描述

总结来说,第 73 行的作用是通过 ID 查询用户信息并赋值给 user
第 74 ~ 77 行,如果 user 不为 null,进行了三个 set 操作,其中传入的参数是来自 mallUser。也就是说,将查询到的用户信息中的内容设置成了用户输入的内容了。如下图所示:
在这里插入图片描述

第 78 行是关键,通过调用 mallUserMapper.updateByPrimaryKeySelective(user) 方法,将更新后的用户信息保存到数据库。如果更新操作影响的行数大于 0,则执行下面的代码块。我们跟进该方法,通过 MallUserMapper.java 接口跳转到 MallUserMapper.xml 映射器代码中。在这里面我们主要更新了 nick_name,address 以及 introduce_sign 这三个是我们传入的参数,不为 null。如下图所示:
在这里插入图片描述

第 79 ~ 83 行,是上面代码判断操作是否大于 0,符合该条件则进入这几行代码,我们更新个人信息是否符合这个条件的。这几行代码大致意思是,获取更新的用户信息,然后返回更新成功的响应。
第四步:整个流程我们追踪完了,总的来说,就是通过传入的 userId 获取用户信息后进行信息更新操作。整个流程没有任何权限校验,没有判断 userId 所属关系,进而造成了越权漏洞。
漏洞​验证:
第一个账号:

在这里插入图片描述

抓包发现userid为10
在这里插入图片描述

第二个账号
在这里插入图片描述

抓包发现userid为9
在这里插入图片描述

​第一步:更改第一个账号(昵称以135开头的)的信息,将userid由原来的10改为9发送

在这里插入图片描述

在登录另一个账号(138开头的)进入个人中心,发现信息已被更改
在这里插入图片描述

到此结束​!!!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值