SQL注入系列文章:
目录
前面和大家分享了SQL注入的联合查询,报错注入,盲注,二次注入,本篇将会和大家分享一下SQL注入中的order by 注入ヾ(◍°∇°◍)ノ゙
什么是order by?
在MySQL支持使用ORDER BY语句对查询结果集进行排序处理,使用ORDER BY语句不仅支持对单列数据的排序,还支持对数据表中多列数据的排序。语法格式如下
select * from 表名 order by 列名(或者数字) asc;升序(默认升序)
select * from 表名 order by 列名(或者数字) desc;降序
假设有以下用户表
如果我们现在需要按照username来进行由大到小,升序排列,则需要使用到order by来进行排序了
可以看到username那一列是按照字母从小到大的方式进行排序。
如果需要进行倒叙排列就加一个desc即可:
order by 注入
与联合查询配合使用
order by的一个用法:
对SQL注入有了解或者如果看过我前面文章的小伙伴应该知道我们手工进行注入的时候需要判断数据库中一共有多少列,因此需要使用select 1,2,3...不断变化数字来查找数据库一共有多少列,那么如果某个系统的数据库中有100列,那么我们需要一直到100,非常的麻烦且低消,因此我们可以使用order by 来进行判断:
可以利用 id=1‘ order by n --+不断变换n的值来来判断列数,不会像 1,2,3...那样的很麻烦需要写很多的数字,非常的耗时。
现在就已经知道列数了,然后再配合使用union select语句进行注入出数据即可。
与if语句配合使用
下面的语句只有order=$id,数字型注入时才能生效,order ='$id'导致if语句变成字符串,功能失效
如下图为演示:
字符串型时if()失效,排列顺序不改变
数字型时排列顺序改变
知道列名情况下 if语句返回的是字符类型,不是整型, 因此如果使用数字代替列名是不行的,如下图语句没有根据password排序。
这是在知道列名的前提下使用
?order=if(表达式,id,username)
-
表达式为true时,根据id排序
-
表达式为false是,根据username排序
不知道列名的情况:
?order=if(表达式,1,(select id from information_schema.tables))
-
如果表达式为true时,则会返回正常的页面
-
如果表达式为false,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空
与时间盲注配合使用
格式:
order by if(表达式,sleep(1),1)
-
表达式为true时,延迟显示
-
表达式为false时,正常显示
这里延迟的时间并不是sleep(1)中的1秒,而是大于1秒的。这是因为 它与所查询的数据的条数是成倍数关系的。延迟时间=sleep(1)的秒数*所查询数据条数
与rand()函数配合使用
rand() 函数可以产生随机数介于0和1之间的一个数
当给rand() 一个参数的时候,会将该参数作为一个随机种子,生成一个介于0-1之间的一个数,
种子固定,则生成的数固定
order by rand:这个不是分组,只是排序,rand()只是生成一个随机数,每次检索的结果排序会不同
order by rand(表达式)
当表达式true和false时,排序结果是不同的,所以就可以使用rand()函数进行盲注了。 例:
select * from users order by rand(ascii(mid((select database()),1,1))>114)
select * from users order by rand(ascii(mid((select database()),1,1))>115)
与报错注入配合使用
order by updatexml(1,if(1=2,1,(表达式)),1)
order by extractvalue(1,if(1=2,1,(表达式)));
因为1=2,所以执行表达式内容
例如order by updatexml(1,if(1=2,1,concat(0x7e,database(),0x7e)),1)获取数据库名
若改成1=1,则页面正常显示
到此order by注入就和大家一起学习完毕了,后面还会和大家分享更多的SQL注入的技巧和实验,我们后面再见(^▽^)