本文采用的是《Web安全攻防渗透测试实战指南》提供的代码及数据库。
1 环境介绍
boolean.php
<?php
$con=mysqli_connect("localhost","root","qwer","security");
// 检测连接
if (mysqli_connect_errno())
{
echo "连接失败: " . mysqli_connect_error();
}
$id = $_GET['id'];
if (preg_match("/union|sleep|benchmark/i", $id)) {
exit("no");
}
$result = mysqli_query($con,"select * from users where `id`='".$id."'");
$row = mysqli_fetch_array($result);
if ($row) {
exit("yes");
}else{
exit("no");
}
?>
数据库2 实验过程
2.1 判断是否存在注入
访问该页面时,页面返回yes在URL后添加一个单引号,再次访问,发现返回结果由yes变成no,如图所示。
2.2 获得数据库名长度
访问id=1'and 1=1%23,id=1'and 1=2%23,发现返回的结果分别是yes和no,更改ID的值,发现返回的仍然是yes或者no,由此可判断,页面只返回yes或no,而没有返回数据库中的数据,所以此处不可使用Union注入。此处可以尝试利用Boolean注入,Boolean注入是指构造SQL判断语句,通过查看页面的返回结果来推测哪些SQL判断条件是成立的,以此获取数据库中的数据。我们先判断数据库名的长度,语句如下所示。
' and length(database())>=1--+
有单引号,所以需要注释符来注释。1的位置上可以是任意数字,如
' and length(database())>=8--+
和' and length(database())>=9--+
我们可以构造这样的语句,然后观察页面的返回结果,如下面俩图所示。
然后可以发现当数值为8时,返回的结果是yes;而当数值为9时,返回的结果是no。整个语句的意思是,数据库库名的长度大于等于8,结果为yes;大于等于9,结果为no,由此判断出数据库库名的长度为8.
2.3 获得数据库名
有三种方法都可以
2.3.1 利用substr获得数据库名
接着,使用逐字符判断的方式获取数据库库名。数据库库名的范围一般在az、09之内,可能还有一些特殊字符,这里的字母不区分大小写。逐字符判断的SQL语句为:
' and substr(database(),1,1)='t'--+
substr是截取的意思,其意思是截取database ()的值,从第一个字符开始,每次只返回一个。
substr的用法跟limit的有区别,需要注意。limit是从0开始排序,而这里是从1开始排序。可以使用Burp的爆破功能爆破其中的t' 值,如图4 -25所示,发现当值是s时,页面返回yes,其他值均返回no,因此判断数据库库名的第一位为s, 如图所示。
2.3.2 burpsuite爆破数据库库名
http://192.168.1.101/four/4.1.7/boolean.php?id=1%20%E2%80%98%20and%20substr(database(),1,1)=%27t%27--+
抓本地包方法: https://www.cnblogs.com/coderge/p/13684438.html
将抓到的包Send to intruder
打开burpsuite抓包发送到 Intruder模块,选择Cluster Bomb模式,并添加要爆破的参数。注意青绿色部分是他自己以为是个变量,记得选中然后clear$,不然一会你会发现需要配置4个变量。
设置第一个参数从1-8,因为已知数据库长度为8了
设置第二个参数从a-z。
开始攻击,前面几个返回的数据包长度不一样,可以肯定就是数据库的名字,按序排列:security
2.3.3 利用ord判断数据库库名
其实还可以使用ASCII码的字符进行查询,s的ASCII码是115, 而在MySQL中,ASCII转换的函数为ord,则逐字符判断的SQL语句应改为如下所示。
' and ord(substr(database(),1,1))=115--+
结果如图所示,返回的结果是yes。
现在已知数据库名‘security’
2.4 剩下的查询所有的表名字段名操作基本类似
查询表名、字段名的语句也应粘贴在database () 的位置,从Union注入中已经知道数据库’security' 的第一个表名是emails, 第一个字母应当是e,判断语句如下所示。
' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e'--+
结果如图所示,我们的结论是正确的,依此类推,就可以查询出所有的表名与字段名。