【学习笔记16】buu [SUCTF 2019]Pythonginx

打开一看发现给了一堆代码这样看不方便我们就去查看源码

        @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"

源码给的不太全,但是给了两个提示,这时候我才想起来好像一开始开环境的时候,给了题目网站源码的位置,直接去github上找到源码

from flask import Flask, Blueprint, request, Response, escape ,render_template

from urllib.parse import urlsplit, urlunsplit, unquote

from urllib import parse

import urllib.request

app = Flask(__name__)

# Index

@app.route('/', methods=['GET'])

def app_index():

    return render_template('index.html')

@app.route('/getUrl', methods=['GET', 'POST'])//这以上就是声明一些路由和传参方式没什么太大的用处

def getUrl():

    url = request.args.get("url")//接收传进来的url

    host = parse.urlparse(url).hostname//主要是用于解析url中的参数  对url按照一定格式进行 拆分或拼接 

    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 = []//以上两个if判断就是检测传进来的是不是suctf.cc',如果是就报错

    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'://这里判断到如果为suctf.cc就可以执行读操作

        return urllib.request.urlopen(finalUrl, timeout=2).read()

    else:

        return "我扌 your problem? 333"

if __name__ == "__main__":

    app.run(host='0.0.0.0', port=80)

分析由于三个if判断都是检验是否为suctf.cc,但是我们想要得到flag还要绕过前两个if,只执行最后一个if这时候就看到这样一句话

newhost.append(h.encode('idna').decode('utf-8'))

意思是将域名每个部分进行idna编码后,再utf-8解码,所以我们的思路就是修改一下suctf.cc的格式让他最后可以变为suctf.cc就可以了这时候就可以利用℆来绕过,这样就可以进行文件读取,那首先来读一下nginx的配置文件

file://suctf.c℆sr/local/nginx/conf/nginx.conf

(后来看到有的大佬说的另一种绕过方式是利用ℂ来代替c及进行绕过)

找到了flag的位置,就在fffffflag里那就修改一下payload直接去读取这个文件

file://suctf.c℆sr/fffffflag

后来又查找了一些资料才知道这是blackhat议题之一HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization,blackhat这个议题的PPT链接如下:

https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf

你可能感兴趣的:(【学习笔记16】buu [SUCTF 2019]Pythonginx)