第五十一题——[SUCTF 2019]Pythonginx

题目地址:https://buuoj.cn/challenges

解题思路

第一步:进入题目,看到一个提交框和源码

在这里插入图片描述

@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"
    </code>
    <!-- Dont worry about the suctf.cc. Go on! -->
    <!-- Do you know the nginx? -->

第二步:代码审计

  1. 从/getUrl页面取出参数,并使用parse.urlparse(url)对参数进行划分得到元组,获取其中的hostname值(现已改为netloc),并对host值进行判断若为suctf.cc则报错
  2. 将元组变为列表,并取出第二项对其判断若为suctf.cc,则报错
  3. 对列表里第二项的值以‘.’分割后进行idna编码后使用utf8解码,再用‘.’进行连接
  4. 对列表里的值去除空白字符串后使用urlunsplit函数重新生成URL
  5. 最后对重新生成URL取出host进行判断,若为suctf.cc,读出URL指定的文件内容

第三步:构建漏洞

  1. URL开头可以是http,可以是https,还可以是file。前两者用于访问页面,后者用于读取文件内容,所以我们可以使用file开头读取提示的nginx
  2. 由于使用函数parse.urlparse(url)对url各部分进行划分,当url协议后面满足://的格式时会将后面的第一级目录划定为hostname,当斜杠/数量不是2个时,即使是hostname,也不会识别
url = 'https://a9dedbc8-7d8c-4550-ac62-9e99eb016317.node3.buuoj.cn/'
print(parse.urlparse(url))
结果为:ParseResult(scheme='https', netloc='a9dedbc8-7d8c-4550-ac62-9e99eb016317.node3.buuoj.cn', path='/', params='', query='', fragment='')

url = 'https:/a9dedbc8-7d8c-4550-ac62-9e99eb016317.node3.buuoj.cn/'
print(parse.urlparse(url))
结果为:ParseResult(scheme='https', netloc='', path='/a9dedbc8-7d8c-4550-ac62-9e99eb016317.node3.buuoj.cn/', params='', query='', fragment='')
netloc值不一样
  1. 由于后面使用urlunsplit函数把URL剔除空格后还原,协议后面缺少的://会自动填补上,但是当协议后面的参数开头有两个//时,只补上:
  2. 经过2,3分析我们可以使file后面跟的/数量为4个,file:,这样使用parse.urlparse划分时,将hostname划分到path里面去了,在使用urlunsplit还原时,由于path里面有两个//,则不进行添加,最后由https:a9dedbc8-7d8c-4550-ac62-9e99eb016317.node3.buuoj.cn/变成了https://a9dedbc8-7d8c-4550-ac62-9e99eb016317.node3.buuoj.cn/,而file协议与路径之间有多少个/都不会影响file协议读取文件,file:///D:/jdk/1.txt能读取到1.txt,file:/D:/jdk/1.txt这样也能读取到

第四步:获取nginx配置文件

输入file:suctf.cc/usr/local/nginx/conf/nginx.conf,得到提示:/usr/fffffflag
在这里插入图片描述

第五步:获取flag

输入file:suctf.cc/usr/fffffflag获取flag
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值