Boolean注入攻击
Boolean注入攻击的测试地址:http://43.247.91.228:84/Less-5/?id=1
在URL后添加一个单引号,再次访问,发现返回结果由yes变成no。
43.247.91.228:84/Less-5/?id=1'
判断数据库库名的长度
访问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())>=3--+和' and length(database())>=4--+,我们可以构造这样的语句,然后观察页面的返回结果。
然后可以发现当数值为8时,返回的结果是yes;而当数值为9时,返回的结果是no。整个语句的意思是,数据库库名的长度大于等于8,结果为yes;大于等于9,结果为no,由此判断出数据库库名的长度为8。
利用substr判断数据库的库名
接着,使用逐字符判断的方式获取数据库库名。数据库库名的范围一般在a~z、0~9之间,可能还有一些特殊字符,这里的字母不区分大小写。逐字符判断的SQL语句为:
' and substr(database(),1,1)='t'--+
substr是截取的意思,其意思是截取database()的值,从第一个字符开始,每次只返回一个。
substr的用法跟limit的有区别,需要注意。limit是从0开始排序,而这里是从1开始排序。可以使用Burp的爆破功能爆破其中的't'值,发现当值是s时,页面返回yes,其他值均返回no,因此判断数据库库名的第一位为s。
其实还可以使用ASCII码的字符进行查询,s的ASCII码是115,而在MySQL中,ASCII转换的函数为ord,则逐字符判断的SQL语句应改为如下。
' and ord(substr(database(),1,1))=115--+
返回的结果是yes
判断数据库库名第二位字母是否是e,可以使用以下语句。
' and substr(database(),2,1)='e'--+
返回的结果是yes
利用substr判断数据库的表名
查询表名、字段名的语句也应粘贴在database()的位置,已经知道数据库'security'的第一个表名字母'e',判断语句如下。
' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e'--+
我们的结论是正确的,依此类推,就可以查询出所有的表名与字段名。