总结了sql-labs中关于order by后面的注入的一些关卡

Less46-49

Less46

首先页面呈现

要我们get方式输入一个名为sort的参数

那我们输入/?sort=1

发现输出了users表里面的信息

输入sort=2时,发现排序变化了,按照第二列username的值进行了排序,于是猜测sql语句为select * from users order by get[‘sort’],

但是,又有个问题,之前的关卡都是将查询的结果利用mysql_fetch_array($result)=$row,这样都是输出一行结果,为什么这关输出了所有的结果

看一下源代码

Sql语句与猜想的一样

如果查询的结果不为空,那么

建立一个表格

Th标签能使里面的文件加粗并居中,td标签里的文本是默认向左对齐,不加粗

这是最关键的代码,和之前关卡不一样,这里用到了新的一个函数,mysql_fetch_assoc()

经过查询,这个函数与mysql_fetch_array区别只在于前者返回的是关联数组,而后者既能返回关联数组又能返回索引数组

而要返回多个结果,就需要while循环,如果不用while循环,那么只能返回一个查询结果

源代码搞懂了,那么怎么进行注入呢

输入sort=1 desc,变成降序排列,默认是asc,也就是升序排列

我们通过sql语句观察出这题注入点应该是order by 后面的数字

先认识一个随机查询,select * from users order by rand()

Rand()函数是随机产生一个0到1之间的数字

可以看出两次产生的是不同的随机数

而如果在括号内指定参数即rand(0)和rand(1),则会产生固定的随机数种子

随机查询就是利用rand()函数产生不同的随机数种子,这些产生的随机数进行order by 排序,order by后面的参数如果是产生固定的随机数种子,随机排序的表就是固定的

于是我们利用在rand()函数的参数中构造逻辑表达式,根据返回的表判断逻辑表达式的真假,从而进行注入,比如/?sort=rand(ascii(substr(database(),1,1))=115)

发现返回是rand(false)也就是rand(0)的随机排序表,说明上述逻辑表达式为假

我们再先试试union查询可不可以

报错了,是不是union 和order by不能一起使用了,我们在mysql命令行中测试一下,发现以下两种是不会报错的,一种是在联合两边的select 语句分别加括号,一种是将order by放入后面的select语句

为什么呢,经过查询发现union查询并不是只是简简单单的将两个子查询结果进行拼接,而是将两个查询结果统一查询,所以order by 应该放在最后一个子查询中

然而这关我们是在order by后进行注入,所以不能使用union注入

那能不能使用延时注入呢,也就是通过order by 1 and if(,1,sleep())

我们先在mysql命令行中测试一下

发现sleep了18秒,猜测是因为有18秒的原因,至于为什么是排序成这样,请教学长,学长也无法解释,暂时将这个问题搁在一边,但是抛开这个问题,利用这个方法进行延时注入是可行的,经过测试只要保证order by后面的参数不会报错,就能执行and后面的语句,经过测试带小数的数字,任何字符和字符串,列名,1,2,3都不会报错,但只有列名和1,2,3当做参数,才会对表排序,其他都会得到原来的表

下面试试延时注入

成功延时9秒

再试试能不能通过and 进行报错注入

非常完美,那么就可以进行熟悉爆表爆列了

http://127.0.0.1/sqli/sqli-labs/Less-46/?sort=1%20and%20extractvalue(1,concat(0x3a,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()),0x3a))

http://127.0.0.1/sqli/sqli-labs/Less-46/?sort=1%20and%20extractvalue(1,concat(0x3a,(select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27users%27),0x3a))

那么count(),group by,floor(rand(0)2)的报错注入能不能在这里运用呢

http://127.0.0.1/sqli/sqli-labs/Less-46/?sort=1%20and%201=(select%20count(*)%20from%20information_schema.columns%20group%20by%20concat(0x3a,database(),0x3a,floor(rand(0)*2)))

没问题,但除此之外还有一种方法进行这种报错注入,就是利用sort=(select …)进行报错注入

还有一种方法,可以在order by后面的procedure analyse参数进行报错注入

但是这里又碰到一个问题,procedure analyse后面的报错注入,加入子查询语句会报错,原因未知,可能是语法错误,暂时来看这个方法只能注出库名,用户名和版本

Into outfile 注入

Less-47

输入sort=1,2,3发现都得到原来的表,猜测sort可能被引号包裹,成为字符,所以排序后仍为原来的表,加个单引号

发现报错了,果然被单引号包裹了

先试试随机查询rand()

还是原来的表,说明这里用rand()是不行的

那么用and +报错注入

延时注入

另外一种报错注入,经过测试必须通过and 后面才能执行,之前关卡的sort=(select …)方法测试不会报错

Procedure analyse 报错注入

Less-48

输入sort=1,2,3,发现正常排序,说明sort没有被引号包裹,输入1’

发现没有报错,说明不返回报错信息,所以这关不能用报错注入

排除sort=(select count(*))注入和and +报错和procedure analyse 报错注入

那么试试sort=rand()注入

这是rand(true)排序的表

这是rand(false)排序的表

再试试 and +延时注入

导出文件

Less-49

输入sort=1,2,3发现都得到原来的表,说明有引号包裹,在输入sort=1’,没有输出表,没有报错,说明被单引号包裹,并且没有返回报错信息

那么排除了报错注入,rand(),那只能延时注入和导出文件了

文件导出