SUCTF2019-python-nginx

题目源码:

@app.route('/getUrl', methods = ['GET', 'POST']) 
def getUrl(): 
  url = request.args.get("url") 
  host = parse.urlparse(url).hostname
if host == 'suctf.cc': 
  return "我扌 your problem? 111"
parts = list(urlsplit(url)) 
host = parts[1]
if host == 'suctf.cc': 
  return "我扌 your problem? 222 " + host newhost = []
for h in host.split('.'): 
  newhost.append(h.encode('idna').decode('utf-8')) 
  parts[1] = '.'.join(newhost)
  # 去掉 url 中的空格 
  finalUrl = urlunsplit(parts).split(' ')[0] 
  host = parse.urlparse(finalUrl).hostname
if host == 'suctf.cc': 
  return urllib.request.urlopen(finalUrl).read()
else :
  return "我扌 your problem? 333"

方法一

该题的主要问题是在

h.encode(‘idna’).decode(‘utf-8’)

IDNA实际上是国际化域名

什么是IDN?

国际化域名(Internationalized Domain Name,IDN)又名特殊字符域名,是指部分或完全使用特殊文字或字母组成的互联网域名,包括中文、发育、阿拉伯语、希伯来语或拉丁字母等非英文字母,这些文字经过多字节万国码编码而成。在域名系统中,国际化域名使用punycode转写并以ASCII字符串存储。

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

利用脚本来跑可用字符:

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


发现可利用字符,获取flag:

方法二

利用两此urlsplit漏洞:
这道题不能让他为suctf.cc

但是经过了 urlunsplit 后变成 suctf.cc,很容易就构造出:file////:suctf.cc/usr/local/nginx/conf/nginx.conf,这样就能读取文件了。