CodeReview中我指出了Leader的SQL存在注入问题,有点慌

猿天地

共 2351字,需浏览 5分钟

 ·

2020-07-31 13:18

转自:https://www.freebuf.com/vuls/240578.html

前言

SQL 注入漏洞作为 WEB 安全的最常见的漏洞之一,在 java 中随着预编译与各种 ORM 框架的使用,注入问题也越来越少。新手代码审计者往往对 Java Web 应用的多个框架组合而心生畏惧,不知如何下手,希望通过 Mybatis 框架使用不当导致的 SQL 注入问题为例,能够抛砖引玉给新手一些思路。

一、Mybatis 的 SQL 注入

Mybatis 的 SQL 语句可以基于注解的方式写在类方法上面,更多的是以 xml 的方式写到 xml 文件。Mybatis 中 SQL 语句需要我们自己手动编写或者用 generator 自动生成。编写 xml 文件时,MyBatis 支持两种参数符号,一种是#,另一种是$。比如:

"queryAll"  resultMap="resultMap">
  SELECT * FROM NEWS WHERE ID = #{id}

#使用预编译,$ 使用拼接 SQL。

Mybatis 框架下易产生 SQL 注入漏洞的情况主要分为以下三种:

1、模糊查询

Select * from news where title like ‘%#{title}%’

在这种情况下使用#程序会报错,新手程序员就把#号改成了$,这样如果 java 代码层面没有对用户输入的内容做处理势必会产生 SQL 注入漏洞。

正确写法:

select * from news where tile like concat(‘%’,#{title}, ‘%’)

2、in 之后的多个参数

in 之后多个 id 查询时使用# 同样会报错,

Select * from news where id in (#{ids})

正确用法为使用 foreach,而不是将#替换为$

id in
"ids" item="item" open="("separatosr="," close=")">
#{ids}

3、order by 之后

这种场景应当在 Java 层面做映射,设置一个字段/表名数组,仅允许用户传入索引值。这样保证传入的字段或者表名都在白名单里面。需要注意的是在 mybatis-generator 自动生成的 SQL 语句中,order by 使用的也是$,而 like 和 in 没有问题。

二、实战思路

我们使用一个开源的 cms 来分析,java sql 注入问题适合使用反推,先搜索 xml 查找可能存在注入的漏洞点-->反推到 DAO-->再到实现类-->再通过调用链找到前台 URL,找到利用点,话不多说走起

1、idea 导入项目

Idea 首页 点击 Get from Version Control,输入https://gitee.com/mingSoft/MCMS.git

下载完成,等待 maven 把项目下载完成

a1f9020102047f6f169a4d516877baf5.webp

2、搜索$ 关键字

Ctrl+shift+F 调出 Find in Path,筛选后缀 xml,搜索$ 关键字

34ff68887be684514c4f93395072cffb.webp

根据文件名带 Dao 的 xml 为我们需要的,以 IContentDao.xml 为例,双击打开,ctrl +F 搜索$,查找到 16 个前三个为数据库选择,跳过,

e132a7b4eae1346b8635f2b4ea5e2d2e.webp

继续往下看到疑似 order by 暂时搁置

2d7845fdde0b0139ca79c35a86a6e6a0.webp

继续往下看发现多个普通拼接,此点更容易利用,我们以此为例深入,只查找 ids 从前端哪里传入

28ac8ac78912473ab13203d6fcd58286.webp

3、搜索映射对象

Mybatis 的 select id 对应要映射的对象名,我们以 getSearchCount 为关键字搜索映射的对象

919bdac28770abfb21ce3008647bb3eb.webp

搜到了 IContentDao.java,IContentDaoimpl.java 和 McmsAction.java,分别对应映射的对象,对象的实现类和前端 controler,直接跳转到 controler 类

4870ae86b80d0cb9a131284a6834caa2.webp

发现只有 categoryIds 与目标参数 ids 相似,需进一步确认,返回到 IContentDao.java 按照标准流继续反推

5a59b4715db4947a8d91bb5175a0f708.webp

找到 ids 为 getSearchCount 的最后一个参数,alt+f7 查看调用链

df3c18c22f28d6ec918b27a6cca2189e.webp

调转到 ContentBizImpl,确认前台参数为 categoryIds

e37f6a302957e3c70bd797d077cb6df5.webp

返回到 McmsAction,参数由 BasicUtil.getString 接收,

1dc83e9fa53b23260f8c37557f16b51c.webp

跟进 BasicUtil.getString

20cf4b88f96afc3f914b889e853c32ce.webp

继续跳到 SpringUtil.getRequest(),前端未做处理,sql 注入实锤

ada8789b7261cc4f2cd3e39f20703b7d.webp

4、漏洞确认

项目运行起来,构造 sql 语句http://localhost:8080/ms-mcms/mcms/search.do?categoryId=1%27)%20%20or+updatexml(1,concat(0x7e,(SELECT+%40%40version),0x7e),1)%23 得到 mysql 的版本 5.7.27,验证注入存在。

cd35a3a117d7c139d078e96c1f4b088d.webp

三、总结

以上就是 mybatis 的 sql 注入审计的基本方法,我们没有分析的几个点也有问题,新手可以尝试分析一下不同的注入点来实操一遍,相信会有更多的收获。当我们再遇到类似问题时可以考虑:

1、Mybatis框架下审计SQL注入,重点关注在三个方面like,in和order by
2、xml方式编写sql时,可以先筛选xml文件搜索 $,逐个分析,要特别注意mybatis-generator的order by注入
3、Mybatis注解编写sql时方法类似
4、java层面应该做好参数检查,假定用户输入均为恶意输入,防范潜在的攻击


往期推荐



分布式ID生成服务,真的有必要搞一个

Dubbo服务调用隔离这么玩对么

Kitty中的动态线程池支持Nacos,Apollo多配置中心了

嘘!异步事件这样用真的好么?


后台回复 学习资料 领取学习视频


如有收获,点个在看,诚挚感谢

浏览 16
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报