SQL注入-order by注入
何为order by 注入
它是指可控制的位置在order by子句后,如下order参数可控:select * from goods order by $_GET['order']
order by是mysql中对查询数据进行排序的方法, 使用示例
select * from 表名 order by 列名(或者数字) asc;升序(默认升序)
select * from 表名 order by 列名(或者数字) desc;降序
判断注入类型
数字型order by注入时,语句order by=2 and 1=2
,和order by=2 and 1=1
显示的结果一样,所以无法用来判断注入点类型
而rand()在数字型中,每次刷新会显示不同的排序结果
当在字符型中用?sort=rand()
,则不会有效果,排序不会改变
因此用rand()可判断注入点类型
注入方式
1.和union查询一块使用来判断字段有几个
(不是本主题讨论的重点)
在sql注入时经常利用order by
子句进行快速猜解表中的列数
通过修改order by
参数值,比如调整为较大的整型数如order by 5
,再依据回显情况来判断具体表中包含的列数。
判断出列数后,接着使用union select
语句进行回显。
2.基于if语句盲注(数字型)
下面的语句只有order=$id
,数字型注入时才能生效,
order ='$id'
导致if语句变成字符串,功能失效
如下图为演示
-
字符串型时if()失效,排列顺序不改变
-
数字型时排列顺序改变
知道列名情况下
if语句返回的是字符类型,不是整型, 因此如果使用数字代替列名是不行的,如下图
这是在知道列名的前提下使用
?order=if(表达式,id,username)
- 表达式为true时,根据id排序
- 表达式为false时,根据username排序
不知道列名
id总知道吧
?order=if(表达式,1,(select id from information_schema.tables))
-
如果表达式为true时,则会返回正常的页面。
-
如果表达式为false时,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空
3.基于时间的盲注
order by if(表达式,1,sleep(1))
-
表达式为true时,正常时间显示
-
表达式false时,会延迟一段时间显示
延迟的时间并不是sleep(1)中的1秒,而是大于1秒。 它与所查询的数据的条数是成倍数关系的。
计算公式:延迟时间=sleep(1)的秒数*所查询数据条数
如果查询的数据很多时,延迟的时间就会特别长
在写脚本时,可以添加timeout这一参数来避免延迟时间过长这一情况。
4.基于rand()的盲注(数字型)
rand() 函数可以产生随机数介于0和1之间的一个数
当给rand() 一个参数的时候,会将该参数作为一个随机种子,生成一个介于0-1之间的一个数,
种子固定,则生成的数固定
order by rand
:这个不是分组,只是排序,rand()只是生成一个随机数,每次检索的结果排序会不同
order by rand(表达式)
当表达式为true和false时,排序结果是不同的,所以就可以使用rand()函数进行盲注了。
5.报错注入
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
,则页面正常显示