0X00背景
在国内,政府、国企、央企等重点单位的内网应用系统基本都以JAVA为主。由于重点单位对于应用系统的性能、功能、扩展性等各方面及厂商开发快速性要求,SSM框架成为系统架构首选。这种情况下,有必要对梳理SSM框架相关的渗透测试入侵点。本文将针对Mybatis框架易发生注入的点做简单讨论。
0X01 Mybatis概述
Mybatis是支持定制化的SQL、存储过程以及高级映射的优秀的持久层框架。
避免了几乎所有的JDBC代码,手动设置参数以及获取结果集的操作。可以对配置和原生的Map使用简单的XML或注解,将接口和java的POJOs映射成数据库中的记录,极大提高了开发效率。
因为框架避免了用户直接进行SQL语句的拼接,以至于部分开发或安全同学认为只要使用了Mybatis框架,就可以杜绝SQL注入。显然这是不可能的,须知没有免费的午餐,惰性永存,作为安全从业者的我们就是在对抗人性的缺点。
接下来,我们首先了解Mybatis在配置SQL语句时候的两种描述参数的方式
一种为:#{}
一种为:${}
比如
这个语句selectPerson,接受一个int(或integer)类型的参数,并返回一个hashmap类型的对象。
注意这里的参数符号是:#{id}
该情况下,Mybatis会创建一个预处理语句参数,通过JDBC,这样的一个参数在SQL中会由一个“?”来标识,并传递到一个新的预处理语句当中,就像这样:
那么用$代替#来描述参数会发生什么?
这种情况下,框架会直接把变量拼接到SQL语句当中,不会做其他的处理。就相当于直接字符串拼接SQL语句。
综上:使用#格式的语法,框架会创建预处理语句属性并安全地设置值,这样做安全,迅速,通常也是首选做法。然而有时只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,可以这样来使用: ORDER BY S{columnName}。这里MyBatis不会修改或转义字符串。但显然,这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会导致潜在的SQL注入攻击,
0X03 误用场景
通过上部分的讨论,我们知道使用#符号,Mybatis会进行预编译来处理参数,这样可以有效的避免SQL注入。
那么假如所有人都正确使用了#,也就不存在安全问题了。事实却恰恰相反,总有错误的用法,所以咱们才不会失业。
在程序中,如order by字段、表名等,是无法使用预编译语句的,在like参数、in参数、order by这种尝试用拼接逻辑的场景下,开发同学总会给系统留下一点彩蛋。所以在实际测试当中,能聚焦这方面,有针对性的进行漏洞的挖掘,才可以达到事倍功半的效果。
1、 like参数注入
错误写法示例:
正确写法
对于Oracle可以通过’%’||’#param#’||’%’避免;
对于MySQL可以通过CONCAT(‘%’,#param#,’%’)避免;
对于MSSQL中通过’%’+#param#+’% 。
2 、in参数的SQL注入
错误写法示例:
正确写法
3、Order by SQL注入
因为预编译机制只能处理查询参数,此处显然不是查询参数,是一种错误的写法,因此order by位置的参数需要开发人员自己处理。所以只能使用$去拼接:
针对这种情况要在代码中做过滤、使用转义等方式处理字符,避免改变SQL逻辑。
其实也可以在xml中处理,用if去判断,这样就显得比较硬编码,sql语句会增加较多,显得臃肿,不便阅读。
通过上面的分析,我们了解到使用了mybatis框架容易误用的地方,可以有针对性的对部分功能展开渗透测试。
0X04 真实案列
某单位系统登陆页面未做验证码验证,进一步验证发现未对失败次数做限制,存在可爆破漏洞。同时是服务单位客户系统,存在弱密码可能极大。对于弱密码是有着永远说不完的话题,正好可以利用一波。
通过前期的信息收集,针对性制作弱密码字典,开始爆破行动。
反复尝试了几次,发现账户、密码正确,成功登陆系统。
接下来针对系统作进一步的渗透测试,因为有mybatis框架,我们只需要针对性测试上文总结的几处场景:
系统存在多处查询功能,查询用户名,会用like方式,猜测此处存在sql注入。
抓包手动测试:
‘ or ‘1’=‘0
‘ and ‘1’=‘1
返回结果明显不同,存在sql注入。
直接测模糊查询功能模块,得到多枚SQL注入。
Sqlmap结果,Oracle数据库,3个库。
通过源代码进行修复
我们前面提到like参数场景下的修复方式,如上图在LIKE后面跟 ‘%’||#{字段名}||’%’即可修复。
作为小白一次完整的mybatis框架sql注入针对性渗透测试与修复结束,望大佬们勿喷,请指点。
FROM :ol4three.com | Author:ol4three
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论