打開一看發(fā)現(xiàn)給了一堆代碼這樣看不方便我們就去查看源碼
? ? ? ? @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"
源碼給的不太全,但是給了兩個(gè)提示,這時(shí)候我才想起來好像一開始開環(huán)境的時(shí)候弄诲,給了題目網(wǎng)站源碼的位置挚冤,直接去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'])//這以上就是聲明一些路由和傳參方式?jīng)]什么太大的用處
def getUrl():
? ? url = request.args.get("url")//接收傳進(jìn)來的url
? ? host = parse.urlparse(url).hostname//主要是用于解析url中的參數(shù)? 對(duì)url按照一定格式進(jìn)行 拆分或拼接?
? ? 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 = []//以上兩個(gè)if判斷就是檢測(cè)傳進(jìn)來的是不是suctf.cc'济竹,如果是就報(bào)錯(cuò)
? ? 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就可以執(zhí)行讀操作
? ? ? ? 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)
分析由于三個(gè)if判斷都是檢驗(yàn)是否為suctf.cc趴荸,但是我們想要得到flag還要繞過前兩個(gè)if晌梨,只執(zhí)行最后一個(gè)if這時(shí)候就看到這樣一句話
newhost.append(h.encode('idna').decode('utf-8'))
意思是將域名每個(gè)部分進(jìn)行idna編碼后钙姊,再utf-8解碼毯辅,所以我們的思路就是修改一下suctf.cc的格式讓他最后可以變?yōu)閟uctf.cc就可以了這時(shí)候就可以利用?來繞過,這樣就可以進(jìn)行文件讀取煞额,那首先來讀一下nginx的配置文件
file://suctf.c?sr/local/nginx/conf/nginx.conf
(后來看到有的大佬說的另一種繞過方式是利用?來代替c及進(jìn)行繞過)
找到了flag的位置思恐,就在fffffflag里那就修改一下payload直接去讀取這個(gè)文件
file://suctf.c?sr/fffffflag
后來又查找了一些資料才知道這是blackhat議題之一HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization,blackhat這個(gè)議題的PPT鏈接如下: