Mybatis 框架下 SQL 注入攻击的 3 种方式,真是防不胜防!

Java技术精选

共 2563字,需浏览 6分钟

 ·

2021-10-01 08:19

点击“蓝字”,关注,置顶公众号

每日技术干货,第一时间送达!


1

前言

 

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



2

Mybatis的SQL注入


 

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



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



#使用预编译,$使用拼接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
<foreach collection="ids" item="item" open="("separatosr="," close=")">
#{ids}
foreach
>



3、order by 之后


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


 


3

实战思路


 

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


1、idea导入项目


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

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



2、搜索$关键字


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



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



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



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



3、搜索映射对象


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



搜到了IContentDao.java,IContentDaoimpl.java和McmsAction.java,分别对应映射的对象,对象的实现类和前端controler,直接跳转到controler类,欢迎关注我们,公号IT码徒。



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



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



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



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



跟进BasicUtil.getString



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



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,验证注入存在。





4

总结


 

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



往期推荐








List 中 remove() 方法移除元素的【坑】


厉害了,用 IDEA 神器看源码,效率贼高!

MyBatis vs Hibernate,到底哪个性能更好?

如何设计一个小而美的抢红包系统?

来看看Redis 分布式锁的正确实现方式

IntelliJ idea 高效使用教程,一劳永逸!

Java 程序员必须掌握的 10 款开源工具!


浏览 41
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

分享
举报